Added support for low-level mouse and keyboard hooks.
[wine] / windows / keyboard.c
1 /*
2  * KEYBOARD driver
3  *
4  * Copyright 1993 Bob Amstadt
5  * Copyright 1996 Albrecht Kleine 
6  * Copyright 1997 David Faure
7  * Copyright 1998 Morten Welinder
8  * Copyright 1998 Ulrich Weigand
9  *
10  */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15
16 #include "windef.h"
17 #include "winbase.h"
18 #include "wingdi.h"
19 #include "winuser.h"
20 #include "win.h"
21 #include "user.h"
22 #include "message.h"
23 #include "callback.h"
24 #include "builtin16.h"
25 #include "debugtools.h"
26 #include "winerror.h"
27
28 DEFAULT_DEBUG_CHANNEL(keyboard);
29
30 #include "pshpack1.h"
31 typedef struct _KBINFO
32 {
33     BYTE Begin_First_Range;
34     BYTE End_First_Range;
35     BYTE Begin_Second_Range;
36     BYTE End_Second_Range;
37     WORD StateSize;
38 } KBINFO, *LPKBINFO;
39 #include "poppack.h"
40
41 /**********************************************************************/
42
43 typedef VOID CALLBACK (*LPKEYBD_EVENT_PROC)(BYTE,BYTE,DWORD,DWORD);
44
45 static LPKEYBD_EVENT_PROC DefKeybEventProc;
46 static LPBYTE pKeyStateTable;
47
48 /***********************************************************************
49  *              KEYBOARD_CallKeybdEventProc
50  */
51 static VOID WINAPI KEYBOARD_CallKeybdEventProc( FARPROC16 proc,
52                                                 BYTE bVk, BYTE bScan,
53                                                 DWORD dwFlags, DWORD dwExtraInfo )
54 {
55     CONTEXT86 context;
56
57     memset( &context, 0, sizeof(context) );
58     context.SegCs = SELECTOROF( proc );
59     context.Eip   = OFFSETOF( proc );
60     context.Eax   = bVk | ((dwFlags & KEYEVENTF_KEYUP)? 0x8000 : 0);
61     context.Ebx   = bScan | ((dwFlags & KEYEVENTF_EXTENDEDKEY) ? 0x100 : 0);
62     context.Esi   = LOWORD( dwExtraInfo );
63     context.Edi   = HIWORD( dwExtraInfo );
64
65     wine_call_to_16_regs_short( &context, 0 );
66 }
67
68 /***********************************************************************
69  *              Inquire (KEYBOARD.1)
70  */
71 WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo) 
72 {
73   kbInfo->Begin_First_Range = 0;
74   kbInfo->End_First_Range = 0;
75   kbInfo->Begin_Second_Range = 0;
76   kbInfo->End_Second_Range = 0;
77   kbInfo->StateSize = 16; 
78   
79   return sizeof(KBINFO);
80 }
81
82 /***********************************************************************
83  *              Enable (KEYBOARD.2)
84  */
85 VOID WINAPI KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState )
86 {
87     if (DefKeybEventProc) THUNK_Free( (FARPROC)DefKeybEventProc );
88     DefKeybEventProc = (LPKEYBD_EVENT_PROC)THUNK_Alloc( proc, (RELAY)KEYBOARD_CallKeybdEventProc );
89     pKeyStateTable = lpKeyState;
90
91     memset( lpKeyState, 0, 256 ); /* all states to false */
92 }
93
94 /***********************************************************************
95  *              Disable (KEYBOARD.3)
96  */
97 VOID WINAPI KEYBOARD_Disable(VOID)
98 {
99   THUNK_Free( (FARPROC)DefKeybEventProc );
100   
101   DefKeybEventProc = NULL;
102   pKeyStateTable = NULL;
103 }
104
105
106 /**********************************************************************
107  *              SetSpeed (KEYBOARD.7)
108  */
109 WORD WINAPI SetSpeed16(WORD unused)
110 {
111     FIXME("(%04x): stub\n", unused);
112     return 0xffff;
113 }
114
115 /**********************************************************************
116  *              ScreenSwitchEnable (KEYBOARD.100)
117  */
118 VOID WINAPI ScreenSwitchEnable16(WORD unused)
119 {
120   FIXME("(%04x): stub\n", unused);
121 }
122
123 /**********************************************************************
124  *              OemKeyScan (KEYBOARD.128)
125  *              OemKeyScan (USER32.@)
126  */
127 DWORD WINAPI OemKeyScan(WORD wOemChar)
128 {
129   TRACE("*OemKeyScan (%d)\n", wOemChar);
130
131   return wOemChar;
132 }
133
134 /**********************************************************************
135  *              VkKeyScan (KEYBOARD.129)
136  */
137 WORD WINAPI VkKeyScan16(CHAR cChar)
138 {
139     return VkKeyScanA( cChar );
140 }
141
142 /******************************************************************************
143  *              GetKeyboardType (KEYBOARD.130)
144  */
145 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
146 {
147     return GetKeyboardType( nTypeFlag );
148 }
149
150 /******************************************************************************
151  *              MapVirtualKey (KEYBOARD.131)
152  *
153  * MapVirtualKey translates keycodes from one format to another
154  */
155 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
156 {
157     return MapVirtualKeyA(wCode,wMapType);
158 }
159
160 /****************************************************************************
161  *              GetKBCodePage (KEYBOARD.132)
162  */
163 INT16 WINAPI GetKBCodePage16(void)
164 {
165     return GetKBCodePage();
166 }
167
168 /****************************************************************************
169  *              GetKeyNameText (KEYBOARD.133)
170  */
171 INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
172 {
173     return GetKeyNameTextA( lParam, lpBuffer, nSize );
174 }
175
176 /****************************************************************************
177  *              ToAscii (KEYBOARD.4)
178  *
179  * The ToAscii function translates the specified virtual-key code and keyboard
180  * state to the corresponding Windows character or characters.
181  *
182  * If the specified key is a dead key, the return value is negative. Otherwise,
183  * it is one of the following values:
184  * Value        Meaning
185  * 0    The specified virtual key has no translation for the current state of the keyboard.
186  * 1    One Windows character was copied to the buffer.
187  * 2    Two characters were copied to the buffer. This usually happens when a
188  *      dead-key character (accent or diacritic) stored in the keyboard layout cannot
189  *      be composed with the specified virtual key to form a single character.
190  *
191  * FIXME : should do the above (return 2 for non matching deadchar+char combinations)
192  *
193  */
194 INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, 
195                        LPVOID lpChar, UINT16 flags) 
196 {
197     return ToAscii( virtKey, scanCode, lpKeyState, lpChar, flags );
198 }
199
200 /***********************************************************************
201  *              MessageBeep (USER.104)
202  */
203 void WINAPI MessageBeep16( UINT16 i )
204 {
205     MessageBeep( i );
206 }
207
208 /***********************************************************************
209  *              MessageBeep (USER32.@)
210  */
211 BOOL WINAPI MessageBeep( UINT i )
212 {
213     BOOL active = TRUE;
214     SystemParametersInfoA( SPI_GETBEEP, 0, &active, FALSE );
215     if (active) USER_Driver.pBeep();
216     return TRUE;
217 }