util_os_ui.c (10448B)
1 /* See LICENSE for license details. */ 2 3 // NOTE(rnp): functions which require platform layer support but 4 // otherwise share implementation 5 // TODO(rnp): replace all this with platform specific functions 6 7 void *GetPlatformWindowHandle(void); 8 9 // see: external/raylib/src/external/glfw/include/GLFW/glfw3.h 10 typedef void glfw_window_resize_fn(void *window, i32 width, i32 height); 11 12 glfw_window_resize_fn *glfwSetWindowSizeCallback(void *window, glfw_window_resize_fn *callback); 13 void *glfwSetCharCallback(void *window, void (*callback)(void *window, u32 codepoint)); 14 void *glfwSetKeyCallback(void *window, void (*callback)(void *window, i32 key, i32 scancode, i32 action, i32 mods)); 15 void *glfwSetMouseButtonCallback(void *window, void (*callback)(void *window, i32 button, i32 action, i32 mods)); 16 void *glfwSetScrollCallback(void *window, void (*callback)(void *window, f64 x_delta, f64 y_delta)); 17 18 global BeamformerInput *beamformer_input; 19 global glfw_window_resize_fn *raylib_window_resize; 20 21 function void 22 os_push_input_event(BeamformerInput *input, BeamformerInputEvent event) 23 { 24 assert(input->event_count < countof(input->event_queue)); 25 if (input->event_count < countof(input->event_queue)) 26 input->event_queue[input->event_count++] = event; 27 } 28 29 function BeamformerInputModifiers 30 os_modifiers_from_glfw(i32 modifiers) 31 { 32 BeamformerInputModifiers result = 0; 33 result |= ((modifiers & 0x1) != 0) * BeamformerInputModifier_Shift; 34 result |= ((modifiers & 0x2) != 0) * BeamformerInputModifier_Control; 35 result |= ((modifiers & 0x4) != 0) * BeamformerInputModifier_Alt; 36 result |= ((modifiers & 0x8) != 0) * BeamformerInputModifier_Meta; 37 return result; 38 } 39 40 function void 41 os_scroll_callback(void *window, f64 xoff, f64 yoff) 42 { 43 // TODO(rnp): GLFW doesn't pass modifiers through but the os event would have them 44 os_push_input_event(beamformer_input, (BeamformerInputEvent){ 45 .kind = BeamformerInputEventKind_MouseScroll, 46 .scroll = {.x = xoff, .y = yoff}, 47 }); 48 } 49 50 function void 51 os_key_callback(void *window, i32 key, i32 scancode, i32 action, i32 modifiers) 52 { 53 BeamformerInputEvent input_event = { 54 .kind = action == 0 ? BeamformerInputEventKind_ButtonRelease : BeamformerInputEventKind_ButtonPress, 55 .modifiers = os_modifiers_from_glfw(modifiers), 56 }; 57 58 switch (key) { 59 default:{}break; 60 case BeamformerButtonID_Space: 61 case BeamformerButtonID_Apostrophe: 62 case BeamformerButtonID_Comma: 63 case BeamformerButtonID_Minus: 64 case BeamformerButtonID_Period: 65 case BeamformerButtonID_Slash: 66 case BeamformerButtonID_0: 67 case BeamformerButtonID_1: 68 case BeamformerButtonID_2: 69 case BeamformerButtonID_3: 70 case BeamformerButtonID_4: 71 case BeamformerButtonID_5: 72 case BeamformerButtonID_6: 73 case BeamformerButtonID_7: 74 case BeamformerButtonID_8: 75 case BeamformerButtonID_9: 76 case BeamformerButtonID_Semicolon: 77 case BeamformerButtonID_Equal: 78 case BeamformerButtonID_A: 79 case BeamformerButtonID_B: 80 case BeamformerButtonID_C: 81 case BeamformerButtonID_D: 82 case BeamformerButtonID_E: 83 case BeamformerButtonID_F: 84 case BeamformerButtonID_G: 85 case BeamformerButtonID_H: 86 case BeamformerButtonID_I: 87 case BeamformerButtonID_J: 88 case BeamformerButtonID_K: 89 case BeamformerButtonID_L: 90 case BeamformerButtonID_M: 91 case BeamformerButtonID_N: 92 case BeamformerButtonID_O: 93 case BeamformerButtonID_P: 94 case BeamformerButtonID_Q: 95 case BeamformerButtonID_R: 96 case BeamformerButtonID_S: 97 case BeamformerButtonID_T: 98 case BeamformerButtonID_U: 99 case BeamformerButtonID_V: 100 case BeamformerButtonID_W: 101 case BeamformerButtonID_X: 102 case BeamformerButtonID_Y: 103 case BeamformerButtonID_Z: 104 case BeamformerButtonID_LeftBracket: 105 case BeamformerButtonID_Backslash: 106 case BeamformerButtonID_RightBracket: 107 case BeamformerButtonID_Grave: 108 { 109 input_event.button_id = key; 110 input_event.codepoint = key; 111 if (Between(key, BeamformerButtonID_A, BeamformerButtonID_Z) && 112 ((input_event.modifiers & BeamformerInputModifier_Shift) == 0)) 113 { 114 input_event.codepoint ^= 0x20; 115 } 116 }break; 117 118 case 256:{input_event.button_id = BeamformerButtonID_Escape; }break; 119 case 257:{input_event.button_id = BeamformerButtonID_Enter; }break; 120 case 258:{input_event.button_id = BeamformerButtonID_Tab; }break; 121 case 259:{input_event.button_id = BeamformerButtonID_Backspace; }break; 122 case 260:{input_event.button_id = BeamformerButtonID_Insert; }break; 123 case 261:{input_event.button_id = BeamformerButtonID_Delete; }break; 124 case 262:{input_event.button_id = BeamformerButtonID_Right; }break; 125 case 263:{input_event.button_id = BeamformerButtonID_Left; }break; 126 case 264:{input_event.button_id = BeamformerButtonID_Down; }break; 127 case 265:{input_event.button_id = BeamformerButtonID_Up; }break; 128 case 266:{input_event.button_id = BeamformerButtonID_PageUp; }break; 129 case 267:{input_event.button_id = BeamformerButtonID_PageDown; }break; 130 case 268:{input_event.button_id = BeamformerButtonID_Home; }break; 131 case 269:{input_event.button_id = BeamformerButtonID_End; }break; 132 case 280:{input_event.button_id = BeamformerButtonID_CapsLock; }break; 133 case 281:{input_event.button_id = BeamformerButtonID_ScrollLock; }break; 134 case 282:{input_event.button_id = BeamformerButtonID_NumLock; }break; 135 case 283:{input_event.button_id = BeamformerButtonID_PrintScreen; }break; 136 case 284:{input_event.button_id = BeamformerButtonID_Pause; }break; 137 case 290:{input_event.button_id = BeamformerButtonID_F1; }break; 138 case 291:{input_event.button_id = BeamformerButtonID_F2; }break; 139 case 292:{input_event.button_id = BeamformerButtonID_F3; }break; 140 case 293:{input_event.button_id = BeamformerButtonID_F4; }break; 141 case 294:{input_event.button_id = BeamformerButtonID_F5; }break; 142 case 295:{input_event.button_id = BeamformerButtonID_F6; }break; 143 case 296:{input_event.button_id = BeamformerButtonID_F7; }break; 144 case 297:{input_event.button_id = BeamformerButtonID_F8; }break; 145 case 298:{input_event.button_id = BeamformerButtonID_F9; }break; 146 case 299:{input_event.button_id = BeamformerButtonID_F10; }break; 147 case 300:{input_event.button_id = BeamformerButtonID_F11; }break; 148 case 301:{input_event.button_id = BeamformerButtonID_F12; }break; 149 case 302:{input_event.button_id = BeamformerButtonID_F13; }break; 150 case 303:{input_event.button_id = BeamformerButtonID_F14; }break; 151 case 304:{input_event.button_id = BeamformerButtonID_F15; }break; 152 case 305:{input_event.button_id = BeamformerButtonID_F16; }break; 153 case 306:{input_event.button_id = BeamformerButtonID_F17; }break; 154 case 307:{input_event.button_id = BeamformerButtonID_F18; }break; 155 case 308:{input_event.button_id = BeamformerButtonID_F19; }break; 156 case 309:{input_event.button_id = BeamformerButtonID_F20; }break; 157 case 310:{input_event.button_id = BeamformerButtonID_F21; }break; 158 case 311:{input_event.button_id = BeamformerButtonID_F22; }break; 159 case 312:{input_event.button_id = BeamformerButtonID_F23; }break; 160 case 313:{input_event.button_id = BeamformerButtonID_F24; }break; 161 case 314:{input_event.button_id = BeamformerButtonID_F25; }break; 162 case 320:{input_event.button_id = BeamformerButtonID_KP0; }break; 163 case 321:{input_event.button_id = BeamformerButtonID_KP1; }break; 164 case 322:{input_event.button_id = BeamformerButtonID_KP2; }break; 165 case 323:{input_event.button_id = BeamformerButtonID_KP3; }break; 166 case 324:{input_event.button_id = BeamformerButtonID_KP4; }break; 167 case 325:{input_event.button_id = BeamformerButtonID_KP5; }break; 168 case 326:{input_event.button_id = BeamformerButtonID_KP6; }break; 169 case 327:{input_event.button_id = BeamformerButtonID_KP7; }break; 170 case 328:{input_event.button_id = BeamformerButtonID_KP8; }break; 171 case 329:{input_event.button_id = BeamformerButtonID_KP9; }break; 172 case 330:{input_event.button_id = BeamformerButtonID_KPDecimal; }break; 173 case 331:{input_event.button_id = BeamformerButtonID_KPDivide; }break; 174 case 332:{input_event.button_id = BeamformerButtonID_KPMultiply; }break; 175 case 333:{input_event.button_id = BeamformerButtonID_KPSubtract; }break; 176 case 334:{input_event.button_id = BeamformerButtonID_KPAdd; }break; 177 case 335:{input_event.button_id = BeamformerButtonID_KPEnter; }break; 178 case 336:{input_event.button_id = BeamformerButtonID_KPEqual; }break; 179 case 340:{input_event.button_id = BeamformerButtonID_LeftShift; }break; 180 case 341:{input_event.button_id = BeamformerButtonID_LeftControl; }break; 181 case 342:{input_event.button_id = BeamformerButtonID_LeftAlt; }break; 182 case 343:{input_event.button_id = BeamformerButtonID_LeftSuper; }break; 183 case 344:{input_event.button_id = BeamformerButtonID_RightShift; }break; 184 case 345:{input_event.button_id = BeamformerButtonID_RightControl;}break; 185 case 346:{input_event.button_id = BeamformerButtonID_RightAlt; }break; 186 case 347:{input_event.button_id = BeamformerButtonID_RightSuper; }break; 187 case 348:{input_event.button_id = BeamformerButtonID_Menu; }break; 188 } 189 190 os_push_input_event(beamformer_input, input_event); 191 } 192 193 function void 194 os_mouse_button_callback(void *window, i32 button, i32 action, i32 modifiers) 195 { 196 BeamformerButtonID button_id = BeamformerButtonID_MouseLeft; 197 switch (button) { 198 default:{}break; 199 case 0:{button_id = BeamformerButtonID_MouseLeft; }break; 200 case 1:{button_id = BeamformerButtonID_MouseRight; }break; 201 case 2:{button_id = BeamformerButtonID_MouseMiddle;}break; 202 } 203 204 os_push_input_event(beamformer_input, (BeamformerInputEvent){ 205 .kind = action == 0 ? BeamformerInputEventKind_ButtonRelease : BeamformerInputEventKind_ButtonPress, 206 .modifiers = os_modifiers_from_glfw(modifiers), 207 .button_id = button_id, 208 }); 209 } 210 211 function void 212 os_window_equip_common(BeamformerInput *input, void *window) 213 { 214 beamformer_input = input; 215 216 glfwSetCharCallback(window, 0); 217 glfwSetKeyCallback(window, os_key_callback); 218 glfwSetMouseButtonCallback(window, os_mouse_button_callback); 219 glfwSetScrollCallback(window, os_scroll_callback); 220 } 221 222 function void 223 os_build_frame_input(BeamformerInput *input) 224 { 225 Vector2 new_mouse = {-1, -1}; 226 if (IsWindowFocused()) new_mouse = GetMousePosition(); 227 input->mouse_x = new_mouse.x; 228 input->mouse_y = new_mouse.y; 229 }