fdopen: don't rewind the file after creating the FILE* handle. Added
[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 (WINEDOS16.122)
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    BIOSDATA *data = NULL;
55    BYTE ascii, scan;
56
57    switch AH_reg(context) {
58
59    case 0x00: /* Get Keystroke */
60       /* Returns: AH = Scan code
61                   AL = ASCII character */
62       TRACE("Get Keystroke\n");
63       DOSVM_Int16ReadChar(&ascii, &scan, FALSE);
64       SET_AL( context, ascii );
65       SET_AH( context, scan );
66       break;
67
68    case 0x01: /* Check for Keystroke */
69       /* Returns: ZF set if no keystroke */
70       /*          AH = Scan code */
71       /*          AL = ASCII character */
72       TRACE("Check for Keystroke\n");
73       if (!DOSVM_Int16ReadChar(&ascii, &scan, TRUE))
74       {
75           SET_ZFLAG(context);
76       }
77       else
78       {
79           SET_AL( context, ascii );
80           SET_AH( context, scan );
81           RESET_ZFLAG(context);
82       }
83       /* don't miss the opportunity to break some tight timing loop in DOS
84        * programs causing 100% CPU usage (by doing a Sleep here) */
85       Sleep(5);
86       break;
87
88    case 0x02: /* Get Shift Flags */
89
90       /* read value from BIOS data segment's keyboard status flags field */
91       data = BIOS_DATA;
92       SET_AL( context, data->KbdFlags1 );
93
94       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
95       break;
96
97    case 0x03: /* Set Typematic Rate and Delay */
98       FIXME("Set Typematic Rate and Delay - Not Supported\n");
99       break;
100
101    case 0x09: /* Get Keyboard Functionality */
102       FIXME("Get Keyboard Functionality - Not Supported\n");
103       /* As a temporary measure, say that "nothing" is supported... */
104       SET_AL( context, 0 );
105       break;
106
107    case 0x0a: /* Get Keyboard ID */
108       FIXME("Get Keyboard ID - Not Supported\n");
109       break;
110
111    case 0x10: /* Get Enhanced Keystroke */
112       TRACE("Get Enhanced Keystroke - Partially supported\n");
113       /* Returns: AH = Scan code
114                   AL = ASCII character */
115       DOSVM_Int16ReadChar(&ascii, &scan, FALSE);
116       SET_AL( context, ascii );
117       SET_AH( context, scan );
118       break;
119
120
121    case 0x11: /* Check for Enhanced Keystroke */
122       /* Returns: ZF set if no keystroke */
123       /*          AH = Scan code */
124       /*          AL = ASCII character */
125       TRACE("Check for Enhanced Keystroke - Partially supported\n");
126       if (!DOSVM_Int16ReadChar(&ascii, &scan, TRUE))
127       {
128           SET_ZFLAG(context);
129       }
130       else
131       {
132           SET_AL( context, ascii );
133           SET_AH( context, scan );
134           RESET_ZFLAG(context);
135       }
136       break;
137
138    case 0x12: /* Get Extended Shift States */
139       FIXME("Get Extended Shift States - Not Supported\n");
140       break;
141
142    default:
143       FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context));
144       break;
145
146    }
147 }
148
149 int WINAPI DOSVM_Int16ReadChar(BYTE*ascii,BYTE*scan,BOOL peek)
150 {
151   BIOSDATA *data = BIOS_DATA;
152   WORD CurOfs = data->NextKbdCharPtr;
153
154   /* check if there's data in buffer */
155   if (peek) {
156     if (CurOfs == data->FirstKbdCharPtr)
157       return 0;
158   } else {
159     while (CurOfs == data->FirstKbdCharPtr) {
160       /* no input available yet, so wait... */
161       DOSVM_Wait( -1, 0 );
162     }
163   }
164   /* read from keyboard queue */
165   TRACE("(%p,%p,%d) -> %02x %02x\n",ascii,scan,peek,((BYTE*)data)[CurOfs],((BYTE*)data)[CurOfs+1]);
166   if (ascii) *ascii = ((BYTE*)data)[CurOfs];
167   if (scan) *scan = ((BYTE*)data)[CurOfs+1];
168   if (!peek) {
169     CurOfs += 2;
170     if (CurOfs >= data->KbdBufferEnd) CurOfs = data->KbdBufferStart;
171     data->NextKbdCharPtr = CurOfs;
172   }
173   return 1;
174 }
175
176 int WINAPI DOSVM_Int16AddChar(BYTE ascii,BYTE scan)
177 {
178   BIOSDATA *data = BIOS_DATA;
179   WORD CurOfs = data->FirstKbdCharPtr;
180   WORD NextOfs = CurOfs + 2;
181
182   TRACE("(%02x,%02x)\n",ascii,scan);
183   if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart;
184   /* check if buffer is full */
185   if (NextOfs == data->NextKbdCharPtr) return 0;
186
187   /* okay, insert character in ring buffer */
188   ((BYTE*)data)[CurOfs] = ascii;
189   ((BYTE*)data)[CurOfs+1] = scan;
190
191   data->FirstKbdCharPtr = NextOfs;
192   return 1;
193 }