summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/mouse.c
blob: 71f165b673da501ca95a7f596e909fc0f8890c84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*
** A series of routines to provide access to MicroSoft (and compatible)
** mice.  Consult your mouse documentation for detailed information regarding
** each mouse driver function.
**
** by Bob Jarvis w/ modifications by Bob Stout
*/

#include <dos.h>
#include "mouse.h"

int mouse_present = 0;  /* globally visible */

/*
** Uses driver function 0 to initialize the mouse software to its default
** settings.  If no mouse is present it returns 0.  If a mouse is present, it
** returns -1, and places the value of the mouse type (2 = MicroSoft,
** 3 = Mouse Systems, other values are possible) in *mousetype.  Also
** initializes the global variable mouse_present (0 = no mouse, !0 = mouse
** is available).
*/

int ms_reset(int *mousetype)
{
      union REGS workregs;
      struct SREGS sregs;

      /* check the vector     */

      segread (&sregs);
      workregs.h.ah = 0x35;     /* DOS get vector */
      workregs.h.al = 0x33;     /* mouse vector   */
      intdosx(0x21, &workregs, &workregs, &sregs);

      /* ES:BX now contains the pointer to the interrupt handler */

      if (sregs.es == 0 && inregs.x.bx == 0)
            return mouse_present = 0;

      workregs.x.ax = 0;
      int86(MSMOUSE,&workregs,&workregs);
      *mousetype = workregs.x.bx;
      mouse_present = workregs.x.ax;
      return(mouse_present);
}

/*
** Makes the mouse cursor visible.
*/

