This is the mail archive of the
cygwin-xfree@cygwin.com
mailing list for the Cygwin XFree86 project.
Keyboard Handling
- To: XFree86/Cygwin Mailing list <cygwin-xfree at sources dot redhat dot com>
- Subject: Keyboard Handling
- From: Alexander Gottwald <Alexander dot Gottwald at informatik dot tu-chemnitz dot de>
- Date: Sat, 21 Apr 2001 20:10:05 +0200 (MEST)
Hi,
I've tried some code to handle AltGr more correctly.
I attached a patch to the winwndproc.c from Apr-14 Sourceball
which fixes at least the press of AltGr (the release is not done yet).
It uses mainly the good fact, that the fake Control_L- and Alt_R-message
have the same timestamp. I just cache the Control_L press, set a very
short timestamp and
1) drop the Control_L if the coresponding Alt_R message arrives
2) send the Control_L if
a) another key (not Alt_Gr) was pressed
b) the timeout (currently 1ms) expires
The current code still needs to be cleaned up, but hope you can already
give some hints on possible error and mistakes.
I will make a test version available on http://www.gotti.org/ [1].
bye
ago
[1] http://www-usercgi.tu-chemnitz.de/~goal/xfree
--
Alexander.Gottwald@informatik.tu-chemnitz.de
http://www.gotti.org
+49 3725 3498080
--- winwndproc.c.old Fri Apr 6 22:57:34 2001
+++ winwndproc.c Sat Apr 21 19:53:06 2001
@@ -33,6 +33,12 @@
#include "win.h"
+struct {
+ WPARAM wParam;
+ LPARAM lParam;
+ LONG mTime;
+} controlBuffer;
+
/* Called by the WakeupHandler
* Processes and/or dispatches Windows messages
*/
@@ -84,6 +90,9 @@
/* Store the mode key states so restore doesn't try to restore them */
winStoreModeKeyStates (pScreen);
+
+ /* set the controlBuffer to empty */
+ controlBuffer.mTime = 0 ;
return 0;
case WM_PAINT:
@@ -359,7 +368,87 @@
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
- winTranslateKey (wParam, lParam, &iScanCode);
+ case WM_TIMER:
+
+#define TIMERID 0x1234
+#define TIMERTIMEOUT 1
+ if (wParam == VK_CONTROL || wParam == VK_MENU) {
+ ErrorF("WM*KEYDOWN: 0x%08x 0x%08x 0x%08x\n",
+ wParam,lParam,GetMessageTime());
+ } else if (message == WM_TIMER) {
+ ErrorF("WM_TIMER: 0x%08x 0x%08x 0x%08x\n",
+ wParam,lParam,GetMessageTime());
+ }
+ if (message == WM_TIMER) {
+ /* the message queue has run empty and we can process the control */
+ KillTimer(hWnd,TIMERID);
+ if (controlBuffer.mTime == 0)
+ return 0;
+ winTranslateKey (controlBuffer.wParam, controlBuffer.lParam,
+ &iScanCode);
+ controlBuffer.mTime = 0;
+ ErrorF("Restoring old Keypress\n");
+ } else if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN) &&
+ wParam == VK_CONTROL) {
+ if (controlBuffer.mTime!=0) {
+ /* There is still an message waiting to be processed */
+ KillTimer(hWnd,TIMERID);
+ winTranslateKey (controlBuffer.wParam, controlBuffer.lParam,
+ &iScanCode);
+ ErrorF("Restoring old Keypress\n");
+ /* store the new control message into the buffer */
+ controlBuffer.wParam = wParam;
+ controlBuffer.lParam = lParam;
+ controlBuffer.mTime = GetMessageTime();
+ /* put the dummy message into the queue */
+ SetTimer(hWnd,TIMERID,TIMERTIMEOUT,NULL);
+ ErrorF("Storing keypress for later processing\n");
+ } else {
+ /* store the new control message into the buffer */
+ controlBuffer.wParam = wParam;
+ controlBuffer.lParam = lParam;
+ controlBuffer.mTime = GetMessageTime();
+ /* put the dummy message into the queue */
+ SetTimer(hWnd,TIMERID,TIMERTIMEOUT,NULL);
+ ErrorF("Storing keypress for later processing\n");
+ /* Dont process any further */
+ return 0;
+ }
+ } else {
+ /* Check if controlBuffer is filled */
+ if (controlBuffer.mTime != 0) {
+ if (wParam == VK_MENU &&
+ ((lParam >> 16 ) & 0x1ff) == 0x138 &&
+ controlBuffer.wParam == VK_CONTROL &&
+ ((controlBuffer.lParam >> 16) & 0x1ff) == 0x1d &&
+ controlBuffer.mTime == GetMessageTime()) {
+ /* This is an VK_MENU with a fake VK_CONTROL */
+ /* Drop the control */
+ KillTimer(hWnd,TIMERID);
+ controlBuffer.mTime = 0;
+ winTranslateKey (wParam, lParam, &iScanCode);
+ ErrorF("Dropped Fake Control\n");
+ ErrorF("Send AltGr\n");
+ } else {
+ /* The VK_CONTROL was real, as the VK_MENU is */
+ /* Send the VK_CONTROL Message */
+ winTranslateKey (controlBuffer.wParam, controlBuffer.lParam,
+ &iScanCode);
+ xCurrentEvent.u.u.type = KeyPress;
+ xCurrentEvent.u.u.detail = iScanCode;
+ xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
+ mieqEnqueue (&xCurrentEvent);
+ ErrorF("Send old Control\n");
+ /* clear the buffer */
+ controlBuffer.mTime = 0;
+ /* prepare the VK_MENU */
+ winTranslateKey (wParam, lParam, &iScanCode);
+ ErrorF("Send AltGr\n");
+ }
+ } else {
+ winTranslateKey (wParam, lParam, &iScanCode);
+ }
+ }
xCurrentEvent.u.u.type = KeyPress;
xCurrentEvent.u.u.detail = iScanCode;
xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
@@ -368,6 +457,9 @@
case WM_SYSKEYUP:
case WM_KEYUP:
+ if (wParam == VK_CONTROL || wParam == VK_MENU) {
+ ErrorF("WM*KEYUP: 0x%08x 0x%08x 0x%08x\n",wParam,lParam,GetMessageTime());
+ }
winTranslateKey (wParam, lParam, &iScanCode);
xCurrentEvent.u.u.type = KeyRelease;
xCurrentEvent.u.u.detail = iScanCode;