This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Keyboard Handling


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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]