Changeset 10286 for trunk/src


Ignore:
Timestamp:
Oct 22, 2003, 2:45:13 PM (22 years ago)
Author:
sandervl
Message:

Updates for new keyboard hook

Location:
trunk/src/pmkbdhk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/pmkbdhk/pmkbdhk.cpp

    r10282 r10286  
    1 /* $Id: pmkbdhk.cpp,v 1.7 2003-10-22 09:51:00 sandervl Exp $ */
     1/* $Id: pmkbdhk.cpp,v 1.8 2003-10-22 12:45:12 sandervl Exp $ */
    22/*
    33 * OS/2 native Presentation Manager hooks
     
    66 * Large Portions (C) Ulrich M”ller, XWorkplace
    77 * Copyright 2001 Patrick Haller (patrick.haller@innotek.de)
    8  *
     8 * Copyright 2002-2003 Innotek Systemberatung GmbH
    99 *
    1010 * Project Odin Software License can be found in LICENSE.TXT
    1111 *
    1212 */
     13
    1314#define  INCL_WIN
    1415#define  INCL_WININPUT
     
    1617#define  INCL_WINHOOKS
    1718#define  INCL_PM
    18 #define  INCL_DOSERRORS
    19 #define  INCL_DOSSEMAPHORES
     19#define  INCL_BASE
     20#define  INCL_ERRORS
    2021#include <os2.h>
    2122#include <stdlib.h>
     23#include <stdio.h>
    2224#include <string.h>
    23 
     25#include <signal.h>
    2426#include <pmscan.h>
    2527
     
    2729#include "pmkbdhkp.h"
    2830
    29 /*
    30  
     31
     32/*
     33
    3134 To improve the ODIN keyboard management, it is required to intercept
    3235 any possible key from the Presentation Manager input queue.
    33  
     36
    3437 Sketch:
    35  
     38
    3639 - intercept keyboard messages before accelerators are translated
    3740   (HK_PREACCEL)
     
    4750         WM_MENU if ALT is pressed need to be generated.
    4851       - if no sensible key, pass thru
    49        
     52
    5053   Installation:
    5154   - automatically install hook on loading of the DLL
    5255   - automatically uninstall the hook on DLL termination
    5356   - DLL is GLOBAL INITTERM, used shared mem only!
    54        
     57   - Whenever process terminates OS/2 frees all hooks process initiated,
     58     no matter whether DLL is still in memory or not. So in sequence:
     59     Load 1 VIO app, load 2 VIO app, close 1st VIO app - KBD hook stops working because
     60     it was released by OS/2 on 1 process. Creating hooks for each VIO app solves
     61     this problem. Hook processes needed messages and removes them from other
     62     hooks if needed. On termination of process 1 we still have hook of process 2.
    5563*/
    56        
    57 
    58 /**********
    59  * Prototypes
    60  **********/
     64
    6165
    6266BOOL EXPENTRY hookPreAccelHook(HAB hab, PQMSG pqmsg, ULONG option);
    6367
    64 // _CRT_init is the C run-time environment initialization function.
    65 // It will return 0 to indicate success and -1 to indicate failure.
    66 int _Optlink _CRT_init(void);
    67 
    68 // _CRT_term is the C run-time environment termination function.
    69 // It only needs to be called when the C run-time functions are statically
    70 // linked, as is the case with XWorkplace.
    71 void _Optlink _CRT_term(void);
    72 
    73 
    74 
    75 /******************************************************************
    76  *
    77  *  Module Global Variables
    78  *
    79  ******************************************************************/
    80 
    81 HOOKDATA G_HookData;
    82 
    83 
    84 /******************************************************************
    85  *
    86  *  Helper functions
    87  *
    88  ******************************************************************/
    89 
    90 /*
    91  *@@ InitializeGlobalsForHooks:
     68HOOKDATA G_HookData = {0};
     69
     70
     71/*
     72 *@@ InitializeVioWindow:
    9273 *      this gets called from hookInit to initialize
    9374 *      the global variables. We query the PM desktop,
     
    9677 */
    9778
    98 VOID InitializeGlobalsForHooks(VOID)
    99 {
    100     HENUM   henum;
    101     HWND    hwndThis;
    102     BOOL    fFound;
    103 
    104     // PM desktop (the WPS desktop is handled by the daemon)
    105     G_HookData.hwndPMDesktop = WinQueryDesktopWindow(G_HookData.habDaemonObject,
    106                                                      NULLHANDLE);
    107 
    108     WinQueryWindowProcess(HWND_DESKTOP, &G_HookData.pidPM, NULL);
    109             // V0.9.7 (2001-01-21) [umoeller]
    110 
    111     // enumerate desktop window to find the window list:
    112     // according to PMTREE, the window list has the following
    113     // window hierarchy:
    114     //      WC_FRAME
    115     //        +--- WC_TITLEBAR
    116     //        +--- Menu
    117     //        +--- WindowList
    118     //        +---
    119     fFound = FALSE;
    120     henum = WinBeginEnumWindows(HWND_DESKTOP);
    121     while (     (!fFound)
    122              && (hwndThis = WinGetNextWindow(henum))
    123           )
    124     {
    125         CHAR    szClass[200];
    126         if (WinQueryClassName(hwndThis, sizeof(szClass), szClass))
    127         {
    128             if (!strcmp(szClass, "#1"))
    129             {
    130                 // frame window: check the children
    131                 HENUM   henumFrame;
    132                 HWND    hwndChild;
    133                 henumFrame = WinBeginEnumWindows(hwndThis);
    134                 while (    (!fFound)
    135                         && (hwndChild = WinGetNextWindow(henumFrame))
    136                       )
    137                 {
    138                     CHAR    szChildClass[200];
    139                     if (WinQueryClassName(hwndChild, sizeof(szChildClass), szChildClass))
    140                     {
    141                         if (!strcmp(szChildClass, "WindowList"))
    142                         {
    143                             // yup, found:
    144                             G_HookData.hwndWindowList = hwndThis;
    145                             fFound = TRUE;
    146                         }
    147                     }
    148                 }
    149                 WinEndEnumWindows(henumFrame);
    150             }
    151         }
    152     }
    153     WinEndEnumWindows(henum);
    154 
    155 }
    156 
    157 
    158 /******************************************************************
    159  *
    160  *  Hook interface
    161  *
    162  ******************************************************************/
    163 
    164 /*
    165  *@@ _DLL_InitTerm:
    166  *      this function gets called automatically by the OS/2 DLL
    167  *      during DosLoadModule processing, on the thread which
    168  *      invoked DosLoadModule.
    169  *
    170  *      We override this function (which is normally provided by
    171  *      the runtime library) to intercept this DLL's module handle.
    172  *
    173  *      Since OS/2 calls this function directly, it must have
    174  *      _System linkage.
    175  *
    176  *      Note: You must then link using the /NOE option, because
    177  *      the VAC++ runtimes also contain a _DLL_Initterm, and the
    178  *      linker gets in trouble otherwise.
    179  *      The XWorkplace makefile takes care of this.
    180  *
    181  *      This function must return 0 upon errors or 1 otherwise.
    182  *
    183  *@@changed V0.9.0 [umoeller]: reworked locale initialization
    184  */
     79VOID InitializeVioWindow(VOID)
     80{
     81}
     82
    18583
    18684unsigned long _System _DLL_InitTerm(unsigned long hModule,
     
    19391            // store the DLL handle in the global variable
    19492            G_HookData.hmodDLL = hModule;
    195 
    196             // now initialize the C run-time environment before we
    197             // call any runtime functions
    198             if (_CRT_init() == -1)
    199                return (0);  // error
    200 
    201         break; }
     93            break;
     94        }
    20295
    20396        case 1:
    204             // DLL being freed: cleanup runtime
    205             _CRT_term();
    20697            break;
    20798
    20899        default:
    209             // other code: beep for error
    210             DosBeep(100, 100);
    211100            return (0);     // error
    212101    }
    213 
    214102    // a non-zero value must be returned to indicate success
    215103    return (1);
     
    218106/*
    219107 *@@ hookInit:
    220  *      registers (sets) all the hooks and initializes data.
    221  *
    222  *      In any case, a pointer to the DLL's static HOOKDATA
    223  *      structure is returned. In this struct, the caller
    224  *      can examine the two flags for whether the hooks
    225  *      were successfully installed.
    226  *
    227  *      Note: All the exported hook* interface functions must
    228  *      only be called by the same process, which is the
    229  *      XWorkplace daemon (XWPDAEMN.EXE).
    230  *
    231  *      This gets called by XWPDAEMN.EXE when
    232  *
    233  *@@changed V0.9.1 (2000-02-01) [umoeller]: fixed missing global updates
    234  *@@changed V0.9.2 (2000-02-21) [umoeller]: added new system hooks
    235  */
    236 
    237 PHOOKDATA EXPENTRY hookInit(HAB hab)               
    238 {
    239     APIRET arc = NO_ERROR;
    240 
    241     if (arc == NO_ERROR)
    242     {
     108 *  registers (sets) all the hooks and initializes data.
     109 *  we do call this for every process.
     110 */
     111
     112BOOL WIN32API hookInit(HAB hab, PSZ pszWindowClassName)
     113{
     114   if (G_HookData.hmodDLL)       // initialized by _DLL_InitTerm
     115   {
     116        BOOL fSuccess;
     117
     118        // initialize globals needed by the hook
     119        InitializeVioWindow();
     120
     121        // install hooks, for each app use its own hook
     122        // hooks automatically releases when process finishes
     123        // so we need to set hook for each vio app. The reason why
     124        // djmutex used one global hook is because it was loaded
     125        // by daemon.
     126
    243127        G_HookData.habDaemonObject = hab;
    244 
    245         // G_HookData.hmtxPageMage = hmtxPageMage;
    246 
    247         if (G_HookData.hmodDLL)       // initialized by _DLL_InitTerm
    248         {
    249             // BOOL fSuccess = FALSE;
    250 
    251             // initialize globals needed by the hook
    252             InitializeGlobalsForHooks();
    253 
    254             // install hooks, but only once...
    255 #if 0
    256             if (!G_HookData.fLockupHooked)
    257                 G_HookData.fLockupHooked = WinSetHook(G_HookData.habDaemonObject,
    258                                                       NULLHANDLE, // system hook
    259                                                       HK_LOCKUP,  // lockup hook
    260                                                       (PFN)hookLockupHook,
    261                                                       G_HookData.hmodDLL);
    262 #endif
    263             if (!G_HookData.fPreAccelHooked)
    264                 G_HookData.fPreAccelHooked = WinSetHook(G_HookData.habDaemonObject,
    265                                                         NULLHANDLE, // system hook
    266                                                         HK_PREACCEL,  // pre-accelerator table hook (undocumented)
    267                                                         (PFN)hookPreAccelHook,
    268                                                         G_HookData.hmodDLL);
    269         }
    270 
     128        G_HookData.fPreAccelHooked = WinSetHook(hab, NULLHANDLE, // system hook
     129                                                HK_PREACCEL,  // pre-accelerator table hook (undocumented)
     130                                                (PFN)hookPreAccelHook,
     131                                                G_HookData.hmodDLL);
     132
     133        strncpy(G_HookData.szWindowClass, pszWindowClassName, sizeof(G_HookData.szWindowClass));
     134        return TRUE;
    271135    }
    272 
    273     return (&G_HookData);
     136    return FALSE;
    274137}
    275138
     
    278141 *      deregisters the hook function and frees allocated
    279142 *      resources.
    280  *
    281  *      Note: This function must only be called by the same
    282  *      process which called hookInit (that is, the daemon),
    283  *      or resources cannot be properly freed.
    284  *
    285  *@@changed V0.9.1 (2000-02-01) [umoeller]: fixed missing global updates
    286  *@@changed V0.9.2 (2000-02-21) [umoeller]: added new system hooks
    287  *@@changed V0.9.3 (2000-04-20) [umoeller]: added function keys support
    288  */
    289 
    290 BOOL EXPENTRY hookKill(void)
    291 {
    292     BOOL brc = FALSE;
     143 */
     144
     145BOOL WIN32API hookKill()
     146{
     147    // PM will cleanup the hook when the the creators message queue is destroyed
     148    // or process terminates.
    293149
    294150    if (G_HookData.fPreAccelHooked)
     
    299155                       (PFN)hookPreAccelHook,
    300156                       G_HookData.hmodDLL);
    301         brc = TRUE;
     157
    302158        G_HookData.fPreAccelHooked = FALSE;
    303159    }
    304  
    305 #if 0
    306     if (G_HookData.fLockupHooked)
    307     {
    308         WinReleaseHook(G_HookData.habDaemonObject,
    309                        NULLHANDLE,
    310                        HK_LOCKUP,       // lockup hook
    311                        (PFN)hookLockupHook,
    312                        G_HookData.hmodDLL);
    313         brc = TRUE;
    314         G_HookData.fLockupHooked = FALSE;
    315     }
    316 #endif
    317 
    318     return (brc);
     160
     161    return TRUE;
    319162}
    320163
     
    331174  // Note: this hook is called on the stack of the current process
    332175  // so we rather keep the buffer small ...
    333   CHAR    szClass[80];
    334  
     176  CHAR szClass[80];
     177
    335178  if (hwndLastWin32Window == hwnd)
    336179    return TRUE;
    337  
    338   for(;;)
     180
     181  if (WinQueryClassName(hwnd, sizeof(szClass), szClass))
    339182  {
    340     if (WinQueryClassName(hwnd, sizeof(szClass), szClass))
     183    if (strcmp(szClass, G_HookData.szWindowClass) == 0)
    341184    {
    342       if (strcmp(szClass, WIN32_STDFRAMECLASS) == 0)
    343       {
    344         hwndLastWin32Window = hwnd;
    345         return TRUE;
    346       }
    347       else
    348       {
    349         // walk up the tree
    350         hwnd = WinQueryWindow(hwnd,
    351                               QW_PARENT);
    352        
    353         // no parent window found?
    354         if (NULLHANDLE == hwnd)
    355         {
    356           hwndLastWin32Window = 0;
    357           return FALSE;
    358         }
    359       }
    360     }
    361     else
    362     {
    363       hwndLastWin32Window = 0;
    364       return FALSE;
     185      hwndLastWin32Window = hwnd;
     186      return TRUE;
    365187    }
    366188  }
    367 }
    368 
    369 
    370 /******************************************************************
    371  *
    372  *  Pre-accelerator hook
    373  *
    374  ******************************************************************/
     189  return FALSE;
     190}
     191
    375192
    376193/*
     
    395212 *      when menus have corresponding shortcuts.
    396213 *
    397  *      As a result, as opposed to other hotkey software you
    398  *      might know, XWorkplace does properly react to "Ctrl+Alt"
    399  *      keyboard combinations, even if a menu would get called
    400  *      with the "Alt" key. ;-)
    401  *
    402  *      As with hookInputHook, we return TRUE if the message is
    403  *      to be swallowed, or FALSE if the current application (or
    404  *      the next hook in the hook chain) should still receive the
    405  *      message.
    406  *
    407  *@@changed V0.9.3 (2000-04-09) [umoeller]: added check for system lockup
    408  *@@changed V0.9.3 (2000-04-09) [umoeller]: added PageMage hotkeys
    409  *@@changed V0.9.3 (2000-04-09) [umoeller]: added KC_SCANCODE check
    410  *@@changed V0.9.3 (2000-04-10) [umoeller]: moved debug code to hook
     214 * ODIN: Keep in mind that effort must be taken to make processing as
     215 *       optimal as possible as this is install by each and every Odin
     216 *       process and they will process and reject the exact same messages.
     217 *       Only the first called hook will actually do something useful.
    411218 */
    412219
    413220BOOL EXPENTRY hookPreAccelHook(HAB hab, PQMSG pqmsg, ULONG option)
    414221{
    415     // set return value:
    416     // per default, pass message on to next hook or application
    417     BOOL        brc = FALSE;
    418 
    419222    if (pqmsg == NULL)
    420223        return (FALSE);
     
    422225    switch(pqmsg->msg)
    423226    {
    424         /*
    425          * WM_CHAR:
    426          *      keyboard activity.
    427          */
    428227
    429228        case WM_CHAR:
     
    434233          // if (  (!G_HookData.hwndLockupFrame)    // system not locked up
    435234          // ...
    436          
    437      
     235
    438236          // is this an WIN32 window?
    439237          if (!i_isWin32Window(pqmsg->hwnd))
     
    442240            return FALSE;
    443241          }
    444          
     242
    445243          // check if we've encountered a so called critical key
    446244          // (this is the scan code which is supposed to be valid
     
    448246          switch ( CHAR4FROMMP(pqmsg->mp1) )
    449247          {
    450             default:
    451               return FALSE;
    452            
    453             case PMSCAN_SHIFTLEFT:
    454             case PMSCAN_SHIFTRIGHT:
    455                 //PM layer switching doesn't work as it checks for the frame
    456                 //class name instead of the window type
    457                 if( SHORT1FROMMP(pqmsg->mp1) & KC_ALT )
    458                 {
    459                   BOOL      fsuccess;
    460                   ULONG     ulLayerID;
    461 
    462                   if( CHAR4FROMMP(pqmsg->mp1) == PMSCAN_SHIFTLEFT )
    463                     ulLayerID= KL_NATIONAL;
    464                   else
    465                     ulLayerID= KL_LATIN;
    466                   fsuccess= WinSetKbdLayer( pqmsg->hwnd /* HWND_DESKTOP */
    467                                           , ulLayerID        /* First country/language layout       */
    468                                           , SKLF_SENDMSG );  /* Post the WM_KBDLAYERCHANGED message */
    469                   HWND hwnd;
    470                   /* Store layerFlag in parent(frame) window data */
    471                   hwnd= WinQueryWindow( pqmsg->hwnd, QW_PARENT );
    472                   WinSetWindowULong( hwnd, QWL_KBDLAYER, ulLayerID );
    473                 }
    474                 //no break
    475 
    476             // Intercept PM Window Hotkeys such as
    477             // Alt-F7 do enable window moving by keyboard.
    478             case PMSCAN_F1:
    479             case PMSCAN_F2:
    480             case PMSCAN_F3:
    481             case PMSCAN_F4:
    482             case PMSCAN_F5:
    483             case PMSCAN_F6:
    484             case PMSCAN_F7:
    485             case PMSCAN_F8:
    486             case PMSCAN_F9:
    487             case PMSCAN_F10:
    488             case PMSCAN_F11:
    489             case PMSCAN_F12:
    490            
    491             // Try to prevent Ctrl-Esc, etc. from being intercepted by PM
    492             case PMSCAN_ESC:
    493             case PMSCAN_CTRLLEFT:
    494             case PMSCAN_CTRLRIGHT:
    495            
    496             case PMSCAN_PRINT:
    497             case PMSCAN_ALTLEFT:
    498             case PMSCAN_SCROLLLOCK:
    499             case PMSCAN_ENTER:
    500             case PMSCAN_PADENTER:
    501             case PMSCAN_CAPSLOCK:
    502               // OK, as we've got a special key here, we've got
    503               // to rewrite the message so PM will ignore the key
    504               // and won't translate the message to anything else.
    505            
    506               pqmsg->msg = WM_CHAR_SPECIAL;
    507            
    508               break;
     248             default:
     249               return FALSE;
     250
     251             // Intercept PM Window Hotkeys such as
     252             // Alt-F7 do enable window moving by keyboard.
     253             case PMSCAN_F1:
     254             case PMSCAN_F2:
     255             case PMSCAN_F3:
     256             case PMSCAN_F4:
     257             case PMSCAN_F5:
     258             case PMSCAN_F6:
     259             case PMSCAN_F7:
     260             case PMSCAN_F8:
     261             case PMSCAN_F9:
     262             case PMSCAN_F10:
     263             case PMSCAN_F11:
     264             case PMSCAN_F12:
     265
     266             // Try to prevent Ctrl-Esc, etc. from being intercepted by PM
     267             case PMSCAN_ESC:
     268             case PMSCAN_CTRLLEFT:
     269             case PMSCAN_CTRLRIGHT:
     270
     271             case PMSCAN_PRINT:
     272             case PMSCAN_ALTLEFT:
     273             case PMSCAN_SCROLLLOCK:
     274             case PMSCAN_ENTER:
     275             case PMSCAN_PADENTER:
     276             case PMSCAN_CAPSLOCK:
     277               // OK, as we've got a special key here, we've got
     278               // to rewrite the message so PM will ignore the key
     279               // and won't translate the message to anything else.
     280
     281               pqmsg->msg = WM_CHAR_SPECIAL;
     282
     283               break;
    509284
    510285        //
    511286        // AltGr needs special handling
    512287        //
    513         // AltGr -> WM_KEYDOWN (VK_CONTROL), WM_KEYDOWN (VK_MENU) 
     288        // AltGr -> WM_KEYDOWN (VK_CONTROL), WM_KEYDOWN (VK_MENU)
    514289        //          WM_SYSKEYUP (VK_CONTROL)
    515290        //          WM_KEYUP (VK_MENU)
    516291        //
    517         // Ctrl+AltGr -> WM_KEYDOWN (VK_CONTROL), WM_KEYUP (VK_CONTROL) 
     292        // Ctrl+AltGr -> WM_KEYDOWN (VK_CONTROL), WM_KEYUP (VK_CONTROL)
    518293        //               WM_KEYDOWN (VK_CONTROL)
    519         //               WM_KEYDOWN (VK_MENU) 
     294        //               WM_KEYDOWN (VK_MENU)
    520295        //               WM_KEYUP (VK_MENU)
    521         //               WM_KEYUP (VK_CONTROL) 
    522         //
    523         // AltGr+Ctrl -> WM_KEYDOWN (VK_CONTROL), WM_KEYDOWN (VK_MENU) 
    524         //               WM_KEYDOWN (VK_CONTROL) 
    525         //               WM_SYSKEYUP (VK_CONTROL) 
    526         //               WM_SYSKEYUP (VK_CONTROL) 
     296        //               WM_KEYUP (VK_CONTROL)
     297        //
     298        // AltGr+Ctrl -> WM_KEYDOWN (VK_CONTROL), WM_KEYDOWN (VK_MENU)
     299        //               WM_KEYDOWN (VK_CONTROL)
     300        //               WM_SYSKEYUP (VK_CONTROL)
     301        //               WM_SYSKEYUP (VK_CONTROL)
    527302        //               WM_KEYUP (VK_MENU)
    528303        //
     
    537312        //
    538313        // NOTE: Ctrl = Ctrl-Left; AltGr doesn't care about the right Ctrl key
    539         //
    540           case PMSCAN_ALTRIGHT:
    541           {
    542               QMSG   msg = *pqmsg;
    543               ULONG  ctrlstate;
    544               ULONG  flags;
    545               ULONG  mp1, mp2;
    546 
    547               flags = SHORT1FROMMP(pqmsg->mp1);
    548 
    549               pqmsg->msg = WM_CHAR_SPECIAL;
    550 
    551               if(flags & KC_KEYUP)
    552               {//AltGr up
     314        //
     315             case PMSCAN_ALTRIGHT:
     316             {
     317                QMSG   msg = *pqmsg;
     318                ULONG  ctrlstate;
     319                ULONG  flags;
     320                ULONG  mp1, mp2;
     321
     322                flags = SHORT1FROMMP(pqmsg->mp1);
     323
     324                pqmsg->msg = WM_CHAR_SPECIAL;
     325
     326                if (flags & KC_KEYUP)
     327                {   
     328                  //AltGr up
    553329                  ctrlstate  = WinGetPhysKeyState(HWND_DESKTOP, PMSCAN_CTRLLEFT);
    554                   if(!(ctrlstate & 0x8000))
    555                   {//ctrl is up, translate this message to Ctrl key up
     330                  if (!(ctrlstate & 0x8000))
     331                  { 
     332                      //ctrl is up, translate this message to Ctrl key up
    556333                      mp1  = (PMSCAN_CTRLLEFT << 24);   //scancode
    557334                      mp1 |= (1 << 16);                 //repeat count
     
    562339                      pqmsg->mp2 = (MPARAM)mp2;
    563340
    564                       //and finally, post the AltGr WM_CHAR message           
     341                      //and finally, post the AltGr WM_CHAR message
    565342                      WinPostMsg(msg.hwnd, WM_CHAR_SPECIAL, msg.mp1, msg.mp2);
    566343                  }
    567344                  //else do nothing
    568               }
    569               else
    570               {//AltGr down
     345               }
     346               else
     347               {
     348                  //AltGr down
    571349                  ctrlstate  = WinGetPhysKeyState(HWND_DESKTOP, PMSCAN_CTRLLEFT);
    572                   if(ctrlstate & 0x8000)
    573                   {//ctrl is down, translate this message to Ctrl key up
     350                  if (ctrlstate & 0x8000)
     351                  {
     352                      //ctrl is down, translate this message to Ctrl key up
    574353                      mp1  = (PMSCAN_CTRLLEFT << 24);   //scancode
    575354                      mp1 |= (1 << 16);                 //repeat count
     
    586365                  mp2  = (VK_CTRL << 16);               //virtual keycode
    587366
    588                   if(ctrlstate & 0x8000)
    589                   {//ctrl is down, must post this message
     367                  if (ctrlstate & 0x8000)
     368                  {
     369                      //ctrl is down, must post this message
    590370                      WinPostMsg(msg.hwnd, WM_CHAR_SPECIAL_ALTGRCONTROL, (MPARAM)mp1, (MPARAM)mp2);
    591371                  }
    592                   else
    593                   {//translate this message into control key down
     372                  else
     373                  {
     374                      //translate this message into control key down
    594375                      pqmsg->msg = WM_CHAR_SPECIAL_ALTGRCONTROL;
    595376                      pqmsg->mp1 = (MPARAM)mp1;
    596377                      pqmsg->mp2 = (MPARAM)mp2;
    597378                  }
    598                   //and finally, post the AltGr WM_CHAR message           
     379                  //and finally, post the AltGr WM_CHAR message
    599380                  WinPostMsg(msg.hwnd, WM_CHAR_SPECIAL, msg.mp1, msg.mp2);
    600381              }
    601382              break;
    602           }
    603 
    604           }
     383           }
    605384        }
    606      
    607385        break; // WM_CHAR
     386      }
    608387    } // end switch(msg)
    609 
    610     return (brc);
    611 }
    612 
     388    return FALSE;
     389}
  • trunk/src/pmkbdhk/pmkbdhk.def

    r7623 r10286  
    1 ; $Id: pmkbdhk.def,v 1.2 2001-12-13 12:25:21 sandervl Exp $
     1; $Id: pmkbdhk.def,v 1.3 2003-10-22 12:45:13 sandervl Exp $
    22
    3 LIBRARY PMKBDHK INITGLOBAL
     3LIBRARY PMKBDHK INITINSTANCE TERMINSTANCE
    44DESCRIPTION 'Odin OS/2 Presentation Manager Keyboard Hook'
    5 DATA SINGLE SHARED
     5DATA MULTIPLE NONSHARED LOADONCALL
    66CODE SHARED LOADONCALL
    77
     8IMPORTS
     9        DosQuerySysState   = DOSCALLS.368
     10
    811EXPORTS
    9         hookKill        @2
    10         hookInit        @3
     12        _hookKill@0        @2
     13        _hookInit@8        @3
  • trunk/src/pmkbdhk/pmkbdhkp.h

    r7168 r10286  
    1 /* $Id: pmkbdhkp.h,v 1.2 2001-10-23 13:56:27 achimha Exp $ */
     1/* $Id: pmkbdhkp.h,v 1.3 2003-10-22 12:45:13 sandervl Exp $ */
    22/*
    3  * Window Menu wrapper functions for OS/2
    4  *
     3 * Window low-level keyboard hook
    54 *
    65 * Copyright 2001 Patrick Haller (patrick.haller@innotek.de)
    7  *
    8  *
    9  *      Copyright (C) 1999-2000 Ulrich M”ller.
     6 * Copyright (C) 1999-2000 Ulrich M”ller.
     7 * Copyright 2002-2003 Innotek Systemberatung GmbH
    108 */
    11  
     9
    1210#ifndef __PMKBDHK_PRIVATE_H__
    1311#define __PMKBDHK_PRIVATE_H__
    1412
     13#include <odin.h>
    1514
    1615/*
    17 * HK_PREACCEL:
    18 *      additional undocumented PM hook type,
    19 *      for pre-accelerator table hooks
    20 *      (see xwphook.c for details);
    21 *      this definition taken out of the
    22 *      ProgramCommander/2 source (thanks,
    23 *      Roman Stangl).
    24 */
     16 * HK_PREACCEL:
     17 *      additional undocumented PM hook type
     18 */
    2519
    2620#ifndef HK_PREACCEL
     
    3731#endif
    3832
    39 
    40 /*
    41  * These definitions come from user32\pmframe.h.
    42  * They're repeated here to avoid header conflicts
    43  * with the USER32 module
    44  */
    45 
    46 #ifndef WIN32_STDCLASS
    47 #define WIN32_STDCLASS      "Win32WindowClass"
    48 #endif
    49 
    50 #ifndef WIN32_STDFRAMECLASS
    51 #define WIN32_STDFRAMECLASS "Win32FrameClass"
    52 #endif
    53 
    54     /* ******************************************************************
    55      *                                                                  *
    56      *   Structures                                                     *
    57      *                                                                  *
    58      ********************************************************************/
     33typedef struct _HOOKDATA
     34{
     35   HAB         habDaemonObject;    // anchor block of hwndDaemonObject; cached for speed
     36   BOOL        fPreAccelHooked;
     37   ULONG       pid;
     38   HWND        hwndVio;
     39   HMODULE     hmodDLL;            // module handle
     40   char        szWindowClass[256];
     41} HOOKDATA, *PHOOKDATA;
    5942
    6043
    61     /*
    62      *@@ HOOKDATA:
    63      *      global hook data structure. Only one instance
    64      *      of this is in the shared data segment of
    65      *      XWPHOOK.DLL, and a pointer to that structure
    66      *      is returned to the daemon which initially loads
    67      *      that DLL by hookInit and then stored by the
    68      *      daemon. As a result, this structure is shared
    69      *      between the hook and the daemon, and both can
    70      *      access it at any time.
    71      *
    72      *      This is statically initialized to 0 when the hook
    73      *      DLL is loaded. hookInit will then set up most
    74      *      fields in here.
    75      *
    76      *      This contains setup data (the state of the
    77      *      hook), some data which needs to be cached,
    78      *      as well as the HOOKCONFIG structure which
    79      *      is used to configure the hook and the daemon.
    80      *      That sub-structure gets (re)loaded from OS2.INI
    81      *      upon daemon startup and when XDM_HOOKCONFIG is
    82      *      received by fnwpDaemonObject.
    83      */
     44extern HOOKDATA G_HookData;
    8445
    85     typedef struct _HOOKDATA
    86     {
    87         BOOL        fPreAccelHooked;    // pre-accelerator table hook installed?
    88 
    89         HAB         habDaemonObject;
    90                 // anchor block of hwndDaemonObject; cached for speed
    91 
    92         HMODULE     hmodDLL;
    93                 // XWPHOOK.DLL module handle
    94 
    95         HWND        hwndPMDesktop;
    96                 // desktop window handle (WinQueryDesktopWindow)
    97      
    98         HWND        hwndWindowList;
    99                 // window list handle
    100      
    101         ULONG       pidPM;
    102                 // process ID of first PMSHELL.EXE V0.9.7 (2001-01-21) [umoeller]
    103 
    104 //        HWND        hwndLockupFrame;
    105                 // current lockup window, if any
    106     } HOOKDATA, *PHOOKDATA;
    107 
    108 
    109     /* ******************************************************************
    110      *
    111      *   Hook DLL prototypes
    112      *
    113      ********************************************************************/
    114 
    115     PHOOKDATA EXPENTRY hookInit(HWND hwndDaemonObject);
    116 
    117     BOOL EXPENTRY hookKill(VOID);
    118 
    119     /* ******************************************************************
    120      *
    121      *   Internal prototypes
    122      *
    123      ********************************************************************/
    124 
    125     extern HOOKDATA G_HookData;
     46extern APIRET APIENTRY DosQuerySysState (ULONG func,
     47                                ULONG par1, ULONG pid, ULONG _reserved_,
     48                                PVOID buf,
     49                                ULONG bufsz);
    12650
    12751#endif //__PMKBDHK_PRIVATE_H__
Note: See TracChangeset for help on using the changeset viewer.