Index: trunk/src/user32/HOOK.CPP
===================================================================
--- trunk/src/user32/HOOK.CPP	(revision 7210)
+++ trunk/src/user32/HOOK.CPP	(revision 7211)
@@ -1,3 +1,3 @@
-/* $Id: HOOK.CPP,v 1.29 2001-10-24 12:26:56 phaller Exp $ */
+/* $Id: HOOK.CPP,v 1.30 2001-10-26 09:10:12 phaller Exp $ */
 
 /*
@@ -818,7 +818,10 @@
 	}
     }
-
+  
+    // this undoc (don't care) bit isn't passed through to this hook
+    DWORD lParam = msg->lParam & ~0x02000000;
+  
     return (HOOK_CallHooksA( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
-                             LOWORD (msg->wParam), msg->lParam )
+                             LOWORD (msg->wParam), lParam )
                              ? TRUE : FALSE);
 }
@@ -845,5 +848,5 @@
   
   kbhs.vkCode      = msg->wParam;
-  kbhs.scanCode    = ( (msg->lParam & 0x00ff0000) >> 16);
+  kbhs.scanCode    = ( (msg->lParam & 0x03ff0000) >> 16);
   
   BOOL fKeyUp      = (msg->message == WM_KEYUP) ||
Index: trunk/src/user32/oslibmsg.cpp
===================================================================
--- trunk/src/user32/oslibmsg.cpp	(revision 7210)
+++ trunk/src/user32/oslibmsg.cpp	(revision 7211)
@@ -1,3 +1,3 @@
-/* $Id: oslibmsg.cpp,v 1.46 2001-10-25 15:35:53 phaller Exp $ */
+/* $Id: oslibmsg.cpp,v 1.47 2001-10-26 09:10:12 phaller Exp $ */
 /*
  * Window message translation functions for OS/2
@@ -21,4 +21,5 @@
 #define  INCL_DOSPROCESS
 #include <os2wrap.h>
+#include <odinwrap.h>
 #include <string.h>
 #include <misc.h>
@@ -37,4 +38,7 @@
 #define DBG_LOCALLOG	DBG_oslibmsg
 #include "dbglocal.h"
+
+
+ODINDEBUGCHANNEL(USER32-OSLIBMSG)
 
 
@@ -116,4 +120,5 @@
 void WinToOS2MsgTranslate(MSG *winMsg, QMSG *os2Msg, BOOL isUnicode)
 {
+  dprintf(("WinToOS2MsgTranslate not implemented"));
 //  memcpy(os2Msg, winMsg, sizeof(MSG));
 //  os2Msg->hwnd = Win32ToOS2Handle(winMsg->hwnd);
@@ -201,5 +206,5 @@
 //******************************************************************************
 //******************************************************************************
-BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+BOOL i_OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
                     BOOL isUnicode)
 {
@@ -239,4 +244,13 @@
         teb->o.odin.os2msg.msg  = 0;
         teb->o.odin.os2msg.hwnd = 0;
+    
+        // @@@PH verify this
+        // if this is a keyup or keydown message, we've got to
+        // call the keyboard hook here
+        if(pMsg->message <= WINWM_KEYLAST && pMsg->message >= WINWM_KEYDOWN)
+        {
+          ProcessKbdHook(pMsg, TRUE);
+        }
+    
         return (pMsg->message != WINWM_QUIT);
   }
@@ -288,8 +302,4 @@
   if(pMsg->message <= WINWM_KEYLAST && pMsg->message >= WINWM_KEYDOWN)
   {
-//    if(ProcessKbdHookLL(pMsg, TRUE))
-//      goto continuegetmsg;
-    
-    // @@@PH
     // only supposed to be called upon WM_KEYDOWN
     // and WM_KEYUP according to docs.
@@ -299,4 +309,14 @@
   return rc;
 }
+BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+                    BOOL isUnicode)
+{
+  dprintf(("OSLibWinGetMsg enter"));
+  BOOL fRes = i_OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, isUnicode);
+  dprintf(("OSLibWinGetMsg leave"));
+  return fRes;
+}
+
+
 //******************************************************************************
 //PeekMessage retrieves only messages associated with the window identified by the 
@@ -311,5 +331,5 @@
 //TODO: Not working as specified right now!
 //******************************************************************************
-BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+BOOL i_OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
                      DWORD fRemove, BOOL isUnicode)
 {
@@ -350,4 +370,12 @@
         }
         memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
+    
+        // @@@PH verify this
+        // if this is a keyup or keydown message, we've got to
+        // call the keyboard hook here
+        if(pMsg->message <= WINWM_KEYLAST && pMsg->message >= WINWM_KEYDOWN)
+        {
+          ProcessKbdHook(pMsg, fRemove);
+        }
         return TRUE;
   }
@@ -393,8 +421,4 @@
   if(pMsg->message <= WINWM_KEYLAST && pMsg->message >= WINWM_KEYDOWN)
   {
-//    if(ProcessKbdHookLL(pMsg, fRemove))
-//      goto continuepeekmsg;
-
-    // @@@PH
     // only supposed to be called upon WM_KEYDOWN
     // and WM_KEYUP according to docs.
@@ -405,4 +429,13 @@
   return rc;
 }
+BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
+                    BOOL fRemove, BOOL isUnicode)
+{
+  dprintf(("OSLibWinPeekMsg enter"));
+  BOOL fRes = i_OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, fRemove, isUnicode);
+  dprintf(("OSLibWinPeekMsg leave"));
+  return fRes;
+}
+
 //******************************************************************************
 //******************************************************************************
Index: trunk/src/user32/oslibmsgtranslate.cpp
===================================================================
--- trunk/src/user32/oslibmsgtranslate.cpp	(revision 7210)
+++ trunk/src/user32/oslibmsgtranslate.cpp	(revision 7211)
@@ -1,3 +1,3 @@
-/* $Id: oslibmsgtranslate.cpp,v 1.68 2001-10-25 15:35:53 phaller Exp $ */
+/* $Id: oslibmsgtranslate.cpp,v 1.69 2001-10-26 09:10:12 phaller Exp $ */
 /*
  * Window message translation functions for OS/2
@@ -166,4 +166,10 @@
 
 
+// Note:
+// For a "lonekey"-press of AltGr, we only receive WM_KEYUP
+// messages. If the key is pressed longer and starts to repeat,
+// WM_KEYDOWN messages come in properly.
+static BOOL fKeyAltGrDown = FALSE;
+
 //******************************************************************************
 //******************************************************************************
@@ -684,5 +690,5 @@
 
         dprintf(("PM: WM_CHAR: %x %x rep=%d scancode=%x", SHORT1FROMMP(os2Msg->mp2), SHORT2FROMMP(os2Msg->mp2), repeatCount, scanCode));
-        dprintf(("PM: WM_CHAR: hwnd %x flags %x mp1 %x, mp2 %x", win32wnd->getWindowHandle(), flags, os2Msg->mp1, os2Msg->mp2));
+        dprintf(("PM: WM_CHAR: hwnd %x flags %x mp1 %x, mp2 %x, time=%08xh", win32wnd->getWindowHandle(), flags, os2Msg->mp1, os2Msg->mp2, os2Msg->time));
 
         // vitali add begin
@@ -805,4 +811,5 @@
         // check if additional messages have to be recorded
         // ------------------------------------------------
+#if 0
         {
           MSG extramsg;
@@ -813,21 +820,4 @@
           switch (scanCode)
           {
-            case PMSCAN_ESC:
-            {
-              // Note: ESC generates a WM_CHAR for WINWM_KEYDOWN
-              // under Windows, not under PM
-              // so we've got to post it to ourself here!
-              // WM_CHAR(0x0000001bh, 00010001h)
-              if (winMsg->message == WINWM_KEYDOWN)
-              {
-                extramsg.message = WINWM_CHAR;
-                extramsg.wParam  = VK_ESCAPE_W;
-                extramsg.lParam  = winMsg->lParam;
-                setThreadQueueExtraCharMessage(teb, &extramsg);
-              }
-            }
-            break;
-            
-#if 0
             case PMSCAN_PRINT:
               // Note: PRINT generates a WM_KEYUP under Windows
@@ -841,48 +831,107 @@
               setThreadQueueExtraCharMessage(teb, &extramsg);
               break;
-#endif
             
+            #define WIN_KEY_EXTENDED   0x01000000
+            #define WIN_KEY_DONTCARE   0x02000000
+            #define WIN_KEY_ALTHELD    0x20000000
+            #define WIN_KEY_PREVSTATE  0x40000000
             case PMSCAN_ALTRIGHT:
             {
               // we need very special treatment here for the
               // poor, crippled AltGr key
-              if (keyWasPressed)
+              // Note: see fKeyAltGrDown above!
+              
+              if ( (keyWasPressed) || (fKeyAltGrDown == FALSE) )
               {
+                fKeyAltGrDown = TRUE;
+                
                 // 1 - generate a virtual LCONTROL-keypress
                 // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-AltGr!)
                 // 0xfe000000: mask out extended-key, scancode, repeatcount
+                // Note: Win sends a WINWM_SYSKEYDOWN to the hooks,
+                // the queue gets a WM_KEYDOWN only! (wrong impl. here)
                 extramsg.message = WINWM_KEYDOWN;
                 extramsg.wParam  = VK_RMENU_W;
                 extramsg.lParam  = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_EXTENDED
+                                   | (keyWasPressed ? WIN_KEY_PREVSTATE : 0)
+                                   | WIN_KEY_ALTHELD
                                    | repeatCount
-                                   | (WINSCAN_ALTRIGHT << 24);
+                                   | (WINSCAN_ALTRIGHT << 16);
                 winMsg->message  = WINWM_KEYDOWN;
                 winMsg->wParam   = VK_LCONTROL_W;
                 winMsg->lParam   = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_DONTCARE
+                                   | (keyWasPressed ? WIN_KEY_PREVSTATE : 0)
+                                   | WIN_KEY_ALTHELD
                                    | repeatCount
-                                   | (WINSCAN_CTRLLEFT << 24);
+                                   | (WINSCAN_CTRLLEFT << 16);
               }
               else
               {
+                // OK, now we can release it!
+                fKeyAltGrDown = FALSE;
+                
                 // key up
                 // 1 - generate a virtual LCONTROL-keypress
                 // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-Alt!)
-                extramsg.message = WINWM_KEYDOWN;
+                extramsg.message = WINWM_KEYUP;
                 extramsg.wParam  = VK_RMENU_W;
                 extramsg.lParam  = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_EXTENDED
                                    | repeatCount
-                                   | (WINSCAN_ALTRIGHT << 24);
+                                   | (WINSCAN_ALTRIGHT << 16);
                 winMsg->message  = WINWM_SYSKEYUP;
                 winMsg->wParam   = VK_LCONTROL_W;
                 winMsg->lParam   = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_ALTHELD
                                    | repeatCount
-                                   | (WINSCAN_CTRLLEFT << 24);
+                                   | (WINSCAN_CTRLLEFT << 16);
               }
               
+              // @@@PH
+              // unknown: this leads to an infinite loop
+              // because the OS/2 WM_CHAR_SPECIAL message is never
+              // removed from the queue?!
               setThreadQueueExtraCharMessage(teb, &extramsg);
-            }
+              
+              if ( (keyWasPressed) || (fKeyAltGrDown == FALSE) )
+              {
+                fKeyAltGrDown = TRUE;
+                
+                // 1 - generate a virtual LCONTROL-keypress
+                // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-AltGr!)
+                // 0xfe000000: mask out extended-key, scancode, repeatcount
+                // Note: Win sends a WINWM_SYSKEYDOWN to the hooks,
+                // the queue gets a WM_KEYDOWN only! (wrong impl. here)
+                winMsg->message = WINWM_KEYDOWN;
+                winMsg->wParam  = VK_RMENU_W;
+                winMsg->lParam  = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_EXTENDED
+                                   | (keyWasPressed ? WIN_KEY_PREVSTATE : 0)
+                                   | WIN_KEY_ALTHELD
+                                   | repeatCount
+                                   | (WINSCAN_ALTRIGHT << 16);
+              }
+              else
+              {
+                // OK, now we can release it!
+                fKeyAltGrDown = FALSE;
+                
+                // key up
+                // 1 - generate a virtual LCONTROL-keypress
+                // 2 - send LMENU-keypress (NT emulates ALtGr w/ Ctrl-Alt!)
+                winMsg->message = WINWM_KEYUP;
+                winMsg->wParam  = VK_RMENU_W;
+                winMsg->lParam  = (winMsg->lParam & 0xfe000000)
+                                   | WIN_KEY_EXTENDED
+                                   | repeatCount
+                                   | (WINSCAN_ALTRIGHT << 16);
+              }
+            }
+            break;
           } /* switch */
         }
