Fix GetCurrentDirectoryA and W to return the needed space for the CWD,
[wine] / msdos / int33.c
1 /*
2  * DOS interrupt 33h handler
3  */
4
5 #include <stdlib.h>
6 #include "winuser.h"
7 #include "miscemu.h"
8 #include "dosexe.h"
9 #include "debugtools.h"
10
11 DEFAULT_DEBUG_CHANNEL(int)
12
13 typedef struct {
14   DWORD x, y, but;
15   FARPROC16 callback;
16   WORD callmask;
17 } MOUSESYSTEM;
18
19 /**********************************************************************
20  *          INT_Int33Handler
21  *
22  * Handler for int 33h (MS MOUSE).
23  */
24 void WINAPI INT_Int33Handler( CONTEXT86 *context )
25 {
26   MOUSESYSTEM *sys = (MOUSESYSTEM *)DOSVM_GetSystemData(0x33);
27
28   switch (AX_reg(context)) {
29   case 0x00:
30     TRACE("Reset mouse driver and request status\n");
31     AX_reg(context) = 0xFFFF; /* installed */
32     BX_reg(context) = 3;      /* # of buttons */
33     sys = calloc(1,sizeof(MOUSESYSTEM));
34     DOSVM_SetSystemData(0x33, sys);
35     break;
36   case 0x03:
37     TRACE("Return mouse position and button status\n");
38     BX_reg(context) = sys->but;
39     CX_reg(context) = sys->x;
40     DX_reg(context) = sys->y;
41     break;
42   case 0x0C: /* Define interrupt subroutine */
43     TRACE("Define mouse interrupt subroutine\n");
44     sys->callmask = CX_reg(context);
45     sys->callback = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR(ES_reg(context), DX_reg(context));
46     break;
47   default:
48     INT_BARF(context,0x33);
49   }
50 }
51
52 typedef struct {
53   FARPROC16 proc;
54   WORD mask,but,x,y,mx,my;
55 } MCALLDATA;
56
57 static void MouseRelay(LPDOSTASK lpDosTask,CONTEXT86 *context,void *mdata)
58 {
59   MCALLDATA *data = (MCALLDATA *)mdata;
60   CONTEXT86 ctx = *context;
61
62   EAX_reg(&ctx) = data->mask;
63   EBX_reg(&ctx) = data->but;
64   ECX_reg(&ctx) = data->x;
65   EDX_reg(&ctx) = data->y;
66   ESI_reg(&ctx) = data->mx;
67   EDI_reg(&ctx) = data->my;
68   CS_reg(&ctx)  = SELECTOROF(data->proc);
69   EIP_reg(&ctx) = OFFSETOF(data->proc);
70   free(data);
71   DPMI_CallRMProc(&ctx, NULL, 0, 0);
72 }
73
74 void WINAPI INT_Int33Message(UINT message,WPARAM wParam,LPARAM lParam)
75 {
76   MOUSESYSTEM *sys = (MOUSESYSTEM *)DOSVM_GetSystemData(0x33);
77   WORD mask = 0;
78
79   if (!sys) return;
80   sys->x = LOWORD(lParam);
81   sys->y = HIWORD(lParam);
82   switch (message) {
83   case WM_MOUSEMOVE:
84     mask |= 0x01;
85     break;
86   case WM_LBUTTONDOWN:
87   case WM_LBUTTONDBLCLK:
88     sys->but |= 0x01;
89     mask |= 0x02;
90     break;
91   case WM_LBUTTONUP:
92     sys->but &= ~0x01;
93     mask |= 0x04;
94     break;
95   case WM_RBUTTONDOWN:
96   case WM_RBUTTONDBLCLK:
97     sys->but |= 0x02;
98     mask |= 0x08;
99     break;
100   case WM_RBUTTONUP:
101     sys->but &= ~0x02;
102     mask |= 0x10;
103     break;
104   case WM_MBUTTONDOWN:
105   case WM_MBUTTONDBLCLK:
106     sys->but |= 0x04;
107     mask |= 0x20;
108     break;
109   case WM_MBUTTONUP:
110     sys->but &= ~0x04;
111     mask |= 0x40;
112     break;
113   }
114
115   if ((mask & sys->callmask) && sys->callback) {
116     MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
117     data->proc = sys->callback;
118     data->mask = mask & sys->callmask;
119     data->but = sys->but;
120     data->x = sys->x;
121     data->y = sys->y;
122     DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
123   }
124 }