1 /* Copyright (c) 1992, 1998 John E. Davis
2 * This file is part of JED editor library source.
3 *
4 * You may distribute this file under the terms the GNU General Public
5 * License. See the file COPYING for more information.
6 */
7 #ifdef HAS_MOUSE
8
9 #define INCL_ERRORS
10 #define INCL_SUB
11 #define INCL_DOSPROCESS
12 #define INCL_DOSSEMAPHORES
13 #include "config.h"
14 #include "jed-feat.h"
15
16 #include <os2.h>
17
18 #include <process.h>
19
20 static void show_mouse (int show);
21
22 static int Mouse_X, Mouse_Y;
23
24 #if __os2_16__
25 typedef USHORT APIRET;
26 #define DosSetPriority DosSetPrty
27 #endif
28
29 #define THREADSTACKSIZE 32768
30 static TID Os2_Mouse_ThreadID = (TID) 0;
31
32 static int Mouse_Hidden = 1;
33 static int Last_Mouse_Hidden = 1;
34
35 static HMOU Mouse_Handle = -1;
36
37 #define MOUSE_BN1 (MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_BN1_DOWN)
38 #define MOUSE_BN2 (MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_BN2_DOWN)
39 #define MOUSE_BN3 (MOUSE_MOTION_WITH_BN3_DOWN | MOUSE_BN3_DOWN)
40
41
42 #define MOUSE_NOMOVE (MOUSE_BN1_DOWN | MOUSE_BN2_DOWN | MOUSE_BN3_DOWN)
43 #define MOUSE_DRAGGED (MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_MOTION_WITH_BN3_DOWN)
44 #define MOUSE_MOVED (MOUSE_MOTION | MOUSE_DRAGGED)
45
46 #define MouseNoMove(event) (MOUSE_NOMOVE & event.fs)
47 #define MouseMoved(event) (MOUSE_MOVED & event.fs)
48 #define MouseDragged(event) (MOUSE_DRAGGED & event.fs)
49 #define MouseButtonPressed(event,button) (event.fs & button)
50 #define MouseButtons(event) (event.fs & (MOUSE_BN1 | MOUSE_BN2 | MOUSE_BN3))
51
52 static int buttonDown [3] = {0, 0, 0};
53 static int buttonMask [3];
54 USHORT noButtons;
55
56
os2_add_event(int x,int y,int type,int but)57 static void os2_add_event (int x, int y, int type, int but)
58 {
59 char buf[4];
60 int b, s, id;
61 JMouse_Type jm;
62
63 Mouse_X = jm.x = x;
64 Mouse_Y = jm.y = y;
65
66 b = but & 0xF;
67 s = but >> 4;
68
69 if (b == 1) jm.button = JMOUSE_BUTTON_1; /* left */
70 else if (b == 2) jm.button = JMOUSE_BUTTON_3; /* right */
71 else jm.button = JMOUSE_BUTTON_2; /* middle */
72
73 if (s & 0x8) /* alt key--- use as middle */
74 {
75 jm.button = JMOUSE_BUTTON_2;
76 }
77
78 if (s & 0x3) jm.state = JMOUSE_SHIFT;
79 else if (s & 0x4) jm.state = JMOUSE_CTRL;
80 else jm.state = 0;
81
82 jm.type = type;
83
84 if (-1 == (id = jed_mouse_add_event (&jm)))
85 return;
86
87 buf[0] = 27; buf[1] = 0; buf[2] = (char) id;
88
89 ungetkey_string (buf, 3);
90 }
91
92
os2_mouse_handler(void * Args)93 static void os2_mouse_handler (void *Args)
94 {
95 MOUEVENTINFO event_info;
96 APIRET Error;
97 USHORT wait_flag;
98 int press, i;
99 short x, y;
100 KBDINFO kbd_info;
101
102 (void) Args;
103 wait_flag = MOU_NOWAIT;
104
105 DosSetPriority( PRTYS_THREAD, PRTYC_NOCHANGE, PRTYD_MINIMUM, 0 ) ;
106
107 while (Mouse_Handle) {
108
109 Error = MouReadEventQue (&event_info, &wait_flag, Mouse_Handle);
110 if ((Error != NO_ERROR) || !event_info.time) {
111 DosSleep (5);
112 continue;
113 }
114
115 x = event_info.col + 1;
116 y = event_info.row + 1;
117
118 if (MouseMoved (event_info) && ((x != Mouse_X) || (y != Mouse_Y)))
119 {
120 /* mouse moved so show it. */
121 show_mouse (1);
122 }
123
124 for(i = 0; i < noButtons; i++) {
125 if(MouseButtonPressed (event_info, buttonMask[i])) {
126 if (!buttonDown [i]) {
127 /* I don't think that we can find shift key status in OS/2, since we
128 * are reading the keyboard in another thread */
129 kbd_info.cb = sizeof (kbd_info);
130 KbdGetStatus (&kbd_info, 0);
131 press = (i + 1) | ((kbd_info.fsState & 0xF) << 4);
132 os2_add_event (x, y, JMOUSE_DOWN, press);
133 buttonDown [i] = 1;
134 continue;
135 } else { /* button already down */
136 if (MouseDragged (event_info))
137 {
138 if ((x == Mouse_X) && (y == Mouse_Y)) continue;
139 os2_add_event (x, y, JMOUSE_DRAG, i + 1);
140 continue;
141 }
142 }
143
144 } else {
145 if (buttonDown [i]) {
146 os2_add_event (x, y, JMOUSE_UP, i + 1);
147 buttonDown [i] = 0;
148 continue;
149 }
150 }
151 }
152 }
153 Mouse_Handle = -1;
154 _endthread ();
155 }
156
157
158
os2_get_mouse_event(void)159 static int os2_get_mouse_event (void)
160 {
161 return 0;
162 }
163
164 /* Mouse routines for OS/2 */
165
166
show_mouse(int show)167 static void show_mouse (int show)
168 {
169 NOPTRRECT PtrRect;
170
171 if (show)
172 {
173 if (Mouse_Hidden == 0) return;
174 MouDrawPtr (Mouse_Handle);
175 }
176 else
177 {
178 if (Mouse_Hidden) return;
179 PtrRect.row = 0;
180 PtrRect.col = 0;
181 PtrRect.cRow = Jed_Num_Screen_Rows - 1;
182 PtrRect.cCol = Jed_Num_Screen_Cols - 1;
183 MouRemovePtr (&PtrRect, Mouse_Handle);
184 }
185 Mouse_Hidden = !show;
186 }
187
os2_close_mouse()188 static void os2_close_mouse ()
189 {
190 MouClose (Mouse_Handle);
191 Mouse_Handle = 0;
192 #if defined(__os2_16__)
193 while (!Mouse_Handle) DosSleep(0);
194 #else
195 DosWaitThread (&Os2_Mouse_ThreadID, DCWW_WAIT);
196 #endif
197 Os2_Mouse_ThreadID = 0;
198 }
199
200
201
move_mouse(int x,int y)202 static void move_mouse (int x, int y)
203 {
204 PTRLOC ptr_loc;
205 ptr_loc.row = y - 1;
206 ptr_loc.col = x - 1;
207 MouSetPtrPos (&ptr_loc, Mouse_Handle);
208 }
209
os2_update_open_hook(void)210 static void os2_update_open_hook (void)
211 {
212 Last_Mouse_Hidden = Mouse_Hidden;
213 if (Mouse_Hidden == 0) show_mouse (0);
214 }
215
216 static int Warp_Pending;
os2_update_close_hook(void)217 static void os2_update_close_hook (void)
218 {
219 if (Last_Mouse_Hidden == 0) show_mouse (1);
220 if (Warp_Pending) move_mouse (Screen_Col - 1, Screen_Row - 1);
221 Warp_Pending = 0;
222 }
223
warp_pointer(void)224 static void warp_pointer (void)
225 {
226 Warp_Pending = 1;
227 }
228
229 static char *CutBuffer;
230 static int CutBuffer_Len;
231
insert_cutbuffer(void)232 static int insert_cutbuffer (void)
233 {
234 CHECK_READ_ONLY
235 if (CutBuffer == NULL) return 0;
236 if (CutBuffer_Len) ins_chars ((unsigned char *) CutBuffer, CutBuffer_Len);
237 return CutBuffer_Len;
238 }
239
region_to_cutbuffer(void)240 static void region_to_cutbuffer (void)
241 {
242 int nbytes;
243
244 if (CutBuffer != NULL)
245 {
246 SLfree (CutBuffer);
247 }
248
249 CutBuffer = make_buffer_substring(&nbytes);
250 CutBuffer_Len = nbytes;
251 }
252
253 static SLang_Intrin_Fun_Type os2_mouse_table[] =
254 {
255 MAKE_INTRINSIC("x_warp_pointer", warp_pointer, VOID_TYPE, 0),
256 MAKE_INTRINSIC("x_insert_cutbuffer", insert_cutbuffer, INT_TYPE, 0),
257 /* Prototype: Integer x_insert_cut_buffer ();
258 * Inserts cutbuffer into the current buffer and returns the number
259 * of characters inserted.
260 */
261 MAKE_INTRINSIC("x_copy_region_to_cutbuffer", region_to_cutbuffer, VOID_TYPE, 0),
262 /* Prototype: Void x_copy_region_to_cutbuffer();
263 */
264 SLANG_END_TABLE
265 };
266
267 void (*X_Close_Mouse_Hook)(void);
268
os2_open_mouse()269 static int os2_open_mouse ()
270 {
271 static int not_first_time = 0;
272 USHORT Error;
273
274 X_Close_Mouse_Hook = NULL;
275 JMouse_Event_Hook = NULL;
276 JMouse_Hide_Mouse_Hook = NULL;
277 X_Update_Open_Hook = NULL;
278 X_Update_Close_Hook = NULL;
279
280 /* Now open the device */
281
282 Error = MouOpen (NULL, &Mouse_Handle);
283 if (Error)
284 return -1;
285
286 Mouse_X = Jed_Num_Screen_Cols / 2 + 1;
287 Mouse_Y = Jed_Num_Screen_Rows / 2 + 1;
288
289 MouDrawPtr (Mouse_Handle);
290 MouGetNumButtons (&noButtons, Mouse_Handle);
291 if (noButtons == 3)
292 buttonMask [2] = MOUSE_BN3;
293
294 buttonMask [0] = MOUSE_BN1;
295 buttonMask [1] = MOUSE_BN2;
296
297 MouFlushQue(Mouse_Handle); /* flush mouse queue */
298
299 move_mouse (Mouse_X, Mouse_Y);
300 if (not_first_time == 0)
301 {
302 if (-1 == SLadd_intrin_fun_table (os2_mouse_table, "MOUSE"))
303 return -1;
304
305 not_first_time = 1;
306 }
307
308 #if defined __BORLANDC__
309 Os2_Mouse_ThreadID = _beginthread (os2_mouse_handler, THREADSTACKSIZE, NULL);
310 #else
311 Os2_Mouse_ThreadID = _beginthread (os2_mouse_handler, NULL, THREADSTACKSIZE, NULL);
312 #endif
313
314 JMouse_Hide_Mouse_Hook = show_mouse;
315 X_Close_Mouse_Hook = os2_close_mouse;
316 /* I am not sure if I should set this */
317 JMouse_Event_Hook = os2_get_mouse_event;
318 X_Update_Open_Hook = os2_update_open_hook;
319 X_Update_Close_Hook = os2_update_close_hook;
320 return 1;
321 }
322
323 int (*X_Open_Mouse_Hook)(void) = os2_open_mouse;
324
325 #endif
326