Atlas - SDL_pen.c

Home / ext / SDL / src / events Lines: 1 | Size: 22388 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23// Pressure-sensitive pen handling code for SDL 24 25#include "../SDL_hints_c.h" 26#include "SDL_events_c.h" 27#include "SDL_pen_c.h" 28 29static SDL_PenID pen_touching = 0; // used for synthetic mouse/touch events. 30 31typedef struct SDL_Pen 32{ 33 SDL_PenID instance_id; 34 char *name; 35 SDL_PenInfo info; 36 float axes[SDL_PEN_AXIS_COUNT]; 37 float x; 38 float y; 39 SDL_PenInputFlags input_state; 40 void *driverdata; 41} SDL_Pen; 42 43// we assume there's usually 0-1 pens in most cases and this list doesn't 44// usually change after startup, so a simple array with a RWlock is fine for now. 45static SDL_RWLock *pen_device_rwlock = NULL; 46static SDL_Pen *pen_devices SDL_GUARDED_BY(pen_device_rwlock) = NULL; 47static int pen_device_count SDL_GUARDED_BY(pen_device_rwlock) = 0; 48 49// You must hold pen_device_rwlock before calling this, and result is only safe while lock is held! 50// If SDL isn't initialized, grabbing the NULL lock is a no-op and there will be zero devices, so 51// locking and calling this in that case will do the right thing. 52static SDL_Pen *FindPenByInstanceId(SDL_PenID instance_id) SDL_REQUIRES_SHARED(pen_device_rwlock) 53{ 54 if (instance_id) { 55 for (int i = 0; i < pen_device_count; i++) { 56 if (pen_devices[i].instance_id == instance_id) { 57 return &pen_devices[i]; 58 } 59 } 60 } 61 SDL_SetError("Invalid pen instance ID"); 62 return NULL; 63} 64 65SDL_PenID SDL_FindPenByHandle(void *handle) 66{ 67 SDL_PenID result = 0; 68 SDL_LockRWLockForReading(pen_device_rwlock); 69 for (int i = 0; i < pen_device_count; i++) { 70 if (pen_devices[i].driverdata == handle) { 71 result = pen_devices[i].instance_id; 72 break; 73 } 74 } 75 SDL_UnlockRWLock(pen_device_rwlock); 76 return result; 77} 78 79SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), void *userdata) 80{ 81 SDL_PenID result = 0; 82 SDL_LockRWLockForReading(pen_device_rwlock); 83 for (int i = 0; i < pen_device_count; i++) { 84 if (callback(pen_devices[i].driverdata, userdata)) { 85 result = pen_devices[i].instance_id; 86 break; 87 } 88 } 89 SDL_UnlockRWLock(pen_device_rwlock); 90 return result; 91} 92 93 94 95// public API ... 96 97bool SDL_InitPen(void) 98{ 99 SDL_assert(pen_device_rwlock == NULL); 100 SDL_assert(pen_devices == NULL); 101 SDL_assert(pen_device_count == 0); 102 pen_device_rwlock = SDL_CreateRWLock(); 103 if (!pen_device_rwlock) { 104 return false; 105 } 106 return true; 107} 108 109void SDL_QuitPen(void) 110{ 111 SDL_RemoveAllPenDevices(NULL, NULL); 112 SDL_DestroyRWLock(pen_device_rwlock); 113 pen_device_rwlock = NULL; 114} 115 116#if 0 // not a public API at the moment. 117SDL_PenID *SDL_GetPens(int *count) 118{ 119 SDL_LockRWLockForReading(pen_device_rwlock); 120 const int num_devices = pen_device_count; 121 SDL_PenID *result = (SDL_PenID *) SDL_malloc((num_devices + 1) * sizeof (SDL_PenID)); 122 if (result) { 123 for (int i = 0; i < num_devices; i++) { 124 result[i] = pen_devices[i].instance_id; 125 } 126 result[num_devices] = 0; // null-terminated. 127 } 128 SDL_UnlockRWLock(pen_device_rwlock); 129 130 if (count) { 131 *count = result ? num_devices : 0; 132 } 133 return result; 134} 135 136const char *SDL_GetPenName(SDL_PenID instance_id) 137{ 138 SDL_LockRWLockForReading(pen_device_rwlock); 139 const SDL_Pen *pen = FindPenByInstanceId(instance_id); 140 const char *result = pen ? SDL_GetPersistentString(pen->name) : NULL; 141 SDL_UnlockRWLock(pen_device_rwlock); 142 return result; 143} 144 145bool SDL_GetPenInfo(SDL_PenID instance_id, SDL_PenInfo *info) 146{ 147 SDL_LockRWLockForReading(pen_device_rwlock); 148 const SDL_Pen *pen = FindPenByInstanceId(instance_id); 149 const bool result = pen ? true : false; 150 if (info) { 151 if (result) { 152 SDL_copyp(info, &pen->info); 153 } else { 154 SDL_zerop(info); 155 } 156 } 157 SDL_UnlockRWLock(pen_device_rwlock); 158 return result; 159} 160 161bool SDL_PenConnected(SDL_PenID instance_id) 162{ 163 SDL_LockRWLockForReading(pen_device_rwlock); 164 const SDL_Pen *pen = FindPenByInstanceId(instance_id); 165 const bool result = (pen != NULL); 166 SDL_UnlockRWLock(pen_device_rwlock); 167 return result; 168} 169#endif 170 171SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_axes) 172{ 173 if (num_axes < 0) { 174 num_axes = 0; 175 } 176 177 SDL_LockRWLockForReading(pen_device_rwlock); 178 const SDL_Pen *pen = FindPenByInstanceId(instance_id); 179 SDL_PenInputFlags result = 0; 180 if (pen) { 181 result = pen->input_state; 182 if (axes && num_axes) { 183 SDL_memcpy(axes, pen->axes, SDL_min(num_axes, SDL_PEN_AXIS_COUNT) * sizeof (*axes)); 184 // zero out axes we don't know about, in case the caller built with newer SDL headers that support more of them. 185 if (num_axes > SDL_PEN_AXIS_COUNT) { 186 SDL_memset(&axes[SDL_PEN_AXIS_COUNT], '\0', (num_axes - SDL_PEN_AXIS_COUNT) * sizeof (*axes)); 187 } 188 } 189 } 190 SDL_UnlockRWLock(pen_device_rwlock); 191 return result; 192} 193 194SDL_PenDeviceType SDL_GetPenDeviceType(SDL_PenID instance_id) 195{ 196 SDL_LockRWLockForReading(pen_device_rwlock); 197 const SDL_Pen *pen = FindPenByInstanceId(instance_id); 198 const SDL_PenDeviceType result = pen ? pen->info.device_type : SDL_PEN_DEVICE_TYPE_INVALID; 199 SDL_UnlockRWLock(pen_device_rwlock); 200 return result; 201} 202 203SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis) 204{ 205 // the initial capability bits happen to match up, but as 206 // more features show up later, the bits may no longer be contiguous! 207 if ((axis >= SDL_PEN_AXIS_PRESSURE) && (axis <= SDL_PEN_AXIS_SLIDER)) { 208 return ((SDL_PenCapabilityFlags) 1u) << ((SDL_PenCapabilityFlags) axis); 209 } 210 return 0; // oh well. 211} 212 213SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *window, const SDL_PenInfo *info, void *handle, bool in_proximity) 214{ 215 SDL_assert(handle != NULL); // just allocate a Uint8 so you have a unique pointer if not needed! 216 SDL_assert(SDL_FindPenByHandle(handle) == 0); // Backends shouldn't double-add pens! 217 SDL_assert(pen_device_rwlock != NULL); // subsystem should be initialized by now! 218 219 char *namecpy = SDL_strdup(name ? name : "Unnamed pen"); 220 if (!namecpy) { 221 return 0; 222 } 223 224 SDL_PenID result = 0; 225 226 SDL_LockRWLockForWriting(pen_device_rwlock); 227 228 SDL_Pen *pen = NULL; 229 void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen)); 230 if (ptr) { 231 result = (SDL_PenID) SDL_GetNextObjectID(); 232 pen_devices = (SDL_Pen *) ptr; 233 pen = &pen_devices[pen_device_count]; 234 pen_device_count++; 235 236 SDL_zerop(pen); 237 pen->instance_id = result; 238 pen->name = namecpy; 239 if (info) { 240 SDL_copyp(&pen->info, info); 241 } 242 pen->driverdata = handle; 243 // axes and input state defaults to zero. 244 } 245 SDL_UnlockRWLock(pen_device_rwlock); 246 247 if (!pen) { 248 SDL_free(namecpy); 249 } 250 251 if (result) { 252 SDL_SendPenProximity(timestamp, result, window, in_proximity); 253 } 254 255 return result; 256} 257 258void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instance_id) 259{ 260 if (!instance_id) { 261 return; 262 } 263 264 SDL_SendPenProximity(timestamp, instance_id, window, false); // bye bye 265 266 SDL_LockRWLockForWriting(pen_device_rwlock); 267 SDL_Pen *pen = FindPenByInstanceId(instance_id); 268 if (pen) { 269 SDL_free(pen->name); 270 // we don't free `pen`, it's just part of simple array. Shuffle it out. 271 const int idx = ((int) (pen - pen_devices)); 272 SDL_assert((idx >= 0) && (idx < pen_device_count)); 273 if ( idx < (pen_device_count - 1) ) { 274 SDL_memmove(&pen_devices[idx], &pen_devices[idx + 1], sizeof (*pen) * ((pen_device_count - idx) - 1)); 275 } 276 277 SDL_assert(pen_device_count > 0); 278 pen_device_count--; 279 280 if (pen_device_count) { 281 void *ptr = SDL_realloc(pen_devices, sizeof (*pen) * pen_device_count); // shrink it down. 282 if (ptr) { 283 pen_devices = (SDL_Pen *) ptr; 284 } 285 } else { 286 SDL_free(pen_devices); 287 pen_devices = NULL; 288 } 289 } 290 SDL_UnlockRWLock(pen_device_rwlock); 291} 292 293// This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here. 294void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata) 295{ 296 SDL_LockRWLockForWriting(pen_device_rwlock); 297 if (pen_device_count > 0) { 298 SDL_assert(pen_devices != NULL); 299 for (int i = 0; i < pen_device_count; i++) { 300 if (callback) { 301 callback(pen_devices[i].instance_id, pen_devices[i].driverdata, userdata); 302 } 303 SDL_free(pen_devices[i].name); 304 } 305 } 306 SDL_free(pen_devices); 307 pen_devices = NULL; 308 pen_device_count = 0; 309 pen_touching = 0; 310 SDL_UnlockRWLock(pen_device_rwlock); 311} 312 313void SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool eraser, bool down) 314{ 315 bool send_event = false; 316 SDL_PenInputFlags input_state = 0; 317 float x = 0.0f; 318 float y = 0.0f; 319 320 // note that this locks for _reading_ because the lock protects the 321 // pen_devices array from being reallocated from under us, not the data in it; 322 // we assume only one thread (in the backend) is modifying an individual pen at 323 // a time, so it can update input state cleanly here. 324 SDL_LockRWLockForReading(pen_device_rwlock); 325 SDL_Pen *pen = FindPenByInstanceId(instance_id); 326 if (pen) { 327 input_state = pen->input_state; 328 x = pen->x; 329 y = pen->y; 330 331 if (down && ((input_state & SDL_PEN_INPUT_DOWN) == 0)) { 332 input_state |= SDL_PEN_INPUT_DOWN; 333 send_event = true; 334 } else if (!down && (input_state & SDL_PEN_INPUT_DOWN)) { 335 input_state &= ~SDL_PEN_INPUT_DOWN; 336 send_event = true; 337 } 338 339 if (eraser && ((input_state & SDL_PEN_INPUT_ERASER_TIP) == 0)) { 340 input_state |= SDL_PEN_INPUT_ERASER_TIP; 341 send_event = true; 342 } else if (!eraser && (input_state & SDL_PEN_INPUT_ERASER_TIP)) { 343 input_state &= ~SDL_PEN_INPUT_ERASER_TIP; 344 send_event = true; 345 } 346 347 pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble... 348 } 349 SDL_UnlockRWLock(pen_device_rwlock); 350 351 if (send_event) { 352 const SDL_EventType evtype = down ? SDL_EVENT_PEN_DOWN : SDL_EVENT_PEN_UP; 353 if (SDL_EventEnabled(evtype)) { 354 SDL_Event event; 355 SDL_zero(event); 356 event.ptouch.type = evtype; 357 event.ptouch.timestamp = timestamp; 358 event.ptouch.windowID = window ? window->id : 0; 359 event.ptouch.which = instance_id; 360 event.ptouch.pen_state = input_state; 361 event.ptouch.x = x; 362 event.ptouch.y = y; 363 event.ptouch.eraser = eraser; 364 event.ptouch.down = down; 365 SDL_PushEvent(&event); 366 } 367 368 SDL_Mouse *mouse = SDL_GetMouse(); 369 if (mouse && window) { 370 if (mouse->pen_mouse_events) { 371 if (down) { 372 if (!pen_touching) { 373 SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); 374 SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, true); 375 } 376 } else { 377 if (pen_touching == instance_id) { 378 SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, false); 379 } 380 } 381 } 382 383 if (mouse->pen_touch_events) { 384 const SDL_EventType touchtype = down ? SDL_EVENT_FINGER_DOWN : SDL_EVENT_FINGER_UP; 385 const float normalized_x = x / (float)window->w; 386 const float normalized_y = y / (float)window->h; 387 if (!pen_touching || (pen_touching == instance_id)) { 388 SDL_SendTouch(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, touchtype, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]); 389 } 390 } 391 } 392 393 if (down) { 394 if (!pen_touching) { 395 pen_touching = instance_id; 396 } 397 } else { 398 if (pen_touching == instance_id) { 399 pen_touching = 0; 400 } 401 } 402 } 403} 404 405void SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, SDL_PenAxis axis, float value) 406{ 407 SDL_assert((axis >= 0) && (axis < SDL_PEN_AXIS_COUNT)); // fix the backend if this triggers. 408 409 bool send_event = false; 410 SDL_PenInputFlags input_state = 0; 411 float x = 0.0f; 412 float y = 0.0f; 413 414 // note that this locks for _reading_ because the lock protects the 415 // pen_devices array from being reallocated from under us, not the data in it; 416 // we assume only one thread (in the backend) is modifying an individual pen at 417 // a time, so it can update input state cleanly here. 418 SDL_LockRWLockForReading(pen_device_rwlock); 419 SDL_Pen *pen = FindPenByInstanceId(instance_id); 420 if (pen) { 421 if (pen->axes[axis] != value) { 422 pen->axes[axis] = value; // we could do an SDL_SetAtomicInt here if we run into trouble... 423 input_state = pen->input_state; 424 x = pen->x; 425 y = pen->y; 426 send_event = true; 427 } 428 } 429 SDL_UnlockRWLock(pen_device_rwlock); 430 431 if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_AXIS)) { 432 SDL_Event event; 433 SDL_zero(event); 434 event.paxis.type = SDL_EVENT_PEN_AXIS; 435 event.paxis.timestamp = timestamp; 436 event.paxis.windowID = window ? window->id : 0; 437 event.paxis.which = instance_id; 438 event.paxis.pen_state = input_state; 439 event.paxis.x = x; 440 event.paxis.y = y; 441 event.paxis.axis = axis; 442 event.paxis.value = value; 443 SDL_PushEvent(&event); 444 445 if (window && (axis == SDL_PEN_AXIS_PRESSURE) && (pen_touching == instance_id)) { 446 SDL_Mouse *mouse = SDL_GetMouse(); 447 if (mouse && mouse->pen_touch_events) { 448 const float normalized_x = x / (float)window->w; 449 const float normalized_y = y / (float)window->h; 450 SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, value); 451 } 452 } 453 } 454} 455 456void SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, float x, float y) 457{ 458 bool send_event = false; 459 SDL_PenInputFlags input_state = 0; 460 461 // note that this locks for _reading_ because the lock protects the 462 // pen_devices array from being reallocated from under us, not the data in it; 463 // we assume only one thread (in the backend) is modifying an individual pen at 464 // a time, so it can update input state cleanly here. 465 SDL_LockRWLockForReading(pen_device_rwlock); 466 SDL_Pen *pen = FindPenByInstanceId(instance_id); 467 if (pen) { 468 if ((pen->x != x) || (pen->y != y)) { 469 pen->x = x; // we could do an SDL_SetAtomicInt here if we run into trouble... 470 pen->y = y; // we could do an SDL_SetAtomicInt here if we run into trouble... 471 input_state = pen->input_state; 472 send_event = true; 473 } 474 } 475 SDL_UnlockRWLock(pen_device_rwlock); 476 477 if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_MOTION)) { 478 SDL_Event event; 479 SDL_zero(event); 480 event.pmotion.type = SDL_EVENT_PEN_MOTION; 481 event.pmotion.timestamp = timestamp; 482 event.pmotion.windowID = window ? window->id : 0; 483 event.pmotion.which = instance_id; 484 event.pmotion.pen_state = input_state; 485 event.pmotion.x = x; 486 event.pmotion.y = y; 487 SDL_PushEvent(&event); 488 489 if (window) { 490 SDL_Mouse *mouse = SDL_GetMouse(); 491 if (mouse) { 492 if (pen_touching == instance_id) { 493 if (mouse->pen_mouse_events) { 494 SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); 495 } 496 497 if (mouse->pen_touch_events) { 498 const float normalized_x = x / (float)window->w; 499 const float normalized_y = y / (float)window->h; 500 SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]); 501 } 502 } else if (pen_touching == 0) { // send mouse motion (without a pressed button) for pens that aren't touching. 503 // this might cause a little chaos if you have multiple pens hovering at the same time, but this seems unlikely in the real world, and also something you did to yourself. :) 504 if (mouse->pen_mouse_events) { 505 SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); 506 } 507 } 508 } 509 } 510 } 511} 512 513void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, Uint8 button, bool down) 514{ 515 bool send_event = false; 516 SDL_PenInputFlags input_state = 0; 517 float x = 0.0f; 518 float y = 0.0f; 519 520 if ((button < 1) || (button > 5)) { 521 return; // clamp for now. 522 } 523 524 // note that this locks for _reading_ because the lock protects the 525 // pen_devices array from being reallocated from under us, not the data in it; 526 // we assume only one thread (in the backend) is modifying an individual pen at 527 // a time, so it can update input state cleanly here. 528 SDL_LockRWLockForReading(pen_device_rwlock); 529 SDL_Pen *pen = FindPenByInstanceId(instance_id); 530 if (pen) { 531 input_state = pen->input_state; 532 const Uint32 flag = (Uint32) (1u << button); 533 const bool current = ((input_state & flag) != 0); 534 x = pen->x; 535 y = pen->y; 536 if (down && !current) { 537 input_state |= flag; 538 send_event = true; 539 } else if (!down && current) { 540 input_state &= ~flag; 541 send_event = true; 542 } 543 pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble... 544 } 545 SDL_UnlockRWLock(pen_device_rwlock); 546 547 if (send_event) { 548 const SDL_EventType evtype = down ? SDL_EVENT_PEN_BUTTON_DOWN : SDL_EVENT_PEN_BUTTON_UP; 549 if (SDL_EventEnabled(evtype)) { 550 SDL_Event event; 551 SDL_zero(event); 552 event.pbutton.type = evtype; 553 event.pbutton.timestamp = timestamp; 554 event.pbutton.windowID = window ? window->id : 0; 555 event.pbutton.which = instance_id; 556 event.pbutton.pen_state = input_state; 557 event.pbutton.x = x; 558 event.pbutton.y = y; 559 event.pbutton.button = button; 560 event.pbutton.down = down; 561 SDL_PushEvent(&event); 562 563 if (window && (!pen_touching || (pen_touching == instance_id))) { 564 SDL_Mouse *mouse = SDL_GetMouse(); 565 if (mouse && mouse->pen_mouse_events) { 566 static const Uint8 mouse_buttons[] = { 567 SDL_BUTTON_LEFT, 568 SDL_BUTTON_RIGHT, 569 SDL_BUTTON_MIDDLE, 570 SDL_BUTTON_X1, 571 SDL_BUTTON_X2 572 }; 573 if (button < SDL_arraysize(mouse_buttons)) { 574 SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, mouse_buttons[button], down); 575 } 576 } 577 } 578 } 579 } 580} 581 582void SDL_SendPenProximity(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool in) 583{ 584 bool send_event = false; 585 SDL_PenInputFlags input_state = 0; 586 587 // note that this locks for _reading_ because the lock protects the 588 // pen_devices array from being reallocated from under us, not the data in it; 589 // we assume only one thread (in the backend) is modifying an individual pen at 590 // a time, so it can update input state cleanly here. 591 SDL_LockRWLockForReading(pen_device_rwlock); 592 SDL_Pen *pen = FindPenByInstanceId(instance_id); 593 if (pen) { 594 input_state = pen->input_state; 595 const bool in_proximity = ((input_state & SDL_PEN_INPUT_IN_PROXIMITY) != 0); 596 if (in_proximity != in) { 597 if (in) { 598 input_state |= SDL_PEN_INPUT_IN_PROXIMITY; 599 } else { 600 input_state &= ~SDL_PEN_INPUT_IN_PROXIMITY; 601 } 602 send_event = true; 603 pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble... 604 } 605 } 606 SDL_UnlockRWLock(pen_device_rwlock); 607 608 const Uint32 event_type = in ? SDL_EVENT_PEN_PROXIMITY_IN : SDL_EVENT_PEN_PROXIMITY_OUT; 609 if (send_event && SDL_EventEnabled(event_type)) { 610 SDL_Event event; 611 SDL_zero(event); 612 event.pproximity.type = event_type; 613 event.pproximity.timestamp = timestamp; 614 event.pproximity.windowID = window ? window->id : 0; 615 event.pproximity.which = instance_id; 616 SDL_PushEvent(&event); 617 } 618} 619 620
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.