#help_index "Help System" U8 *KeyMapKeyMStrPrint(I64 sc, U0 (*fp_handler)(I64 sc), U8 *desc, CTask *task = NULL) { I64 i = 9, k, c; U8 *st, *st2, *res, *ptr; CHashTable *old_hash = Fs->hash_table; st = ScanCode2KeyName(sc); if (sc & SCF_CTRL) i += 5; if (sc & SCF_ALT) i += 4; if (sc & (SCF_SHIFT | SCF_NO_SHIFT)) i += 6; if (TaskValidate(task)) Fs->hash_table = task->hash_table; st2 = SrcEdLink(fp_handler, 256); Fs->hash_table = old_hash; k = *desc(U32 *); if (k == 'Edit') c = BLUE; else if (k == 'Dol ') c = GREEN; else if (k == 'Cmd ') c = RED; else c = BLACK; res = MStrPrint("%-*s $FG,%d$$TX+UL+L+PU,\"%$Q\",A=\"%s\"$$FG$\n", i, st, c, desc, st2); Free(st); Free(st2); ptr = res; while (*ptr) ptr++; return res; } U0 KeyMapKeyPrint(I64 sc, U0 (*fp_handler)(I64 sc), U8 *desc, CTask *task = NULL) { U8 *st = KeyMapKeyMStrPrint(sc, fp_handler, desc, task); "%s", st; Free(st); } U0 KeyMapCtrlAltFamily(Bool no_shift, Bool shift) { I64 i, no_shift_f; if (no_shift && shift) no_shift_f = SCF_NO_SHIFT; else no_shift_f = 0; if (no_shift) KeyMapKeyPrint(SC_DELETE + SCF_CTRL + SCF_ALT + no_shift_f, &Reboot, "Cmd /Reboot"); if (no_shift) KeyMapKeyPrint(SC_ESC + SCF_CTRL + SCF_ALT + no_shift_f, &User, "Cmd /Terminal Window"); if (no_shift) KeyMapKeyPrint(SC_TAB + SCF_CTRL + SCF_ALT + no_shift_f, &WinToTop, "Cmd /Next Focus Task"); for (i = 0; i < 26; i++) if (keydev.fp_ctrl_alt_cbs[i]) { if (no_shift && keydev.ctrl_alt_no_shift_descs[i]) KeyMapKeyPrint(Char2ScanCode(i + 'a') + SCF_CTRL + SCF_ALT + no_shift_f, keydev.fp_ctrl_alt_cbs[i], keydev.ctrl_alt_no_shift_descs[i]); if (shift && keydev.ctrl_alt_shift_descs[i]) KeyMapKeyPrint(Char2ScanCode(i + 'a') + SCF_CTRL + SCF_ALT + SCF_SHIFT, keydev.fp_ctrl_alt_cbs[i], keydev.ctrl_alt_shift_descs[i]); } } U0 KMComparePrepare(U8 *buf, I64 *src) { I64 i, *dst = buf; U8 *ptr; if (src) { *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; *dst(U8 *) = 0; if (ptr = StrMatch("SHIFT", buf)) { for (i = 0; i < 5; i++) ptr[i] = CH_SPACE; if (ptr = StrMatch("$", buf)) *ptr = 255; } } else *buf=0; } I64 KMCompare(U8 *e1, U8 *e2) { U8 buf1[STR_LEN], buf2[STR_LEN]; KMComparePrepare(buf1, e1); KMComparePrepare(buf2, e2); return StrCompare(buf1, buf2); } U0 KeyMapFamily2(U8 **entries, CTask *task, I64 scf) { I64 i, arg1, arg2; for (i = 0; i < 256; i++) { arg2 = scf | i | SCF_KEY_DESC; arg1 = ScanCode2Char(arg2); *keydev.desc = 0; keydev.handler = NULL; if (TaskValidate(task) && !Bt(&task->win_inhibit, WIf_SELF_KEY_DESC)) { if (task == Fs) PutKey(arg1, arg2); else MessagePost(task, MESSAGE_KEY_DOWN, arg1, arg2); Refresh(0, TRUE); Sleep(1); //Open loop because might be no response. TODO: Drops messages. } if (*keydev.desc && StrNCompare(keydev.desc, "Char /",7)) entries[i] = KeyMapKeyMStrPrint(arg2, keydev.handler, keydev.desc, task); } } U0 KeyMapFamily(CTask *task, I64 scf, Bool no_shift, Bool shift) { I64 i, count=0; U8 **entries = CAlloc(2 * 256 * sizeof(U8 *)), **ptr = entries; if (no_shift) { if (shift) KeyMapFamily2(ptr, task, scf + SCF_NO_SHIFT); else KeyMapFamily2(ptr, task, scf); ptr += 256; count += 256; } if (shift) { KeyMapFamily2(ptr, task, scf + SCF_SHIFT); ptr += 256; count += 256; } QuickSortI64(entries,count, &KMCompare); for (i = 0;i < count; i++) if (entries[i]) { "%s", entries[i]; Free(entries[i]); } Free(entries); } public U0 KeyMap(CTask *task = NULL) {//Report desc of all keys. Bool old_key_desc; if (!task) task = Fs; old_key_desc = LBtr(&task->win_inhibit, WIf_SELF_KEY_DESC); DocMax; KeyMapFamily(task, 0, TRUE, TRUE); KeyMapFamily(task, SCF_CTRL, TRUE, TRUE); KeyMapFamily(task, SCF_ALT, TRUE, TRUE); KeyMapCtrlAltFamily(TRUE, TRUE); LBEqual(&task->win_inhibit, WIf_SELF_KEY_DESC, old_key_desc); "\nKeyMap Completed.\n"; } #help_index "Help System/Training" public U0 TipOfDay(U8 *tip_file = "::/Doc/Tips.DD") {//Print random tip-of-day from ::/Doc/Tips.DD. I64 i = RandU16; CDoc *doc = DocRead(tip_file), *doc2 = DocNew; CDocEntry *doc_e = doc->head.next; "$WW,1$\n"; while (TRUE) { if (doc_e->type_u8 == DOCT_TEXT && *doc_e->tag == '*') if (!i--) break; doc_e = doc_e->next; } if (doc_e->type_u8 == DOCT_TEXT && *doc_e->tag == '*') { while (doc_e != doc) { if (doc_e->type_u8 != DOCT_ERROR) DocInsEntry(doc2, DocEntryCopy(doc2, doc_e)); doc_e = doc_e->next; if (doc_e->type_u8 == DOCT_TEXT && *doc_e->tag == '*') break; } } DocInsDoc(DocPut, doc2); DocDel(doc2); DocDel(doc); }