U0 PutKey(I64 ch=0, I64 sc=0) {//See Keyboard Devices. CKeyDevEntry *tmpk; if (ch || sc) { tmpk = keydev.put_key_head.next; if (!Bt(&Fs->display_flags, DISPLAYf_SILENT)) { if (kbd.scan_code & SCF_SCROLL && sys_focus_task == Fs) while (kbd.scan_code & SCF_SCROLL) Yield; //Wait on SCROLL LOCK Key while (tmpk != &keydev.put_key_head) { if ((!(sc & SCF_KEY_DESC) || tmpk->flags & KDF_HAS_DESCS) && (*tmpk->put_key)(ch, sc)) break; tmpk = tmpk->next; } } } } U0 PutChars(U64 ch) {//Output chars. Up to 8 chars in a single U64. //Don't use this. See Print() shortcut. while (ch) { PutKey(ch & 255, 0); ch >>= 8; } } U0 PutS(U8 *st) {//Use Print(). See Keyboard Devices. //Don't use this. See Print() shortcut. I64 ch; U8 *ptr; Bool cont = TRUE; if (!st) return; CKeyDevEntry *tmpk = keydev.put_key_head.next; if (!Bt(&Fs->display_flags, DISPLAYf_SILENT)) { if (kbd.scan_code & SCF_SCROLL && sys_focus_task == Fs) while (kbd.scan_code & SCF_SCROLL) Yield; while (cont && tmpk != &keydev.put_key_head) { if (tmpk->put_s) { if ((*tmpk->put_s)(st)) break; } else { ptr = st; while (ch = *ptr++) if ((*tmpk->put_key)(ch, 0)) cont = FALSE; } tmpk = tmpk->next; } } } U0 KeyDescSet(U8 *format, ...) {//Call this from key handler to report description in KeyMap(). U8 *buf = StrPrintJoin(NULL, format, argc, argv); StrCopy(keydev.desc, buf); keydev.handler = Caller; Free(buf); } U0 KeyDevRemove(CKeyDevEntry *tmpk) {//Remove StdOut hook and free. QueueRemove(tmpk); Free(tmpk); } CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch, I64 sc), Bool (*fp_puts)(U8 *st), I64 priority, Bool key_descs=FALSE) {//Places hook in StdOut chain. See Keyboard Devices. CKeyDevEntry *tmpk = keydev.put_key_head.last, *tmpk1 = SysCAlloc(sizeof(CKeyDevEntry)); tmpk1->put_key = fp_put_key; tmpk1->put_s = fp_puts; tmpk1->priority = priority; if (key_descs) tmpk1->flags |= KDF_HAS_DESCS; while (tmpk->priority > priority) tmpk = tmpk->last; QueueInsert(tmpk1, tmpk); if (tmpk->priority == priority) KeyDevRemove(tmpk); return tmpk1; } Bool KDRawPutKey(I64 ch, I64) { if (IsRaw) { RawPutChar(ch); return TRUE; } else return FALSE; } Bool KDRawPutS(U8 *st) { I64 ch; if (IsRaw) { while (ch = *st++) RawPutChar(ch); return TRUE; } else return FALSE; } Bool KDInputFilterPutKey(I64 ch, I64 scan_code) { if (Bt(&Fs->task_flags, TASKf_INPUT_FILTER_TASK)) { Message(MESSAGE_KEY_DOWN, ch, scan_code); return TRUE; } else return FALSE; } Bool KDInputFilterPutS(U8 *st) { I64 ch; if (Bt(&Fs->task_flags, TASKf_INPUT_FILTER_TASK)) { while (ch = *st++) Message(MESSAGE_KEY_DOWN, ch, 0); return TRUE; } else return FALSE; } U0 CtrlAltDel(I64) { LBts(sys_ctrl_alt_flags, CTRL_ALT_DEL); } U0 CtrlAltC(I64) { LBts(sys_ctrl_alt_flags, CTRL_ALT_C); } U0 CtrlAltD(I64) { if (!IsDebugMode) { if (Fs == Gs->idle_task) BptS(sys_winmgr_task->rip, sys_winmgr_task); else BptS(*keydev.ctrl_alt_ret_addr); } } U0 CtrlAltF(I64) { SwapI64(&text.font, &text.aux_font); } U0 CtrlAltM(I64) { Mute(!IsMute); } U0 CtrlAltN(I64) { LBts(sys_ctrl_alt_flags, CTRL_ALT_TAB); } U0 CtrlAltT(I64) { User; } U0 CtrlAltV(I64) { LFBFlush; text.is_fb_busy = FALSE; } U0 CtrlAltX(I64) { LBts(sys_ctrl_alt_flags, CTRL_ALT_X); } U0 CtrlAltCBSet(U8 ch, U0 (*fp_handler)(I64 sc), U8 *no_shift_desc=NULL, U8 *shift_desc=NULL, Bool in_irq=FALSE) {//Set callback for <CTRL-ALT-letter>. ch = ToUpper(ch) - 'A'; if (ch < 26) { keydev.fp_ctrl_alt_cbs[ch] = fp_handler; Free(keydev.ctrl_alt_no_shift_descs[ch]); if (no_shift_desc) keydev.ctrl_alt_no_shift_descs[ch] = SysStrNew(no_shift_desc); else keydev.ctrl_alt_no_shift_descs[ch] = NULL; Free(keydev.ctrl_alt_shift_descs[ch]); if (shift_desc) keydev.ctrl_alt_shift_descs[ch] = SysStrNew(shift_desc); else keydev.ctrl_alt_shift_descs[ch] = NULL; BEqual(&keydev.ctrl_alt_in_irq_flags, ch, in_irq); } } U0 KeyDevInit() { keydev.fp_ctrl_alt_cbs = CAlloc(26 * sizeof(U8 *)); keydev.ctrl_alt_no_shift_descs = CAlloc(26 * sizeof(U8 *)); keydev.ctrl_alt_shift_descs = CAlloc(26 * sizeof(U8 *)); keydev.ctrl_alt_in_irq_flags = 0; MemSet(&keydev.put_key_head, 0, sizeof(CKeyDevEntry)); QueueInit(&keydev.put_key_head); KeyDevAdd(&KDInputFilterPutKey, &KDInputFilterPutS, 0x40000000, FALSE); KeyDevAdd(&KDRawPutKey, &KDRawPutS, 0x60000000, FALSE); CtrlAltCBSet('C', &CtrlAltC, "Cmd /Break Execution",, TRUE); CtrlAltCBSet('D', &CtrlAltD, "Cmd /Enter Debugger",, TRUE); CtrlAltCBSet('F', &CtrlAltF, "Cmd /Toggle Aux Font"); CtrlAltCBSet('M', &CtrlAltM, "Cmd /Toggle Mute"); CtrlAltCBSet('N', &CtrlAltN, "Cmd /Next Focus Task",, TRUE); CtrlAltCBSet('T', &CtrlAltT, "Cmd /Terminal Window"); CtrlAltCBSet('V', &CtrlAltV, "Cmd /Video Framebuffer Flush",, TRUE); CtrlAltCBSet('X', &CtrlAltX, "Cmd /Kill Focused Task",, TRUE); }