/* * conversion from key top code to key code */ EXPORT UH kpToKeycode( KeyTop keytop, KpMetaBut *meta ) { #define keyTab kbdef->keyDef.keytab KbDef *kbdef; W sel; UH code; kbdef = GetKbDef(meta->o.kbsel, keytop.u.kid); if ( kbdef == NULL ) { /* if keytable for kbsel does not exist, then use keyboard definition 1 (kbsel=0) */ kbdef = GetKbDef(0, keytop.u.kid); if ( kbdef == NULL ) return InvalidKeycode; } if ( keytop.u.kcode >= keyTab.keymax ) return InvalidKeycode; sel = (*(UW*)meta & 0xfc) >> 2; code = keyTab.kct[keyTab.keymax * keyTab.kctsel[sel] + keytop.u.kcode]; return code; #undef keyTab }
/* * key top code after addition of offset */ EXPORT W kpKeyTopCode( KeyTop keytop, UW kbsel ) { KbDef *kbdef; W keytopcode, keytopofs; kbdef = GetKbDef(kbsel, keytop.u.kid); if ( kbdef == NULL ) { /* if keytable for kbsel does not exist, then use keyboard definition 1 (kbsel=0) */ kbdef = GetKbDef(0, keytop.u.kid); } keytopofs = ( kbdef == NULL )? 0: kbdef->keyDef.keytopofs; keytopcode = keytop.u.kcode + keytopofs; if ( keytopcode >= KEYMAX ) return InvalidKeytop; return keytopcode; }
/* * keyboard definition * keytopofs < 0 change keytable only * keytabsz <= 0 change keytop code offset only */ LOCAL ER defineKeyboard( UW kbsel, UW kid, W keytopofs, KeyTab *keytab, W keytabsz ) { KbDef *kbdef = GetKbDef(kbsel, kid); ER err; if ( keytabsz <= 0 ) { /* change keytop code offset only */ if ( kbdef == NULL ) { err = E_NOEXS; goto err_ret; } } else { /* change keytable, too */ if ( keytabsz < offsetof(KeyTab, kct) || !(keytab->keymax > 0 && keytab->keymax <= KEYMAX) || !(keytab->kctmax > 0 && keytab->kctmax <= KCTSEL) || !(keytabsz >= keytab->keymax * keytab->kctmax * sizeof(UH) + offsetof(KeyTab, kct)) ) { err = E_PAR; goto err_ret; } /* During new registration, if keytop code offset is unspecified, set keytop code offset to 0 */ if ( kbdef == NULL && keytopofs < 0 ) keytopofs = 0; } if ( keytabsz > 0 ) { /* chnage keytable */ kbdef = Vrealloc(kbdef, offsetof(KbDef, keyDef.keytab) + keytabsz); if ( kbdef == NULL ) { err = E_NOMEM; goto err_ret; } kbdef->size = offsetof(KeyDef, keytab) + keytabsz; SetKbDef(kbsel, kid, kbdef); memcpy(&kbdef->keyDef.keytab, keytab, keytabsz); } if ( keytopofs >= 0 ) { /* change keytop code offset */ kbdef->keyDef.keytopofs = keytopofs; } return E_OK; err_ret: DEBUG_PRINT(("defineKeyboard err = %d\n", err)); return err; }
/* * configure keyboard definition (DN_KEYDEF) */ LOCAL ER setKeyDef( KeyDef *keydef, UW kbsel, UW kid, W datacnt ) { ER err; if ( datacnt >= offsetof(KeyDef, keytab.kctmax) && keydef->keytab.keymax == 0 ) { /* deletion */ KbDef *kbdef = GetKbDef(kbsel, kid); if ( kbdef != NULL ) { SetKbDef(kbsel, kid, NULL); Vfree(kbdef); } } else { /* set */ if ( (datacnt -= offsetof(KeyDef, keytab)) < 0 ) return E_PAR; err = defineKeyboard(kbsel, kid, keydef->keytopofs, &keydef->keytab, datacnt); if ( err < E_OK ) return err; } return E_OK; }
/* * data write */ LOCAL INT writeData( ID devid, INT datano, INT datacnt, void *buf, SDI sdi ) { W size; KbDef *kbdef; UW kbsel, kid; ER err = E_OK; /* parameter check */ if ( datacnt < 0 ) { DEBUG_PRINT(("writeData, datacnt(%d) err\n", datacnt)); return E_PAR; } kbsel = kid = 0; switch ( datano ) { case DN_KPEVENT: /* message buffer ID for event notification (RW) */ size = sizeof(kpMgrInfo.eventMbf); break; case DN_KPSTAT: /* KB/PD status (RW) */ size = sizeof(kpMgrInfo.kpState); break; case DN_KEYTAB: /* keytable (RW) */ kbdef = GetKbDef(0, kpMgrInfo.kb.keyID); size = ( kbdef == NULL )? 0: kbdef->size - offsetof(KeyDef, keytab); break; case DN_KEYMODE: /* change key mode (RW) */ size = sizeof(kpMgrInfo.kb.keyMode); break; case DN_PDMODE: /* PD mode (RW) */ size = sizeof(kpMgrInfo.pd.pdMode); break; case DN_PDRANGE: /* PD range (RW) */ size = sizeof(kpMgrInfo.pd.pdRange); break; case DN_PDSIM: /* PD simulation speed (RW) */ size = sizeof(kpMgrInfo.pd.pdSimSpeed); break; case DN_PDSIMINH: /* halt PD simulation temporarily (RW) */ size = sizeof(kpMgrInfo.pd.pdSimInh); break; case DN_KEYID: /* keyboard ID (RW) */ size = sizeof(kpMgrInfo.kb.keyID); break; case DN_KPMETABUT: /* meta key / button status (W) */ size = sizeof(MetaBut) * 2; break; case DN_KEYMAP: /* keymap (R) */ case DN_KPINPUT: /* input mailbox ID (R) */ /* read-only attribute data */ DEBUG_PRINT(("writeData, read only\n")); return E_PAR; default: if ( SelKbDef(&kbsel, &kid, datano) ) { /* DN_KEYDEF keyboard definition (RW) */ kbdef = GetKbDef(kbsel, kid); size = ( kbdef == NULL )? 0: kbdef->size; } else { /* data number error */ DEBUG_PRINT(("writeData, datano(%d) err\n", datano)); return E_PAR; } } if ( datacnt > 0 ) { if ( datano != DN_KEYTAB && !(datano <= DN_KEYDEF_S && datano >= DN_KEYDEF_E) && !(datano <= DN_KEYDEF2_S && datano >= DN_KEYDEF2_E) ) { /* except for keytable, partial write is prohibited */ if ( datacnt < size ) return E_PAR; } /* data write */ switch ( datano ) { case DN_KPEVENT: /* message buffer ID for event notification */ kpMgrInfo.eventMbf = *(ID*)buf; break; case DN_KPSTAT: /* KB/PD status */ err = setKpState((KPStat*)buf); break; case DN_KEYTAB: /* keytable */ err = setKeyTab((KeyTab*)buf, datacnt); break; case DN_KEYMODE: /* key mode */ err = setKeyMode((KeyMode*)buf); break; case DN_PDMODE: /* PD mode */ err = setPdMode((PdMode*)buf); break; case DN_PDRANGE: /* PD range */ err = setPdRange((PdRange*)buf); break; case DN_PDSIM: /* PD simulation speed */ err = setPdSimSpeed(*(W*)buf); break; case DN_PDSIMINH: /* halt PD simulation temporarily */ err = setPdSimInh(*(BOOL*)buf); break; case DN_KEYID: /* keyboard ID */ err = setKeyID(*(UW*)buf); break; case DN_KPMETABUT: /* meta key / button status */ err = setKpMetaBut((MetaBut*)buf); break; default: /* keyboard definition */ err = setKeyDef((KeyDef*)buf, kbsel, kid, datacnt); } } if ( err != E_OK ) { DEBUG_PRINT(("writeData, write err = %d\n", err)); return err; } return size; }
/* * read data */ LOCAL INT readData( ID devid, INT datano, INT datacnt, void *buf, SDI sdi ) { #define setAddrAndSize(var) addr = &(var); size = sizeof(var) void *addr; W size; KbDef *kbdef; UW kbsel, kid; /* parameter check */ if ( datacnt < 0 ) { DEBUG_PRINT(("readData, datacnt(%d) err\n", datacnt)); return E_PAR; } switch ( datano ) { case DN_KPEVENT: /* message buffer ID for event notification (RW) */ setAddrAndSize(kpMgrInfo.eventMbf); break; case DN_KPSTAT: /* KB/PD status (RW) */ setAddrAndSize(kpMgrInfo.kpState); break; case DN_KEYMAP: /* keymap (R) */ setAddrAndSize(kpMgrInfo.kb.keyMap); break; case DN_KEYTAB: /* keytable (RW) */ kbdef = GetKbDef(0, kpMgrInfo.kb.keyID); if ( kbdef == NULL ) return E_NOEXS; addr = &kbdef->keyDef.keytab; size = kbdef->size - offsetof(KeyDef, keytab); break; case DN_KEYMODE: /* change key mode (RW) */ setAddrAndSize(kpMgrInfo.kb.keyMode); break; case DN_PDMODE: /* PD mode (RW) */ setAddrAndSize(kpMgrInfo.pd.pdMode); break; case DN_PDRANGE: /* PD range (RW) */ setAddrAndSize(kpMgrInfo.pd.pdRange); break; case DN_PDSIM: /* PD simulation speed (RW) */ setAddrAndSize(kpMgrInfo.pd.pdSimSpeed); break; case DN_PDSIMINH: /* halt PD simulation temporarily (RW) */ setAddrAndSize(kpMgrInfo.pd.pdSimInh); break; case DN_KPINPUT: /* input mailbox ID (R) */ setAddrAndSize(kpMgrInfo.dataMbx); break; case DN_KEYID: /* keyboard ID (RW) */ setAddrAndSize(kpMgrInfo.kb.keyID); break; default: if ( SelKbDef(&kbsel, &kid, datano) ) { /* DN_KEYDEF keyboard definition (RW) */ kbdef = GetKbDef(kbsel, kid); if ( kbdef == NULL ) return E_NOEXS; addr = &kbdef->keyDef; size = kbdef->size; } else { /* data number error */ DEBUG_PRINT(("readData, datano(%d) err\n", datano)); return E_PAR; } } if ( datacnt > 0 ) { /* read data */ if ( datacnt < size ) size = datacnt; memcpy(buf, addr, size); } return size; #undef setAddrAndSize }