void ms_show_cursor(void)
{
      union REGS workregs;

      workregs.x.ax = 1;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Hides the mouse cursor.  Should be called before changing any portion of
** the screen under the mouse cursor.
*/

void ms_hide_cursor(void)
{
      union REGS workregs;

      workregs.x.ax = 2;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Obtains information about the mouse position and button status.
** Places the current horizontal and vertical positions in *horizpos and
** *vertpos, respectively.  Returns the mouse button status, which is
** mapped at the bit level as follows:
**    Bit 0 - left button    \
**    Bit 1 - right button    >-- 0 = button up, 1 = button down
**    Bit 2 - middle button  /
*/

int ms_get_mouse_pos(int *horizpos, int *vertpos) /* Returns button status */
{
      union REGS workregs;

      workregs.x.ax = 3;
      int86(MSMOUSE,&workregs,&workregs);
      *horizpos = workregs.x.cx;
      *vertpos  = workregs.x.dx;
      return(workregs.x.bx);
}

/*
** Moves the mouse cursor to a new position.
*/

void ms_set_mouse_pos(int horizpos, int vertpos)
{
      union REGS workregs;

      workregs.x.ax = 4;
      workregs.x.cx = horizpos;
      workregs.x.dx = vertpos;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Obtains information about the last time the specified button
** (0 = left, 1 = right, 2 = middle) was pressed.  Returns the current
** button status (same format as return from ms_get_mouse_pos() above).
*/

int ms_button_press_status(int  button,
                           int *press_count,
                           int *column,
                           int *row)
{
      union REGS workregs;

      workregs.x.ax = 5;
      workregs.x.bx = button;
      int86(MSMOUSE,&workregs,&workregs);
      *press_count = workregs.x.bx;
      *column = workregs.x.cx;
      *row = workregs.x.dx;
      return(workregs.x.ax);
}

/*
** Similar to above but obtains information about the last release of the
** specified button.
*/

int ms_button_release_status(int  button,
                             int *release_count,
                             int *column,
                             int *row)
{
      union REGS workregs;

      workregs.x.ax = 6;
      workregs.x.bx = button;
      int86(MSMOUSE,&workregs,&workregs);
      *release_count = workregs.x.bx;
      *column = workregs.x.cx;
      *row = workregs.x.dx;
      return(workregs.x.ax);
}

/*
** Forces the mouse cursor to remain within the range specified.
*/

void ms_restrict_horiz(int min, int max)
{
      union REGS workregs;

      workregs.x.ax = 7;
      workregs.x.cx = min;
      workregs.x.dx = max;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Forces the mouse cursor to remain within the range specified.
*/

void ms_restrict_vert(int min, int max)
{
      union REGS workregs;

      workregs.x.ax = 8;
      workregs.x.cx = min;
      workregs.x.dx = max;
      int86(MSMOUSE,&workregs,&workregs);
}

void ms_define_window(int left, int top, int right, int bottom)
{
      ms_restrict_horiz(left,right);
      ms_restrict_vert(top,bottom);
}

/*
** Allows the user to set the graphics cursor to a new shape.  Check your
** mouse reference manual for full information about the use of this function.
*/

void ms_set_graphics_cursor(int      horiz_hotspot,
                            int      vert_hotspot,
                            unsigned seg_shape_tables,
                            unsigned offset_shape_tables)
{
      union REGS workregs;
      struct SREGS segregs;

      workregs.x.ax = 9;
      workregs.x.bx = horiz_hotspot;
      workregs.x.cx = vert_hotspot;
      workregs.x.dx = offset_shape_tables;
      segregs.es  = seg_shape_tables;
      int86x(MSMOUSE,&workregs,&workregs,&segregs);
}

/*
** Selects either the software or hardware cursor and sets the start and stop
** scan lines (for the hardware cursor) or the screen and cursor masks (for
** the software cursor).  Consult your mouse reference for more information.
*/

void ms_set_text_cursor(int type, int screen_mask, int cursor_mask)
{
      union REGS workregs;

      workregs.x.ax = 10;
      workregs.x.bx = type;
      workregs.x.cx = screen_mask;
      workregs.x.dx = cursor_mask;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Obtains the horizontal and vertical raw motion counts since the last
** request.
*/

void ms_read_motion_counters(int *horiz, int *vert)
{
      union REGS workregs;

      workregs.x.ax = 11;
      int86(MSMOUSE,&workregs,&workregs);
      *horiz = workregs.x.cx;
      *vert  = workregs.x.dx;
}

/*
** Sets up a subroutine to be called when a given event occurs.
** NOTE: Use with extreme care.  The function whose address is provided MUST
**    terminate with a far return (i.e. must be compiled using large model).
**    Also, no DOS or BIOS services may be used, as the user-defined function
**    is (in effect) an extension to an interrupt service routine.
*/

void ms_set_event_subroutine(int      mask,
                             unsigned seg_routine,
                             unsigned offset_routine)
{
      union REGS workregs;
      struct SREGS segregs;

      workregs.x.ax = 12;
      workregs.x.cx = mask;
      workregs.x.dx = offset_routine;
      segregs.es  = seg_routine;
      int86x(MSMOUSE,&workregs,&workregs,&segregs);
}

/*
** Turns light pen emulation mode on.
*/

void ms_light_pen_on(void)
{
      union REGS workregs;

      workregs.x.ax = 13;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** turns light pen emulation mode off.
*/

void ms_light_pen_off(void)
{
      union REGS workregs;

      workregs.x.ax = 14;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Sets the sensitivity of the mouse.  Defaults are 8 and 16 for horizontal
** and vertical sensitivity (respectively).
*/

void ms_set_sensitivity(int horiz, int vert)
{
      union REGS workregs;

      workregs.x.ax = 15;
      workregs.x.cx = horiz;
      workregs.x.dx = vert;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
** Sets up a region of the screen inside of which the mouse cursor will
** automatically be 'hidden'.
*/

void ms_protect_area(int left, int top, int right, int bottom)
{
      union REGS workregs;

      workregs.x.ax = 16;
      workregs.x.cx = left;
      workregs.x.dx = top;
      workregs.x.si = right;
      workregs.x.di = bottom;
      int86(MSMOUSE,&workregs,&workregs);
}

/*
* Similar to ms_set_graphics_cursor() but allows a larger cursor.  Consult
** your mouse documentation for information on how to use this function.
*/

int ms_set_large_graphics_cursor(int      width,
                                 int      height,
                                 int      horiz_hotspot,
                                 int      vert_hotspot,
                                 unsigned seg_shape_tables,
                                 unsigned offset_shape_tables)
{
      union REGS workregs;
      struct SREGS segregs;

      workregs.x.ax = 18;
      workregs.x.bx = (width << 8) + horiz_hotspot;
      workregs.x.cx = (height << 8) + vert_hotspot;
      workregs.x.dx = offset_shape_tables;
      segregs.es  = seg_shape_tables;
      int86x(MSMOUSE,&workregs,&workregs,&segregs);
      if(workregs.x.ax == -1)
            return(workregs.x.ax); /* Return -1 if function 18 supported */
      else  return(0);             /* else return 0                      */
}

/*
** Sets the threshold value for doubling cursor motion.  Default value is 64.
*/

void ms_set_doublespeed_threshold(int speed)
{
      union REGS workregs;

      workregs.x.ax = 19;
      workregs.x.dx = speed;
      int86(MSMOUSE,&workregs,&workregs);
}