-      
+#endif
       
         if (ISKDB_CAPTURED())
@@ -1046,47 +1095,64 @@
     //      the newly generated WM_CHAR message.
     if(!teb->o.odin.fTranslated && teb->o.odin.os2msg.msg == WM_CHAR && !((SHORT1FROMMP(teb->o.odin.os2msg.mp1) & KC_KEYUP) == KC_KEYUP))
-    {//TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
-            ULONG fl = SHORT1FROMMP(teb->o.odin.os2msg.mp1);
-            MSG extramsg;
-
-            memcpy(&extramsg, msg, sizeof(MSG));
-            extramsg.wParam = SHORT1FROMMP(teb->o.odin.os2msg.mp2);
-            extramsg.lParam = 0;
-
-            if(!(fl & KC_CHAR) && msg->message < WINWM_SYSKEYDOWN) {
-                return FALSE;
-            }
-
-            if(fl & KC_VIRTUALKEY) {
-                if(msg->wParam) {
-                    if ((msg->wParam >= VK_NUMPAD0_W) && (msg->wParam <= VK_NUMPAD9_W))
-                        extramsg.wParam = msg->wParam - 0x30;
-                    else
-                        extramsg.wParam = msg->wParam;
-                }
-                else    extramsg.wParam = SHORT2FROMMP(teb->o.odin.os2msg.mp2);
-            }
-
-
-            if(msg->message >= WINWM_SYSKEYDOWN) {
-                    extramsg.message = WINWM_SYSCHAR;
-            }
-            else    extramsg.message = WINWM_CHAR;
-
-            if(fl & KC_DEADKEY) {
-                extramsg.message++;  //WM_DEADCHAR/WM_SYSDEADCHAR
-            }
-
-            extramsg.lParam = msg->lParam & 0x00FFFFFF;
-            if(fl & KC_ALT)
-                extramsg.lParam |= (1<<29);
-            if(fl & KC_PREVDOWN)
-                extramsg.lParam |= (1<<30);
-            if(fl & KC_KEYUP)
-                extramsg.lParam |= (1<<31);
-      
-            // insert message into the queue
-            setThreadQueueExtraCharMessage(teb, &extramsg);
-            return TRUE;
+    {
+      //TranslatedMessage was called before DispatchMessage, so queue WM_CHAR message
+      ULONG fl = SHORT1FROMMP(teb->o.odin.os2msg.mp1);
+      MSG extramsg;
+
+      memcpy(&extramsg, msg, sizeof(MSG));
+      extramsg.wParam = SHORT1FROMMP(teb->o.odin.os2msg.mp2);
+      extramsg.lParam = 0;
+
+      // ESCAPE generates a WM_CHAR under windows, so take
+      // special care for this here.
+      UCHAR ucPMScanCode = CHAR4FROMMP(teb->o.odin.os2msg.mp1);
+      switch (ucPMScanCode)
+      {
+        case PMSCAN_ESC:
+          extramsg.wParam  = VK_ESCAPE_W;
+          fl |= KC_CHAR;
+        break;
+      }
+
+      if(!(fl & KC_CHAR) && msg->message < WINWM_SYSKEYDOWN) 
+      {
+        return FALSE;
+      }
+
+      if(fl & KC_VIRTUALKEY)
+      {
+        if(msg->wParam)
+        {
+          if ((msg->wParam >= VK_NUMPAD0_W) && 
+              (msg->wParam <= VK_NUMPAD9_W))
+            extramsg.wParam = msg->wParam - 0x30;
+          else
+            extramsg.wParam = msg->wParam;
+        }
+        else    
+          extramsg.wParam = SHORT2FROMMP(teb->o.odin.os2msg.mp2);
+      }
+
+
+      if(msg->message >= WINWM_SYSKEYDOWN) 
+        extramsg.message = WINWM_SYSCHAR;
+      else    
+        extramsg.message = WINWM_CHAR;
+
+      if(fl & KC_DEADKEY)
+        extramsg.message++;  //WM_DEADCHAR/WM_SYSDEADCHAR
+
+
+      extramsg.lParam = msg->lParam & 0x00FFFFFF;
+      if(fl & KC_ALT)
+        extramsg.lParam |= (1<<29);
+      if(fl & KC_PREVDOWN)
+        extramsg.lParam |= (1<<30);
+      if(fl & KC_KEYUP)
+        extramsg.lParam |= (1<<31);
+
+      // insert message into the queue
+      setThreadQueueExtraCharMessage(teb, &extramsg);
+      return TRUE;
     }
     return FALSE;
Index: trunk/src/user32/pmwindow.cpp
===================================================================
--- trunk/src/user32/pmwindow.cpp	(revision 7210)
+++ trunk/src/user32/pmwindow.cpp	(revision 7211)
@@ -1,3 +1,3 @@
-/* $Id: pmwindow.cpp,v 1.158 2001-10-25 10:40:45 sandervl Exp $ */
+/* $Id: pmwindow.cpp,v 1.159 2001-10-26 09:10:12 phaller Exp $ */
 /*
  * Win32 Window Managment Code for OS/2
@@ -45,4 +45,5 @@
 #include "options.h"
 #include "menu.h"
+#include <pmkbdhk.h>
 
 #define DBG_LOCALLOG    DBG_pmwindow
@@ -502,5 +503,8 @@
         win32wnd->DispatchMsgA(pWinMsg);
         break;
-
+      
+    case WM_CHAR_SPECIAL:
+      /* NO BREAK! FALLTHRU CASE! */
+      
     case WM_CHAR:
         dprintf(("OS2: WM_CHAR %x %x %x, %x %x", win32wnd->getWindowHandle(), mp1, mp2, pWinMsg->wParam, pWinMsg->lParam));
