1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19:
20: #include "kbpd.h"
21: #include "scancode.h"
22:
23: 24: 25:
26: #define MAXRAWEVT 32
27: LOCAL RawEvt evtbuf[MAXRAWEVT + 1];
28: LOCAL W evtbuf_init = 0;
29:
30: 31: 32:
33: #define RATIO_ONE (24)
34: #define ACC_RATE (3)
35: #define PDMOV_XMAX 512
36: LOCAL UB sensetbl[] =
37: {6, 8, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168};
38: LOCAL UB threshold[] = {0, 3, 7, 11, 15, 23, 39, 63};
39:
40: 41: 42:
43: LOCAL UB numtbl[] = {
44: T_7, T_8, T_9, 0x4a,
45: T_4, T_5, T_6, 0x4e,
46: T_1, T_2, T_3,
47: T_0, T_PERIOD
48: };
49:
50: 51: 52:
53: EXPORT void* MemAlloc(W size)
54: {
55: static W blksz = 0;
56: T_RSMB msts;
57: void* ptr;
58:
59: if (blksz == 0) {
60: if (tk_ref_smb(&msts) < E_OK) return NULL;
61: blksz = msts.blksz;
62: }
63: if (tk_get_smb(&ptr, (size + blksz - 1) / blksz,
64: TA_RNG0) >= E_OK) return ptr;
65: return NULL;
66: }
67: EXPORT void MemFree(void *ptr)
68: {
69: tk_rel_smb(ptr);
70: }
71: 72: 73:
74: EXPORT ER kpSendMsg(RawEvt *msg)
75: {
76: ER er;
77: W i;
78:
79: if (evtbuf_init == 0) {
80: MEMSET(evtbuf, 0, sizeof(evtbuf));
81: for (i = 0; i < MAXRAWEVT + 1; i++) evtbuf[i].p.stat.read = 1;
82: evtbuf_init++;
83: }
84:
85:
86: for (i = 0; i < MAXRAWEVT && evtbuf[i].p.stat.read == 0; i++);
87:
88:
89: if (i == MAXRAWEVT && evtbuf[i].p.stat.read == 0) {
90: DP(("kpSendMsg: evtbuf overflow\n"));
91: er = E_TMOUT;
92: goto fin0;
93: }
94:
95:
96: evtbuf[i] = *msg;
97:
98:
99: if (i == MAXRAWEVT) {
100: DP(("kpSendMsg: DEV_OVRRUN\n"));
101: evtbuf[i].p.stat.err = DEV_OVRRUN;
102: }
103:
104:
105: er = tk_snd_mbx(EvtMbx, (T_MSG*)&evtbuf[i]);
106: if (er < E_OK) {
107: evtbuf[i].p.stat.read = 1;
108: DP(("kpSendMsg: err=%#x\n", er));
109: }
110: fin0:
111: return er;
112: }
113: 114: 115:
116: EXPORT void kpScalingPos(RawEvt *evt, W x, W y, PNT *fract, W x_max)
117: {
118: W acc, sns, ax, ay, max_xy;
119: W ratio, bias;
120: W base = RATIO_ONE;
121:
122: sns = PdSense & PD_SNMSK;
123: acc = (PdSense & PD_ACMSK) >> 9;
124:
125:
126: if (acc != 0) {
127: if ((ax = x) < 0) ax = - ax;
128: if ((ay = y) < 0) ay = - ay;
129: if ((max_xy = ax) < ay) max_xy = ay;
130: if (max_xy > (bias = threshold[acc])) {
131: bias *= (ACC_RATE - 1);
132: ax = ax * ACC_RATE - (bias * ax / max_xy);
133: ay = ay * ACC_RATE - (bias * ay / max_xy);
134: x = (x < 0) ? (- ax) : (ax);
135: y = (y < 0) ? (- ay) : (ay);
136: }
137:
138: base += sns;
139: }
140:
141:
142: ratio = sensetbl[sns];
143:
144: if (x_max > 0) {
145: 146:
147: ratio *= PDMOV_XMAX / base;
148: base = x_max;
149: }
150: 151:
152: x = x * ratio + fract->x;
153: evt->p.xpos = x / base;
154: fract->x = (evt->p.xpos == 0) ? x : 0;
155:
156: y = y * ratio + fract->y;
157: evt->p.ypos = y / base;
158: fract->y = (evt->p.ypos == 0) ? y : 0;
159: }
160: 161: 162:
163: EXPORT void kpSendPdEvt(RawEvt *evt, UW *lsts, RawEvt *last)
164: {
165: union {
166: PdInStat stat;
167: UW uw;
168: } u;
169:
170:
171: u.stat = evt->p.stat;
172: if (lsts[0] == u.uw &&
173: evt->p.stat.inv == 0 && evt->p.stat.vst == 0) {
174:
175: if (evt->p.stat.abs == 0) {
176: if (evt->p.xpos == 0 && evt->p.ypos == 0) return;
177: } else {
178: if (evt->p.xpos == last->p.xpos &&
179: evt->p.ypos == last->p.ypos) return;
180: }
181: }
182:
183:
184: lsts[0] = u.uw;
185: *last = *evt;
186:
187:
188: kpSendMsg(evt);
189: }
190: 191: 192:
193: EXPORT void kpSendWheelEvt(W z)
194: {
195: RawEvt evt;
196: union {
197: PdIn2Stat stat;
198: UW uw;
199: } u;
200:
201: if (z != 0) {
202: u.uw = 0;
203: evt.p2.stat = u.stat;
204: evt.p2.stat.cmd = INP_PD2;
205: evt.p2.wheel = z;
206: evt.p2.rsv = 0;
207: kpSendMsg(&evt);
208: }
209: }
210: 211: 212:
213: EXPORT void kpSendMouseEvt(W but, W x, W y, W z, UW *lsts)
214: {
215: RawEvt evt, dummy;
216: union {
217: PdInStat stat;
218: UW uw;
219: } u;
220:
221:
222: kpSendWheelEvt(z);
223:
224:
225: kpScalingPos(&evt, x, y, (PNT*)&lsts[1], 0);
226:
227:
228: u.uw = 0;
229: evt.p.stat = u.stat;
230: evt.p.stat.cmd = INP_PD;
231: evt.p.stat.butrev = 1;
232: evt.p.stat.onebut = 1;
233: evt.p.stat.main = (but & 0x01) ? 1 : 0;
234: evt.p.stat.sub = (but & 0x02) ? 1 : 0;
235: evt.p.stat.qpress = (but & 0x04) ? 1 : 0;
236:
237:
238: kpSendPdEvt(&evt, lsts, &dummy);
239: }
240: 241: 242:
243: EXPORT void kpSendKeyEvt(W sts, W keycode)
244: {
245: RawEvt evt;
246: union {
247: KeyInStat stat;
248: UW uw;
249: } u;
250:
251: if (keycode <= 0) return;
252:
253:
254: if (keycode == NumLock) {
255: if (sts & 1) {
256: kpSendDrvCmd(InputModeCmd(
257: ((InpMode ^ NumLockON) & NumLockON) | 0x100));
258: }
259: return;
260: }
261:
262: u.uw = 0;
263: evt.k.stat = u.stat;
264: evt.k.stat.cmd = INP_KEY;
265: evt.k.stat.kbid = KbdId;
266: evt.k.stat.press = sts & 1;
267:
268:
269: if (keycode >= NumLockLo && keycode <= NumLockHi) {
270: if ((InpMode & NumLockON) == 0)
271: keycode = numtbl[keycode - NumLockLo];
272: evt.k.stat.tenkey = 1;
273: }
274: evt.k.keytop = keycode;
275:
276:
277: kpSendMsg(&evt);
278: }
279: 280: 281:
282: EXPORT ER kpSendDrvCmd(UW cmd)
283: {
284: ER er;
285: UINT dmy;
286:
287: 288:
289: er = tk_wai_flg(CmdFlg, DeviceCommandReady, TWF_ORW | TWF_CLR,
290: &dmy, 200);
291: if (er >= E_OK) {
292: er = tk_set_flg(CmdFlg, cmd);
293: }
294: if (er < E_OK) {
295: DP(("kpSendDrvCmd: err=%#x\n", er));
296: }
297: return er;
298: }
299: 300: 301:
302: EXPORT void kpDataTask(void)
303: {
304: InMsg msg;
305: W sz;
306:
307: for (;;) {
308:
309: if ((sz = tk_rcv_mbf(InpMbf, &msg, TMO_FEVR)) < E_OK) {
310: continue;
311: }
312: if (sz != sizeof(msg)) continue;
313: if (Suspended == TRUE) continue;
314:
315:
316: hwProc(&msg);
317: }
318: }
319: 320: 321:
322: EXPORT void kpCmdTask(void)
323: {
324: UW dt;
325: UINT cmd;
326:
327: for (;;) {
328:
329:
330: if (tk_set_flg(CmdFlg, DeviceCommandReady) < E_OK) continue;
331:
332:
333: if (tk_wai_flg(CmdFlg, ~DeviceCommandReady, TWF_ORW | TWF_CLR,
334: &cmd, TMO_FEVR) < E_OK) continue;
335:
336:
337: dt = cmd & 0x00ffffff;
338: switch (cmd & 0xff000000) {
339: case ScanRateCmd(0):
340: break;
341:
342: case SenseCmd(0):
343: PdSense = dt;
344: break;
345:
346: case InputModeCmd(0):
347: 348:
349: dt |= InpMode & ((dt & ~0x3) ? 0x3 : ~0x3);
350: if ((dt &= 0xff) != InpMode) {
351: InpMode = dt;
352: if (Suspended == FALSE) {
353: hwImode(dt);
354: }
355: }
356: break;
357:
358: case SuspendKBPD:
359: if (cmd == SuspendKBPD) {
360: if (Suspended == FALSE) {
361: Suspended = TRUE;
362: hwInit(DC_SUSPEND);
363: }
364: } else {
365: if (Suspended == TRUE) {
366: hwInit(DC_RESUME);
367: Suspended = FALSE;
368: }
369: }
370: break;
371:
372: default:
373: DP(("kpCmdTask: cmd=%#08x\n", cmd));
374: }
375: }
376: }