PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
sdl/PlatformEventQueue.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/platforms/sdl/PlatformEventQueue.cpp
4// Purpose: Interface to platform-specific event queue.
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2004-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28#include "PlatformEventQueue.h"
29#include "PlatformEnvironment.h"
30#include "../../devices/PEventQueue.h"
31#include "../../devices/PEvent.h"
32#include "../../utility/PError.h"
33#include "SDL.h"
34#include "SDL_mouse.h"
35#ifdef PEBL_MOVIES
36#include "WAAVE.h"
37#endif
38
39#include <cstring>
40#include "../../apps/Globals.h"
41// cout removed - use cerr for debug output
42using std::endl;
43
44extern Evaluator * myEval;
46
47
48//This should be moved into PEventQueue
52
56
57
58
63{
64
65
66 SDL_Event test_event;
67 unsigned long int time = SDL_GetTicks();
68
69 if(SDL_HasEvents(SDL_MOUSEBUTTONDOWN,SDL_MOUSEBUTTONUP))
70 {
71 // cerr <<"\n#*#*#*#*#*#*#*#*#*#*#*#*#*#Mouse click/unclick\n";
72
73 }
74 std::string error = SDL_GetError();
75 if(error!="")
76 {
77 // cerr <<"SDL Error: "<< error << endl;
78 SDL_ClearError();
79
80 }
81 //Get the next event in the queue. SDL_PollEvent returns 0
82 //when there are no pending events available.
83
84 while(SDL_PollEvent(&test_event))
85 //while(SDL_WaitEvent(&test_event))
86
87 {
88
89 if(((int)(test_event.type))==1024)
90 {
91 //cerr << "." << std::flush;
92 }else{
93
94 //cerr << "-------------------------\n";
95 //cerr << "EVented\n";
96 //cerr << "Event [" << (int)(test_event.type) << "]\n";
97 }
98
99 #if 0
100
101 cerr << "event types: " << endl
102 << "SDL_KEYDOWN: " << SDL_KEYDOWN << endl
103 << "SDL_KEYUP: " << SDL_KEYUP <<endl
104 << "SDL_TEXTEDITING: " << SDL_TEXTEDITING << endl
105 << "SDL_TEXTINPUT: " << SDL_TEXTINPUT << endl
106 << "SDL_MOUSEMOTION: " << SDL_MOUSEMOTION << endl
107 << "SDL_MOUSEBUTTON.down:" << SDL_MOUSEBUTTONDOWN << endl
108 << "SDL_MOUSEBUTTON.up: " << SDL_MOUSEBUTTONUP << endl
109 << "SDL_MOUSEWHEEL: " << SDL_MOUSEWHEEL << endl;
110
111 #endif
112
113 //first, check to see if the event is the 'magic' abort event:
114 //ctrl-alt-shift-X.
115
116 if(test_event.type == SDL_KEYDOWN)
117 {
118
119 if(test_event.key.keysym.sym == SDLK_BACKSLASH)
120 {
121 if((test_event.key.keysym.mod & KMOD_SHIFT )
122 && (test_event.key.keysym.mod & KMOD_ALT)
123 && (test_event.key.keysym.mod & KMOD_CTRL))
124 {
125 PError::ExitQuietly("Stopping execution: Received abort key-combo.\n");
126 }
127 }
128
129 }
130
131 //Create a PEBL event from the SDL event, if possible.
132
133 switch(test_event.type)
134 {
135
136
137 case SDL_KEYDOWN:
138 {
139
140
141 //Determine which key is being used.
142
143 PEvent evt(PDT_KEYBOARD, time,test_event.key.windowID);
145 //cerr << "Keydown event...PRESSED->[" << SDL_GetKeyName(test_event.key.keysym.sym)<<"] \n";
146 //cerr << "Keycode:" <<SDL_SCANCODE_TO_KEYCODE(test_event.key.keysym.scancode) << endl;
147
148 pke.key = (PEBL_Keycode)test_event.key.keysym.sym;
149 pke.scancode = (PEBL_Keycode)(test_event.key.keysym.scancode);
150 pke.modkeys = test_event.key.keysym.mod;
151 pke.state = PEBL_PRESSED;
152
153
154 //cerr << "keystate in platformeventqueue is: " << pke.state << "|" << pke.key << endl;
155
156 evt.SetKeyboardEvent(pke);
157 mEventQueue.push(evt);
158
159 }
160 break;
161
162 case SDL_KEYUP:
163 {
164 // cerr << "KEYUP\n";
165 //create a new event to add to the queue.
166 PEvent evt(PDT_KEYBOARD, time,test_event.key.windowID);
167
168 //The event has a keyboard event inside it.
170 //pke.key = (PEBLKey)(test_event.key.keysym.sym);
171
172 pke.key = (PEBL_Keycode)test_event.key.keysym.sym;
173 pke.scancode = (PEBL_Keycode)(test_event.key.keysym.scancode);
174 pke.modkeys = test_event.key.keysym.mod;
175
176 pke.state = PEBL_RELEASED;
177
178
179 evt.SetKeyboardEvent(pke);
180 mEventQueue.push(evt);
181
182 }
183
184 break;
185
186 //Text editing event...in-progress textinput event.
187 case SDL_TEXTEDITING:
188
189 {
190 //cerr << "SDL_TEXTEDITING EVENT\n";
191 /*
192
193 PEvent evt(PDT_TEXT_EDITING, time);
194 PEBL_TextEditingEvent pee;
195
196
197 pee.text =test_event.edit.text;
198 pee.window = 0;
199
200 evt.SetTextEditingEvent(pee);
201 mEventQueue.push(evt);
202 */
203 }
204
205 break;
206
207 //This is a textinput event, which is new
208 //for SDL2. It handle input from a variety of modes
209 //and generally let's us support international
210 //character inputs.
211 case SDL_TEXTINPUT:
212 {
213
214 //cerr << "SDL_TEXTINPUT EVENT\n";
215 PEvent evt(PDT_TEXT_INPUT, time,test_event.edit.windowID);
217 //cerr << "Transferring: " << test_event.edit.text << endl;
218
219 pti.text = strdup(test_event.edit.text);
220
221 pti.window = 0;
222 pti.start = test_event.edit.start;
223 pti.length = test_event.edit.length;
224 evt.SetTextInputEvent(pti);
225 mEventQueue.push(evt);
226
227 }
228
229 break;
230 case SDL_QUIT:
231 PError::ExitQuietly("Stopping execution because of quit signal.\n");
232 break;
233
234 case SDL_MOUSEBUTTONDOWN:
235 {
236 //cerr << "Mouse button down in platformeventqueue\n";
237 PEvent evt(PDT_MOUSE_BUTTON, time,test_event.button.windowID);
239
240 pme.x= test_event.button.x;
241 pme.y= test_event.button.y;
242 pme.button=test_event.button.button;
243 pme.state =test_event.button.state;
244
245
246 pme.state = PEBL_PRESSED;
247
248 evt.SetMouseButtonEvent(pme);
249 mEventQueue.push(evt);
250 //cerr << "mouse down ["<< pme.x << " " << pme.y << "--" << pme.button<<"]\n";
251
252 }
253 break;
254
255 case SDL_MOUSEBUTTONUP:
256 {
257 //cerr << "Mouse button up in platformeventqueue\n";
258 PEvent evt(PDT_MOUSE_BUTTON, time,test_event.button.windowID);
260
261 pme.x= test_event.button.x;
262 pme.y= test_event.button.y;
263 pme.button=test_event.button.button;
264 pme.state =test_event.button.state;
265
266 pme.state = PEBL_RELEASED;
267
268 evt.SetMouseButtonEvent(pme);
269 mEventQueue.push(evt);
270
271 }
272 break;
273 case SDL_MOUSEMOTION:
274 {
275 PEvent evt(PDT_MOUSE_MOVEMENT, time,test_event.motion.windowID);
277 //cerr << "mousemove\n";
278 pme.x= test_event.motion.x;
279 pme.y= test_event.motion.y;
280 pme.relx =test_event.motion.xrel;
281 pme.rely =test_event.motion.yrel;
282
283
284 evt.SetMouseMovementEvent(pme);
285 mEventQueue.push(evt);
286
287 }
288 break;
289
290 case SDL_MOUSEWHEEL:
291 {
292
293 PEvent evt(PDT_MOUSE_WHEEL,time,test_event.wheel.windowID);
295
296 int xpos,ypos;
297 //get the mouse position
298 SDL_GetMouseState(&xpos,&ypos);
299
300
301 pmwe.x = xpos;
302 pmwe.y = ypos;
303
304 pmwe.deltax = test_event.wheel.x;
305 pmwe.deltay = test_event.wheel.y;
306
307
308 //this may not work on SDL 2.0 sligthly older libraries, or maybe not o n windows.
309#ifdef SDL_MOUSEWHEEL_FLIPPED
310 if(test_event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED )
311 pmwe.direction = -1;
312 else
313 pmwe.direction = 1;
314#else
315 pmwe.direction = 1;
316#endif
317
318 evt.SetMouseWheelEvent(pmwe);
319 mEventQueue.push(evt);
320 }
321 break;
322
323 //catch-all for various window resize/focus issues. This is used to address
324 //failure to redraw launcher when window minimized then replaced after running a script.
325 case SDL_WINDOWEVENT:
326 {
327 switch(test_event.window.event)
328 {
329 case SDL_WINDOWEVENT_RESIZED:
330 case SDL_WINDOWEVENT_SIZE_CHANGED:
331 case SDL_WINDOWEVENT_RESTORED:
332 case SDL_WINDOWEVENT_EXPOSED:
333 case SDL_WINDOWEVENT_SHOWN:
334 case SDL_WINDOWEVENT_HIDDEN:
335
336 //we want the environment to issue a 'draw' command here.
337 //we need access to the environmnet or the renderer.
338 //PlatformEnvironment::Draw();
339 if(myEnv)
340 {
341 myEnv->Draw();
342 //cerr << "My window drawing stuff\n";
343 }
344 break;
345 }
346
347#ifdef SDL2_DELETE
348
349 PEvent evt(PDT_WINDOW_RESIZE,time,test_event.resize.windowID);
350
351
353
354 pwe.w= test_event.resize.w;
355 pwe.h= test_event.resize.h;
356 evt.SetWindowEvent(pwe);
357 mEventQueue.push(evt);
358
359
360 //Change the video size.
361 myEval->gGlobalVariableMap.AddVariable("gVideoWidth", pwe.w);
362 myEval->gGlobalVariableMap.AddVariable("gVideoHeight", pwe.h);
363
364#endif
365
366 }
367 break;
368
369 case SDL_RENDER_TARGETS_RESET:
370 // case SDL_RENDER_DEVICE_RESET:
371 {
372 PError::SignalWarning("Rendering targets reset error.");
373 }
374 default:
375#ifdef PEBL_MOVIES
376 //WV_REFRESH_EVENT is not const, so we need to do some acrobatics here.
377 if(test_event.type == WV_REFRESH_EVENT)
378 {
379 //cerr <<" XXXXX Refresh movie event\n";
380 //cerr << test_event << endl;
381 //PEvent evt(PDT_MOVIE_REFRESH,time);
382 WV_refreshVideoFrame(&test_event);
383
384
385
386
387 }else if(test_event.type==WV_EOF_EVENT)
388 {
389
390 //cerr << "End of movie:\n";
391 PEvent evt(PDT_MOVIE_END, time, test_event.key.windowID);
392 mEventQueue.push(evt);
393
394
395 }
396 break;
397#endif
398
399
400 //cerr << "Unknown event\n";
401 ;
402 }
403 //cerr << "Loop active\n";
404 time = SDL_GetTicks();
405 //cerr << "time: " << time << endl;
406 }
407}
Evaluator * myEval
Definition PEBL.cpp:188
@ PDT_MOUSE_WHEEL
Definition PDevice.h:47
@ PDT_MOVIE_END
Definition PDevice.h:58
@ PDT_TEXT_INPUT
Definition PDevice.h:43
@ PDT_MOUSE_MOVEMENT
Definition PDevice.h:45
@ PDT_MOUSE_BUTTON
Definition PDevice.h:46
@ PDT_KEYBOARD
Definition PDevice.h:42
@ PDT_WINDOW_RESIZE
Definition PDevice.h:59
PlatformEnvironment * myEnv
Definition PEBL.cpp:189
@ PEBL_RELEASED
Definition PEvent.h:46
@ PEBL_PRESSED
Definition PEvent.h:45
PEBL_Keycode
Definition PKeyboard.h:78
This class has got everything you need to evaluate stuff.
static VariableMap gGlobalVariableMap
queue< PEvent > mEventQueue
Definition PEventQueue.h:68
void SetWindowEvent(const PEBL_WindowEvent &evt)
Definition PEvent.cpp:175
void SetKeyboardEvent(const PEBL_KeyboardEvent &evt)
Definition PEvent.cpp:122
void SetTextInputEvent(const PEBL_TextInputEvent &evt)
Definition PEvent.cpp:136
void SetMouseMovementEvent(const PEBL_MouseMovementEvent &evt)
Definition PEvent.cpp:143
void SetMouseButtonEvent(const PEBL_MouseButtonEvent &evt)
Definition PEvent.cpp:149
void SetMouseWheelEvent(const PEBL_MouseWheelEvent &evt)
Definition PEvent.cpp:157
void AddVariable(const std::string &varname, const Variant &val)
void ExitQuietly(const std::string &message, int exitCode=0)
Definition PError.cpp:126
void SignalWarning(const std::string &message)
Definition PError.cpp:119
PlatformEnvironment * myEnv
Definition PEBL.cpp:189
Evaluator * myEval
Definition PEBL.cpp:188
unsigned int state
Definition PEvent.h:67
PEBL_Keycode scancode
Definition PEvent.h:61
PEBL_Keycode key
Definition PEvent.h:66
unsigned int x
Definition PEvent.h:105
unsigned int y
Definition PEvent.h:105
unsigned int y
Definition PEvent.h:97
unsigned int x
Definition PEvent.h:97
long unsigned int x
Definition PEvent.h:115
long unsigned int y
Definition PEvent.h:115
unsigned int window
Definition PEvent.h:85
unsigned int length
Definition PEvent.h:88
unsigned int start
Definition PEvent.h:87