X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fblackberry%2Ffg_main_blackberry.c;h=73b9f41d4e24b98cc8bfcce1a5328ff0dd0b4a52;hb=ef4ef888c1bf3ee5d3a3fb5ef7439b1bd8e7e4eb;hp=d16f315c740f84c5ab80a1d1090ec44e7c520e5f;hpb=9a532a933cc702e5380501c8bcff74d1b1a19a0a;p=freeglut diff --git a/src/blackberry/fg_main_blackberry.c b/src/blackberry/fg_main_blackberry.c index d16f315..73b9f41 100644 --- a/src/blackberry/fg_main_blackberry.c +++ b/src/blackberry/fg_main_blackberry.c @@ -51,6 +51,7 @@ extern void fgPlatformPopWindow( SFG_Window *window ); extern void fgPlatformHideWindow( SFG_Window *window ); extern void fgPlatformIconifyWindow( SFG_Window *window ); extern void fgPlatformShowWindow( SFG_Window *window ); +extern void fgPlatformMainLoopPostWork ( void ); static struct touchscreen touchscreen; @@ -160,7 +161,7 @@ fg_time_t fgPlatformSystemTime ( void ) void fgPlatformSleepForEvents( fg_time_t msec ) { //XXX: Is this right? Is there a more direct way to access the context? - if(fgStructure.CurrentWindow && bps_get_event(&fgStructure.CurrentWindow->Window.pContext.event, (int)msec) != BPS_SUCCESS) { + if(fgStructure.CurrentWindow && fgDisplay.pDisplay.event == NULL && bps_get_event(&fgDisplay.pDisplay.event, (int)msec) != BPS_SUCCESS) { LOGW("BPS couldn't get event"); } } @@ -253,26 +254,40 @@ void handle_left_mouse(int x, int y, int height, int eventType, SFG_Window* wind } } +/* + * Determine a GLUT modifier mask based on BlackBerry modifier info. + */ +int fgPlatformGetModifiers (int mod) +{ + return (((mod & KEYMOD_SHIFT) ? GLUT_ACTIVE_SHIFT : 0) | + ((mod & KEYMOD_CTRL) ? GLUT_ACTIVE_CTRL : 0) | + ((mod & KEYMOD_ALT) ? GLUT_ACTIVE_ALT : 0)); +} + void fgPlatformProcessSingleEvent ( void ) { + if(fgStructure.CurrentWindow == NULL) { + //XXX Is this right? Would this just cause a whole lot of busy looping while we wait for events? + LOGW("fgPlatformProcessSingleEvent: Missing current window. Skipping event processing"); + return; + } + int domain; - bps_event_t** eventPtr = &fgStructure.CurrentWindow->Window.pContext.event; //XXX Is there a more direct way to access the context? - bps_event_t* event; do { - if(*eventPtr != NULL) { + if(fgDisplay.pDisplay.event != NULL) { SFG_Window* window = fgStructure.CurrentWindow; - if (window != NULL && window->Window.Handle != NULL) { + if (window->Window.Handle != NULL) { int size[2]; screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); fghOnReshapeNotify(window,size[0],size[1],GL_FALSE); } - event = *eventPtr; - domain = bps_event_get_domain(event); + domain = bps_event_get_domain(fgDisplay.pDisplay.event); if (domain == screen_get_domain()) { int eventType; - screen_event_t screenEvent = screen_event_get_event(event); + int mod; + screen_event_t screenEvent = screen_event_get_event(fgDisplay.pDisplay.event); screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_TYPE, &eventType); switch (eventType) { @@ -283,7 +298,13 @@ void fgPlatformProcessSingleEvent ( void ) { mtouch_event_t touchEvent; screen_get_mtouch_event(screenEvent, &touchEvent, 0); - LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_MTOUCH_*: Type: 0x%X, X: %d, Y: %d, Contact Id: %d", SLOG2_FA_SIGNED(eventType), SLOG2_FA_SIGNED(touchEvent.x), SLOG2_FA_SIGNED(touchEvent.y), SLOG2_FA_SIGNED(touchEvent.contact_id)); + screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); + + 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)); + + /* Remember the current modifiers state so user can query it from their callback */ + fgState.Modifiers = fgPlatformGetModifiers(mod); + if(touchEvent.contact_id == 0) { int size[2]; screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); @@ -301,6 +322,8 @@ void fgPlatformProcessSingleEvent ( void ) INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_UP ) ); INVOKE_WCB( *window, MultiEntry, ( touchEvent.contact_id, GLUT_LEFT ) ); } + + fgState.Modifiers = INVALID_MODIFIERS; break; } @@ -318,13 +341,17 @@ void fgPlatformProcessSingleEvent ( void ) screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons); screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position); screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel); + screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); int size[2]; screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size); - LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel)); + 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)); //XXX Should multitouch be handled? + /* Remember the current modifiers state so user can query it from their callback */ + fgState.Modifiers = fgPlatformGetModifiers(mod); + // Handle left mouse. Interpret as touch if the left mouse event is not consumed. if (buttons & SCREEN_LEFT_MOUSE_BUTTON) { if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) { @@ -372,9 +399,49 @@ void fgPlatformProcessSingleEvent ( void ) } if (wheel) { + /* Very slightly modified from fg_main_mswin. + * Because we don't want MouseWheel to be called every. single. time. + * That the action occurs, we mimic the Windows version with "wheel deltas" + * XXX Do we even want this? + * XXX If we want this, it's possible to get horizontal scroll as well. + * XXX -Vertical scroll=wheel 0, horizontal=wheel 1? */ fgState.MouseWheelTicks -= wheel; - //TODO: Implement wheel support (based on fg_main_mswin... though it seems excessive) + if (abs(fgState.MouseWheelTicks) >= WHEEL_DELTA) + { + int wheel_number = 0; + int direction = (fgState.MouseWheelTicks > 0) ? -1 : 1; + + if (!FETCH_WCB(*window, MouseWheel) && !FETCH_WCB(*window, Mouse)) + break; + + //XXX fgSetWindow(window); + + while(abs(fgState.MouseWheelTicks) >= WHEEL_DELTA) + { + if (FETCH_WCB(*window, MouseWheel)) + INVOKE_WCB(*window, MouseWheel, (wheel_number, direction, window->State.MouseX, window->State.MouseY)); + else /* No mouse wheel, call the mouse button callback twice */ + { + /* + * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4 + * " " one +1 to 5, -1 to 6, ... + * + * XXX The below assumes that you have no more than 3 mouse + * XXX buttons. Sorry. + */ + int button = wheel_number * 2 + 3; + if (direction < 0) + ++button; + INVOKE_WCB(*window, Mouse, (button, GLUT_DOWN, window->State.MouseX, window->State.MouseY)); + INVOKE_WCB(*window, Mouse, (button, GLUT_UP, window->State.MouseX, window->State.MouseY)); + } + + fgState.MouseWheelTicks -= WHEEL_DELTA * direction; + } + } } + + fgState.Modifiers = INVALID_MODIFIERS; break; } @@ -385,11 +452,19 @@ void fgPlatformProcessSingleEvent ( void ) int value; screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags); screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_SYM, &value); - LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Flags: 0x%X, Sym: 0x%X", SLOG2_FA_SIGNED(flags), SLOG2_FA_SIGNED(value)); - // Suppress key repeats if desired - if ((flags & KEY_REPEAT) == 0 || (fgState.KeyRepeat == GLUT_KEY_REPEAT_ON && !fgStructure.CurrentWindow->State.IgnoreKeyRepeat)) { + screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); + + 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)); + + /* Suppress key repeats if desired. Based off fg_main_mswin */ + if ((flags & KEY_REPEAT) == 0 || (fgState.KeyRepeat == GLUT_KEY_REPEAT_OFF && fgStructure.CurrentWindow->State.IgnoreKeyRepeat == GL_TRUE)) { unsigned int keypress = 0; unsigned char ascii = 0; + + /* Remember the current modifiers state so user can query it from their callback */ + fgState.Modifiers = fgPlatformGetModifiers(mod); + + /* Process keys */ if ((keypress = key_special(value))) { if(flags & KEY_DOWN) { INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY)); @@ -402,7 +477,11 @@ void fgPlatformProcessSingleEvent ( void ) } else { INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY)); } + } else { + LOGW("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Unhandled key event"); } + + fgState.Modifiers = INVALID_MODIFIERS; } break; } @@ -416,13 +495,13 @@ void fgPlatformProcessSingleEvent ( void ) break; } } else if (domain == navigator_get_domain()) { - int eventType = bps_event_get_code(event); + int eventType = bps_event_get_code(fgDisplay.pDisplay.event); switch (eventType) { case NAVIGATOR_WINDOW_STATE: { LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE"); - navigator_window_state_t state = navigator_event_get_window_state(event); + navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event); switch (state) { case NAVIGATOR_WINDOW_FULLSCREEN: @@ -444,6 +523,9 @@ void fgPlatformProcessSingleEvent ( void ) case NAVIGATOR_EXIT: { LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_EXIT"); + + fgPlatformMainLoopPostWork(); + /* User closed the application for good, let's kill the window */ SFG_Window* window = fgStructure.CurrentWindow; if (window != NULL) { @@ -474,17 +556,32 @@ void fgPlatformProcessSingleEvent ( void ) } } } - } while(bps_get_event(eventPtr, 1) == BPS_SUCCESS && *eventPtr != NULL); + } while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL); /* Reset event to reduce chances of triggering something */ - *eventPtr = NULL; + fgDisplay.pDisplay.event = NULL; } void fgPlatformMainLoopPreliminaryWork ( void ) { LOGI("fgPlatformMainLoopPreliminaryWork"); + + /* Request navigator events */ + navigator_request_events(0); + //XXX rotation lock? navigator_rotation_lock(true); + + /* Request window events */ + screen_request_events(fgDisplay.pDisplay.screenContext); } +void fgPlatformMainLoopPostWork ( void ) +{ + LOGI("fgPlatformMainLoopPostWork"); + + screen_stop_events(fgDisplay.pDisplay.screenContext); + + navigator_stop_events(0); +} /* deal with work list items */ void fgPlatformInitWork(SFG_Window* window) @@ -542,4 +639,3 @@ void fgPlatformVisibilityWork(SFG_Window* window) break; } } -