Better implementation of GetCalendarInfo{A,W}, not perfect.
[wine] / dlls / winedos / int16.c
1 /*
2  * DOS interrupt 16h handler
3  *
4  * Copyright 1998 Joseph Pranevich
5  * Copyright 1999 Ove Kåven
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "module.h"
29 #include "dosexe.h"
30 #include "wincon.h"
31 #include "wine/debug.h"
32 #include "windef.h"
33 #include "wingdi.h"
34 #include "winuser.h"
35 #include "miscemu.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(int);
38
39 /**********************************************************************
40  *          DOSVM_Int16Handler
41  *
42  * Handler for int 16h (keyboard)
43  *
44  * NOTE:
45  * 
46  *    KEYB.COM (DOS >3.2) adds functions to this interrupt, they are
47  *    not currently listed here.
48  */
49
50 void WINAPI DOSVM_Int16Handler( CONTEXT86 *context )
51 {
52    switch AH_reg(context) {
53
54    case 0x00: /* Get Keystroke */
55       /* Returns: AH = Scan code
56                   AL = ASCII character */
57       TRACE("Get Keystroke\n");
58       DOSVM_Int16ReadChar(&AL_reg(context), &AH_reg(context), FALSE);
59       break;
60
61    case 0x01: /* Check for Keystroke */
62       /* Returns: ZF set if no keystroke */
63       /*          AH = Scan code */
64       /*          AL = ASCII character */
65       TRACE("Check for Keystroke\n");
66       if (!DOSVM_Int16ReadChar(&AL_reg(context), &AH_reg(context), TRUE))
67       {
68           SET_ZFLAG(context);
69       }
70       else
71       {
72           RESET_ZFLAG(context);
73       }
74       break;
75
76    case 0x02: /* Get Shift Flags */
77       AL_reg(context) = 0;
78
79       if (GetAsyncKeyState(VK_RSHIFT))
80           AL_reg(context) |= 0x01;
81       if (GetAsyncKeyState(VK_LSHIFT))
82           AL_reg(context) |= 0x02;
83       if (GetAsyncKeyState(VK_LCONTROL) || GetAsyncKeyState(VK_RCONTROL))
84           AL_reg(context) |= 0x04;
85       if (GetAsyncKeyState(VK_LMENU) || GetAsyncKeyState(VK_RMENU))
86           AL_reg(context) |= 0x08;
87       if (GetAsyncKeyState(VK_SCROLL))
88           AL_reg(context) |= 0x10;
89       if (GetAsyncKeyState(VK_NUMLOCK))
90           AL_reg(context) |= 0x20;
91       if (GetAsyncKeyState(VK_CAPITAL))
92           AL_reg(context) |= 0x40;
93       if (GetAsyncKeyState(VK_INSERT))
94           AL_reg(context) |= 0x80;
95       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
96       break;
97
98    case 0x03: /* Set Typematic Rate and Delay */
99       FIXME("Set Typematic Rate and Delay - Not Supported\n");
100       break;
101
102    case 0x09: /* Get Keyboard Functionality */
103       FIXME("Get Keyboard Functionality - Not Supported\n");
104       /* As a temporary measure, say that "nothing" is supported... */
105       AL_reg(context) = 0;
106       break;
107
108    case 0x0a: /* Get Keyboard ID */
109       FIXME("Get Keyboard ID - Not Supported\n");
110       break;
111
112    case 0x10: /* Get Enhanced Keystroke */
113       TRACE("Get Enhanced Keystroke - Partially supported\n");
114       /* Returns: AH = Scan code
115                   AL = ASCII character */
116       DOSVM_Int16ReadChar(&AL_reg(context), &AH_reg(context), FALSE);
117       break;
118
119
120    case 0x11: /* Check for Enhanced Keystroke */
121       /* Returns: ZF set if no keystroke */
122       /*          AH = Scan code */
123       /*          AL = ASCII character */
124       TRACE("Check for Enhanced Keystroke - Partially supported\n");
125       if (!DOSVM_Int16ReadChar(&AL_reg(context), &AH_reg(context), TRUE))
126       {
127           SET_ZFLAG(context);
128       }
129       else
130       {
131           RESET_ZFLAG(context);
132       }
133       break;
134
135    case 0x12: /* Get Extended Shift States */
136       FIXME("Get Extended Shift States - Not Supported\n");
137       break;
138
139    default:
140       FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context));
141       break;
142
143    }
144 }
145
146 int WINAPI DOSVM_Int16ReadChar(BYTE*ascii,BYTE*scan,BOOL peek)
147 {
148   BIOSDATA *data = DOSMEM_BiosData();
149   WORD CurOfs = data->NextKbdCharPtr;
150
151   /* check if there's data in buffer */
152   if (peek) {
153     if (CurOfs == data->FirstKbdCharPtr)
154       return 0;
155   } else {
156     while (CurOfs == data->FirstKbdCharPtr) {
157       /* no input available yet, so wait... */
158       DOSVM_Wait( -1, 0 );
159     }
160   }
161   /* read from keyboard queue */
162   TRACE("(%p,%p,%d) -> %02x %02x\n",ascii,scan,peek,((BYTE*)data)[CurOfs],((BYTE*)data)[CurOfs+1]);
163   if (ascii) *ascii = ((BYTE*)data)[CurOfs];
164   if (scan) *scan = ((BYTE*)data)[CurOfs+1];
165   if (!peek) {
166     CurOfs += 2;
167     if (CurOfs >= data->KbdBufferEnd) CurOfs = data->KbdBufferStart;
168     data->NextKbdCharPtr = CurOfs;
169   }
170   return 1;
171 }
172
173 int WINAPI DOSVM_Int16AddChar(BYTE ascii,BYTE scan)
174 {
175   BIOSDATA *data = DOSMEM_BiosData();
176   WORD CurOfs = data->FirstKbdCharPtr;
177   WORD NextOfs = CurOfs + 2;
178
179   TRACE("(%02x,%02x)\n",ascii,scan);
180   if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart;
181   /* check if buffer is full */
182   if (NextOfs == data->NextKbdCharPtr) return 0;
183
184   /* okay, insert character in ring buffer */
185   ((BYTE*)data)[CurOfs] = ascii;
186   ((BYTE*)data)[CurOfs+1] = scan;
187
188   data->FirstKbdCharPtr = NextOfs;
189   return 1;
190 }