Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/freeglut/src/blackberry/fg_main_blackberry.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * fg_main_blackberry.c | |
| 3 * | |
| 4 * The BlackBerry-specific windows message processing methods. | |
| 5 * | |
| 6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. | |
| 7 * Written by Pawel W. Olszta, <olszta@sourceforge.net> | |
| 8 * Copied for Platform code by Evan Felix <karcaw at gmail.com> | |
| 9 * Copyright (C) 2012 Sylvain Beucler | |
| 10 * Copyright (C) 2013 Vincent Simonetti | |
| 11 * | |
| 12 * Permission is hereby granted, free of charge, to any person obtaining a | |
| 13 * copy of this software and associated documentation files (the "Software"), | |
| 14 * to deal in the Software without restriction, including without limitation | |
| 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 16 * and/or sell copies of the Software, and to permit persons to whom the | |
| 17 * Software is furnished to do so, subject to the following conditions: | |
| 18 * | |
| 19 * The above copyright notice and this permission notice shall be included | |
| 20 * in all copies or substantial portions of the Software. | |
| 21 * | |
| 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 25 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
| 26 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| 27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 28 */ | |
| 29 | |
| 30 #include <GL/freeglut.h> | |
| 31 #include "fg_internal.h" | |
| 32 #include "egl/fg_window_egl.h" | |
| 33 | |
| 34 #ifdef NDEBUG | |
| 35 #define LOGI(...) | |
| 36 #endif | |
| 37 | |
| 38 #ifdef __PLAYBOOK__ | |
| 39 #include <sys/slog.h> | |
| 40 #ifndef LOGI | |
| 41 #define LOGI(...) ((void)slogf(1337, _SLOG_INFO, __VA_ARGS__)) | |
| 42 #endif | |
| 43 #define LOGW(...) ((void)slogf(1337, _SLOG_WARNING, __VA_ARGS__)) | |
| 44 #ifndef SLOG2_FA_SIGNED | |
| 45 #define SLOG2_FA_SIGNED(x) (x) | |
| 46 #endif | |
| 47 #else | |
| 48 #include <slog2.h> | |
| 49 #ifndef LOGI | |
| 50 #define LOGI(...) ((void)slog2fa(NULL, 1337, SLOG2_INFO, __VA_ARGS__, SLOG2_FA_END)) | |
| 51 #endif | |
| 52 #define LOGW(...) ((void)slog2fa(NULL, 1337, SLOG2_WARNING, __VA_ARGS__, SLOG2_FA_END)) | |
| 53 #endif | |
| 54 #include <sys/keycodes.h> | |
| 55 #include <input/screen_helpers.h> | |
| 56 #include <bps/bps.h> | |
| 57 #include <bps/event.h> | |
| 58 #include <bps/screen.h> | |
| 59 #include <bps/navigator.h> | |
| 60 #include <bps/virtualkeyboard.h> | |
| 61 | |
| 62 extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean forceNotify); | |
| 63 extern void fghOnPositionNotify(SFG_Window *window, int x, int y, GLboolean forceNotify); | |
| 64 extern void fgPlatformFullScreenToggle( SFG_Window *win ); | |
| 65 extern void fgPlatformPositionWindow( SFG_Window *window, int x, int y ); | |
| 66 extern void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ); | |
| 67 extern void fgPlatformPushWindow( SFG_Window *window ); | |
| 68 extern void fgPlatformPopWindow( SFG_Window *window ); | |
| 69 extern void fgPlatformHideWindow( SFG_Window *window ); | |
| 70 extern void fgPlatformIconifyWindow( SFG_Window *window ); | |
| 71 extern void fgPlatformShowWindow( SFG_Window *window ); | |
| 72 extern void fgPlatformMainLoopPostWork ( void ); | |
| 73 extern void fgPlatformRotateWindow( SFG_Window *window, int rotation ); | |
| 74 extern void fgPlatformFlushCommands ( void ); | |
| 75 | |
| 76 static struct touchscreen touchscreen; | |
| 77 | |
| 78 #define ESCAPE_BUTTON_KEY 0x001B | |
| 79 | |
| 80 unsigned int key_special(int qnxKeycode) | |
| 81 { | |
| 82 switch(qnxKeycode) { | |
| 83 case KEYCODE_F1: | |
| 84 return GLUT_KEY_F1; | |
| 85 case KEYCODE_F2: | |
| 86 return GLUT_KEY_F2; | |
| 87 case KEYCODE_F3: | |
| 88 return GLUT_KEY_F3; | |
| 89 case KEYCODE_F4: | |
| 90 return GLUT_KEY_F4; | |
| 91 case KEYCODE_F5: | |
| 92 return GLUT_KEY_F5; | |
| 93 case KEYCODE_F6: | |
| 94 return GLUT_KEY_F6; | |
| 95 case KEYCODE_F7: | |
| 96 return GLUT_KEY_F7; | |
| 97 case KEYCODE_F8: | |
| 98 return GLUT_KEY_F8; | |
| 99 case KEYCODE_F9: | |
| 100 return GLUT_KEY_F9; | |
| 101 case KEYCODE_F10: | |
| 102 return GLUT_KEY_F10; | |
| 103 case KEYCODE_F11: | |
| 104 return GLUT_KEY_F11; | |
| 105 case KEYCODE_F12: | |
| 106 return GLUT_KEY_F12; | |
| 107 case KEYCODE_PG_UP: | |
| 108 return GLUT_KEY_PAGE_UP; | |
| 109 case KEYCODE_PG_DOWN: | |
| 110 return GLUT_KEY_PAGE_DOWN; | |
| 111 case KEYCODE_HOME: | |
| 112 return GLUT_KEY_HOME; | |
| 113 case KEYCODE_END: | |
| 114 return GLUT_KEY_END; | |
| 115 case KEYCODE_INSERT: | |
| 116 return GLUT_KEY_INSERT; | |
| 117 case KEYCODE_UP: | |
| 118 //case KEYCODE_KP_UP: | |
| 119 return GLUT_KEY_UP; | |
| 120 case KEYCODE_DOWN: | |
| 121 //case KEYCODE_KP_DOWN: | |
| 122 return GLUT_KEY_DOWN; | |
| 123 case KEYCODE_LEFT: | |
| 124 //case KEYCODE_KP_LEFT: | |
| 125 return GLUT_KEY_LEFT; | |
| 126 case KEYCODE_RIGHT: | |
| 127 //case KEYCODE_KP_RIGHT: | |
| 128 return GLUT_KEY_RIGHT; | |
| 129 case KEYCODE_NUM_LOCK: | |
| 130 return GLUT_KEY_NUM_LOCK; | |
| 131 case KEYCODE_LEFT_ALT: | |
| 132 return GLUT_KEY_ALT_L; | |
| 133 case KEYCODE_RIGHT_ALT: | |
| 134 return GLUT_KEY_ALT_R; | |
| 135 case KEYCODE_LEFT_SHIFT: | |
| 136 return GLUT_KEY_SHIFT_L; | |
| 137 case KEYCODE_RIGHT_SHIFT: | |
| 138 return GLUT_KEY_SHIFT_R; | |
| 139 case KEYCODE_LEFT_CTRL: | |
| 140 return GLUT_KEY_CTRL_L; | |
| 141 case KEYCODE_RIGHT_CTRL: | |
| 142 return GLUT_KEY_CTRL_R; | |
| 143 } | |
| 144 return 0; | |
| 145 } | |
| 146 | |
| 147 unsigned char key_ascii(int qnxKeycode) | |
| 148 { | |
| 149 if (qnxKeycode >= KEYCODE_PC_KEYS && qnxKeycode <= UNICODE_PRIVATE_USE_AREA_LAST) { | |
| 150 switch (qnxKeycode) { | |
| 151 case KEYCODE_BACKSPACE: | |
| 152 return 0x0008; | |
| 153 case KEYCODE_TAB: | |
| 154 return 0x0009; | |
| 155 case KEYCODE_KP_ENTER: | |
| 156 case KEYCODE_RETURN: | |
| 157 return 0x000A; | |
| 158 case KEYCODE_ESCAPE: | |
| 159 return ESCAPE_BUTTON_KEY; | |
| 160 } | |
| 161 } | |
| 162 return qnxKeycode; | |
| 163 } | |
| 164 | |
| 165 //From fg_main_x11 | |
| 166 fg_time_t fgPlatformSystemTime ( void ) | |
| 167 { | |
| 168 #ifdef CLOCK_MONOTONIC | |
| 169 struct timespec now; | |
| 170 clock_gettime(CLOCK_MONOTONIC, &now); | |
| 171 return now.tv_nsec/1000000 + now.tv_sec*1000; | |
| 172 #elif defined(HAVE_GETTIMEOFDAY) | |
| 173 struct timeval now; | |
| 174 gettimeofday( &now, NULL ); | |
| 175 return now.tv_usec/1000 + now.tv_sec*1000; | |
| 176 #endif | |
| 177 } | |
| 178 | |
| 179 /* | |
| 180 * Does the magic required to relinquish the CPU until something interesting | |
| 181 * happens. | |
| 182 */ | |
| 183 void fgPlatformSleepForEvents( fg_time_t msec ) | |
| 184 { | |
| 185 if(fgStructure.CurrentWindow && fgDisplay.pDisplay.event == NULL && | |
| 186 bps_get_event(&fgDisplay.pDisplay.event, (int)msec) != BPS_SUCCESS) { | |
| 187 LOGW("BPS couldn't get event"); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 void handle_left_mouse(int x, int y, int height, int eventType, SFG_Window* window) | |
| 192 { | |
| 193 bool handled = false; | |
| 194 /* Virtual arrows PAD */ | |
| 195 /* Don't interfere with existing mouse move event */ | |
| 196 if (!touchscreen.in_mmotion) { | |
| 197 struct vpad_state prev_vpad = touchscreen.vpad; | |
| 198 touchscreen.vpad.left = touchscreen.vpad.right = touchscreen.vpad.up = touchscreen.vpad.down = false; | |
| 199 | |
| 200 if (eventType == SCREEN_EVENT_MTOUCH_TOUCH || eventType == SCREEN_EVENT_MTOUCH_MOVE) { | |
| 201 if ((x > 0 && x < 100) && (y > (height - 100) && y < height)) | |
| 202 { | |
| 203 touchscreen.vpad.left = true; | |
| 204 } | |
| 205 if ((x > 200 && x < 300) && (y > (height - 100) && y < height)) | |
| 206 { | |
| 207 touchscreen.vpad.right = true; | |
| 208 } | |
| 209 if ((x > 100 && x < 200) && (y > (height - 100) && y < height)) | |
| 210 { | |
| 211 touchscreen.vpad.down = true; | |
| 212 } | |
| 213 if ((x > 100 && x < 200) && (y > (height - 200) && y < (height - 100))) | |
| 214 { | |
| 215 touchscreen.vpad.up = true; | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 if (eventType == SCREEN_EVENT_MTOUCH_TOUCH && | |
| 220 (touchscreen.vpad.left || touchscreen.vpad.right || touchscreen.vpad.down || touchscreen.vpad.up)) { | |
| 221 touchscreen.vpad.on = true; | |
| 222 } | |
| 223 if (eventType == SCREEN_EVENT_MTOUCH_RELEASE) { | |
| 224 touchscreen.vpad.on = false; | |
| 225 } | |
| 226 | |
| 227 if (prev_vpad.left != touchscreen.vpad.left | |
| 228 || prev_vpad.right != touchscreen.vpad.right | |
| 229 || prev_vpad.up != touchscreen.vpad.up | |
| 230 || prev_vpad.down != touchscreen.vpad.down | |
| 231 || prev_vpad.on != touchscreen.vpad.on) { | |
| 232 if (FETCH_WCB(*window, Special)) { | |
| 233 if (prev_vpad.left == false && touchscreen.vpad.left == true) { | |
| 234 INVOKE_WCB(*window, Special, (GLUT_KEY_LEFT, x, y)); | |
| 235 } | |
| 236 else if (prev_vpad.right == false && touchscreen.vpad.right == true) { | |
| 237 INVOKE_WCB(*window, Special, (GLUT_KEY_RIGHT, x, y)); | |
| 238 } | |
| 239 else if (prev_vpad.up == false && touchscreen.vpad.up == true) { | |
| 240 INVOKE_WCB(*window, Special, (GLUT_KEY_UP, x, y)); | |
| 241 } | |
| 242 else if (prev_vpad.down == false && touchscreen.vpad.down == true) { | |
| 243 INVOKE_WCB(*window, Special, (GLUT_KEY_DOWN, x, y)); | |
| 244 } | |
| 245 } | |
| 246 if (FETCH_WCB(*window, SpecialUp)) { | |
| 247 if (prev_vpad.left == true && touchscreen.vpad.left == false) { | |
| 248 INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_LEFT, x, y)); | |
| 249 } | |
| 250 if (prev_vpad.right == true && touchscreen.vpad.right == false) { | |
| 251 INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_RIGHT, x, y)); | |
| 252 } | |
| 253 if (prev_vpad.up == true && touchscreen.vpad.up == false) { | |
| 254 INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_UP, x, y)); | |
| 255 } | |
| 256 if (prev_vpad.down == true && touchscreen.vpad.down == false) { | |
| 257 INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_DOWN, x, y)); | |
| 258 } | |
| 259 } | |
| 260 handled = true; | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 /* Normal mouse events */ | |
| 265 if (!handled && !touchscreen.vpad.on) { | |
| 266 window->State.MouseX = x; | |
| 267 window->State.MouseY = y; | |
| 268 | |
| 269 if(eventType == SCREEN_EVENT_MTOUCH_MOVE) { | |
| 270 INVOKE_WCB(*window, Motion, (x, y)); | |
| 271 } else if(FETCH_WCB(*window, Mouse)) { | |
| 272 touchscreen.in_mmotion = eventType == SCREEN_EVENT_MTOUCH_TOUCH; | |
| 273 int glutTouchType = eventType == SCREEN_EVENT_MTOUCH_TOUCH ? GLUT_DOWN : GLUT_UP; | |
| 274 INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, glutTouchType, x, y)); | |
| 275 } | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 /* | |
| 280 * Determine a GLUT modifier mask based on BlackBerry modifier info. | |
| 281 */ | |
| 282 int fgPlatformGetModifiers (int mod) | |
| 283 { | |
| 284 return (((mod & KEYMOD_SHIFT) ? GLUT_ACTIVE_SHIFT : 0) | | |
| 285 ((mod & KEYMOD_CTRL) ? GLUT_ACTIVE_CTRL : 0) | | |
| 286 ((mod & KEYMOD_ALT) ? GLUT_ACTIVE_ALT : 0)); | |
| 287 } | |
| 288 | |
| 289 void fgPlatformHandleKeyboardHeight(SFG_Window* window, int height) | |
| 290 { | |
| 291 int size[2]; | |
| 292 int screenHeight; | |
| 293 int nScreenHeight = -1; | |
| 294 | |
| 295 screenHeight = glutGet(GLUT_WINDOW_HEIGHT); //Using this takes rotation into account | |
| 296 if(height == 0) { | |
| 297 nScreenHeight = screenHeight; | |
| 298 } | |
| 299 else if(!screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_POSITION, size)) { | |
| 300 /* Calculate the new screen size */ //XXX Make sure to use display size instead of screen size | |
| 301 nScreenHeight = ((size[1] + screenHeight) - height) - size[1]; | |
| 302 } | |
| 303 | |
| 304 if(nScreenHeight != -1) { | |
| 305 /* If nScreenHeight is less then zero then window is covered. If nScreenHeight == height, then no change in size. Else, change in size */ | |
| 306 | |
| 307 int screenWidth = glutGet(GLUT_WINDOW_WIDTH); | |
| 308 if(nScreenHeight < 0) { | |
| 309 LOGI("fgPlatformHandleKeyboardHeight: Covered window state"); | |
| 310 window->State.Visible = GL_FALSE; | |
| 311 window->State.pWState.windowCovered = GL_TRUE; | |
| 312 INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_COVERED)); | |
| 313 fghOnReshapeNotify(window, screenWidth, 0, GL_FALSE); | |
| 314 } else { | |
| 315 if(window->State.pWState.windowCovered == GL_TRUE) { | |
| 316 LOGI("fgPlatformHandleKeyboardHeight: Resetting window state"); | |
| 317 | |
| 318 /* Reset window status if it was previously covered */ | |
| 319 switch(window->State.pWState.windowState) { | |
| 320 case NAVIGATOR_WINDOW_FULLSCREEN: | |
| 321 window->State.Visible = GL_TRUE; | |
| 322 INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED)); | |
| 323 break; | |
| 324 case NAVIGATOR_WINDOW_THUMBNAIL: | |
| 325 window->State.Visible = GL_TRUE; | |
| 326 INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED)); | |
| 327 break; | |
| 328 case NAVIGATOR_WINDOW_INVISIBLE: | |
| 329 window->State.Visible = GL_FALSE; | |
| 330 INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN)); | |
| 331 break; | |
| 332 } | |
| 333 window->State.pWState.windowCovered = GL_FALSE; | |
| 334 } | |
| 335 fghOnReshapeNotify(window, screenWidth, nScreenHeight, GL_FALSE); | |
| 336 } | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 void fgPlatformProcessSingleEvent ( void ) | |
| 341 { | |
| 342 if(fgStructure.CurrentWindow == NULL) { | |
| 343 //XXX Is this right? Would this just cause a whole lot of busy looping while we wait for events? | |
| 344 LOGW("fgPlatformProcessSingleEvent: Missing current window. Skipping event processing"); | |
| 345 return; | |
| 346 } | |
| 347 | |
| 348 if(fgDisplay.pDisplay.event == NULL) | |
| 349 /* Nothing to do */ | |
| 350 return; | |
| 351 | |
| 352 int domain; | |
| 353 do | |
| 354 { | |
| 355 SFG_Window* window = fgStructure.CurrentWindow; | |
| 356 /* Get the keyboard height before doing anything since we otherwise don't get it until it changes */ | |
| 357 if(window->State.pWState.keyboardHeight == 0) { | |
| 358 virtualkeyboard_get_height(&window->State.pWState.keyboardHeight); | |
| 359 } | |
| 360 domain = bps_event_get_domain(fgDisplay.pDisplay.event); | |
| 361 if (domain == screen_get_domain()) { | |
| 362 int eventType; | |
| 363 int mod; | |
| 364 screen_event_t screenEvent = screen_event_get_event(fgDisplay.pDisplay.event); | |
| 365 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_TYPE, &eventType); | |
| 366 switch (eventType) { | |
| 367 | |
| 368 //Mostly from fg_main_android | |
| 369 case SCREEN_EVENT_MTOUCH_TOUCH: | |
| 370 case SCREEN_EVENT_MTOUCH_RELEASE: | |
| 371 case SCREEN_EVENT_MTOUCH_MOVE: | |
| 372 { | |
| 373 mtouch_event_t touchEvent; | |
| 374 screen_get_mtouch_event(screenEvent, &touchEvent, 0); | |
| 375 #ifndef __PLAYBOOK__ | |
| 376 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); | |
| 377 #else | |
| 378 mod = 0; | |
| 379 #endif | |
| 380 | |
| 381 LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_MTOUCH_*: Type: 0x%X, X: %d, Y: %d, Contact Id: %d, Mod: 0x%X", SLOG2_FA_SIGNED(eventType), SLOG2_FA_SIGNED(touchEvent.x), SLOG2_FA_SIGNED(touchEvent.y), SLOG2_FA_SIGNED(touchEvent.contact_id), SLOG2_FA_SIGNED(mod)); | |
| 382 | |
| 383 /* Remember the current modifiers state so user can query it from their callback */ | |
| 384 fgState.Modifiers = fgPlatformGetModifiers(mod); | |
| 385 | |
| 386 if(touchEvent.contact_id == 0) { | |
| 387 int size[2]; | |
| 388 screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); | |
| 389 handle_left_mouse(touchEvent.x, touchEvent.y, size[1], eventType, window); | |
| 390 } | |
| 391 | |
| 392 //Now handle mutlitouch (adapted from fg_main_windows) | |
| 393 if (eventType == SCREEN_EVENT_MTOUCH_TOUCH) { | |
| 394 INVOKE_WCB( *window, MultiEntry, ( touchEvent.contact_id, GLUT_ENTERED ) ); | |
| 395 INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_DOWN ) ); | |
| 396 } else if (eventType == SCREEN_EVENT_MTOUCH_MOVE) { | |
| 397 INVOKE_WCB( *window, MultiMotion, ( touchEvent.contact_id, touchEvent.x, touchEvent.y ) ); | |
| 398 //XXX No motion is performed without contact, thus MultiPassive is never used | |
| 399 } else if (eventType == SCREEN_EVENT_MTOUCH_RELEASE) { | |
| 400 INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_UP ) ); | |
| 401 INVOKE_WCB( *window, MultiEntry, ( touchEvent.contact_id, GLUT_LEFT ) ); | |
| 402 } | |
| 403 | |
| 404 fgState.Modifiers = INVALID_MODIFIERS; | |
| 405 break; | |
| 406 } | |
| 407 | |
| 408 case SCREEN_EVENT_POINTER: | |
| 409 { | |
| 410 //Based off/part taken from GamePlay3d PlatformBlackBerry | |
| 411 static int mouse_pressed = 0; | |
| 412 int buttons; | |
| 413 int position[2]; | |
| 414 int wheel; | |
| 415 // A move event will be fired unless a button state changed. | |
| 416 bool move = true; | |
| 417 bool left_move = false; | |
| 418 // This is a mouse move event, it is applicable to a device with a usb mouse or simulator. | |
| 419 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons); | |
| 420 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position); | |
| 421 #ifndef __PLAYBOOK__ | |
| 422 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel); | |
| 423 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); | |
| 424 #else | |
| 425 wheel = mod = 0; | |
| 426 #endif | |
| 427 int size[2]; | |
| 428 screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); | |
| 429 | |
| 430 LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d, Mod: 0x%X", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel), SLOG2_FA_SIGNED(mod)); | |
| 431 | |
| 432 //XXX Is multitouch be handled in a good way? | |
| 433 | |
| 434 /* Remember the current modifiers state so user can query it from their callback */ | |
| 435 fgState.Modifiers = fgPlatformGetModifiers(mod); | |
| 436 | |
| 437 // Handle left mouse. Interpret as touch if the left mouse event is not consumed. | |
| 438 if (buttons & SCREEN_LEFT_MOUSE_BUTTON) { | |
| 439 if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) { | |
| 440 left_move = true; | |
| 441 } else { | |
| 442 move = false; | |
| 443 mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON; | |
| 444 handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_TOUCH, window); | |
| 445 } | |
| 446 } else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) { | |
| 447 move = false; | |
| 448 mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON; | |
| 449 handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_RELEASE, window); | |
| 450 } | |
| 451 | |
| 452 // Handle right mouse. | |
| 453 if (buttons & SCREEN_RIGHT_MOUSE_BUTTON) { | |
| 454 if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0) { | |
| 455 move = false; | |
| 456 mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON; | |
| 457 INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_DOWN, position[0], position[1])); | |
| 458 } | |
| 459 } else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) { | |
| 460 move = false; | |
| 461 mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON; | |
| 462 INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_UP, position[0], position[1])); | |
| 463 } | |
| 464 | |
| 465 // Handle middle mouse. | |
| 466 if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON) { | |
| 467 if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0) { | |
| 468 move = false; | |
| 469 mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON; | |
| 470 INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_DOWN, position[0], position[1])); | |
| 471 } | |
| 472 } else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) { | |
| 473 move = false; | |
| 474 mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON; | |
| 475 INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_UP, position[0], position[1])); | |
| 476 } | |
| 477 | |
| 478 // Fire a move event if none of the buttons changed. | |
| 479 if (left_move || move) { | |
| 480 handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_MOVE, window); | |
| 481 } | |
| 482 | |
| 483 if (wheel) { | |
| 484 /* Very slightly modified from fg_main_mswin. | |
| 485 * Because we don't want MouseWheel to be called every. single. time. | |
| 486 * That the action occurs, we mimic the Windows version with "wheel deltas" | |
| 487 * XXX Do we even want this? | |
| 488 * XXX If we want this, it's possible to get horizontal scroll as well. | |
| 489 * XXX -Vertical scroll=wheel 0, horizontal=wheel 1? */ | |
| 490 fgState.MouseWheelTicks -= wheel; | |
| 491 if (abs(fgState.MouseWheelTicks) >= WHEEL_DELTA) | |
| 492 { | |
| 493 int wheel_number = 0; | |
| 494 int direction = (fgState.MouseWheelTicks > 0) ? -1 : 1; | |
| 495 | |
| 496 if (!FETCH_WCB(*window, MouseWheel) && !FETCH_WCB(*window, Mouse)) | |
| 497 break; | |
| 498 | |
| 499 //XXX fgSetWindow(window); | |
| 500 | |
| 501 while(abs(fgState.MouseWheelTicks) >= WHEEL_DELTA) | |
| 502 { | |
| 503 if (FETCH_WCB(*window, MouseWheel)) | |
| 504 INVOKE_WCB(*window, MouseWheel, (wheel_number, direction, window->State.MouseX, window->State.MouseY)); | |
| 505 else /* No mouse wheel, call the mouse button callback twice */ | |
| 506 { | |
| 507 /* | |
| 508 * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4 | |
| 509 * " " one +1 to 5, -1 to 6, ... | |
| 510 * | |
| 511 * XXX The below assumes that you have no more than 3 mouse | |
| 512 * XXX buttons. Sorry. | |
| 513 */ | |
| 514 int button = wheel_number * 2 + 3; | |
| 515 if (direction < 0) | |
| 516 ++button; | |
| 517 INVOKE_WCB(*window, Mouse, (button, GLUT_DOWN, window->State.MouseX, window->State.MouseY)); | |
| 518 INVOKE_WCB(*window, Mouse, (button, GLUT_UP, window->State.MouseX, window->State.MouseY)); | |
| 519 } | |
| 520 | |
| 521 fgState.MouseWheelTicks -= WHEEL_DELTA * direction; | |
| 522 } | |
| 523 } | |
| 524 } | |
| 525 | |
| 526 fgState.Modifiers = INVALID_MODIFIERS; | |
| 527 break; | |
| 528 } | |
| 529 | |
| 530 //Based off fg_main_android | |
| 531 case SCREEN_EVENT_KEYBOARD: | |
| 532 { | |
| 533 int flags; | |
| 534 int value; | |
| 535 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags); | |
| 536 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_SYM, &value); | |
| 537 screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); | |
| 538 | |
| 539 LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Flags: 0x%X, Sym: 0x%X, Mod: 0x%X", SLOG2_FA_SIGNED(flags), SLOG2_FA_SIGNED(value), SLOG2_FA_SIGNED(mod)); | |
| 540 | |
| 541 /* Suppress key repeats if desired. Based off fg_main_mswin */ | |
| 542 if ((flags & KEY_REPEAT) == 0 || (fgState.KeyRepeat == GLUT_KEY_REPEAT_OFF && fgStructure.CurrentWindow->State.IgnoreKeyRepeat == GL_TRUE)) { | |
| 543 unsigned int keypress = 0; | |
| 544 unsigned char ascii = 0; | |
| 545 | |
| 546 /* Remember the current modifiers state so user can query it from their callback */ | |
| 547 fgState.Modifiers = fgPlatformGetModifiers(mod); | |
| 548 | |
| 549 /* Process keys */ | |
| 550 if ((keypress = key_special(value))) { | |
| 551 if(flags & KEY_DOWN) { | |
| 552 INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY)); | |
| 553 } else { | |
| 554 INVOKE_WCB(*window, SpecialUp, (keypress, window->State.MouseX, window->State.MouseY)); | |
| 555 } | |
| 556 } else if((flags & KEY_SYM_VALID) && (ascii = key_ascii(value))) { | |
| 557 if(flags & KEY_DOWN) { | |
| 558 INVOKE_WCB(*window, Keyboard, (ascii, window->State.MouseX, window->State.MouseY)); | |
| 559 } else { | |
| 560 INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY)); | |
| 561 } | |
| 562 } else { | |
| 563 LOGW("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Unhandled key event"); | |
| 564 } | |
| 565 | |
| 566 fgState.Modifiers = INVALID_MODIFIERS; | |
| 567 } | |
| 568 break; | |
| 569 } | |
| 570 | |
| 571 case SCREEN_EVENT_PROPERTY: | |
| 572 case SCREEN_EVENT_IDLE: | |
| 573 break; | |
| 574 | |
| 575 default: | |
| 576 LOGW("fgPlatformProcessSingleEvent: unknown screen event: 0x%X", SLOG2_FA_SIGNED(eventType)); | |
| 577 break; | |
| 578 } | |
| 579 } else if (domain == navigator_get_domain()) { | |
| 580 unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event); | |
| 581 switch (eventType) { | |
| 582 | |
| 583 case NAVIGATOR_WINDOW_STATE: | |
| 584 { | |
| 585 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE"); | |
| 586 | |
| 587 /* Covered only happens due to keyboard. When the app is minimized, the keyboard is closed. | |
| 588 When the keyboard is open, and the app is fullscreened, the keyboard is also closed. | |
| 589 If a window is covered and the app is minimized, the state will be set and the keyboard event | |
| 590 will adjust the screen size and change window status. */ | |
| 591 navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event); | |
| 592 if(window->State.pWState.windowCovered == GL_FALSE) | |
| 593 { | |
| 594 switch (state) | |
| 595 { | |
| 596 case NAVIGATOR_WINDOW_FULLSCREEN: | |
| 597 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN"); | |
| 598 window->State.Visible = GL_TRUE; | |
| 599 INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED)); | |
| 600 break; | |
| 601 case NAVIGATOR_WINDOW_THUMBNAIL: | |
| 602 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL"); | |
| 603 window->State.Visible = GL_TRUE; | |
| 604 INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED)); | |
| 605 break; | |
| 606 case NAVIGATOR_WINDOW_INVISIBLE: | |
| 607 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE"); | |
| 608 window->State.Visible = GL_FALSE; | |
| 609 INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN)); | |
| 610 break; | |
| 611 default: | |
| 612 LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state)); | |
| 613 break; | |
| 614 } | |
| 615 } | |
| 616 window->State.pWState.windowState = state; | |
| 617 break; | |
| 618 } | |
| 619 | |
| 620 case NAVIGATOR_EXIT: | |
| 621 { | |
| 622 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_EXIT"); | |
| 623 | |
| 624 fgPlatformMainLoopPostWork(); | |
| 625 | |
| 626 /* User closed the application for good, let's kill the window */ | |
| 627 SFG_Window* window = fgStructure.CurrentWindow; | |
| 628 if (window != NULL) { | |
| 629 fgDestroyWindow(window); | |
| 630 } else { | |
| 631 LOGW("NAVIGATOR_EXIT: No current window"); | |
| 632 } | |
| 633 | |
| 634 //XXX Should this be a bit more "forceful" so that it doesn't continue to loop through events? | |
| 635 break; | |
| 636 } | |
| 637 | |
| 638 case NAVIGATOR_SWIPE_DOWN: | |
| 639 /* XXX Open app menu */ | |
| 640 break; | |
| 641 | |
| 642 /* Orientation is a bunch of handshakes. | |
| 643 - First the app get's asked if it wants to rotate (NAVIGATOR_ORIENTATION_CHECK) | |
| 644 - If the app wants to rotate, then it will be told what size it will be after rotate (NAVIGATOR_ORIENTATION_SIZE). | |
| 645 - Once the OS confirms that it's ready to rotate, it tells the app to handle rotation (NAVIGATOR_ORIENTATION). | |
| 646 - Once rotation is complete, the OS tells the app it's done (NAVIGATOR_ORIENTATION_DONE) */ | |
| 647 case NAVIGATOR_ORIENTATION_CHECK: | |
| 648 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_CHECK"); | |
| 649 | |
| 650 /* Reset sizes */ | |
| 651 window->State.pWState.newWidth = 0; | |
| 652 window->State.pWState.newHeight = 0; | |
| 653 | |
| 654 #ifdef __PLAYBOOK__ | |
| 655 /* On rotation, the keyboard is closed. This prevents two resize calls */ | |
| 656 window->State.pWState.keyboardOpen = GL_FALSE; | |
| 657 #endif | |
| 658 | |
| 659 /* Notify that we want to rotate */ | |
| 660 navigator_orientation_check_response(fgDisplay.pDisplay.event, true); | |
| 661 break; | |
| 662 | |
| 663 case NAVIGATOR_ORIENTATION: | |
| 664 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION"); | |
| 665 | |
| 666 /* NAVIGATOR_ORIENTATION occurs before NAVIGATOR_KEYBOARD_POSITION */ | |
| 667 | |
| 668 /* Rotate and resize the window */ | |
| 669 fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event)); | |
| 670 fgPlatformFlushCommands(); | |
| 671 #ifdef __PLAYBOOK__ | |
| 672 /* PlayBook doesn't indicate what the new size will be, so we need to retrieve it from the window itself */ | |
| 673 window->State.pWState.newWidth = glutGet(GLUT_WINDOW_WIDTH); | |
| 674 window->State.pWState.newHeight = glutGet(GLUT_WINDOW_HEIGHT); | |
| 675 fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE); | |
| 676 #else | |
| 677 if(window->State.pWState.keyboardOpen == GL_FALSE) { | |
| 678 /* On rotation, if the keyboard is open, it will get the keyboard resize events anyway. Otherwise, handle the resize. */ | |
| 679 fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE); | |
| 680 } | |
| 681 #endif | |
| 682 | |
| 683 /* Reset sizes */ | |
| 684 window->State.pWState.newWidth = 0; | |
| 685 window->State.pWState.newHeight = 0; | |
| 686 | |
| 687 /* Done rotating */ | |
| 688 navigator_done_orientation(fgDisplay.pDisplay.event); | |
| 689 break; | |
| 690 | |
| 691 case NAVIGATOR_BACK: | |
| 692 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_BACK"); | |
| 693 INVOKE_WCB(*window, Keyboard, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY)); | |
| 694 INVOKE_WCB(*window, KeyboardUp, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY)); | |
| 695 break; | |
| 696 | |
| 697 case NAVIGATOR_WINDOW_ACTIVE: | |
| 698 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_ACTIVE"); | |
| 699 INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_RESUME)); | |
| 700 break; | |
| 701 | |
| 702 case NAVIGATOR_WINDOW_INACTIVE: | |
| 703 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_INACTIVE"); | |
| 704 INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE)); | |
| 705 break; | |
| 706 | |
| 707 case NAVIGATOR_ORIENTATION_DONE: | |
| 708 case NAVIGATOR_ORIENTATION_RESULT: | |
| 709 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE/NAVIGATOR_ORIENTATION_RESULT"); | |
| 710 break; | |
| 711 | |
| 712 #ifndef __PLAYBOOK__ | |
| 713 case NAVIGATOR_KEYBOARD_STATE: | |
| 714 case NAVIGATOR_KEYBOARD_POSITION: | |
| 715 /* See virtual keyboard handling for info on why this is not used. */ | |
| 716 break; | |
| 717 | |
| 718 case NAVIGATOR_DEVICE_LOCK_STATE: | |
| 719 break; | |
| 720 | |
| 721 case NAVIGATOR_WINDOW_COVER: | |
| 722 case NAVIGATOR_WINDOW_COVER_ENTER: | |
| 723 case NAVIGATOR_WINDOW_COVER_EXIT: | |
| 724 /* BlackBerry specific. Let app status and window status take care of everything */ | |
| 725 break; | |
| 726 | |
| 727 case NAVIGATOR_APP_STATE: | |
| 728 /* Can do the same as NAVIGATOR_WINDOW_ACTIVE/NAVIGATOR_WINDOW_INACTIVE but | |
| 729 seems like it doesn't work when the app comes to the foreground. Might be a bug */ | |
| 730 break; | |
| 731 | |
| 732 case NAVIGATOR_ORIENTATION_SIZE: | |
| 733 LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_SIZE"); | |
| 734 | |
| 735 /* Get new window size */ | |
| 736 window->State.pWState.newWidth = navigator_event_get_orientation_size_width(fgDisplay.pDisplay.event); | |
| 737 window->State.pWState.newHeight = navigator_event_get_orientation_size_height(fgDisplay.pDisplay.event); | |
| 738 break; | |
| 739 #endif | |
| 740 | |
| 741 case 0: //Doesn't exist in header, but shows up when keyboard shows and resizes | |
| 742 case NAVIGATOR_OTHER: | |
| 743 break; | |
| 744 | |
| 745 default: | |
| 746 LOGW("fgPlatformProcessSingleEvent: unknown navigator event: 0x%X", SLOG2_FA_SIGNED(eventType)); | |
| 747 break; | |
| 748 } | |
| 749 } | |
| 750 /* | |
| 751 * BlackBerry 10 navigator provides keyboard events, but they conflict with how we handle keyboard events. | |
| 752 * Causing multiple reshape messages and can leave window state incorrectly setup. | |
| 753 */ | |
| 754 else if(domain == virtualkeyboard_get_domain()) { | |
| 755 unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event); | |
| 756 switch (eventType) { | |
| 757 case VIRTUALKEYBOARD_EVENT_VISIBLE: | |
| 758 LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_VISIBLE"); | |
| 759 if(window->State.pWState.keyboardOpen != GL_TRUE) { | |
| 760 window->State.pWState.keyboardOpen = GL_TRUE; | |
| 761 fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight); | |
| 762 } | |
| 763 break; | |
| 764 | |
| 765 case VIRTUALKEYBOARD_EVENT_HIDDEN: | |
| 766 LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_HIDDEN"); | |
| 767 if(window->State.pWState.keyboardOpen != GL_FALSE) { | |
| 768 window->State.pWState.keyboardOpen = GL_FALSE; | |
| 769 fgPlatformHandleKeyboardHeight(window, 0); | |
| 770 } | |
| 771 break; | |
| 772 | |
| 773 case VIRTUALKEYBOARD_EVENT_INFO: | |
| 774 LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_INFO"); | |
| 775 window->State.pWState.keyboardHeight = virtualkeyboard_event_get_height(fgDisplay.pDisplay.event); | |
| 776 if(window->State.pWState.keyboardOpen == GL_TRUE) { | |
| 777 fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight); | |
| 778 } | |
| 779 break; | |
| 780 | |
| 781 default: | |
| 782 LOGW("fgPlatformProcessSingleEvent: unknown virtualkeyboard event: 0x%X", eventType); | |
| 783 break; | |
| 784 } | |
| 785 } | |
| 786 } while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL); | |
| 787 | |
| 788 /* Reset event to reduce chances of triggering something */ | |
| 789 fgDisplay.pDisplay.event = NULL; | |
| 790 } | |
| 791 | |
| 792 void fgPlatformMainLoopPreliminaryWork ( void ) | |
| 793 { | |
| 794 LOGI("fgPlatformMainLoopPreliminaryWork"); | |
| 795 | |
| 796 /* Request navigator events */ | |
| 797 navigator_request_events(NAVIGATOR_EXTENDED_DATA); | |
| 798 | |
| 799 /* Allow rotation */ | |
| 800 navigator_rotation_lock(false); | |
| 801 | |
| 802 /* Request keyboard events */ | |
| 803 virtualkeyboard_request_events(0); | |
| 804 | |
| 805 /* Request window events */ | |
| 806 screen_request_events(fgDisplay.pDisplay.screenContext); | |
| 807 } | |
| 808 | |
| 809 void fgPlatformMainLoopPostWork ( void ) | |
| 810 { | |
| 811 LOGI("fgPlatformMainLoopPostWork"); | |
| 812 | |
| 813 /* Stop all events */ | |
| 814 screen_stop_events(fgDisplay.pDisplay.screenContext); | |
| 815 | |
| 816 #ifndef __PLAYBOOK__ | |
| 817 navigator_stop_events(0); | |
| 818 #endif | |
| 819 } | |
| 820 | |
| 821 /* deal with work list items */ | |
| 822 void fgPlatformInitWork(SFG_Window* window) | |
| 823 { | |
| 824 LOGI("fgPlatformInitWork"); | |
| 825 | |
| 826 /* Position callback, always at 0,0 */ | |
| 827 fghOnPositionNotify(window, 0, 0, GL_TRUE); | |
| 828 | |
| 829 /* Get window size */ | |
| 830 int size[2]; | |
| 831 screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); | |
| 832 fghOnReshapeNotify(window, size[0], size[1], GL_FALSE); | |
| 833 | |
| 834 /* Size gets notified on window creation with size detection in mainloop above | |
| 835 * XXX CHECK: does this messages happen too early like on windows, | |
| 836 * so client code cannot have registered a callback yet and the message | |
| 837 * is thus never received by client? | |
| 838 */ | |
| 839 } | |
| 840 | |
| 841 void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) | |
| 842 { | |
| 843 if (workMask & GLUT_FULL_SCREEN_WORK) | |
| 844 fgPlatformFullScreenToggle( window ); | |
| 845 if (workMask & GLUT_POSITION_WORK) | |
| 846 fgPlatformPositionWindow( window, window->State.DesiredXpos, window->State.DesiredYpos ); | |
| 847 if (workMask & GLUT_SIZE_WORK) | |
| 848 fgPlatformReshapeWindow ( window, window->State.DesiredWidth, window->State.DesiredHeight ); | |
| 849 if (workMask & GLUT_ZORDER_WORK) | |
| 850 { | |
| 851 if (window->State.DesiredZOrder < 0) | |
| 852 fgPlatformPushWindow( window ); | |
| 853 else | |
| 854 fgPlatformPopWindow( window ); | |
| 855 } | |
| 856 } | |
| 857 | |
| 858 void fgPlatformVisibilityWork(SFG_Window* window) | |
| 859 { | |
| 860 /* Visibility status of window should get updated in the window message handlers | |
| 861 * For now, none of these functions called below do anything, so don't worry | |
| 862 * about it | |
| 863 */ | |
| 864 SFG_Window *win = window; | |
| 865 switch (window->State.DesiredVisibility) | |
| 866 { | |
| 867 case DesireHiddenState: | |
| 868 fgPlatformHideWindow( window ); | |
| 869 break; | |
| 870 case DesireIconicState: | |
| 871 /* Call on top-level window */ | |
| 872 while (win->Parent) | |
| 873 win = win->Parent; | |
| 874 fgPlatformIconifyWindow( win ); | |
| 875 break; | |
| 876 case DesireNormalState: | |
| 877 fgPlatformShowWindow( window ); | |
| 878 break; | |
| 879 } | |
| 880 } |
