static void setSessionEntry (void) { describeScreen(&scr); if (scr.number == -1) scr.number = userVirtualTerminal(0); { typedef enum {SAME, DIFFERENT, FIRST} State; State state = (!ses)? FIRST: (scr.number == ses->number)? SAME: DIFFERENT; if (state != SAME) { ses = getSessionEntry(scr.number); if (state == FIRST) { pushCommandEnvironment("main", preprocessCommand, postprocessCommand); pushCommandHandler("unhandled", KTB_CTX_DEFAULT, handleUnhandledCommand, NULL); #ifdef ENABLE_SPEECH_SUPPORT pushCommandHandler("speech", KTB_CTX_DEFAULT, handleSpeechCommand, NULL); #endif /* ENABLE_SPEECH_SUPPORT */ pushCommandHandler("navigation", KTB_CTX_DEFAULT, handleNavigationCommand, NULL); pushCommandHandler("screen", KTB_CTX_DEFAULT, handleScreenCommand, NULL); } } } }
static void postprocessCommand (void *state, int command, int handled) { PrecommandState *pre = state; if (pre) { resumeUpdates(0); if (handled) scheduleUpdate("command executed"); if ((ses->winx != pre->motionColumn) || (ses->winy != pre->motionRow)) { /* The window has been manually moved. */ ses->motx = ses->winx; ses->moty = ses->winy; #ifdef ENABLE_CONTRACTED_BRAILLE isContracted = 0; #endif /* ENABLE_CONTRACTED_BRAILLE */ #ifdef ENABLE_SPEECH_SUPPORT if (ses->trackCursor && spk.track.isActive && (scr.number == spk.track.screenNumber)) { ses->trackCursor = 0; playTune(&tune_cursor_unlinked); } #endif /* ENABLE_SPEECH_SUPPORT */ } if (!(command & BRL_MSK_BLK)) { if (command & BRL_FLG_MOTION_ROUTE) { int left = ses->winx; int right = MIN(left+textCount, scr.cols) - 1; int top = ses->winy; int bottom = MIN(top+brl.textRows, scr.rows) - 1; if ((scr.posx < left) || (scr.posx > right) || (scr.posy < top) || (scr.posy > bottom)) { if (routeCursor(MIN(MAX(scr.posx, left), right), MIN(MAX(scr.posy, top), bottom), scr.number)) { playTune(&tune_routing_started); checkRoutingStatus(ROUTING_WRONG_COLUMN, 1); { ScreenDescription description; describeScreen(&description); if (description.number == scr.number) { slideWindowVertically(description.posy); placeWindowHorizontally(description.posx); } } } } } } free(pre); } }
static int getCurrentPosition (RoutingData *routing) { ScreenDescription description; describeScreen(&description); if (description.number != routing->screenNumber) { logRouting("screen changed: num=%d", description.number); routing->screenNumber = description.number; return 0; } if (!routing->rowBuffer) { routing->screenRows = description.rows; routing->screenColumns = description.cols; routing->verticalDelta = 0; if (!(routing->rowBuffer = calloc(routing->screenColumns, sizeof(*routing->rowBuffer)))) { logMallocError(); goto error; } logRouting("screen: num=%d cols=%d rows=%d", routing->screenNumber, routing->screenColumns, routing->screenRows); } else if ((routing->screenRows != description.rows) || (routing->screenColumns != description.cols)) { logRouting("size changed: cols=%d rows=%d", description.cols, description.rows); goto error; } routing->cury = description.posy - routing->verticalDelta; routing->curx = description.posx; if (readScreenRow(routing, NULL, description.posy)) return 1; logRouting("read failed: row=%d", description.posy); error: routing->screenNumber = -1; return 0; }
int cpbLinearCopy (int column, int row) { int copied = 0; ScreenDescription screen; describeScreen(&screen); { int rightColumn = screen.cols - 1; size_t length; wchar_t *buffer = cpbReadScreen(&length, 0, beginRow, rightColumn, row); if (buffer) { if (column < rightColumn) { wchar_t *start = buffer + length; while (start != buffer) { if (*--start == WC_C('\r')) { start += 1; break; } } { int adjustment = (column + 1) - (buffer + length - start); if (adjustment < 0) length += adjustment; } } if (beginColumn) { wchar_t *start = wmemchr(buffer, WC_C('\r'), length); if (!start) start = buffer + length; if ((start - buffer) > beginColumn) start = buffer + beginColumn; if (start != buffer) wmemmove(buffer, start, (length -= start - buffer)); } { const wchar_t *from = buffer; const wchar_t *end = from + length; wchar_t *to = buffer; int spaces = 0; int newlines = 0; while (from != end) { wchar_t character = *from++; switch (character) { case WC_C(' '): spaces += 1; continue; case WC_C('\r'): newlines += 1; continue; default: break; } if (newlines) { if ((newlines > 1) || (spaces > 0)) spaces = 1; newlines = 0; } while (spaces) { *to++ = WC_C(' '); spaces -= 1; } *to++ = character; } length = to - buffer; } if (cpbEndOperation(buffer, length)) copied = 1; free(buffer); } } return copied; }
int main (int argc, char *argv[]) { ProgramExitStatus exitStatus; void *driverObject; { static const OptionsDescriptor descriptor = { OPTION_TABLE(programOptions), .applicationName = "scrtest", .argumentsSummary = "[parameter=value ...]" }; PROCESS_OPTIONS(descriptor, argc, argv); } if ((screen = loadScreenDriver(opt_screenDriver, &driverObject, opt_driversDirectory))) { const char *const *parameterNames = getScreenParameters(screen); char **parameterSettings; if (!parameterNames) { static const char *const noNames[] = {NULL}; parameterNames = noNames; } { const char *const *name = parameterNames; unsigned int count; char **setting; while (*name) ++name; count = name - parameterNames; if (!(parameterSettings = malloc((count + 1) * sizeof(*parameterSettings)))) { logMallocError(); return PROG_EXIT_FATAL; } setting = parameterSettings; while (count--) *setting++ = ""; *setting = NULL; } while (argc) { char *assignment = *argv++; int ok = 0; char *delimiter = strchr(assignment, '='); if (!delimiter) { logMessage(LOG_ERR, "missing screen parameter value: %s", assignment); } else if (delimiter == assignment) { logMessage(LOG_ERR, "missing screen parameter name: %s", assignment); } else { size_t nameLength = delimiter - assignment; const char *const *name = parameterNames; while (*name) { if (strncasecmp(assignment, *name, nameLength) == 0) { parameterSettings[name - parameterNames] = delimiter + 1; ok = 1; break; } ++name; } if (!ok) logMessage(LOG_ERR, "invalid screen parameter: %s", assignment); } if (!ok) return PROG_EXIT_SYNTAX; --argc; } if (constructScreenDriver(parameterSettings)) { ScreenDescription description; int left, top, width, height; describeScreen(&description); printf("Screen: %dx%d\n", description.cols, description.rows); printf("Cursor: [%d,%d]\n", description.posx, description.posy); if (setRegion(&left, opt_boxLeft, "starting column", &width, opt_boxWidth, description.cols, "region width")) { if (setRegion(&top, opt_boxTop, "starting row", &height, opt_boxHeight, description.rows, "region height")) { printf("Region: %dx%d@[%d,%d]\n", width, height, left, top); { ScreenCharacter buffer[width * height]; if (readScreen(left, top, width, height, buffer)) { int line; for (line=0; line<height; line++) { int column; for (column=0; column<width; column++) { wchar_t character = buffer[line * width + column].text; if (!iswLatin1(character)) { putchar('?'); } else if (!isprint(character)) { putchar('*'); } else { putchar(character); } } putchar('\n'); } exitStatus = PROG_EXIT_SUCCESS; } else { logMessage(LOG_ERR, "Can't read screen."); exitStatus = PROG_EXIT_FATAL; } } } else { exitStatus = PROG_EXIT_SYNTAX; } } else { exitStatus = PROG_EXIT_SYNTAX; } } else { logMessage(LOG_ERR, "can't open screen."); exitStatus = PROG_EXIT_FATAL; } destructScreenDriver(); } else { logMessage(LOG_ERR, "can't load screen driver."); exitStatus = PROG_EXIT_FATAL; } return exitStatus; }