/* _al_xwin_mouse_motion_notify_handler: [bgman thread] * Called by _xwin_process_event() for MotionNotify events received from the X * server. */ void _al_xwin_mouse_motion_notify_handler(int x, int y, ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_XGLX *glx = (void *)display; int event_type = ALLEGRO_EVENT_MOUSE_AXES; if (!xmouse_installed) return; /* Is this an event generated in response to al_set_mouse_xy? */ if (glx->mouse_warp) { glx->mouse_warp = false; event_type = ALLEGRO_EVENT_MOUSE_WARPED; } _al_event_source_lock(&the_mouse.parent.es); scale_xy(&x, &y); int dx = x - the_mouse.state.x; int dy = y - the_mouse.state.y; the_mouse.state.x = x; the_mouse.state.y = y; the_mouse.state.display = display; generate_mouse_event( event_type, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, the_mouse.state.pressure, dx, dy, 0, 0, 0, display); _al_event_source_unlock(&the_mouse.parent.es); }
static void android_keyboard_handle_event(ALLEGRO_DISPLAY *display, int scancode, int unichar, ALLEGRO_EVENT_TYPE event_type) { ALLEGRO_EVENT event; ASSERT(display != NULL); ASSERT(scancode > 0); if (event_type == ALLEGRO_EVENT_KEY_UP) { _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, scancode); } else { _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, scancode); } _al_event_source_lock(&the_keyboard.es); if (_al_event_source_needs_to_generate_event(&the_keyboard.es)) { event.keyboard.type = event_type; event.keyboard.timestamp = al_get_time(); event.keyboard.display = display; event.keyboard.keycode = scancode; event.keyboard.unichar = unichar; event.keyboard.modifiers = 0; event.keyboard.repeat = event_type == ALLEGRO_EVENT_KEY_CHAR; _al_event_source_emit_event(&the_keyboard.es, &event); } _al_event_source_unlock(&the_keyboard.es); }
/* _al_xwin_mouse_button_release_handler: [bgman thread] * Called by _xwin_process_event() for ButtonRelease events received from the * X server. */ void _al_xwin_mouse_button_release_handler(int x_button, ALLEGRO_DISPLAY *display) { int al_button; if (!xmouse_installed) return; al_button = x_button_to_al_button(x_button); if (al_button == 0) return; _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.buttons &=~ (1 << (al_button - 1)); the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; /* TODO */ generate_mouse_event( ALLEGRO_EVENT_MOUSE_BUTTON_UP, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, the_mouse.state.pressure, 0, 0, 0, 0, al_button, display); } _al_event_source_unlock(&the_mouse.parent.es); }
/* _al_xwin_mouse_button_press_handler: [bgman thread] * Called by _xwin_process_event() for ButtonPress events received from the X * server. */ void _al_xwin_mouse_button_press_handler(int x_button, ALLEGRO_DISPLAY *display) { unsigned int al_button; if (!xmouse_installed) return; wheel_motion_handler(x_button, display); /* Is this button supported by the Allegro API? */ al_button = x_button_to_al_button(x_button); if (al_button == 0) return; _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.buttons |= (1 << (al_button - 1)); the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; /* TODO */ generate_mouse_event( ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, the_mouse.state.pressure, 0, 0, 0, 0, al_button, display); } _al_event_source_unlock(&the_mouse.parent.es); }
/* xmouse_set_mouse_axis: * Set the mouse wheel position. Return true if successful. */ static bool xmouse_set_mouse_axis(int which, int v) { ASSERT(xmouse_installed); if (which != 2 && which != 3) { return false; } _al_event_source_lock(&the_mouse.parent.es); { int z = which == 2 ? v : the_mouse.state.z; int w = which == 3 ? v : the_mouse.state.w; int dz = z - the_mouse.state.z; int dw = w - the_mouse.state.w; if (dz != 0 || dw != 0) { the_mouse.state.z = z; the_mouse.state.w = w; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, the_mouse.state.pressure, 0, 0, dz, dw, 0, the_mouse.state.display); } } _al_event_source_unlock(&the_mouse.parent.es); return true; }
/* wheel_motion_handler: [bgman thread] * Called by _al_xwin_mouse_button_press_handler() if the ButtonPress event * received from the X server is actually for a mouse wheel movement. */ static void wheel_motion_handler(int x_button, ALLEGRO_DISPLAY *display) { int dz = 0, dw = 0; if (x_button == Button4) dz = 1; if (x_button == Button5) dz = -1; if (x_button == 6) dw = -1; if (x_button == 7) dw = 1; if (dz == 0 && dw == 0) return; dz *= al_get_mouse_wheel_precision(); dw *= al_get_mouse_wheel_precision(); _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.z += dz; the_mouse.state.w += dw; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, the_mouse.state.pressure, 0, 0, dz, dw, 0, display); } _al_event_source_unlock(&the_mouse.parent.es); }
/* lkeybd_clear_keyboard_state: [primary thread] * Clear the current keyboard state, with any necessary locking. */ static void lkeybd_clear_keyboard_state(void) { _al_event_source_lock(&the_keyboard.parent.es); { memset(&the_keyboard.state, 0, sizeof(the_keyboard.state)); } _al_event_source_unlock(&the_keyboard.parent.es); }
static void android_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { _al_event_source_lock(&the_keyboard.es); { *ret_state = the_state; } _al_event_source_unlock(&the_keyboard.es); }
/* xmouse_get_state: * Copy the current mouse state into RET_STATE, with any necessary locking. */ static void xmouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) { ASSERT(xmouse_installed); _al_event_source_lock(&the_mouse.parent.es); { *ret_state = the_mouse.state; } _al_event_source_unlock(&the_mouse.parent.es); }
/* ljoy_get_joystick_state: [primary thread] * * Copy the internal joystick state to a user-provided structure. */ static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *) joy_; _al_event_source_lock(&joy->parent.es); { *ret_state = joy->joystate; } _al_event_source_unlock(&joy->parent.es); }
/* ljoy_get_joystick_state: [primary thread] * * Copy the internal joystick state to a user-provided structure. */ static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *) joy_; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); { *ret_state = joy->joystate; } _al_event_source_unlock(es); }
/* ljoy_process_new_data: [fdwatch thread] * * Process new data arriving in the joystick's fd. */ static void ljoy_process_new_data(void *data) { ALLEGRO_JOYSTICK_LINUX *joy = data; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!es) { // Joystick driver not fully initialized return; } _al_event_source_lock(es); { struct input_event input_events[32]; int bytes, nr, i; while ((bytes = read(joy->fd, &input_events, sizeof input_events)) > 0) { nr = bytes / sizeof(struct input_event); for (i = 0; i < nr; i++) { int type = input_events[i].type; int code = input_events[i].code; int value = input_events[i].value; if (type == EV_KEY) { int number = map_button_number(joy, code); if (number >= 0) { if (value) joy->joystate.button[number] = 32767; else joy->joystate.button[number] = 0; ljoy_generate_button_event(joy, number, (value ? ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN : ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)); } } else if (type == EV_ABS) { int number = code; if (number < TOTAL_JOYSTICK_AXES) { const AXIS_MAPPING *map = &joy->axis_mapping[number]; int stick = map->stick; int axis = map->axis; float pos = norm_pos(map, value); joy->joystate.stick[stick].axis[axis] = pos; ljoy_generate_axis_event(joy, stick, axis, pos); } } } } } _al_event_source_unlock(es); }
/* Internal function: _al_event_source_on_unregistration_from_queue * This function is called by al_unregister_event_source() when an * event source is unregistered from a queue. */ void _al_event_source_on_unregistration_from_queue(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT_QUEUE *queue) { _al_event_source_lock(es); { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; _al_vector_find_and_delete(&this->queues, &queue); } _al_event_source_unlock(es); }
static void wakeup_with_fake_timer_event(void) { ALLEGRO_EVENT_SOURCE *es = al_get_keyboard_event_source(); _al_event_source_lock(es); ALLEGRO_EVENT event; event.timer.type = ALLEGRO_EVENT_TIMER; event.timer.timestamp = al_get_time(); event.timer.count = 0; event.timer.error = 0; _al_event_source_emit_event(es, &event); _al_event_source_unlock(es); }
/* Internal function: _al_event_source_on_registration_to_queue * This function is called by al_register_event_source() when an * event source is registered to an event queue. This gives the * event source a chance to remember which queues it is registered * to. */ void _al_event_source_on_registration_to_queue(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT_QUEUE *queue) { _al_event_source_lock(es); { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* Add the queue to the source's list. */ ALLEGRO_EVENT_QUEUE **slot = _al_vector_alloc_back(&this->queues); *slot = queue; } _al_event_source_unlock(es); }
void _al_win_touch_input_handle_cancel(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) { ALLEGRO_TOUCH_STATE* state; (void)primary; state = find_touch_state_with_id(id); if (NULL == state) return; _al_event_source_lock(&touch_input.es); state->dx = x - state->x; state->dy = y - state->y; state->x = x; state->y = y; _al_event_source_unlock(&touch_input.es); generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, get_time_stamp(timestamp), state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); _al_event_source_lock(&touch_input.es); memset(state, 0, sizeof(ALLEGRO_TOUCH_STATE)); _al_event_source_unlock(&touch_input.es); }
/* Handle X11 switch event. [X11 thread] */ void _al_xwin_display_switch_handler_inner(ALLEGRO_DISPLAY *display, bool focus_in) { ALLEGRO_EVENT_SOURCE *es = &display->es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; if (focus_in) event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; else event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); }
/* ljoy_process_new_data: [fdwatch thread] * * Process new data arriving in the joystick's fd. */ static void ljoy_process_new_data(void *data) { ALLEGRO_JOYSTICK_LINUX *joy = data; _al_event_source_lock(&joy->parent.es); { struct js_event js_events[32]; int bytes, nr, i; while ((bytes = read(joy->fd, &js_events, sizeof js_events)) > 0) { nr = bytes / sizeof(struct js_event); for (i = 0; i < nr; i++) { int type = js_events[i].type; int number = js_events[i].number; int value = js_events[i].value; if (type & JS_EVENT_BUTTON) { if (number < _AL_MAX_JOYSTICK_BUTTONS) { if (value) joy->joystate.button[number] = 32767; else joy->joystate.button[number] = 0; ljoy_generate_button_event(joy, number, (value ? ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN : ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)); } } else if (type & JS_EVENT_AXIS) { if (number < TOTAL_JOYSTICK_AXES) { int stick = joy->axis_mapping[number].stick; int axis = joy->axis_mapping[number].axis; float pos = value / 32767.0; joy->joystate.stick[stick].axis[axis] = pos; ljoy_generate_axis_event(joy, stick, axis, pos); } } } } } _al_event_source_unlock(&joy->parent.es); }
/* process_new_data: [fdwatch thread] * Process new data arriving in the keyboard's fd. */ static void process_new_data(void *unused) { _al_event_source_lock(&the_keyboard.parent.es); { unsigned char buf[128]; size_t bytes_read; unsigned int ch; bytes_read = read(the_keyboard.fd, &buf, sizeof(buf)); for (ch = 0; ch < bytes_read; ch++) process_character(buf[ch]); } _al_event_source_unlock(&the_keyboard.parent.es); (void)unused; }
void _al_xwin_display_expose(ALLEGRO_DISPLAY *display, XExposeEvent *xevent) { ALLEGRO_EVENT_SOURCE *es = &display->es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; event.display.timestamp = al_get_time(); event.display.x = xevent->x; event.display.y = xevent->y; event.display.width = xevent->width; event.display.height = xevent->height; _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); }
void _al_win_touch_input_handle_begin(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) { ALLEGRO_TOUCH_STATE* state = find_free_touch_state(); if (NULL == state) return; _al_event_source_lock(&touch_input.es); state->id = id; state->x = x; state->y = y; state->dx = 0.0f; state->dy = 0.0f; state->primary = primary; _al_event_source_unlock(&touch_input.es); generate_touch_input_event(ALLEGRO_EVENT_TOUCH_BEGIN, get_time_stamp(timestamp), state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); }
/* Function: al_emit_user_event */ bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) { size_t num_queues; bool rc; ASSERT(src); ASSERT(event); ASSERT(ALLEGRO_EVENT_TYPE_IS_USER(event->any.type)); if (dtor) { ALLEGRO_USER_EVENT_DESCRIPTOR *descr = al_malloc(sizeof(*descr)); descr->refcount = 0; descr->dtor = dtor; event->user.__internal__descr = descr; } else { event->user.__internal__descr = NULL; } _al_event_source_lock(src); { ALLEGRO_EVENT_SOURCE_REAL *rsrc = (ALLEGRO_EVENT_SOURCE_REAL *)src; num_queues = _al_vector_size(&rsrc->queues); if (num_queues > 0) { event->user.timestamp = al_get_time(); _al_event_source_emit_event(src, event); rc = true; } else { rc = false; } } _al_event_source_unlock(src); if (dtor && !rc) { dtor(&event->user); al_free(event->user.__internal__descr); } return rc; }
/* _al_win_kbd_handle_key_release: * Does stuff when a key is released. */ void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, ALLEGRO_DISPLAY_WIN *win_disp) { ALLEGRO_EVENT event; int my_code; if (!installed) return; my_code = 0; if (extended) my_code = extkey_to_keycode(vcode); if (my_code == 0) { if (vcode == VK_SHIFT) vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX); my_code = hw_to_mycode[vcode]; } update_modifiers(my_code, false); _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, my_code); /* Windows only sends a WM_KEYUP message for the Shift keys when both have been released. If one of the Shift keys is still reported as down, we need to release it as well. */ if (my_code == ALLEGRO_KEY_LSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT)) _al_win_kbd_handle_key_release(scode, VK_RSHIFT, extended, win_disp); else if (my_code == ALLEGRO_KEY_RSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT)) _al_win_kbd_handle_key_release(scode, VK_LSHIFT, extended, win_disp); if (!_al_event_source_needs_to_generate_event(&the_keyboard.es)) return; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = (void*)win_disp; event.keyboard.keycode = my_code; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_lock(&the_keyboard.es); _al_event_source_emit_event(&the_keyboard.es, &event); _al_event_source_unlock(&the_keyboard.es); }
/* _al_xwin_keyboard_switch_handler: * Handle a focus switch event. */ void _al_xwin_keyboard_switch_handler(ALLEGRO_DISPLAY *display, bool focus_in) { _al_event_source_lock(&the_keyboard.parent.es); if (focus_in) { the_keyboard.state.display = display; #ifdef ALLEGRO_XWINDOWS_WITH_XIM if (xic) { ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; XSetICValues(xic, XNClientWindow, display_glx->window, NULL); } #endif } else { the_keyboard.state.display = NULL; } _al_event_source_unlock(&the_keyboard.parent.es); }
void _al_sdl_display_event(SDL_Event *e) { ALLEGRO_EVENT event; event.display.timestamp = al_get_time(); ALLEGRO_DISPLAY *d = NULL; if (e->type == SDL_WINDOWEVENT) { d = _al_sdl_find_display(e->window.windowID); if (e->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; } if (e->window.event == SDL_WINDOWEVENT_FOCUS_LOST) { event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; } if (e->window.event == SDL_WINDOWEVENT_CLOSE) { event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; } if (e->window.event == SDL_WINDOWEVENT_RESIZED) { event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.width = e->window.data1; event.display.height = e->window.data2; } } if (e->type == SDL_QUIT) { event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; /* Use the first display as event source if we have any displays. */ ALLEGRO_SYSTEM *s = al_get_system_driver(); if (_al_vector_size(&s->displays) > 0) { void **v = (void **)_al_vector_ref(&s->displays, 0); d = *v; } } if (!d) return; ALLEGRO_EVENT_SOURCE *es = &d->es; _al_event_source_lock(es); _al_event_source_emit_event(es, &event); _al_event_source_unlock(es); }
/* _al_xwin_mouse_switch_handler: * Handle a focus switch event. */ void _al_xwin_mouse_switch_handler(ALLEGRO_DISPLAY *display, const XCrossingEvent *event) { int event_type; /* Ignore events where any of the buttons are held down. */ if (event->state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)) { return; } _al_event_source_lock(&the_mouse.parent.es); switch (event->type) { case EnterNotify: the_mouse.state.display = display; the_mouse.state.x = event->x; the_mouse.state.y = event->y; event_type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; break; case LeaveNotify: the_mouse.state.display = NULL; the_mouse.state.x = event->x; the_mouse.state.y = event->y; event_type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; break; default: ASSERT(false); event_type = 0; break; } generate_mouse_event( event_type, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.pressure, the_mouse.state.w, 0, 0, 0, 0, 0, display); _al_event_source_unlock(&the_mouse.parent.es); }
/* Generate a resize event if the size has changed. We cannot asynchronously * change the display size here yet, since the user will only know about a * changed size after receiving the resize event. Here we merely add the * event to the queue. */ static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_display; ALLEGRO_EVENT_SOURCE *es = &display->es; WINDOWINFO wi; int x, y, w, h; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_display->window, &wi); x = wi.rcClient.left; y = wi.rcClient.top; w = wi.rcClient.right - wi.rcClient.left; h = wi.rcClient.bottom - wi.rcClient.top; /* Don't generate events when restoring after minimise. */ if (w == 0 && h == 0 && x == -32000 && y == -32000) return; if (display->w != w || display->h != h) { _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.timestamp = al_get_time(); event.display.x = x; event.display.y = y; event.display.width = w; event.display.height = h; event.display.source = display; _al_event_source_emit_event(es, &event); /* Generate an expose event. */ /* This seems a bit redundant after a resize. */ if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; _al_event_source_emit_event(es, &event); } } _al_event_source_unlock(es); } }
/* Handle X11 switch event. [X11 thread] */ void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *display, XFocusChangeEvent *xevent) { /* Anything but NotifyNormal seem to indicate the switch is not "real". * TODO: Find out details? */ if (xevent->mode != NotifyNormal) return; ALLEGRO_EVENT_SOURCE *es = &display->es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; if (xevent->type == FocusOut) event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; else event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); }
/* handle_key_release: [bgman thread] * Hook for the X event dispatcher to handle key releases. * The caller must lock the X-display. */ static void handle_key_release(int mycode, ALLEGRO_DISPLAY *display) { if (last_press_code == mycode) last_press_code = -1; _al_event_source_lock(&the_keyboard.parent.es); { /* Update the key_down array. */ _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode); /* Generate the release event if necessary. */ if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) { ALLEGRO_EVENT event; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = display; event.keyboard.keycode = mycode; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_emit_event(&the_keyboard.parent.es, &event); } } _al_event_source_unlock(&the_keyboard.parent.es); }
/* update_joystick: [joystick thread] * Reads in data for a single DirectInput joystick device, updates * the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro * events required. */ static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy) { DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE]; DWORD num_items = DEVICE_BUFFER_SIZE; HRESULT hr; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); /* some devices require polling */ IDirectInputDevice8_Poll(joy->device); /* get device data into buffer */ hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0); if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) { if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { ALLEGRO_WARN("joystick device not acquired or lost\n"); } else { ALLEGRO_ERROR("unexpected error while polling the joystick\n"); } return; } /* don't bother locking the event source if there's no work to do */ /* this happens a lot for polled devices */ if (num_items == 0) return; _al_event_source_lock(es); { unsigned int i; for (i = 0; i < num_items; i++) { const DIDEVICEOBJECTDATA *item = &buffer[i]; const int dwOfs = item->dwOfs; const DWORD dwData = item->dwData; switch (dwOfs) { case DIJOFS_X: handle_axis_event(joy, &joy->x_mapping, dwData); break; case DIJOFS_Y: handle_axis_event(joy, &joy->y_mapping, dwData); break; case DIJOFS_Z: handle_axis_event(joy, &joy->z_mapping, dwData); break; case DIJOFS_RX: handle_axis_event(joy, &joy->rx_mapping, dwData); break; case DIJOFS_RY: handle_axis_event(joy, &joy->ry_mapping, dwData); break; case DIJOFS_RZ: handle_axis_event(joy, &joy->rz_mapping, dwData); break; case DIJOFS_SLIDER(0): handle_axis_event(joy, &joy->slider_mapping[0], dwData); break; case DIJOFS_SLIDER(1): handle_axis_event(joy, &joy->slider_mapping[1], dwData); break; case DIJOFS_POV(0): handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); break; case DIJOFS_POV(1): handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); break; case DIJOFS_POV(2): handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); break; case DIJOFS_POV(3): handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); break; default: /* buttons */ if ((dwOfs >= DIJOFS_BUTTON0) && (dwOfs < DIJOFS_BUTTON(joy->parent.info.num_buttons))) { int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0); handle_button_event(joy, num, (dwData & 0x80)); } break; } } } _al_event_source_unlock(es); }