/* This function is called from two threads, one each to monitor the * keyboard and mouse messages. * All packets are passed on unchanged. The thread just clears a * semaphore to alert the main background process that there has been some * activity, which means it won't blank or will restore the screen if * it is already blanked. * * Parameter is name of device to be monitored. */ void CALLBACK MonitorThread(NPSZ npName) { int rc; MONIN mnin; /* monitor buffers */ MONOUT mnout; HMONITOR hmon; char bDataBuf[sizeof(MONIN)]; /* buffer used */ USHORT cbDataBufLen; PIDINFO pidi; /* It has to be time-critical, so it doesn't impact response. */ DosGetPID(&pidi); DosSetPrty(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, pidi.tid); /* Initialize the lengths of the monitor buffer structures. */ mnin.cb = sizeof(MONIN); mnout.cb = sizeof(MONOUT); /* * Register for the current session. */ TRACE(tpMonOpen, TRUE, 0, npName); if (rc = DosMonOpen(npName, &hmon)) ERRORCHK("DosMonOpen", rc); TRACE(tpMonReg, TRUE, 0, npName); rc = DosMonReg(hmon, (PBYTE) & mnin, (PBYTE) & mnout, MONITOR_BEGIN, sgMonitor); TRACE(tpMonReg, FALSE, rc, npName); if (rc == 0) /* * Loop, passing on data and signalling main thread. */ for (;;) { cbDataBufLen = sizeof(MONIN); if (DosMonRead((PBYTE) & mnin, DCWW_WAIT, bDataBuf, &cbDataBufLen)) break; /* We shouldn't get a length 0 return, but best to check, before * testing the first byte... */ if (cbDataBufLen > 0) { if (DosMonWrite((PBYTE) & mnout, bDataBuf, cbDataBufLen)) break; /* Test for open/close/flush packets and ignore them; * they don't represent mouse/keyboard actions. */ if (!(bDataBuf[0] & 0x07)) { TRACE(tpMonAction, FALSE, cbDataBufLen, npName); DosSemClear(&pSharedseg->semAction); } } } else { /* Failed to register */ WtiLStrCpy(bDataBuf, "DosMonReg for "); WtiLStrCat(bDataBuf, npName); ERRORCHK(bDataBuf, rc); } /* If blanked, undo it, whatever the reason we're leaving... */ if (pSharedseg->bBlanked) DosSemClear(&pSharedseg->semAction); /* Told to withdraw */ DosExit(EXIT_THREAD, 0); }
void os2KbdMonitorThread(void* arg) { struct KeyPacket packet; APIRET rc; USHORT length,print_flag; ULONG queueParam; HMONITOR hKbdMonitor; MONIN monInbuf; MONOUT monOutbuf; char queueName[128]; #if 0 monInbuf=(MONIN *)_tmalloc(2*sizeof(MONIN)); if (monInbuf==NULL) { xf86Msg(X_ERROR, "Could not allocate memory in kbd monitor thread!\n"); exit(1); } monOutbuf=(MONOUT *) &monInbuf[1]; #endif monInbuf.cb=sizeof(MONIN); monOutbuf.cb=sizeof(MONOUT); rc = DosMonOpen("KBD$",&hKbdMonitor); xf86Msg(X_INFO,"Opened kbd monitor, rc=%d\n",rc); rc = DosMonReg(hKbdMonitor, (PBYTE)&monInbuf,(PBYTE)&monOutbuf,(USHORT)2,(USHORT)-1); xf86Msg(X_INFO,"Kbd monitor registered, rc=%d\n",rc); if (rc) { DosMonClose(hKbdMonitor); exit(1); } /* create a queue */ sprintf(queueName,"\\QUEUES\\XF86KBD\\%d",getpid()); rc = DosCreateQueue(&hKbdQueue,0L,queueName); xf86Msg(X_INFO,"Kbd Queue created, rc=%d\n",rc); (void)DosPurgeQueue(hKbdQueue); while (1) { length = sizeof(packet); rc = DosMonRead((PBYTE)&monInbuf,0,(PBYTE)&packet,&length); if (rc) { xf86Msg(X_ERROR, "DosMonRead returned bad RC! rc=%d\n",rc); DosMonClose(hKbdMonitor); exit(1); } queueParam = packet.mnflags+(packet.ddflags<<16); if (packet.mnflags&0x7F00) DosWriteQueue(hKbdQueue,queueParam,0L,NULL,0L); /*xf86Msg(X_INFO,"Wrote a char to queue, rc=%d\n",rc); */ print_flag = packet.ddflags & 0x1F; /*xf86Msg(X_INFO,"Kbd Monitor: Key press %d, scan code %d, ddflags %d\n", packet.mnflags&0x8000,(packet.mnflags&0x7F00)>>8,packet.ddflags); */ /* This line will swallow print-screen keypresses */ if (print_flag == 0x13 || print_flag == 0x14 || print_flag == 0x15 || print_flag == 0x16) rc = 0; else rc = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&packet,length); if (rc) { xf86Msg(X_ERROR, "DosMonWrite returned bad RC! rc=%d\n",rc); DosMonClose(hKbdMonitor); exit(1); } } DosCloseQueue(hKbdQueue); DosMonClose(hKbdMonitor); }