Keep track of per-column information inside the listview.
[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 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29
30 #include "module.h"
31 #include "dosexe.h"
32 #include "wincon.h"
33 #include "wine/debug.h"
34 #include "windef.h"
35 #include "wingdi.h"
36 #include "winuser.h"
37 #include "miscemu.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(int);
40
41 /**********************************************************************
42  *          DOSVM_Int16Handler
43  *
44  * Handler for int 16h (keyboard)
45  *
46  * NOTE:
47  *
48  *    KEYB.COM (DOS >3.2) adds functions to this interrupt, they are
49  *    not currently listed here.
50  */
51
52 void WINAPI DOSVM_Int16Handler( CONTEXT86 *context )
53 {
54     BYTE ascii, scan;
55    switch AH_reg(context) {
56
57    case 0x00: /* Get Keystroke */
58       /* Returns: AH = Scan code
59                   AL = ASCII character */
60       TRACE("Get Keystroke\n");
61       DOSVM_Int16ReadChar(&ascii, &scan, FALSE);
62       SET_AL( context, ascii );
63       SET_AH( context, scan );
64       break;
65
66    case 0x01: /* Check for Keystroke */
67       /* Returns: ZF set if no keystroke */
68       /*          AH = Scan code */
69       /*          AL = ASCII character */
70       TRACE("Check for Keystroke\n");
71       if (!DOSVM_Int16ReadChar(&ascii, &scan, TRUE))
72       {
73           SET_ZFLAG(context);
74       }
75       else
76       {
77           SET_AL( context, ascii );
78           SET_AH( context, scan );
79           RESET_ZFLAG(context);
80       }
81       /* don't miss the opportunity to break some tight timing loop in DOS
82        * programs causing 100% CPU usage (by doing a Sleep here) */
83       Sleep(5);
84       break;
85
86    case 0x02: /* Get Shift Flags */
87       SET_AL( context, 0 );
88
89       if (GetAsyncKeyState(VK_RSHIFT))
90           context->Eax |= 0x01;
91       if (GetAsyncKeyState(VK_LSHIFT))
92           context->Eax |= 0x02;
93       if (GetAsyncKeyState(VK_LCONTROL) || GetAsyncKeyState(VK_RCONTROL))
94           context->Eax |= 0x04;
95       if (GetAsyncKeyState(VK_LMENU) || GetAsyncKeyState(VK_RMENU))
96           context->Eax |= 0x08;
97       if (GetAsyncKeyState(VK_SCROLL))
98           context->Eax |= 0x10;
99       if (GetAsyncKeyState(VK_NUMLOCK))
100           context->Eax |= 0x20;
101       if (GetAsyncKeyState(VK_CAPITAL))
102           context->Eax |= 0x40;
103       if (GetAsyncKeyState(VK_INSERT))
104           context->Eax |= 0x80;
105       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
106       break;
107
108    case 0x03: /* Set Typematic Rate and Delay */
109       FIXME("Set Typematic Rate and Delay - Not Supported\n");
110       break;
111
112    case 0x09: /* Get Keyboard Functionality */
113       FIXME("Get Keyboard Functionality - Not Supported\n");
114       /* As a temporary measure, say that "nothing" is supported... */
115       SET_AL( context, 0 );
116       break;
117
118    case 0x0a: /* Get Keyboard ID */
119       FIXME("Get Keyboard ID - Not Supported\n");
120       break;
121
122    case 0x10: /* Get Enhanced Keystroke */
123       TRACE("Get Enhanced Keystroke - Partially supported\n");
124       /* Returns: AH = Scan code
125                   AL = ASCII character */
126       DOSVM_Int16ReadChar(&ascii, &scan, FALSE);
127       SET_AL( context, ascii );
128       SET_AH( context, scan );
129       break;
130
131
132    case 0x11: /* Check for Enhanced Keystroke */
133       /* Returns: ZF set if no keystroke */
134       /*          AH = Scan code */
135       /*          AL = ASCII character */
136       TRACE("Check for Enhanced Keystroke - Partially supported\n");
137       if (!DOSVM_Int16ReadChar(&ascii, &scan, TRUE))
138       {
139           SET_ZFLAG(context);
140       }
141       else
142       {
143           SET_AL( context, ascii );
144           SET_AH( context, scan );
145           RESET_ZFLAG(context);
146       }
147       break;
148
149    case 0x12: /* Get Extended Shift States */
150       FIXME("Get Extended Shift States - Not Supported\n");
151       break;
152
153    default:
154       FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context));
155       break;
156
157    }
158 }
159
160 int WINAPI DOSVM_Int16ReadChar(BYTE*ascii,BYTE*scan,BOOL peek)
161 {
162   BIOSDATA *data = BIOS_DATA;
163   WORD CurOfs = data->NextKbdCharPtr;
164
165   /* check if there's data in buffer */
166   if (peek) {
167     if (CurOfs == data->FirstKbdCharPtr)
168       return 0;
169   } else {
170     while (CurOfs == data->FirstKbdCharPtr) {
171       /* no input available yet, so wait... */
172       DOSVM_Wait( -1, 0 );
173     }
174   }
175   /* read from keyboard queue */
176   TRACE("(%p,%p,%d) -> %02x %02x\n",ascii,scan,peek,((BYTE*)data)[CurOfs],((BYTE*)data)[CurOfs+1]);
177   if (ascii) *ascii = ((BYTE*)data)[CurOfs];
178   if (scan) *scan = ((BYTE*)data)[CurOfs+1];
179   if (!peek) {
180     CurOfs += 2;
181     if (CurOfs >= data->KbdBufferEnd) CurOfs = data->KbdBufferStart;
182     data->NextKbdCharPtr = CurOfs;
183   }
184   return 1;
185 }
186
187 int WINAPI DOSVM_Int16AddChar(BYTE ascii,BYTE scan)
188 {
189   BIOSDATA *data = BIOS_DATA;
190   WORD CurOfs = data->FirstKbdCharPtr;
191   WORD NextOfs = CurOfs + 2;
192
193   TRACE("(%02x,%02x)\n",ascii,scan);
194   if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart;
195   /* check if buffer is full */
196   if (NextOfs == data->NextKbdCharPtr) return 0;
197
198   /* okay, insert character in ring buffer */
199   ((BYTE*)data)[CurOfs] = ascii;
200   ((BYTE*)data)[CurOfs+1] = scan;
201
202   data->FirstKbdCharPtr = NextOfs;
203   return 1;
204 }