Replaced ToAscii by ToUnicode in the User driver interface.
[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 "wingdi.h"
18 #include "winuser.h"
19 #include "wine/keyboard16.h"
20 #include "win.h"
21 #include "heap.h"
22 #include "keyboard.h"
23 #include "user.h"
24 #include "message.h"
25 #include "callback.h"
26 #include "builtin16.h"
27 #include "debugtools.h"
28 #include "struct32.h"
29 #include "winerror.h"
30
31 DEFAULT_DEBUG_CHANNEL(keyboard)
32 DECLARE_DEBUG_CHANNEL(event)
33
34 /**********************************************************************/
35
36 static LPKEYBD_EVENT_PROC DefKeybEventProc = NULL;
37 LPBYTE pKeyStateTable = NULL;
38
39 /***********************************************************************
40  *           KEYBOARD_Inquire                   (KEYBOARD.1)
41  */
42 WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo) 
43 {
44   kbInfo->Begin_First_Range = 0;
45   kbInfo->End_First_Range = 0;
46   kbInfo->Begin_Second_Range = 0;
47   kbInfo->End_Second_Range = 0;
48   kbInfo->StateSize = 16; 
49   
50   return sizeof(KBINFO);
51 }
52
53 /***********************************************************************
54  *           KEYBOARD_Enable                    (KEYBOARD.2)
55  */
56 VOID WINAPI KEYBOARD_Enable( LPKEYBD_EVENT_PROC lpKeybEventProc, 
57                              LPBYTE lpKeyState )
58 {
59   static BOOL initDone = FALSE;
60
61   THUNK_Free( (FARPROC)DefKeybEventProc );
62   
63   DefKeybEventProc = lpKeybEventProc;
64   pKeyStateTable = lpKeyState;
65   
66   /* all states to false */
67   memset( lpKeyState, 0, 256 );
68   
69   if (!initDone) USER_Driver.pInitKeyboard();
70   initDone = TRUE;
71 }
72
73 static VOID WINAPI KEYBOARD_CallKeybdEventProc( FARPROC16 proc,
74                                                 BYTE bVk, BYTE bScan,
75                                                 DWORD dwFlags, DWORD dwExtraInfo )
76 {
77     CONTEXT86 context;
78
79     memset( &context, 0, sizeof(context) );
80     context.SegCs = SELECTOROF( proc );
81     context.Eip   = OFFSETOF( proc );
82     context.Eax   = bVk | ((dwFlags & KEYEVENTF_KEYUP)? 0x8000 : 0);
83     context.Ebx   = bScan | ((dwFlags & KEYEVENTF_EXTENDEDKEY) ? 0x100 : 0);
84     context.Esi   = LOWORD( dwExtraInfo );
85     context.Edi   = HIWORD( dwExtraInfo );
86
87     CallTo16RegisterShort( &context, 0 );
88 }
89
90 VOID WINAPI WIN16_KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState )
91 {
92     LPKEYBD_EVENT_PROC thunk = 
93       (LPKEYBD_EVENT_PROC)THUNK_Alloc( proc, (RELAY)KEYBOARD_CallKeybdEventProc );
94
95     KEYBOARD_Enable( thunk, lpKeyState );
96 }
97
98 /***********************************************************************
99  *           KEYBOARD_Disable                   (KEYBOARD.3)
100  */
101 VOID WINAPI KEYBOARD_Disable(VOID)
102 {
103   THUNK_Free( (FARPROC)DefKeybEventProc );
104   
105   DefKeybEventProc = NULL;
106   pKeyStateTable = NULL;
107 }
108
109 /***********************************************************************
110  *           KEYBOARD_SendEvent
111  */
112 void KEYBOARD_SendEvent( BYTE bVk, BYTE bScan, DWORD dwFlags,
113                          DWORD posX, DWORD posY, DWORD time )
114 {
115   WINE_KEYBDEVENT wke;
116   int iWndsLocks;
117   
118   if ( !DefKeybEventProc ) return;
119   
120   TRACE_(event)("(%d,%d,%04lX)\n", bVk, bScan, dwFlags );
121   
122   wke.magic = WINE_KEYBDEVENT_MAGIC;
123   wke.posX  = posX;
124   wke.posY  = posY;
125   wke.time  = time;
126   
127   /* To avoid deadlocks, we have to suspend all locks on windows structures
128      before the program control is passed to the keyboard driver */
129   iWndsLocks = WIN_SuspendWndsLock();
130   DefKeybEventProc( bVk, bScan, dwFlags, (DWORD)&wke );
131   WIN_RestoreWndsLock(iWndsLocks);
132 }
133
134 /**********************************************************************
135  *           SetSpeed16      (KEYBOARD.7)
136  */
137 WORD WINAPI SetSpeed16(WORD unused)
138 {
139     FIXME("(%04x): stub\n", unused);
140     return 0xffff;
141 }
142
143 /**********************************************************************
144  *           ScreenSwitchEnable      (KEYBOARD.100)
145  */
146 VOID WINAPI ScreenSwitchEnable16(WORD unused)
147 {
148   FIXME("(%04x): stub\n", unused);
149 }
150
151 /**********************************************************************
152  *           OemKeyScan      (KEYBOARD.128)(USER32.401)
153  */
154 DWORD WINAPI OemKeyScan(WORD wOemChar)
155 {
156   TRACE("*OemKeyScan (%d)\n", wOemChar);
157
158   return wOemChar;
159 }
160
161 /**********************************************************************
162  *      VkKeyScan                       [KEYBOARD.129]
163  */
164 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
165  * for the current keyboard.
166  * high-order byte yields :
167  *      0       Unshifted
168  *      1       Shift
169  *      2       Ctrl
170  *      3-5     Shift-key combinations that are not used for characters
171  *      6       Ctrl-Alt
172  *      7       Ctrl-Alt-Shift
173  *      I.e. :  Shift = 1, Ctrl = 2, Alt = 4.
174  * FIXME : works ok except for dead chars :
175  * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
176  * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
177  */
178
179 WORD WINAPI VkKeyScan16(CHAR cChar)
180 {
181     return USER_Driver.pVkKeyScan(cChar);
182 }
183
184 /******************************************************************************
185  *      GetKeyboardType16      (KEYBOARD.130)
186  */
187 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
188 {
189   TRACE("(%d)\n", nTypeFlag);
190   switch(nTypeFlag)
191     {
192     case 0:      /* Keyboard type */
193       return 4;    /* AT-101 */
194       break;
195     case 1:      /* Keyboard Subtype */
196       return 0;    /* There are no defined subtypes */
197       break;
198     case 2:      /* Number of F-keys */
199       return 12;   /* We're doing an 101 for now, so return 12 F-keys */
200       break;
201     default:     
202       WARN("Unknown type\n");
203       return 0;    /* The book says 0 here, so 0 */
204     }
205 }
206
207 /******************************************************************************
208  *      MapVirtualKey16      (KEYBOARD.131)
209  *
210  * MapVirtualKey translates keycodes from one format to another
211  */
212 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
213 {
214     return USER_Driver.pMapVirtualKey(wCode,wMapType);
215 }
216
217 /****************************************************************************
218  *      GetKBCodePage16   (KEYBOARD.132)
219  */
220 INT16 WINAPI GetKBCodePage16(void)
221 {
222   TRACE("(void)\n");
223   return 850;
224 }
225
226 /****************************************************************************
227  *      GetKeyNameText16   (KEYBOARD.133)
228  */
229 INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
230 {
231     return USER_Driver.pGetKeyNameText(lParam, lpBuffer, nSize);
232 }
233
234 /****************************************************************************
235  *      ToAscii   (KEYBOARD.4)
236  *
237  * The ToAscii function translates the specified virtual-key code and keyboard
238  * state to the corresponding Windows character or characters.
239  *
240  * If the specified key is a dead key, the return value is negative. Otherwise,
241  * it is one of the following values:
242  * Value        Meaning
243  * 0    The specified virtual key has no translation for the current state of the keyboard.
244  * 1    One Windows character was copied to the buffer.
245  * 2    Two characters were copied to the buffer. This usually happens when a
246  *      dead-key character (accent or diacritic) stored in the keyboard layout cannot
247  *      be composed with the specified virtual key to form a single character.
248  *
249  * FIXME : should do the above (return 2 for non matching deadchar+char combinations)
250  *
251  */
252 INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, 
253                        LPVOID lpChar, UINT16 flags) 
254 {
255     return ToAscii( virtKey, scanCode, lpKeyState, lpChar, flags );
256 }
257
258 /***********************************************************************
259  *              KEYBOARD_GetBeepActive
260  */
261 BOOL KEYBOARD_GetBeepActive()
262 {
263     return USER_Driver.pGetBeepActive();
264 }
265
266 /***********************************************************************
267  *              KEYBOARD_SetBeepActive
268  */
269 void KEYBOARD_SetBeepActive(BOOL bActivate)
270 {
271     USER_Driver.pSetBeepActive(bActivate);
272 }
273
274 /***********************************************************************
275  *           MessageBeep16   (USER.104)
276  */
277 void WINAPI MessageBeep16( UINT16 i )
278 {
279     MessageBeep( i );
280 }
281
282 /***********************************************************************
283  *           MessageBeep   (USER32.390)
284  */
285 BOOL WINAPI MessageBeep( UINT i )
286 {
287     USER_Driver.pBeep();
288     return TRUE;
289 }