static int keyboard_notifier_call(struct notifier_block *blk, unsigned long code, void *_param) { struct keyboard_notifier_param *param = _param; struct vc_data *vc = param->vc; int ret = NOTIFY_OK; if (!param->down) return ret; switch (code) { case KBD_KEYCODE: if (console_show) { if (param->value == BRAILLE_KEY) { console_show = 0; beep(880); vc_maybe_cursor_moved(vc); vc_refresh(vc); ret = NOTIFY_STOP; } } else { ret = NOTIFY_STOP; switch (param->value) { case KEY_INSERT: beep(440); console_show = 1; lastVC = -1; braille_write(console_buf); break; case KEY_LEFT: if (vc_x > 0) { vc_x -= WIDTH; if (vc_x < 0) vc_x = 0; } else if (vc_y >= 1) { beep(880); vc_y--; vc_x = vc->vc_cols-WIDTH; } else beep(220); break; case KEY_RIGHT: if (vc_x + WIDTH < vc->vc_cols) { vc_x += WIDTH; } else if (vc_y + 1 < vc->vc_rows) { beep(880); vc_y++; vc_x = 0; } else beep(220); break; case KEY_DOWN: if (vc_y + 1 < vc->vc_rows) vc_y++; else beep(220); break; case KEY_UP: if (vc_y >= 1) vc_y--; else beep(220); break; case KEY_HOME: vc_follow_cursor(vc); break; case KEY_PAGEUP: vc_x = 0; vc_y = 0; break; case KEY_PAGEDOWN: vc_x = 0; vc_y = vc->vc_rows-1; break; default: ret = NOTIFY_OK; break; } if (ret == NOTIFY_STOP) vc_refresh(vc); } break; case KBD_POST_KEYSYM: { unsigned char type = KTYP(param->value) - 0xf0; if (type == KT_SPEC) { unsigned char val = KVAL(param->value); int on_off = -1; switch (val) { case KVAL(K_CAPS): on_off = vc_kbd_led(kbd_table + fg_console, VC_CAPSLOCK); break; case KVAL(K_NUM): on_off = vc_kbd_led(kbd_table + fg_console, VC_NUMLOCK); break; case KVAL(K_HOLD): on_off = vc_kbd_led(kbd_table + fg_console, VC_SCROLLOCK); break; } if (on_off == 1) beep(880); else if (on_off == 0) beep(440); } } case KBD_UNBOUND_KEYCODE: case KBD_UNICODE: case KBD_KEYSYM: /* Unused */ break; } return ret; }
static int vt_notifier_call(struct notifier_block *blk, unsigned long code, void *_param) { struct vt_notifier_param *param = _param; struct vc_data *vc = param->vc; switch (code) { case VT_ALLOCATE: break; case VT_DEALLOCATE: break; case VT_WRITE: { unsigned char c = param->c; if (vc->vc_num != fg_console) break; switch (c) { case '\b': case 127: if (console_cursor > 0) { console_cursor--; console_buf[console_cursor] = ' '; } break; case '\n': case '\v': case '\f': case '\r': console_newline = 1; break; case '\t': c = ' '; /* Fallthrough */ default: if (c < 32) /* Ignore other control sequences */ break; if (console_newline) { memset(console_buf, 0, sizeof(console_buf)); console_cursor = 0; console_newline = 0; } if (console_cursor == WIDTH) memmove(console_buf, &console_buf[1], (WIDTH-1) * sizeof(*console_buf)); else console_cursor++; console_buf[console_cursor-1] = c; break; } if (console_show) braille_write(console_buf); else { vc_maybe_cursor_moved(vc); vc_refresh(vc); } break; } case VT_UPDATE: /* Maybe a VT switch, flush */ if (console_show) { if (vc->vc_num != lastVC) { lastVC = vc->vc_num; memset(console_buf, 0, sizeof(console_buf)); console_cursor = 0; braille_write(console_buf); } } else { vc_maybe_cursor_moved(vc); vc_refresh(vc); } break; } return NOTIFY_OK; }
/* process vgpane methods */ static int vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc, char *argv[]) { int vargc, length, i, j, n, result; char c, *s, **vargv, vbuf[30]; vgpane_t *vgp, **vgpp; point p, q, *ps; poly *tpp; double alpha, gain; Pvector_t slopes[2]; Ppolyline_t line, spline; int pp, qp; /* polygon indices for p, q */ Pedge_t *barriers; int n_barriers; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", " ", argv[0], " method ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } if (!(vgpp = (vgpane_t **) tclhandleXlate(vgpaneTable, argv[0]))) { Tcl_AppendResult(interp, "Invalid handle: \"", argv[0], "\"", (char *) NULL); return TCL_ERROR; } vgp = *vgpp; c = argv[1][0]; length = strlen(argv[1]); if ((c == 'c') && (strncmp(argv[1], "coords", length) == 0)) { if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id ?x1 y1 x2 y2...?\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } if (argc == 3) { /* find poly and return its coordinates */ for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { n = vgp->poly[i].boundary.pn; for (j = 0; j < n; j++) { appendpoint(interp, vgp->poly[i].boundary.ps[j]); } return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } /* accept either inline or delimited list */ if ((argc == 4)) { result = Tcl_SplitList(interp, argv[3], &vargc, (CONST84 char ***) &vargv); if (result != TCL_OK) { return result; } } else { vargc = argc - 3; vargv = &argv[3]; } if (!vargc || vargc % 2) { Tcl_AppendResult(interp, "There must be a multiple of two terms in the list.", (char *) NULL); return TCL_ERROR; } /* remove old poly, add modified polygon to the end with the same id as the original */ if (!(remove_poly(vgp, polyid))) { Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } return (insert_poly(interp, vgp, polyid, vargv, vargc)); } else if ((c == 'd') && (strncmp(argv[1], "debug", length) == 0)) { /* debug only */ printf("debug output goes here\n"); return TCL_OK; } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) { /* delete a vgpane and all memory associated with it */ if (vgp->vc) Pobsclose(vgp->vc); free(vgp->poly); /* ### */ Tcl_DeleteCommand(interp, argv[0]); free((char *) tclhandleFree(vgpaneTable, argv[0])); return TCL_OK; } else if ((c == 'f') && (strncmp(argv[1], "find", length) == 0)) { /* find the polygon that the point is inside and return it id, or null */ if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " x y\"", (char *) NULL); return TCL_ERROR; } if (argc == 3) { result = Tcl_SplitList(interp, argv[2], &vargc, (CONST84 char ***) &vargv); if (result != TCL_OK) { return result; } } else { vargc = argc - 2; vargv = &argv[2]; } result = scanpoint(interp, &vargv[0], &p); if (result != TCL_OK) return result; /* determine the polygons (if any) that contain the point */ for (i = 0; i < vgp->Npoly; i++) { if (in_poly(vgp->poly[i].boundary, p)) { sprintf(vbuf, "%d", vgp->poly[i].id); Tcl_AppendElement(interp, vbuf); } } return TCL_OK; } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0)) { /* add poly to end poly list, and it coordinates to the end of the point list */ if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " x1 y1 x2 y2 ...\"", (char *) NULL); return TCL_ERROR; } /* accept either inline or delimited list */ if ((argc == 3)) { result = Tcl_SplitList(interp, argv[2], &vargc, (CONST84 char ***) &vargv); if (result != TCL_OK) { return result; } } else { vargc = argc - 2; vargv = &argv[2]; } if (!vargc || vargc % 2) { Tcl_AppendResult(interp, "There must be a multiple of two terms in the list.", (char *) NULL); return TCL_ERROR; } polyid++; result = insert_poly(interp, vgp, polyid, vargv, vargc); if (result != TCL_OK) return result; sprintf(vbuf, "%d", polyid); Tcl_AppendResult(interp, vbuf, (char *) NULL); return TCL_OK; } else if ((c == 'l') && (strncmp(argv[1], "list", length) == 0)) { /* return list of polygon ids */ for (i = 0; i < vgp->Npoly; i++) { sprintf(vbuf, "%d", vgp->poly[i].id); Tcl_AppendElement(interp, vbuf); } return TCL_OK; } else if ((c == 'p') && (strncmp(argv[1], "path", length) == 0)) { /* return a list of points corresponding to the shortest path that does not cross the remaining "visible" polygons. */ if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " x1 y1 x2 y2\"", (char *) NULL); return TCL_ERROR; } if (argc == 3) { result = Tcl_SplitList(interp, argv[2], &vargc, (CONST84 char ***) &vargv); if (result != TCL_OK) { return result; } } else { vargc = argc - 2; vargv = &argv[2]; } if ((vargc < 4)) { Tcl_AppendResult(interp, "invalid points: should be: \"x1 y1 x2 y2\"", (char *) NULL); return TCL_ERROR; } result = scanpoint(interp, &vargv[0], &p); if (result != TCL_OK) return result; result = scanpoint(interp, &vargv[2], &q); if (result != TCL_OK) return result; /* only recompute the visibility graph if we have to */ if ((vc_refresh(vgp))) { Pobspath(vgp->vc, p, POLYID_UNKNOWN, q, POLYID_UNKNOWN, &line); for (i = 0; i < line.pn; i++) { appendpoint(interp, line.ps[i]); } } return TCL_OK; } else if ((c == 'b') && (strncmp(argv[1], "bind", length) == 0)) { if ((argc < 2) || (argc > 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " bind triangle ?command?\"", (char *) NULL); return TCL_ERROR; } if (argc == 2) { Tcl_AppendElement(interp, "triangle"); return TCL_OK; } length = strlen(argv[2]); if (strncmp(argv[2], "triangle", length) == 0) { s = vgp->triangle_cmd; if (argc == 4) vgp->triangle_cmd = s = buildBindings(s, argv[3]); } else { Tcl_AppendResult(interp, "unknown event \"", argv[2], "\": must be one of:\n\ttriangle.", (char *) NULL); return TCL_ERROR; } if (argc == 3) Tcl_AppendResult(interp, s, (char *) NULL); return TCL_OK; } else if ((c == 'b') && (strncmp(argv[1], "bpath", length) == 0)) { /* return a list of points corresponding to the shortest path that does not cross the remaining "visible" polygons. */ if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " x1 y1 x2 y2\"", (char *) NULL); return TCL_ERROR; } if (argc == 3) { result = Tcl_SplitList(interp, argv[2], &vargc, (CONST84 char ***) &vargv); if (result != TCL_OK) { return result; } } else { vargc = argc - 2; vargv = &argv[2]; } if ((vargc < 4)) { Tcl_AppendResult(interp, "invalid points: should be: \"x1 y1 x2 y2\"", (char *) NULL); return TCL_ERROR; } result = scanpoint(interp, &vargv[0], &p); if (result != TCL_OK) return result; result = scanpoint(interp, &vargv[2], &q); if (result != TCL_OK) return result; /* determine the polygons (if any) that contain the endpoints */ pp = qp = POLYID_NONE; for (i = 0; i < vgp->Npoly; i++) { tpp = &(vgp->poly[i]); if ((pp == POLYID_NONE) && in_poly(tpp->boundary, p)) pp = i; if ((qp == POLYID_NONE) && in_poly(tpp->boundary, q)) qp = i; } if (vc_refresh(vgp)) { /*Pobspath(vgp->vc, p, pp, q, qp, &line); */ Pobspath(vgp->vc, p, POLYID_UNKNOWN, q, POLYID_UNKNOWN, &line); make_barriers(vgp, pp, qp, &barriers, &n_barriers); slopes[0].x = slopes[0].y = 0.0; slopes[1].x = slopes[1].y = 0.0; Proutespline(barriers, n_barriers, line, slopes, &spline); for (i = 0; i < spline.pn; i++) { appendpoint(interp, spline.ps[i]); } } return TCL_OK; } else if ((c == 'b') && (strncmp(argv[1], "bbox", length) == 0)) { if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { Ppoly_t pp = vgp->poly[i].boundary; point LL, UR; LL = UR = pp.ps[0]; for (j = 1; j < pp.pn; j++) { p = pp.ps[j]; if (p.x > UR.x) UR.x = p.x; if (p.y > UR.y) UR.y = p.y; if (p.x < LL.x) LL.x = p.x; if (p.y < LL.y) LL.y = p.y; } appendpoint(interp, LL); appendpoint(interp, UR); return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } else if ((c == 'c') && (strncmp(argv[1], "center", length) == 0)) { if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { appendpoint(interp, center(vgp->poly[i].boundary.ps, vgp->poly[i].boundary.pn)); return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } else if ((c == 't') && (strncmp(argv[1], "triangulate", length) == 0)) { if ((argc < 2)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " id ", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { Ptriangulate(&(vgp->poly[i].boundary), triangle_callback, vgp); return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } else if ((c == 'r') && (strncmp(argv[1], "rotate", length) == 0)) { if ((argc < 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id alpha\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } if (sscanf(argv[3], "%lg", &alpha) != 1) { Tcl_AppendResult(interp, "not an angle in radians: ", argv[3], (char *) NULL); return TCL_ERROR; } for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { n = vgp->poly[i].boundary.pn; ps = vgp->poly[i].boundary.ps; p = center(ps, n); for (j = 0; j < n; j++) { appendpoint(interp, rotate(p, ps[j], alpha)); } return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } else if ((c == 's') && (strncmp(argv[1], "scale", length) == 0)) { if ((argc < 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id gain\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } if (sscanf(argv[3], "%lg", &gain) != 1) { Tcl_AppendResult(interp, "not a number: ", argv[3], (char *) NULL); return TCL_ERROR; } for (i = 0; i < vgp->Npoly; i++) { if (vgp->poly[i].id == polyid) { n = vgp->poly[i].boundary.pn; ps = vgp->poly[i].boundary.ps; for (j = 0; j < n; j++) { appendpoint(interp, scale(p, ps[j], gain)); } return TCL_OK; } } Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } else if ((c == 'r') && (strncmp(argv[1], "remove", length) == 0)) { if ((argc < 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", argv[1], " id\"", (char *) NULL); return TCL_ERROR; } if (sscanf(argv[2], "%d", &polyid) != 1) { Tcl_AppendResult(interp, "not an integer: ", argv[2], (char *) NULL); return TCL_ERROR; } if (remove_poly(vgp, polyid)) return TCL_OK; Tcl_AppendResult(interp, " no such polygon: ", argv[2], (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, "bad method \"", argv[1], "\" must be one of:", "\n\tbbox, bind, bpath, center, coords, delete, find,", "\n\tinsert, list, path, remove, rotate, scale, triangulate.", (char *) NULL); return TCL_ERROR; }