src/video/mir/SDL_mirevents.c
changeset 10089 25fda20d0173
parent 9998 f67cf37e9cd4
child 10180 7356b2938fba
equal deleted inserted replaced
10088:33bee97dbcbb 10089:25fda20d0173
    56 static void
    56 static void
    57 CheckKeyboardFocus(SDL_Window* sdl_window)
    57 CheckKeyboardFocus(SDL_Window* sdl_window)
    58 {
    58 {
    59     SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
    59     SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
    60 
    60 
    61     if (keyboard_window != sdl_window)
    61     if (sdl_window && keyboard_window != sdl_window)
    62         SDL_SetKeyboardFocus(sdl_window);
    62         SDL_SetKeyboardFocus(sdl_window);
    63 }
    63 }
    64 
    64 
    65 
    65 
    66 /* FIXME
    66 /* FIXME
    67    Mir still needs to implement its IM API, for now we assume
    67    Mir still needs to implement its IM API, for now we assume
    68    a single key press produces a character.
    68    a single key press produces a character.
    69 */
    69 */
    70 static void
    70 static void
    71 HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
    71 HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
    72 {
    72 {
    73     uint32_t scancode = SDL_SCANCODE_UNKNOWN;
    73     xkb_keysym_t key_code;
    74     Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
    74     Uint8 key_state;
       
    75     int event_scancode;
       
    76     uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;
       
    77 
       
    78     MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);
       
    79 
       
    80     key_state      = SDL_PRESSED;
       
    81     key_code       = MIR_mir_keyboard_event_key_code(key_event);
       
    82     event_scancode = MIR_mir_keyboard_event_scan_code(key_event);
       
    83 
       
    84     if (action == mir_keyboard_action_up)
       
    85         key_state = SDL_RELEASED;
    75 
    86 
    76     CheckKeyboardFocus(window);
    87     CheckKeyboardFocus(window);
    77 
    88 
    78     if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
    89     if (event_scancode < SDL_arraysize(xfree86_scancode_table2))
    79         scancode = xfree86_scancode_table2[ev.scan_code];
    90         sdl_scancode = xfree86_scancode_table2[event_scancode];
    80 
    91 
    81     if (scancode != SDL_SCANCODE_UNKNOWN)
    92     if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
    82         SDL_SendKeyboardKey(key_state, scancode);
    93         SDL_SendKeyboardKey(key_state, sdl_scancode);
    83 
    94 
    84     if (key_state == SDL_PRESSED)
    95     if (key_state == SDL_PRESSED)
    85         HandleKeyText(ev.key_code);
    96         HandleKeyText(key_code);
    86 }
    97 }
    87 
    98 
    88 static void
    99 static void
    89 HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
   100 HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
    90 {
   101 {
    91     static uint32_t last_sdl_button;
   102     uint32_t sdl_button           = SDL_BUTTON_LEFT;
    92     uint32_t sdl_button;
   103     MirPointerButton button_state = mir_pointer_button_primary;
       
   104 
       
   105     static uint32_t old_button_states = 0;
       
   106     uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);
       
   107 
       
   108     // XOR on our old button states vs our new states to get the newley pressed/released button
       
   109     button_state = new_button_states ^ old_button_states;
    93 
   110 
    94     switch (button_state) {
   111     switch (button_state) {
    95         case mir_motion_button_primary:
   112         case mir_pointer_button_primary:
    96             sdl_button = SDL_BUTTON_LEFT;
   113             sdl_button = SDL_BUTTON_LEFT;
    97             break;
   114             break;
    98         case mir_motion_button_secondary:
   115         case mir_pointer_button_secondary:
    99             sdl_button = SDL_BUTTON_RIGHT;
   116             sdl_button = SDL_BUTTON_RIGHT;
   100             break;
   117             break;
   101         case mir_motion_button_tertiary:
   118         case mir_pointer_button_tertiary:
   102             sdl_button = SDL_BUTTON_MIDDLE;
   119             sdl_button = SDL_BUTTON_MIDDLE;
   103             break;
   120             break;
   104         case mir_motion_button_forward:
   121         case mir_pointer_button_forward:
   105             sdl_button = SDL_BUTTON_X1;
   122             sdl_button = SDL_BUTTON_X1;
   106             break;
   123             break;
   107         case mir_motion_button_back:
   124         case mir_pointer_button_back:
   108             sdl_button = SDL_BUTTON_X2;
   125             sdl_button = SDL_BUTTON_X2;
   109             break;
   126             break;
   110         default:
   127         default:
   111             sdl_button = last_sdl_button;
   128             break;
   112             break;
   129     }
   113     }
   130 
   114 
   131     old_button_states = new_button_states;
   115     last_sdl_button = sdl_button;
   132 
   116     SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
   133     SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
   117 }
   134 }
   118 
   135 
   119 static void
   136 static void
   120 HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
   137 HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
   146     if (SDL_AddTouch(device_id, "") < 0)
   163     if (SDL_AddTouch(device_id, "") < 0)
   147         SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
   164         SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
   148 }
   165 }
   149 
   166 
   150 static void
   167 static void
   151 HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
   168 HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
   152 {
   169 {
   153     int device_id = motion.device_id;
   170     int i, point_count;
   154     int id = motion.pointer_coordinates[cord_index].id;
   171     point_count = MIR_mir_touch_event_point_count(touch);
   155 
   172 
   156     int width  = sdl_window->w;
   173     AddTouchDevice(device_id);
   157     int height = sdl_window->h;
   174 
   158     float x   = motion.pointer_coordinates[cord_index].x;
   175     for (i = 0; i < point_count; i++) {
   159     float y   = motion.pointer_coordinates[cord_index].y;
   176         int id = MIR_mir_touch_event_id(touch, i);
   160 
   177 
   161     float n_x = x / width;
   178         int width  = sdl_window->w;
   162     float n_y = y / height;
   179         int height = sdl_window->h;
   163     float pressure = motion.pointer_coordinates[cord_index].pressure;
   180 
   164 
   181         float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
   165     AddTouchDevice(motion.device_id);
   182         float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);
   166 
   183 
   167     switch (motion.action) {
   184         float n_x = x / width;
   168         case mir_motion_action_down:
   185         float n_y = y / height;
   169         case mir_motion_action_pointer_down:
   186 
   170             HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
   187         float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);
   171             break;
   188 
   172         case mir_motion_action_up:
   189         switch (MIR_mir_touch_event_action(touch, i)) {
   173         case mir_motion_action_pointer_up:
   190             case mir_touch_action_up:
   174             HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
   191                 HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
   175             break;
   192                 break;
   176         case mir_motion_action_hover_move:
   193             case mir_touch_action_down:
   177         case mir_motion_action_move:
   194                 HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
   178             HandleTouchMotion(device_id, id, n_x, n_y, pressure);
   195                 break;
   179             break;
   196             case mir_touch_action_change:
       
   197                 HandleTouchMotion(device_id, id, n_x, n_y, pressure);
       
   198                 break;
       
   199         }
       
   200     }
       
   201 }
       
   202 
       
   203 static void
       
   204 HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window)
       
   205 {
       
   206     SDL_SetMouseFocus(sdl_window);
       
   207 
       
   208     switch (MIR_mir_pointer_event_action(pointer)) {
       
   209         case mir_pointer_action_button_down:
       
   210             HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
       
   211             break;
       
   212         case mir_pointer_action_button_up:
       
   213             HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
       
   214             break;
       
   215         case mir_pointer_action_motion: {
       
   216             int x, y;
       
   217             int hscroll, vscroll;
       
   218             SDL_Mouse* mouse = SDL_GetMouse();
       
   219             x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
       
   220             y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
       
   221             hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
       
   222             vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);
       
   223 
       
   224             if (mouse && (mouse->x != x || mouse->y != y))
       
   225                 HandleMouseMotion(sdl_window, x, y);
       
   226             if (vscroll != 0 || hscroll != 0)
       
   227                 HandleMouseScroll(sdl_window, hscroll, vscroll);
       
   228         }
       
   229             break;
       
   230         case mir_pointer_action_leave:
       
   231             SDL_SetMouseFocus(NULL);
       
   232             break;
       
   233         case mir_pointer_action_enter:
   180         default:
   234         default:
   181             break;
   235             break;
   182     }
   236     }
   183 }
   237 }
   184 
   238 
   185 static void
   239 static void
   186 HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
   240 MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window)
   187 {
   241 {
   188     SDL_SetMouseFocus(sdl_window);
   242     switch (MIR_mir_input_event_get_type(input_event)) {
   189 
   243         case (mir_input_event_type_key):
   190     switch (motion.action) {
   244             HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
   191         case mir_motion_action_down:
   245             break;
   192         case mir_motion_action_pointer_down:
   246         case (mir_input_event_type_pointer):
   193             HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state);
   247             HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
   194             break;
   248             break;
   195         case mir_motion_action_up:
   249         case (mir_input_event_type_touch):
   196         case mir_motion_action_pointer_up:
   250             HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
   197             HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
   251                              MIR_mir_input_event_get_device_id(input_event),
   198             break;
   252                              window);
   199         case mir_motion_action_hover_move:
       
   200         case mir_motion_action_move:
       
   201             HandleMouseMotion(sdl_window,
       
   202                               motion.pointer_coordinates[cord_index].x,
       
   203                               motion.pointer_coordinates[cord_index].y);
       
   204             break;
       
   205         case mir_motion_action_outside:
       
   206             SDL_SetMouseFocus(NULL);
       
   207             break;
       
   208         case mir_motion_action_scroll:
       
   209             HandleMouseScroll(sdl_window,
       
   210                               motion.pointer_coordinates[cord_index].hscroll,
       
   211                               motion.pointer_coordinates[cord_index].vscroll);
       
   212             break;
       
   213         case mir_motion_action_cancel:
       
   214         case mir_motion_action_hover_enter:
       
   215         case mir_motion_action_hover_exit:
       
   216             break;
   253             break;
   217         default:
   254         default:
   218             break;
   255             break;
   219     }
   256     }
   220 }
   257 }
   221 
   258 
   222 static void
   259 static void
   223 HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
   260 MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window)
   224 {
   261 {
   225     int cord_index;
   262     int new_w = MIR_mir_resize_event_get_width (resize_event);
   226     for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) {
   263     int new_h = MIR_mir_resize_event_get_height(resize_event);
   227         if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) {
   264 
   228             HandleTouchEvent(motion, cord_index, sdl_window);
   265     int old_w = window->w;
       
   266     int old_h = window->h;
       
   267 
       
   268     if (new_w != old_w || new_h != old_h)
       
   269         SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
       
   270 }
       
   271 
       
   272 void
       
   273 MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context)
       
   274 {
       
   275     MirEventType event_type = MIR_mir_event_get_type(ev);
       
   276     SDL_Window* window      = (SDL_Window*)context;
       
   277 
       
   278     if (window) {
       
   279         switch (event_type) {
       
   280             case (mir_event_type_input):
       
   281                 MIR_HandleInput(MIR_mir_event_get_input_event(ev), window);
       
   282                 break;
       
   283             case (mir_event_type_resize):
       
   284                 MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window);
       
   285                 break;
       
   286             default:
       
   287                 break;
   229         }
   288         }
   230         else {
       
   231             HandleMouseEvent(motion, cord_index, sdl_window);
       
   232         }
       
   233     }
       
   234 }
       
   235 
       
   236 void
       
   237 MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
       
   238 {
       
   239     SDL_Window* window = (SDL_Window*)context;
       
   240     switch (ev->type) {
       
   241         case (mir_event_type_key):
       
   242             HandleKeyEvent(ev->key, window);
       
   243             break;
       
   244         case (mir_event_type_motion):
       
   245             HandleMotionEvent(ev->motion, window);
       
   246             break;
       
   247         default:
       
   248             break;
       
   249     }
   289     }
   250 }
   290 }
   251 
   291 
   252 #endif /* SDL_VIDEO_DRIVER_MIR */
   292 #endif /* SDL_VIDEO_DRIVER_MIR */
   253 
   293