]>
Commit | Line | Data |
---|---|---|
c7de829c WD |
1 | /**************************************************************************** |
2 | * | |
3 | * SciTech Multi-platform Graphics Library | |
4 | * | |
5 | * ======================================================================== | |
6 | * | |
7 | * The contents of this file are subject to the SciTech MGL Public | |
8 | * License Version 1.0 (the "License"); you may not use this file | |
9 | * except in compliance with the License. You may obtain a copy of | |
10 | * the License at http://www.scitechsoft.com/mgl-license.txt | |
11 | * | |
12 | * Software distributed under the License is distributed on an | |
13 | * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | |
14 | * implied. See the License for the specific language governing | |
15 | * rights and limitations under the License. | |
16 | * | |
17 | * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. | |
18 | * | |
19 | * The Initial Developer of the Original Code is SciTech Software, Inc. | |
20 | * All Rights Reserved. | |
21 | * | |
22 | * ======================================================================== | |
23 | * | |
24 | * Language: ANSI C | |
25 | * Environment: RTTarget-32 | |
26 | * | |
27 | * Description: Win32 implementation for the SciTech cross platform | |
28 | * event library. | |
29 | * | |
30 | ****************************************************************************/ | |
31 | ||
32 | /*---------------------------- Global Variables ---------------------------*/ | |
33 | ||
34 | static ushort keyUpMsg[256] = {0}; /* Table of key up messages */ | |
35 | static int rangeX,rangeY; /* Range of mouse coordinates */ | |
36 | ||
37 | /*---------------------------- Implementation -----------------------------*/ | |
38 | ||
39 | /* These are not used under Win32 */ | |
40 | #define _EVT_disableInt() 1 | |
41 | #define _EVT_restoreInt(flags) | |
42 | ||
43 | /**************************************************************************** | |
44 | PARAMETERS: | |
45 | scanCode - Scan code to test | |
46 | ||
47 | REMARKS: | |
48 | This macro determines if a specified key is currently down at the | |
49 | time that the call is made. | |
50 | ****************************************************************************/ | |
51 | #define _EVT_isKeyDown(scanCode) (keyUpMsg[scanCode] != 0) | |
52 | ||
53 | /**************************************************************************** | |
54 | REMARKS: | |
55 | This function is used to return the number of ticks since system | |
56 | startup in milliseconds. This should be the same value that is placed into | |
57 | the time stamp fields of events, and is used to implement auto mouse down | |
58 | events. | |
59 | ****************************************************************************/ | |
60 | ulong _EVT_getTicks(void) | |
61 | { return timeGetTime(); } | |
62 | ||
63 | /**************************************************************************** | |
64 | REMARKS: | |
65 | Pumps all messages in the message queue from Win32 into our event queue. | |
66 | ****************************************************************************/ | |
67 | void _EVT_pumpMessages(void) | |
68 | { | |
69 | MSG msg; | |
70 | MSG charMsg; | |
71 | event_t evt; | |
72 | ||
73 | while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { | |
8bde7f77 WD |
74 | memset(&evt,0,sizeof(evt)); |
75 | switch (msg.message) { | |
76 | case WM_MOUSEMOVE: | |
77 | evt.what = EVT_MOUSEMOVE; | |
78 | break; | |
79 | case WM_LBUTTONDBLCLK: | |
80 | evt.what = EVT_MOUSEDOWN; | |
81 | evt.message = EVT_LEFTBMASK | EVT_DBLCLICK; | |
82 | break; | |
83 | case WM_LBUTTONDOWN: | |
84 | evt.what = EVT_MOUSEDOWN; | |
85 | evt.message = EVT_LEFTBMASK; | |
86 | break; | |
87 | case WM_LBUTTONUP: | |
88 | evt.what = EVT_MOUSEUP; | |
89 | evt.message = EVT_LEFTBMASK; | |
90 | break; | |
91 | case WM_RBUTTONDBLCLK: | |
92 | evt.what = EVT_MOUSEDOWN | EVT_DBLCLICK; | |
93 | evt.message = EVT_RIGHTBMASK; | |
94 | break; | |
95 | case WM_RBUTTONDOWN: | |
96 | evt.what = EVT_MOUSEDOWN; | |
97 | evt.message = EVT_RIGHTBMASK; | |
98 | break; | |
99 | case WM_RBUTTONUP: | |
100 | evt.what = EVT_MOUSEUP; | |
101 | evt.message = EVT_RIGHTBMASK; | |
102 | break; | |
103 | case WM_KEYDOWN: | |
104 | case WM_SYSKEYDOWN: | |
105 | if (HIWORD(msg.lParam) & KF_REPEAT) { | |
106 | evt.what = EVT_KEYREPEAT; | |
107 | } | |
108 | else { | |
109 | evt.what = EVT_KEYDOWN; | |
110 | } | |
111 | break; | |
112 | case WM_KEYUP: | |
113 | case WM_SYSKEYUP: | |
114 | evt.what = EVT_KEYUP; | |
115 | break; | |
116 | } | |
c7de829c | 117 | |
8bde7f77 WD |
118 | /* Convert mouse event modifier flags */ |
119 | if (evt.what & EVT_MOUSEEVT) { | |
120 | evt.where_x = msg.pt.x; | |
121 | evt.where_y = msg.pt.y; | |
122 | if (evt.what == EVT_MOUSEMOVE) { | |
123 | if (oldMove != -1) { | |
124 | evtq[oldMove].where_x = evt.where_x;/* Modify existing one */ | |
125 | evtq[oldMove].where_y = evt.where_y; | |
126 | evt.what = 0; | |
127 | } | |
128 | else { | |
129 | oldMove = freeHead; /* Save id of this move event */ | |
130 | } | |
131 | } | |
132 | else | |
133 | oldMove = -1; | |
134 | if (msg.wParam & MK_LBUTTON) | |
135 | evt.modifiers |= EVT_LEFTBUT; | |
136 | if (msg.wParam & MK_RBUTTON) | |
137 | evt.modifiers |= EVT_RIGHTBUT; | |
138 | if (msg.wParam & MK_SHIFT) | |
139 | evt.modifiers |= EVT_SHIFTKEY; | |
140 | if (msg.wParam & MK_CONTROL) | |
141 | evt.modifiers |= EVT_CTRLSTATE; | |
142 | } | |
c7de829c | 143 | |
8bde7f77 WD |
144 | /* Convert keyboard codes */ |
145 | TranslateMessage(&msg); | |
146 | if (evt.what & EVT_KEYEVT) { | |
147 | int scanCode = (msg.lParam >> 16) & 0xFF; | |
148 | if (evt.what == EVT_KEYUP) { | |
149 | /* Get message for keyup code from table of cached down values */ | |
150 | evt.message = keyUpMsg[scanCode]; | |
151 | keyUpMsg[scanCode] = 0; | |
152 | } | |
153 | else { | |
154 | if (PeekMessage(&charMsg,NULL,WM_CHAR,WM_CHAR,PM_REMOVE)) | |
155 | evt.message = charMsg.wParam; | |
156 | if (PeekMessage(&charMsg,NULL,WM_SYSCHAR,WM_SYSCHAR,PM_REMOVE)) | |
157 | evt.message = charMsg.wParam; | |
158 | evt.message |= ((msg.lParam >> 8) & 0xFF00); | |
159 | keyUpMsg[scanCode] = (ushort)evt.message; | |
160 | } | |
161 | if (evt.what == EVT_KEYREPEAT) | |
162 | evt.message |= (msg.lParam << 16); | |
163 | if (HIWORD(msg.lParam) & KF_ALTDOWN) | |
164 | evt.modifiers |= EVT_ALTSTATE; | |
165 | if (GetKeyState(VK_SHIFT) & 0x8000U) | |
166 | evt.modifiers |= EVT_SHIFTKEY; | |
167 | if (GetKeyState(VK_CONTROL) & 0x8000U) | |
168 | evt.modifiers |= EVT_CTRLSTATE; | |
169 | oldMove = -1; | |
170 | } | |
c7de829c | 171 | |
8bde7f77 WD |
172 | if (evt.what != 0) { |
173 | /* Add time stamp and add the event to the queue */ | |
174 | evt.when = msg.time; | |
175 | if (count < EVENTQSIZE) { | |
176 | addEvent(&evt); | |
177 | } | |
178 | } | |
179 | DispatchMessage(&msg); | |
180 | } | |
c7de829c WD |
181 | } |
182 | ||
183 | /**************************************************************************** | |
184 | REMARKS: | |
185 | This macro/function is used to converts the scan codes reported by the | |
186 | keyboard to our event libraries normalised format. We only have one scan | |
187 | code for the 'A' key, and use shift modifiers to determine if it is a | |
188 | Ctrl-F1, Alt-F1 etc. The raw scan codes from the keyboard work this way, | |
189 | but the OS gives us 'cooked' scan codes, we have to translate them back | |
190 | to the raw format. | |
191 | ****************************************************************************/ | |
192 | #define _EVT_maskKeyCode(evt) | |
193 | ||
194 | /**************************************************************************** | |
195 | REMARKS: | |
196 | Safely abort the event module upon catching a fatal error. | |
197 | ****************************************************************************/ | |
198 | void _EVT_abort() | |
199 | { | |
200 | EVT_exit(); | |
201 | PM_fatalError("Unhandled exception!"); | |
202 | } | |
203 | ||
204 | /**************************************************************************** | |
205 | PARAMETERS: | |
206 | mouseMove - Callback function to call wheneve the mouse needs to be moved | |
207 | ||
208 | REMARKS: | |
209 | Initiliase the event handling module. Here we install our mouse handling ISR | |
210 | to be called whenever any button's are pressed or released. We also build | |
211 | the free list of events in the event queue. | |
212 | ||
213 | We use handler number 2 of the mouse libraries interrupt handlers for our | |
214 | event handling routines. | |
215 | ****************************************************************************/ | |
216 | void EVTAPI EVT_init( | |
217 | _EVT_mouseMoveHandler mouseMove) | |
218 | { | |
219 | /* Initialise the event queue */ | |
220 | _mouseMove = mouseMove; | |
221 | initEventQueue(); | |
222 | memset(keyUpMsg,0,sizeof(keyUpMsg)); | |
223 | ||
224 | /* Catch program termination signals so we can clean up properly */ | |
225 | signal(SIGABRT, _EVT_abort); | |
226 | signal(SIGFPE, _EVT_abort); | |
227 | signal(SIGINT, _EVT_abort); | |
228 | } | |
229 | ||
230 | /**************************************************************************** | |
231 | REMARKS | |
232 | Changes the range of coordinates returned by the mouse functions to the | |
233 | specified range of values. This is used when changing between graphics | |
234 | modes set the range of mouse coordinates for the new display mode. | |
235 | ****************************************************************************/ | |
236 | void EVTAPI EVT_setMouseRange( | |
237 | int xRes, | |
238 | int yRes) | |
239 | { | |
240 | rangeX = xRes; | |
241 | rangeY = yRes; | |
242 | } | |
243 | ||
244 | /**************************************************************************** | |
245 | REMARKS | |
246 | Modifes the mouse coordinates as necessary if scaling to OS coordinates, | |
247 | and sets the OS mouse cursor position. | |
248 | ****************************************************************************/ | |
249 | void _EVT_setMousePos( | |
250 | int *x, | |
251 | int *y) | |
252 | { | |
253 | SetCursorPos(*x,*y); | |
254 | } | |
255 | ||
256 | /**************************************************************************** | |
257 | REMARKS: | |
258 | Initiailises the internal event handling modules. The EVT_suspend function | |
259 | can be called to suspend event handling (such as when shelling out to DOS), | |
260 | and this function can be used to resume it again later. | |
261 | ****************************************************************************/ | |
262 | void EVT_resume(void) | |
263 | { | |
8bde7f77 | 264 | /* Do nothing for Win32 */ |
c7de829c WD |
265 | } |
266 | ||
267 | /**************************************************************************** | |
268 | REMARKS | |
269 | Suspends all of our event handling operations. This is also used to | |
270 | de-install the event handling code. | |
271 | ****************************************************************************/ | |
272 | void EVT_suspend(void) | |
273 | { | |
8bde7f77 | 274 | /* Do nothing for Win32 */ |
c7de829c WD |
275 | } |
276 | ||
277 | /**************************************************************************** | |
278 | REMARKS | |
279 | Exits the event module for program terminatation. | |
280 | ****************************************************************************/ | |
281 | void EVT_exit(void) | |
282 | { | |
283 | /* Restore signal handlers */ | |
284 | signal(SIGABRT, SIG_DFL); | |
285 | signal(SIGFPE, SIG_DFL); | |
286 | signal(SIGINT, SIG_DFL); | |
287 | } |