| 79 | } |
| 80 | |
| 81 | GameEventsXcb::EventType GameEventsXcb::nextEvent(struct HotKey &hk) |
| 82 | { |
| 83 | while (true) { |
| 84 | std::unique_ptr<xcb_generic_event_t> event; |
| 85 | |
| 86 | if (next_event) { |
| 87 | event = std::move(next_event); |
| 88 | } |
| 89 | else { |
| 90 | event.reset(xcb_poll_for_event(context->conn)); |
| 91 | } |
| 92 | |
| 93 | if (!event) { |
| 94 | |
| 95 | if (!context->hotkey_pressed_queue.empty()) { |
| 96 | /* Processing a pressed hotkey pushed by the UI */ |
| 97 | context->hotkey_pressed_queue.pop(hk.type); |
| 98 | return EVENT_TYPE_PRESS; |
| 99 | } |
| 100 | else if (!context->hotkey_released_queue.empty()) { |
| 101 | /* Processing a pressed hotkey pushed by the UI */ |
| 102 | context->hotkey_released_queue.pop(hk.type); |
| 103 | return EVENT_TYPE_RELEASE; |
| 104 | } |
| 105 | else { |
| 106 | return EVENT_TYPE_NONE; |
| 107 | } |
| 108 | } |
| 109 | else { |
| 110 | /* Processing a hotkey pressed by the user */ |
| 111 | uint8_t response_type = (event->response_type & ~0x80); |
| 112 | |
| 113 | if ((response_type == XCB_KEY_PRESS) || (response_type == XCB_KEY_RELEASE)) { |
| 114 | /* Get the actual pressed/released key */ |
| 115 | xcb_key_press_event_t* key_event = reinterpret_cast<xcb_key_press_event_t*>(event.get()); |
| 116 | xcb_keycode_t kc = key_event->detail; |
| 117 | |
| 118 | /* Detecting auto-repeat, either if detectable auto-repeat is |
| 119 | * supported or not by the X server. |
| 120 | * If detectable auto-repeat is supported, we detect if pressed |
| 121 | * event is from the same key as the last pressed key, without |
| 122 | * a key release. |
| 123 | * If detectable auto-repeat is not supported, we detect if a |
| 124 | * released event is followed by a pressed event with the same |
| 125 | * sequence number. If not, we must keep the later event for |
| 126 | * the next call (xcb does not support peeking events). |
| 127 | */ |
| 128 | if (kc == last_pressed_key) { |
| 129 | if (response_type == XCB_KEY_RELEASE) { |
| 130 | /* Check the next event. We wait a bit for the next |
| 131 | * event to be generated if auto-repeat. There are still |
| 132 | * are few cases where we would have to wait a significantly |
| 133 | * longer time. |
| 134 | */ |
| 135 | usleep(500); |
| 136 | next_event.reset(xcb_poll_for_event(context->conn)); |
| 137 | xcb_key_press_event_t* next_key_event = reinterpret_cast<xcb_key_press_event_t*>(next_event.get()); |
| 138 |
nothing calls this directly
no test coverage detected