Use DrawFrameControl instead of bitmaps in certain cases.
[wine] / dlls / winedos / int33.c
1 /*
2  * DOS interrupt 33h handler
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "windef.h"
9 #include "winbase.h"
10 #include "wingdi.h"
11 #include "winuser.h"
12 #include "miscemu.h"
13 #include "dosexe.h"
14 #include "vga.h"
15 #include "debugtools.h"
16
17 DEFAULT_DEBUG_CHANNEL(int);
18
19 static struct
20 {
21   DWORD x, y, but;
22   FARPROC16 callback;
23   WORD callmask;
24 } mouse_info;
25
26 /**********************************************************************
27  *          DOSVM_Int33Handler
28  *
29  * Handler for int 33h (MS MOUSE).
30  */
31 void WINAPI DOSVM_Int33Handler( CONTEXT86 *context )
32 {
33   switch (LOWORD(context->Eax)) {
34   case 0x00:
35     TRACE("Reset mouse driver and request status\n");
36     AX_reg(context) = 0xFFFF; /* installed */
37     BX_reg(context) = 3;      /* # of buttons */
38     memset( &mouse_info, 0, sizeof(mouse_info) );
39     break;
40   case 0x01:
41     FIXME("Show mouse cursor\n");
42     break;
43   case 0x02:
44     FIXME("Hide mouse cursor\n");
45     break;
46   case 0x03:
47     TRACE("Return mouse position and button status\n");
48     BX_reg(context) = mouse_info.but;
49     CX_reg(context) = mouse_info.x;
50     DX_reg(context) = mouse_info.y;
51     break;
52   case 0x04:
53     FIXME("Position mouse cursor\n");
54     break;
55   case 0x07:
56     FIXME("Define horizontal mouse cursor range\n");
57     break;
58   case 0x08:
59     FIXME("Define vertical mouse cursor range\n");
60     break;
61   case 0x09:
62     FIXME("Define graphics mouse cursor\n");
63     break;
64   case 0x0A:
65     FIXME("Define text mouse cursor\n");
66     break;
67   case 0x0C:
68     TRACE("Define mouse interrupt subroutine\n");
69     mouse_info.callmask = CX_reg(context);
70     mouse_info.callback = (FARPROC16)MAKESEGPTR(context->SegEs, LOWORD(context->Edx));
71     break;
72   case 0x10:
73     FIXME("Define screen region for update\n");
74     break;
75   default:
76     INT_BARF(context,0x33);
77   }
78 }
79
80 typedef struct {
81   FARPROC16 proc;
82   WORD mask,but,x,y,mx,my;
83 } MCALLDATA;
84
85 static void MouseRelay(CONTEXT86 *context,void *mdata)
86 {
87   MCALLDATA *data = (MCALLDATA *)mdata;
88   CONTEXT86 ctx = *context;
89
90   ctx.Eax   = data->mask;
91   ctx.Ebx   = data->but;
92   ctx.Ecx   = data->x;
93   ctx.Edx   = data->y;
94   ctx.Esi   = data->mx;
95   ctx.Edi   = data->my;
96   ctx.SegCs = SELECTOROF(data->proc);
97   ctx.Eip   = OFFSETOF(data->proc);
98   free(data);
99   DPMI_CallRMProc(&ctx, NULL, 0, 0);
100 }
101
102 void WINAPI DOSVM_Int33Message(UINT message,WPARAM wParam,LPARAM lParam)
103 {
104   WORD mask = 0;
105   unsigned Height, Width, SX=1, SY=1;
106
107   if (!VGA_GetMode(&Height,&Width,NULL)) {
108     /* may need to do some coordinate scaling */
109     SX = 640/Width;
110     if (!SX) SX=1;
111   }
112   mouse_info.x = LOWORD(lParam) * SX;
113   mouse_info.y = HIWORD(lParam) * SY;
114   switch (message) {
115   case WM_MOUSEMOVE:
116     mask |= 0x01;
117     break;
118   case WM_LBUTTONDOWN:
119   case WM_LBUTTONDBLCLK:
120     mouse_info.but |= 0x01;
121     mask |= 0x02;
122     break;
123   case WM_LBUTTONUP:
124     mouse_info.but &= ~0x01;
125     mask |= 0x04;
126     break;
127   case WM_RBUTTONDOWN:
128   case WM_RBUTTONDBLCLK:
129     mouse_info.but |= 0x02;
130     mask |= 0x08;
131     break;
132   case WM_RBUTTONUP:
133     mouse_info.but &= ~0x02;
134     mask |= 0x10;
135     break;
136   case WM_MBUTTONDOWN:
137   case WM_MBUTTONDBLCLK:
138     mouse_info.but |= 0x04;
139     mask |= 0x20;
140     break;
141   case WM_MBUTTONUP:
142     mouse_info.but &= ~0x04;
143     mask |= 0x40;
144     break;
145   }
146
147   if ((mask & mouse_info.callmask) && mouse_info.callback) {
148     MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
149     data->proc = mouse_info.callback;
150     data->mask = mask & mouse_info.callmask;
151     data->but = mouse_info.but;
152     data->x = mouse_info.x;
153     data->y = mouse_info.y;
154     DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
155   }
156 }