SDL  2.0
SDL_cocoakeyboard.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
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 #if SDL_VIDEO_DRIVER_COCOA
24 
25 #include "SDL_cocoavideo.h"
26 
27 #include "../../events/SDL_events_c.h"
28 #include "../../events/SDL_keyboard_c.h"
29 #include "../../events/scancodes_darwin.h"
30 
31 #include <Carbon/Carbon.h>
32 #include <IOKit/hid/IOHIDLib.h>
33 
34 /*#define DEBUG_IME NSLog */
35 #define DEBUG_IME(...)
36 
37 @interface SDLTranslatorResponder : NSView <NSTextInputClient> {
38  NSString *_markedText;
39  NSRange _markedRange;
40  NSRange _selectedRange;
41  SDL_Rect _inputRect;
42 }
43 - (void)doCommandBySelector:(SEL)myselector;
44 - (void)setInputRect:(SDL_Rect *)rect;
45 @end
46 
47 @implementation SDLTranslatorResponder
48 
49 - (void)setInputRect:(SDL_Rect *)rect
50 {
51  _inputRect = *rect;
52 }
53 
54 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
55 {
56  /* TODO: Make use of replacementRange? */
57 
58  const char *str;
59 
60  DEBUG_IME(@"insertText: %@", aString);
61 
62  /* Could be NSString or NSAttributedString, so we have
63  * to test and convert it before return as SDL event */
64  if ([aString isKindOfClass: [NSAttributedString class]]) {
65  str = [[aString string] UTF8String];
66  } else {
67  str = [aString UTF8String];
68  }
69 
71 }
72 
73 - (void)doCommandBySelector:(SEL)myselector
74 {
75  /* No need to do anything since we are not using Cocoa
76  selectors to handle special keys, instead we use SDL
77  key events to do the same job.
78  */
79 }
80 
81 - (BOOL)hasMarkedText
82 {
83  return _markedText != nil;
84 }
85 
86 - (NSRange)markedRange
87 {
88  return _markedRange;
89 }
90 
91 - (NSRange)selectedRange
92 {
93  return _selectedRange;
94 }
95 
96 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
97 {
98  if ([aString isKindOfClass:[NSAttributedString class]]) {
99  aString = [aString string];
100  }
101 
102  if ([aString length] == 0) {
103  [self unmarkText];
104  return;
105  }
106 
107  if (_markedText != aString) {
108  [_markedText release];
109  _markedText = [aString retain];
110  }
111 
112  _selectedRange = selectedRange;
113  _markedRange = NSMakeRange(0, [aString length]);
114 
115  SDL_SendEditingText([aString UTF8String],
116  (int) selectedRange.location, (int) selectedRange.length);
117 
118  DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText,
119  selRange.location, selRange.length);
120 }
121 
122 - (void)unmarkText
123 {
124  [_markedText release];
125  _markedText = nil;
126 
127  SDL_SendEditingText("", 0, 0);
128 }
129 
130 - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
131 {
132  NSWindow *window = [self window];
133  NSRect contentRect = [window contentRectForFrameRect:[window frame]];
134  float windowHeight = contentRect.size.height;
135  NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h,
136  _inputRect.w, _inputRect.h);
137 
138  if (actualRange) {
139  *actualRange = aRange;
140  }
141 
142  DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@",
143  aRange.location, aRange.length, windowHeight,
144  NSStringFromRect(rect));
145 
146 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
147  if (![window respondsToSelector:@selector(convertRectToScreen:)]) {
148  rect.origin = [window convertBaseToScreen:rect.origin];
149  } else
150 #endif
151  {
152  rect = [window convertRectToScreen:rect];
153  }
154 
155  return rect;
156 }
157 
158 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
159 {
160  DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length);
161  return nil;
162 }
163 
164 - (NSInteger)conversationIdentifier
165 {
166  return (NSInteger) self;
167 }
168 
169 /* This method returns the index for character that is
170  * nearest to thePoint. thPoint is in screen coordinate system.
171  */
172 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
173 {
174  DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
175  return 0;
176 }
177 
178 /* This method is the key to attribute extension.
179  * We could add new attributes through this method.
180  * NSInputServer examines the return value of this
181  * method & constructs appropriate attributed string.
182  */
183 - (NSArray *)validAttributesForMarkedText
184 {
185  return [NSArray array];
186 }
187 
188 @end
189 
190 /*------------------------------------------------------------------------------
191 Set up a HID callback to properly detect Caps Lock up/down events.
192 Derived from:
193 http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events
194 */
195 
196 static IOHIDManagerRef s_hidManager = NULL;
197 
198 static void
199 HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
200 {
201  if (context != s_hidManager) {
202  /* An old callback, ignore it (related to bug 2157 below) */
203  return;
204  }
205 
206  IOHIDElementRef elem = IOHIDValueGetElement(value);
207  if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad
208  || IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) {
209  return;
210  }
211  CFIndex pressed = IOHIDValueGetIntegerValue(value);
213 }
214 
215 static CFDictionaryRef
216 CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage)
217 {
218  CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
219  0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
220  if (dict) {
221  CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage);
222  if (number) {
223  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number);
224  CFRelease(number);
225  number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
226  if (number) {
227  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number);
228  CFRelease(number);
229  return dict;
230  }
231  }
232  CFRelease(dict);
233  }
234  return NULL;
235 }
236 
237 static void
238 QuitHIDCallback()
239 {
240  if (!s_hidManager) {
241  return;
242  }
243 
244 #if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier,
245  * so just leak it for now. See bug 2157 for details.
246  */
247  IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
248  IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
249  IOHIDManagerClose(s_hidManager, 0);
250 
251  CFRelease(s_hidManager);
252 #endif
253  s_hidManager = NULL;
254 }
255 
256 static void
257 InitHIDCallback()
258 {
259  s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
260  if (!s_hidManager) {
261  return;
262  }
263  CFDictionaryRef keyboard = NULL, keypad = NULL;
264  CFArrayRef matches = NULL;
265  keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
266  if (!keyboard) {
267  goto fail;
268  }
269  keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad);
270  if (!keypad) {
271  goto fail;
272  }
273  CFDictionaryRef matchesList[] = { keyboard, keypad };
274  matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL);
275  if (!matches) {
276  goto fail;
277  }
278  IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches);
279  IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager);
280  IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
281  if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
282  goto cleanup;
283  }
284 
285 fail:
286  QuitHIDCallback();
287 
288 cleanup:
289  if (matches) {
290  CFRelease(matches);
291  }
292  if (keypad) {
293  CFRelease(keypad);
294  }
295  if (keyboard) {
296  CFRelease(keyboard);
297  }
298 }
299 
300 /* This is a helper function for HandleModifierSide. This
301  * function reverts back to behavior before the distinction between
302  * sides was made.
303  */
304 static void
305 HandleNonDeviceModifier(unsigned int device_independent_mask,
306  unsigned int oldMods,
307  unsigned int newMods,
308  SDL_Scancode scancode)
309 {
310  unsigned int oldMask, newMask;
311 
312  /* Isolate just the bits we care about in the depedent bits so we can
313  * figure out what changed
314  */
315  oldMask = oldMods & device_independent_mask;
316  newMask = newMods & device_independent_mask;
317 
318  if (oldMask && oldMask != newMask) {
320  } else if (newMask && oldMask != newMask) {
321  SDL_SendKeyboardKey(SDL_PRESSED, scancode);
322  }
323 }
324 
325 /* This is a helper function for HandleModifierSide.
326  * This function sets the actual SDL_PrivateKeyboard event.
327  */
328 static void
329 HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
330  SDL_Scancode scancode,
331  unsigned int sided_device_dependent_mask)
332 {
333  unsigned int old_dep_mask, new_dep_mask;
334 
335  /* Isolate just the bits we care about in the depedent bits so we can
336  * figure out what changed
337  */
338  old_dep_mask = oldMods & sided_device_dependent_mask;
339  new_dep_mask = newMods & sided_device_dependent_mask;
340 
341  /* We now know that this side bit flipped. But we don't know if
342  * it went pressed to released or released to pressed, so we must
343  * find out which it is.
344  */
345  if (new_dep_mask && old_dep_mask != new_dep_mask) {
346  SDL_SendKeyboardKey(SDL_PRESSED, scancode);
347  } else {
349  }
350 }
351 
352 /* This is a helper function for DoSidedModifiers.
353  * This function will figure out if the modifier key is the left or right side,
354  * e.g. left-shift vs right-shift.
355  */
356 static void
357 HandleModifierSide(int device_independent_mask,
358  unsigned int oldMods, unsigned int newMods,
359  SDL_Scancode left_scancode,
360  SDL_Scancode right_scancode,
361  unsigned int left_device_dependent_mask,
362  unsigned int right_device_dependent_mask)
363 {
364  unsigned int device_dependent_mask = (left_device_dependent_mask |
365  right_device_dependent_mask);
366  unsigned int diff_mod;
367 
368  /* On the basis that the device independent mask is set, but there are
369  * no device dependent flags set, we'll assume that we can't detect this
370  * keyboard and revert to the unsided behavior.
371  */
372  if ((device_dependent_mask & newMods) == 0) {
373  /* Revert to the old behavior */
374  HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
375  return;
376  }
377 
378  /* XOR the previous state against the new state to see if there's a change */
379  diff_mod = (device_dependent_mask & oldMods) ^
380  (device_dependent_mask & newMods);
381  if (diff_mod) {
382  /* A change in state was found. Isolate the left and right bits
383  * to handle them separately just in case the values can simulataneously
384  * change or if the bits don't both exist.
385  */
386  if (left_device_dependent_mask & diff_mod) {
387  HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
388  }
389  if (right_device_dependent_mask & diff_mod) {
390  HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
391  }
392  }
393 }
394 
395 /* This is a helper function for DoSidedModifiers.
396  * This function will release a key press in the case that
397  * it is clear that the modifier has been released (i.e. one side
398  * can't still be down).
399  */
400 static void
401 ReleaseModifierSide(unsigned int device_independent_mask,
402  unsigned int oldMods, unsigned int newMods,
403  SDL_Scancode left_scancode,
404  SDL_Scancode right_scancode,
405  unsigned int left_device_dependent_mask,
406  unsigned int right_device_dependent_mask)
407 {
408  unsigned int device_dependent_mask = (left_device_dependent_mask |
409  right_device_dependent_mask);
410 
411  /* On the basis that the device independent mask is set, but there are
412  * no device dependent flags set, we'll assume that we can't detect this
413  * keyboard and revert to the unsided behavior.
414  */
415  if ((device_dependent_mask & oldMods) == 0) {
416  /* In this case, we can't detect the keyboard, so use the left side
417  * to represent both, and release it.
418  */
419  SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
420  return;
421  }
422 
423  /*
424  * This could have been done in an if-else case because at this point,
425  * we know that all keys have been released when calling this function.
426  * But I'm being paranoid so I want to handle each separately,
427  * so I hope this doesn't cause other problems.
428  */
429  if ( left_device_dependent_mask & oldMods ) {
430  SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
431  }
432  if ( right_device_dependent_mask & oldMods ) {
433  SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
434  }
435 }
436 
437 /* This function will handle the modifier keys and also determine the
438  * correct side of the key.
439  */
440 static void
441 DoSidedModifiers(unsigned short scancode,
442  unsigned int oldMods, unsigned int newMods)
443 {
444  /* Set up arrays for the key syms for the left and right side. */
445  const SDL_Scancode left_mapping[] = {
450  };
451  const SDL_Scancode right_mapping[] = {
456  };
457  /* Set up arrays for the device dependent masks with indices that
458  * correspond to the _mapping arrays
459  */
460  const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
461  const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
462 
463  unsigned int i, bit;
464 
465  /* Iterate through the bits, testing each against the old modifiers */
466  for (i = 0, bit = NSEventModifierFlagShift; bit <= NSEventModifierFlagCommand; bit <<= 1, ++i) {
467  unsigned int oldMask, newMask;
468 
469  oldMask = oldMods & bit;
470  newMask = newMods & bit;
471 
472  /* If the bit is set, we must always examine it because the left
473  * and right side keys may alternate or both may be pressed.
474  */
475  if (newMask) {
476  HandleModifierSide(bit, oldMods, newMods,
477  left_mapping[i], right_mapping[i],
478  left_device_mapping[i], right_device_mapping[i]);
479  }
480  /* If the state changed from pressed to unpressed, we must examine
481  * the device dependent bits to release the correct keys.
482  */
483  else if (oldMask && oldMask != newMask) {
484  ReleaseModifierSide(bit, oldMods, newMods,
485  left_mapping[i], right_mapping[i],
486  left_device_mapping[i], right_device_mapping[i]);
487  }
488  }
489 }
490 
491 static void
492 HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
493 {
495 
496  if (modifierFlags == data->modifierFlags) {
497  return;
498  }
499 
500  DoSidedModifiers(scancode, data->modifierFlags, modifierFlags);
501  data->modifierFlags = modifierFlags;
502 }
503 
504 static void
505 UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
506 {
507  TISInputSourceRef key_layout;
508  const void *chr_data;
509  int i;
510  SDL_Scancode scancode;
511  SDL_Keycode keymap[SDL_NUM_SCANCODES];
512 
513  /* See if the keymap needs to be updated */
514  key_layout = TISCopyCurrentKeyboardLayoutInputSource();
515  if (key_layout == data->key_layout) {
516  return;
517  }
518  data->key_layout = key_layout;
519 
520  SDL_GetDefaultKeymap(keymap);
521 
522  /* Try Unicode data first */
523  CFDataRef uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData);
524  if (uchrDataRef) {
525  chr_data = CFDataGetBytePtr(uchrDataRef);
526  } else {
527  goto cleanup;
528  }
529 
530  if (chr_data) {
531  UInt32 keyboard_type = LMGetKbdType();
532  OSStatus err;
533 
534  for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) {
535  UniChar s[8];
536  UniCharCount len;
537  UInt32 dead_key_state;
538 
539  /* Make sure this scancode is a valid character scancode */
540  scancode = darwin_scancode_table[i];
541  if (scancode == SDL_SCANCODE_UNKNOWN ||
542  (keymap[scancode] & SDLK_SCANCODE_MASK)) {
543  continue;
544  }
545 
546  dead_key_state = 0;
547  err = UCKeyTranslate ((UCKeyboardLayout *) chr_data,
548  i, kUCKeyActionDown,
549  0, keyboard_type,
550  kUCKeyTranslateNoDeadKeysMask,
551  &dead_key_state, 8, &len, s);
552  if (err != noErr) {
553  continue;
554  }
555 
556  if (len > 0 && s[0] != 0x10) {
557  keymap[scancode] = s[0];
558  }
559  }
560  SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
561  if (send_event) {
563  }
564  return;
565  }
566 
567 cleanup:
568  CFRelease(key_layout);
569 }
570 
571 void
573 {
575 
576  UpdateKeymap(data, SDL_FALSE);
577 
578  /* Set our own names for the platform-dependent but layout-independent keys */
579  /* This key is NumLock on the MacBook keyboard. :) */
580  /*SDL_SetScancodeName(SDL_SCANCODE_NUMLOCKCLEAR, "Clear");*/
581  SDL_SetScancodeName(SDL_SCANCODE_LALT, "Left Option");
582  SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Command");
583  SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
584  SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
585 
586  data->modifierFlags = [NSEvent modifierFlags];
588 
589  InitHIDCallback();
590 }
591 
592 void
594 { @autoreleasepool
595 {
597  SDL_Window *window = SDL_GetKeyboardFocus();
598  NSWindow *nswindow = nil;
599  if (window) {
600  nswindow = ((SDL_WindowData*)window->driverdata)->nswindow;
601  }
602 
603  NSView *parentView = [nswindow contentView];
604 
605  /* We only keep one field editor per process, since only the front most
606  * window can receive text input events, so it make no sense to keep more
607  * than one copy. When we switched to another window and requesting for
608  * text input, simply remove the field editor from its superview then add
609  * it to the front most window's content view */
610  if (!data->fieldEdit) {
611  data->fieldEdit =
612  [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
613  }
614 
615  if (![[data->fieldEdit superview] isEqual:parentView]) {
616  /* DEBUG_IME(@"add fieldEdit to window contentView"); */
617  [data->fieldEdit removeFromSuperview];
618  [parentView addSubview: data->fieldEdit];
619  [nswindow makeFirstResponder: data->fieldEdit];
620  }
621 }}
622 
623 void
625 { @autoreleasepool
626 {
628 
629  if (data && data->fieldEdit) {
630  [data->fieldEdit removeFromSuperview];
631  [data->fieldEdit release];
632  data->fieldEdit = nil;
633  }
634 }}
635 
636 void
638 {
640 
641  if (!rect) {
642  SDL_InvalidParamError("rect");
643  return;
644  }
645 
646  [data->fieldEdit setInputRect:rect];
647 }
648 
649 void
651 {
653  if (!data) {
654  return; /* can happen when returning from fullscreen Space on shutdown */
655  }
656 
657  unsigned short scancode = [event keyCode];
658  SDL_Scancode code;
659 #if 0
660  const char *text;
661 #endif
662 
663  if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
664  /* see comments in SDL_cocoakeys.h */
665  scancode = 60 - scancode;
666  }
667 
668  if (scancode < SDL_arraysize(darwin_scancode_table)) {
669  code = darwin_scancode_table[scancode];
670  } else {
671  /* Hmm, does this ever happen? If so, need to extend the keymap... */
672  code = SDL_SCANCODE_UNKNOWN;
673  }
674 
675  switch ([event type]) {
676  case NSEventTypeKeyDown:
677  if (![event isARepeat]) {
678  /* See if we need to rebuild the keyboard layout */
679  UpdateKeymap(data, SDL_TRUE);
680  }
681 
683 #if 1
684  if (code == SDL_SCANCODE_UNKNOWN) {
685  fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
686  }
687 #endif
689  /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
690  [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
691 #if 0
692  text = [[event characters] UTF8String];
693  if(text && *text) {
694  SDL_SendKeyboardText(text);
695  [data->fieldEdit setString:@""];
696  }
697 #endif
698  }
699  break;
700  case NSEventTypeKeyUp:
702  break;
703  case NSEventTypeFlagsChanged:
704  /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
705  HandleModifiers(_this, scancode, [event modifierFlags]);
706  break;
707  default: /* just to avoid compiler warnings */
708  break;
709  }
710 }
711 
712 void
714 {
715  QuitHIDCallback();
716 }
717 
718 #endif /* SDL_VIDEO_DRIVER_COCOA */
719 
720 /* vi: set ts=4 sw=4 expandtab: */
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
Definition: SDL_keyboard.c:588
void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
GLuint64EXT * result
GLdouble s
Definition: SDL_opengl.h:2063
SDLTranslatorResponder * fieldEdit
SDL_Rect rect
Definition: testrelative.c:27
static screen_context_t context
Definition: video.c:25
#define SDLK_SCANCODE_MASK
Definition: SDL_keycode.h:47
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define SDL_GetKeyboardFocus
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
unsigned int modifierFlags
void Cocoa_StartTextInput(_THIS)
Sint32 SDL_Keycode
The SDL virtual key representation.
Definition: SDL_keycode.h:45
GLenum GLsizei len
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:679
void Cocoa_QuitKeyboard(_THIS)
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
Definition: SDL_keyboard.c:594
static const SDL_Scancode darwin_scancode_table[]
GLsizeiptr const void GLenum usage
#define _THIS
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:789
struct _cl_event * event
GLsizei const GLfloat * value
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
Definition: SDL_keyboard.c:616
static const NSUInteger NSEventModifierFlagCapsLock
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
Definition: SDL_keyboard.c:865
#define NULL
Definition: begin_code.h:164
SDL_bool
Definition: SDL_stdinc.h:139
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:950
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_EventState
void Cocoa_InitKeyboard(_THIS)
void Cocoa_StopTextInput(_THIS)
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_QUERY
Definition: SDL_events.h:719
GLuint GLsizei GLsizei * length
#define SDL_RELEASED
Definition: SDL_events.h:49
static void cleanup(void)
Definition: testfile.c:44
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
int SDL_SendEditingText(const char *text, int start, int length)
Definition: SDL_keyboard.c:812
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64