1 /**
2 ** dosinput.c ---- polled mode mouse and keyboard interface for DOS
3 **
4 ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
5 ** [e-mail: csaba@vuse.vanderbilt.edu]
6 **
7 ** This file is part of the GRX graphics library.
8 **
9 ** The GRX graphics library is free software; you can redistribute it
10 ** and/or modify it under some conditions; see the "copying.grx" file
11 ** for details.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 **
17 **/
18
19 #include <stdlib.h>
20
21 #if defined(__TURBOC__) || defined(__WATCOMC__) /* GS - Watcom C++ 11.0 */
22 #include <conio.h>
23 #endif
24
25 #ifdef __DJGPP__
26 #include <pc.h>
27 #endif
28
29 #include "libgrx.h"
30 #include "grxkeys.h"
31 #include "allocate.h"
32 #include "arith.h"
33 #include "int86.h"
34 #include "memcopy.h"
35 #include "memfill.h"
36 #include "mouse/input.h"
37
38 static int kbd_enabled = TRUE;
39 static int mou_enabled = TRUE;
40 static int mou_buttons = 0;
41 static long evt_lasttime;
42
uninit(void)43 static void uninit(void)
44 {
45 if(MOUINFO->msstatus > 1) MOUINFO->msstatus = 1;
46 }
47
GrMouseDetect(void)48 int GrMouseDetect(void)
49 {
50 Int86Regs r;
51 if(MOUINFO->msstatus == 0) {
52 MOUINFO->msstatus = (-1); /* assume missing */
53 sttzero(&r);
54 int33(&r);
55 if(IREG_AX(r) != 0) {
56 atexit(uninit);
57 MOUINFO->msstatus = 1; /* present, but not initted */
58 }
59 }
60 return((MOUINFO->msstatus > 0) ? TRUE : FALSE);
61 }
62
GrMouseInitN(int queue_size)63 void GrMouseInitN(int queue_size)
64 {
65 uninit();
66 queue_size = umax(4,umin(256,queue_size));
67 init_queue(queue_size);
68 if(GrMouseDetect()) {
69 GrMouseSetSpeed(1,1);
70 GrMouseSetAccel(100,1);
71 GrMouseSetLimits(0,0,SCRN->gc_xmax,SCRN->gc_ymax);
72 GrMouseWarp((SCRN->gc_xmax >> 1),(SCRN->gc_ymax >> 1));
73 _GrInitMouseCursor();
74 MOUINFO->msstatus = 2;
75 mou_buttons = 0;
76 }
77 GrMouseEventEnable(TRUE,TRUE);
78 real_time(evt_lasttime);
79 MOUINFO->uninit = uninit;
80 }
81
GrMouseSetSpeed(int spmult,int spdiv)82 void GrMouseSetSpeed(int spmult,int spdiv)
83 {
84 MOUINFO->spmult = umin(16,umax(1,spmult));
85 MOUINFO->spdiv = umin(16,umax(1,spdiv));
86 }
87
GrMouseSetAccel(int thresh,int accel)88 void GrMouseSetAccel(int thresh,int accel)
89 {
90 MOUINFO->thresh = umin(64,umax(1,thresh));
91 MOUINFO->accel = umin(16,umax(1,accel));
92 }
93
GrMouseSetLimits(int x1,int y1,int x2,int y2)94 void GrMouseSetLimits(int x1,int y1,int x2,int y2)
95 {
96 isort(x1,x2);
97 isort(y1,y2);
98 MOUINFO->xmin = imax(0,imin(x1,SCRN->gc_xmax));
99 MOUINFO->ymin = imax(0,imin(y1,SCRN->gc_ymax));
100 MOUINFO->xmax = imax(0,imin(x2,SCRN->gc_xmax));
101 MOUINFO->ymax = imax(0,imin(y2,SCRN->gc_ymax));
102 }
103
GrMouseWarp(int x,int y)104 void GrMouseWarp(int x,int y)
105 {
106 MOUINFO->xpos = imax(MOUINFO->xmin,imin(MOUINFO->xmax,x));
107 MOUINFO->ypos = imax(MOUINFO->ymin,imin(MOUINFO->ymax,y));
108 GrMouseUpdateCursor();
109 }
110
GrMouseEventEnable(int enable_kb,int enable_ms)111 void GrMouseEventEnable(int enable_kb,int enable_ms)
112 {
113 kbd_enabled = enable_kb;
114 mou_enabled = enable_ms;
115 }
116
_GrUpdateInputs(void)117 void _GrUpdateInputs(void)
118 {
119 for( ; ; ) {
120 Int86Regs r;
121 GrMouseEvent ev;
122 int gotevt = FALSE;
123 if(mou_enabled && (MOUINFO->msstatus == 2)) {
124 int mick,btn;
125 sttzero(&r);
126 IREG_AX(r) = 11; /* read mickey counters */
127 int33(&r);
128 if((mick = (short)IREG_CX(r)) != 0) {
129 update_coord(x,mick);
130 }
131 if((mick = (short)IREG_DX(r)) != 0) {
132 update_coord(y,mick);
133 }
134 IREG_AX(r) = 3; /* read button state */
135 int33(&r);
136 btn = IREG_BX(r);
137 if(btn != mou_buttons) {
138 fill_mouse_ev(
139 ev,
140 mou_buttons,btn,
141 GR_M_LEFT,
142 GR_M_MIDDLE,
143 GR_M_RIGHT,
144 GR_M_P4,
145 GR_M_P5,
146 GrKeyStat()
147 );
148 real_dtime(ev.dtime,evt_lasttime);
149 enqueue_event(ev);
150 MOUINFO->moved = FALSE;
151 mou_buttons = btn;
152 gotevt = TRUE;
153 }
154 }
155 if(kbd_enabled && GrKeyPressed()) {
156 fill_keybd_ev(ev,GrKeyRead(),GrKeyStat());
157 real_dtime(ev.dtime,evt_lasttime);
158 enqueue_event(ev);
159 MOUINFO->moved = FALSE;
160 gotevt = TRUE;
161 }
162 if(!gotevt) break;
163 }
164 }
165
GrMouseGetEventT(int flags,GrMouseEvent * ev,long tout)166 void GrMouseGetEventT(int flags,GrMouseEvent *ev,long tout)
167 {
168 int msdraw;
169 long prevtime;
170 if(MOUINFO->msstatus == 0) GrMouseInit();
171 msdraw = !MOUINFO->displayed && !(flags & GR_M_NOPAINT);
172 if(msdraw) GrMouseDisplayCursor();
173 real_time(prevtime);
174 for( ; ; ) {
175 _GrUpdateInputs();
176 GrMouseUpdateCursor();
177 while(MOUINFO->qlength > 0) {
178 dequeue_event((*ev));
179 if(ev->flags & flags) {
180 if(msdraw) GrMouseEraseCursor();
181 return;
182 }
183 }
184 if((flags & GR_M_POLL) ||
185 (tout == 0L) ||
186 (MOUINFO->moved && (flags & GR_M_MOTION))) {
187 fill_mouse_ev(
188 (*ev),
189 mou_buttons,mou_buttons,
190 GR_M_LEFT,
191 GR_M_MIDDLE,
192 GR_M_RIGHT,
193 GR_M_P4,
194 GR_M_P5,
195 GrKeyStat()
196 );
197 if ( ev->flags ) /* something happend */
198 real_dtime(ev->dtime,evt_lasttime);
199 else
200 ev->dtime = -1; /* special time if nothing happend */
201 MOUINFO->moved = FALSE;
202 if(msdraw) GrMouseEraseCursor();
203 return;
204 }
205 if(tout > 0L) {
206 long dtime;
207 real_dtime(dtime,prevtime);
208 if((tout -= dtime) < 0L) tout = 0L;
209 }
210 }
211 }
212
213