/* ** brl.c for eutp in /home/obert01/work/eutp/src ** ** Made by Olivier BERT ** Login */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 500 #endif /* _XOPEN_SOURCE */ /* globals */ unsigned char extensions[] = {'K', 'L', 'B', 'T', 'A'}; unsigned char positions[] = {3, 7, 16}; #include #include #include #include #include #include #include "brlapi.h" #include #include #include "eutp_brl.h" #include "eutp_pc.h" #include "eutp_tools.h" #include "eutp_transfer.h" void eutp_abort(int exitstatus) { brlapi_leaveRawMode(); brlapi_closeConnection(); exit(exitstatus); } /* ** Asks a Yes/No question. ** If the user says Yes (key # pressed) the function returns 1. ** IF the answer is No (key * pressed) the function return 0. */ int brl_yesno_question(char *prompt) { unsigned char buf[BUFFER_SIZE]; brl_message(prompt, 0); while (1) { brl_read(buf); if (!strncmp((char*)buf, "\003KT#", 4)) return 1; if (!strncmp((char*)buf, "\003KT*", 4)) return 0; } } /* ** Read raw data from the terminal */ ssize_t brl_read(unsigned char *buf) { ssize_t res; while (1) { alarm(20); res = brlapi_recvRaw(buf, BUFFER_SIZE); alarm(0); if (res < 0) { brlapi_perror("reading on terminal"); eutp_abort(E_READ); return 0; } if (res) break; } return res; } ssize_t brl_write(unsigned char *str, size_t len) { ssize_t res; alarm(20); res = brlapi_sendRaw(str, len); alarm(0); if (res < 0) { brlapi_perror("Error writing to the terminal"); eutp_abort(E_WRITE); return 0; } return res; } /* ** Get model identification ** ident must be a buffer of at least 20 bytes. */ void get_ident(char* ident) { char buf[256]; char *p; unsigned char ln = 0; brl_writeStr("SI"); brl_read((unsigned char*)buf); p = buf; while (1) { ln = *(p++); if (ln == 22 && !strncmp(p, "SI", 2)) { memcpy(ident, p + 2, 20); break; } else p += ln; } } /* ** Write a string to the terminal ** The string is supposed terminated by a \0 character */ void brl_writeStr(char *str) { brl_write((unsigned char*)str, strlen(str)); } /* ** Initialize the application and connect to brlapi ** Init brlapi raw mode and print a welcome message on the terminal */ int brl_init(t_env *env) { int res; char p[100]; unsigned int x, y; /* Connect to BrlAPI */ if (brlapi_initializeConnection(NULL, NULL) < 0) { brlapi_perror("brlapi_initializeConnection"); return -1; } /* Get driver id & name */ res = brlapi_getDriverName(p, sizeof(p)); if (res == -1) brlapi_perror("brlapi_getDriverName"); else printf("Driver name: %s\n",p); /* Get display size */ if (brlapi_getDisplaySize(&x, &y) < 0) brlapi_perror("brlapi_getDisplaySize"); else printf("Braille display has %d line%s of %d column%s\n",y,y>1?"s":"",x,x>1?"s":""); /* Try entering raw mode, immediately go out from raw mode */ printf("Trying to enter in raw mode... "); if (brlapi_enterRawMode("EuroBraille") < 0) brlapi_perror("brlapi_getRaw"); else { printf("Ok\n"); } /* welcome message */ brl_lasting_message(EUTP_VERSION); get_ident(env->ident); printf("Identification: %20s\n", env->ident); return 0; } /* ** Closes the connection to BRLAPI */ int brl_close(void) { brlapi_leaveRawMode(); brlapi_closeConnection(); return 0; } /* ** Displays a message to the braille terminal ** The cursor can be positionned with the second argument */ int brl_message(char *str, unsigned char cursorpos) { int ret = 0; unsigned int len = strlen((char*)str); char* q = str; unsigned char i = 1; unsigned char* buffer = malloc(512); unsigned char* p = buffer; *p++ = 'D'; *p++ = 'M'; while (*q) { if (cursorpos >= 1 && i == cursorpos) { *p++ = '\x1b'; *p++ = '\x02'; } *p++ = *q++; i++; } brl_write(buffer, cursorpos == 0 ? len + 2 : len + 4); free(buffer); return ret; } static int showbrfile(t_env* env) { unsigned char cursorpos = positions[env->status]; unsigned char ext = extensions[env->curext]; unsigned char* buf = malloc(256); unsigned char* str = malloc(256); /* the string to display */ buf[0] = '\005'; buf[1] = 'F'; buf[2] = 'N'; buf[3] = ext; buf[4] = (env->brfilenum & 0xff00) >> 2; buf[5] = env->brfilenum & 0x00ff; brl_write(buf+1, 5); while (1) { brl_read(buf); if (!strncmp((char*)buf, "\003KT", 3)) continue; else break; } if (!strncmp((char*)buf, "\003FE", 3)) { env->brfilenum--; return 0; } strcpy((char*)str, env->brpc ? "BR>PC " : "PC>BR "); strncat((char*)str, ((char*)&(buf[6])), buf[0] - 5); strcat((char*)str, "."); strncat((char*)str, (char*)&ext, 1); brl_message((char*)str, cursorpos); free(buf); free(str); return 0; } /* ** Show the list of files either of the braille terminal or of the PC ** It is the main loop of the program. */ int brl_listfiles(t_env* env) { unsigned char end = 0; unsigned char* buf = malloc(256); env->curext = 0; env->brpc = 1; env->brfilenum = 1; env->pcfilenum = 0; env->status = 1; while (!end) { if (env->brpc == 1) showbrfile(env); else showpcfiles(env); brl_read(buf); if (!strncmp("\003KT*", (char*)buf, 4)) end = 1; if (!strncmp("\003KT4", (char*)buf, 4) && env->status) env->status--; if (!strncmp("\003KT6", (char*)buf, 4) && ((env->status != 2 && env->brpc) || (!env->brpc && env->status != 1))) env->status++; if (!strncmp("\003KT8", (char*)buf, 4)) { if (env->status == 0) env->brpc = !env->brpc; if (env->status == 1 && env->brpc) env->brfilenum++; if (env->status == 1 && !env->brpc && env->pcfilenum < env->n - 1) env->pcfilenum++; if (env->status == 2 && env->curext < MAXENT - 1) env->curext++, env->brfilenum = 1; } if (!strncmp("\003KT2", (char*)buf, 4)) { if (env->status == 0) env->brpc = !env->brpc; if (env->status == 1 && env->brfilenum > 1 && env->brpc) env->brfilenum--; if (env->status == 1 && env->pcfilenum > 0) env->pcfilenum--; if (env->status == 2 && env->curext > 0) env->curext--, env->brfilenum = 1; } if (!strncmp("\003KT#", (char*)buf, 4)) { if (env->brpc) { if (!brtopc(env)) end = 1; } else { if (!pctobr(env)) end = 1; } } } free(buf); return 0; }