// Function adapted from Gens/GS (source/gens/input/input_sdl.c) gint input_sdl_gdk_keysnoop(GtkWidget *grab, GdkEventKey *event, gpointer user_data) { SDL_Event sdlev; SDLKey sdlkey; int keystate; // Only grab keys from the Gens window. (or controller config window) if (grab != main_window) { // Don't push this key onto the SDL event stack. return FALSE; } switch (event->type) { case GDK_KEY_PRESS: sdlev.type = SDL_KEYDOWN; sdlev.key.state = SDL_PRESSED; keystate = 1; break; case GDK_KEY_RELEASE: sdlev.type = SDL_KEYUP; sdlev.key.state = SDL_RELEASED; keystate = 0; break; default: fprintf(stderr, "Unhandled GDK event type: %d", event->type); return FALSE; } // Convert this keypress from GDK to SDL. sdlkey = (SDLKey)input_sdl_gdk_to_gens_keyval(event->keyval); // Create an SDL event from the keypress. sdlev.key.keysym.sym = sdlkey; if (sdlkey != 0) SDL_PushEvent(&sdlev); // Change the keyboard state based on the keypress. if(key) key[sdlkey] = keystate; // Allow GTK+ to process this key. return FALSE; }
/** * input_sdl_gdk_keysnoop(): Keysnooping callback event for GTK+/GDK. * @param grab_widget Widget this key was snooped from. * @param event Event information. * @param func_data User data. * @return TRUE to stop processing this event; FALSE to allow GTK+ to process this event. */ static gint input_sdl_gdk_keysnoop(GtkWidget *grab, GdkEventKey *event, gpointer user_data) { SDL_Event sdlev; // Only grab keys from the Gens window. (or controller config window) if (grab != gens_window) { // Not the Gens window. if (grab == cc_window && cc_window_is_configuring) { // Configuring controllers. // Don't allow GTK+ to handle this keypress. return TRUE; } // Don't push this key onto the SDL event stack. return FALSE; } switch (event->type) { case GDK_KEY_PRESS: sdlev.type = SDL_KEYDOWN; sdlev.key.state = SDL_PRESSED; break; case GDK_KEY_RELEASE: sdlev.type = SDL_KEYUP; sdlev.key.state = SDL_RELEASED; break; default: LOG_MSG(input, LOG_MSG_LEVEL_ERROR, "Unhandled GDK event type: %d", event->type); return FALSE; } // Convert this keypress from GDK to SDL. // TODO: Use GENS key defines instead. sdlev.key.keysym.sym = (SDLKey)input_sdl_gdk_to_gens_keyval(event->keyval); if (sdlev.key.keysym.sym != -1) SDL_PushEvent(&sdlev); // Allow GTK+ to process this key. return FALSE; }
/** * input_sdl_get_key(): Get a key. (Used for controller configuration.) * @return Key value. */ uint16_t input_sdl_get_key(void) { // TODO: Optimize this function. GdkEvent *event; // Update the UI. GensUI_update(); // Save the current SDL joystick state. input_sdl_joystate_t prev_joystate[INPUT_SDL_MAX_JOYSTICKS]; memcpy(prev_joystate, input_sdl_joystate, sizeof(prev_joystate)); // Poll for keypresses. while (!input_sdl_update()) { // Check if any joystick states have changed. int js; for (js = 0; js < input_sdl_num_joysticks; js++) { int i, num_items; input_sdl_joystate_t *cur_joy = &input_sdl_joystate[js]; input_sdl_joystate_t *prev_joy = &prev_joystate[js]; // Check buttons. num_items = SDL_JoystickNumButtons(input_sdl_joys[js]); if (num_items > INPUT_JOYSTICK_MAX_BUTTONS) num_items = INPUT_JOYSTICK_MAX_BUTTONS; for (i = 0; i < num_items; i++) { if (!prev_joy->buttons[i] && cur_joy->buttons[i]) { // Button pressed. return INPUT_GETKEY_BUTTON(js, i); } } // Check axes. num_items = SDL_JoystickNumAxes(input_sdl_joys[js]); if (num_items > INPUT_JOYSTICK_MAX_AXES) num_items = INPUT_JOYSTICK_MAX_AXES; for (i = 0; i < num_items; i++) { if (prev_joy->axes[i] == INPUT_SDL_JOYSTATE_AXIS_CENTER && cur_joy->axes[i] != INPUT_SDL_JOYSTATE_AXIS_CENTER) { // Axis moved. // NOTE: Axis values are different! // * input_sdl axes: 0 == center; 1 == negative; 2 == positive // * Key values: 0 == negative, 1 == positive return INPUT_GETKEY_AXIS(js, i, (cur_joy->axes[i] - 1)); } } // Check POV hats. (Needed on Ubuntu 9.04+; maybe 8.10, too.) num_items = SDL_JoystickNumHats(input_sdl_joys[js]); if (num_items > INPUT_JOYSTICK_MAX_POVHATS) num_items = INPUT_JOYSTICK_MAX_POVHATS; for (i = 0; i < num_items; i++) { if (prev_joy->povhats[i] == SDL_HAT_CENTERED && cur_joy->povhats[i] != SDL_HAT_CENTERED) { // POV hat moved. int povHatDirection; if (cur_joy->povhats[i] & SDL_HAT_UP) povHatDirection = INPUT_JOYSTICK_POVHAT_UP; else if (cur_joy->povhats[i] & SDL_HAT_RIGHT) povHatDirection = INPUT_JOYSTICK_POVHAT_RIGHT; else if (cur_joy->povhats[i] & SDL_HAT_DOWN) povHatDirection = INPUT_JOYSTICK_POVHAT_DOWN; else if (cur_joy->povhats[i] & SDL_HAT_LEFT) povHatDirection = INPUT_JOYSTICK_POVHAT_LEFT; else continue; return INPUT_GETKEY_POVHAT_DIRECTION(js, i, povHatDirection); } } } // Check if a GDK key press occurred. event = gdk_event_get(); if (event && event->type == GDK_KEY_PRESS) return input_sdl_gdk_to_gens_keyval(event->key.keyval); // Save the current SDL joystick state. memcpy(prev_joystate, input_sdl_joystate, sizeof(prev_joystate)); // Sleep for 1 ms. usleep(1000); // Make sure the "Controller Configuration" window is still configuring. if (!cc_window_is_configuring) break; } // No key returned. return 0; }