SDL  2.0
SDL_cocoakeyboard.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 ([window respondsToSelector:@selector(convertRectToScreen:)]) {
147  rect = [window convertRectToScreen:rect];
148  } else {
149  rect.origin = [window convertBaseToScreen:rect.origin];
150  }
151 
152  return rect;
153 }
154 
155 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange;
156 {
157  DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length);
158  return nil;
159 }
160 
161 - (NSInteger)conversationIdentifier
162 {
163  return (NSInteger) self;
164 }
165 
166 /* This method returns the index for character that is
167  * nearest to thePoint. thPoint is in screen coordinate system.
168  */
169 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
170 {
171  DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
172  return 0;
173 }
174 
175 /* This method is the key to attribute extension.
176  * We could add new attributes through this method.
177  * NSInputServer examines the return value of this
178  * method & constructs appropriate attributed string.
179  */
180 - (NSArray *)validAttributesForMarkedText
181 {
182  return [NSArray array];
183 }
184 
185 @end
186 
187 /*------------------------------------------------------------------------------
188 Set up a HID callback to properly detect Caps Lock up/down events.
189 Derived from:
190 http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events
191 */
192 
193 static IOHIDManagerRef s_hidManager = NULL;
194 
195 static void
196 HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
197 {
198  if (context != s_hidManager) {
199  /* An old callback, ignore it (related to bug 2157 below) */
200  return;
201  }
202 
203  IOHIDElementRef elem = IOHIDValueGetElement(value);
204  if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad
205  || IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) {
206  return;
207  }
208  CFIndex pressed = IOHIDValueGetIntegerValue(value);
210 }
211 
212 static CFDictionaryRef
213 CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage)
214 {
215  CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
216  0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
217  if (dict) {
218  CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage);
219  if (number) {
220  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number);
221  CFRelease(number);
222  number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
223  if (number) {
224  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number);
225  CFRelease(number);
226  return dict;
227  }
228  }
229  CFRelease(dict);
230  }
231  return NULL;
232 }
233 
234 static void
235 QuitHIDCallback()
236 {
237  if (!s_hidManager) {
238  return;
239  }
240 
241 #if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier,
242  * so just leak it for now. See bug 2157 for details.
243  */
244  IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
245  IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
246  IOHIDManagerClose(s_hidManager, 0);
247 
248  CFRelease(s_hidManager);
249 #endif
250  s_hidManager = NULL;
251 }
252 
253 static void
254 InitHIDCallback()
255 {
256  s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
257  if (!s_hidManager) {
258  return;
259  }
260  CFDictionaryRef keyboard = NULL, keypad = NULL;
261  CFArrayRef matches = NULL;
262  keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
263  if (!keyboard) {
264  goto fail;
265  }
266  keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad);
267  if (!keypad) {
268  goto fail;
269  }
270  CFDictionaryRef matchesList[] = { keyboard, keypad };
271  matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL);
272  if (!matches) {
273  goto fail;
274  }
275  IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches);
276  IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager);
277  IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
278  if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
279  goto cleanup;
280  }
281 
282 fail:
283  QuitHIDCallback();
284 
285 cleanup:
286  if (matches) {
287  CFRelease(matches);
288  }
289  if (keypad) {
290  CFRelease(keypad);
291  }
292  if (keyboard) {
293  CFRelease(keyboard);
294  }
295 }
296 
297 /* This is a helper function for HandleModifierSide. This
298  * function reverts back to behavior before the distinction between
299  * sides was made.
300  */
301 static void
302 HandleNonDeviceModifier(unsigned int device_independent_mask,
303  unsigned int oldMods,
304  unsigned int newMods,
305  SDL_Scancode scancode)
306 {
307  unsigned int oldMask, newMask;
308 
309  /* Isolate just the bits we care about in the depedent bits so we can
310  * figure out what changed
311  */
312  oldMask = oldMods & device_independent_mask;
313  newMask = newMods & device_independent_mask;
314 
315  if (oldMask && oldMask != newMask) {
317  } else if (newMask && oldMask != newMask) {
318  SDL_SendKeyboardKey(SDL_PRESSED, scancode);
319  }
320 }
321 
322 /* This is a helper function for HandleModifierSide.
323  * This function sets the actual SDL_PrivateKeyboard event.
324  */
325 static void
326 HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
327  SDL_Scancode scancode,
328  unsigned int sided_device_dependent_mask)
329 {
330  unsigned int old_dep_mask, new_dep_mask;
331 
332  /* Isolate just the bits we care about in the depedent bits so we can
333  * figure out what changed
334  */
335  old_dep_mask = oldMods & sided_device_dependent_mask;
336  new_dep_mask = newMods & sided_device_dependent_mask;
337 
338  /* We now know that this side bit flipped. But we don't know if
339  * it went pressed to released or released to pressed, so we must
340  * find out which it is.
341  */
342  if (new_dep_mask && old_dep_mask != new_dep_mask) {
343  SDL_SendKeyboardKey(SDL_PRESSED, scancode);
344  } else {
346  }
347 }
348 
349 /* This is a helper function for DoSidedModifiers.
350  * This function will figure out if the modifier key is the left or right side,
351  * e.g. left-shift vs right-shift.
352  */
353 static void
354 HandleModifierSide(int device_independent_mask,
355  unsigned int oldMods, unsigned int newMods,
356  SDL_Scancode left_scancode,
357  SDL_Scancode right_scancode,
358  unsigned int left_device_dependent_mask,
359  unsigned int right_device_dependent_mask)
360 {
361  unsigned int device_dependent_mask = (left_device_dependent_mask |
362  right_device_dependent_mask);
363  unsigned int diff_mod;
364 
365  /* On the basis that the device independent mask is set, but there are
366  * no device dependent flags set, we'll assume that we can't detect this
367  * keyboard and revert to the unsided behavior.
368  */
369  if ((device_dependent_mask & newMods) == 0) {
370  /* Revert to the old behavior */
371  HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
372  return;
373  }
374 
375  /* XOR the previous state against the new state to see if there's a change */
376  diff_mod = (device_dependent_mask & oldMods) ^
377  (device_dependent_mask & newMods);
378  if (diff_mod) {
379  /* A change in state was found. Isolate the left and right bits
380  * to handle them separately just in case the values can simulataneously
381  * change or if the bits don't both exist.
382  */
383  if (left_device_dependent_mask & diff_mod) {
384  HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
385  }
386  if (right_device_dependent_mask & diff_mod) {
387  HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
388  }
389  }
390 }
391 
392 /* This is a helper function for DoSidedModifiers.
393  * This function will release a key press in the case that
394  * it is clear that the modifier has been released (i.e. one side
395  * can't still be down).
396  */
397 static void
398 ReleaseModifierSide(unsigned int device_independent_mask,
399  unsigned int oldMods, unsigned int newMods,
400  SDL_Scancode left_scancode,
401  SDL_Scancode right_scancode,
402  unsigned int left_device_dependent_mask,
403  unsigned int right_device_dependent_mask)
404 {
405  unsigned int device_dependent_mask = (left_device_dependent_mask |
406  right_device_dependent_mask);
407 
408  /* On the basis that the device independent mask is set, but there are
409  * no device dependent flags set, we'll assume that we can't detect this
410  * keyboard and revert to the unsided behavior.
411  */
412  if ((device_dependent_mask & oldMods) == 0) {
413  /* In this case, we can't detect the keyboard, so use the left side
414  * to represent both, and release it.
415  */
416  SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
417  return;
418  }
419 
420  /*
421  * This could have been done in an if-else case because at this point,
422  * we know that all keys have been released when calling this function.
423  * But I'm being paranoid so I want to handle each separately,
424  * so I hope this doesn't cause other problems.
425  */
426  if ( left_device_dependent_mask & oldMods ) {
427  SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
428  }
429  if ( right_device_dependent_mask & oldMods ) {
430  SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
431  }
432 }
433 
434 /* This function will handle the modifier keys and also determine the
435  * correct side of the key.
436  */
437 static void
438 DoSidedModifiers(unsigned short scancode,
439  unsigned int oldMods, unsigned int newMods)
440 {
441  /* Set up arrays for the key syms for the left and right side. */
442  const SDL_Scancode left_mapping[] = {
447  };
448  const SDL_Scancode right_mapping[] = {
453  };
454  /* Set up arrays for the device dependent masks with indices that
455  * correspond to the _mapping arrays
456  */
457  const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
458  const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
459 
460  unsigned int i, bit;
461 
462  /* Iterate through the bits, testing each against the old modifiers */
463  for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
464  unsigned int oldMask, newMask;
465 
466  oldMask = oldMods & bit;
467  newMask = newMods & bit;
468 
469  /* If the bit is set, we must always examine it because the left
470  * and right side keys may alternate or both may be pressed.
471  */
472  if (newMask) {
473  HandleModifierSide(bit, oldMods, newMods,
474  left_mapping[i], right_mapping[i],
475  left_device_mapping[i], right_device_mapping[i]);
476  }
477  /* If the state changed from pressed to unpressed, we must examine
478  * the device dependent bits to release the correct keys.
479  */
480  else if (oldMask && oldMask != newMask) {
481  ReleaseModifierSide(bit, oldMods, newMods,
482  left_mapping[i], right_mapping[i],
483  left_device_mapping[i], right_device_mapping[i]);
484  }
485  }
486 }
487 
488 static void
489 HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
490 {
492 
493  if (modifierFlags == data->modifierFlags) {
494  return;
495  }
496 
497  DoSidedModifiers(scancode, data->modifierFlags, modifierFlags);
498  data->modifierFlags = modifierFlags;
499 }
500 
501 static void
502 UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
503 {
504  TISInputSourceRef key_layout;
505  const void *chr_data;
506  int i;
507  SDL_Scancode scancode;
508  SDL_Keycode keymap[SDL_NUM_SCANCODES];
509 
510  /* See if the keymap needs to be updated */
511  key_layout = TISCopyCurrentKeyboardLayoutInputSource();
512  if (key_layout == data->key_layout) {
513  return;
514  }
515  data->key_layout = key_layout;
516 
517  SDL_GetDefaultKeymap(keymap);
518 
519  /* Try Unicode data first */
520  CFDataRef uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData);
521  if (uchrDataRef) {
522  chr_data = CFDataGetBytePtr(uchrDataRef);
523  } else {
524  goto cleanup;
525  }
526 
527  if (chr_data) {
528  UInt32 keyboard_type = LMGetKbdType();
529  OSStatus err;
530 
531  for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) {
532  UniChar s[8];
533  UniCharCount len;
534  UInt32 dead_key_state;
535 
536  /* Make sure this scancode is a valid character scancode */
537  scancode = darwin_scancode_table[i];
538  if (scancode == SDL_SCANCODE_UNKNOWN ||
539  (keymap[scancode] & SDLK_SCANCODE_MASK)) {
540  continue;
541  }
542 
543  dead_key_state = 0;
544  err = UCKeyTranslate ((UCKeyboardLayout *) chr_data,
545  i, kUCKeyActionDown,
546  0, keyboard_type,
547  kUCKeyTranslateNoDeadKeysMask,
548  &dead_key_state, 8, &len, s);
549  if (err != noErr) {
550  continue;
551  }
552 
553  if (len > 0 && s[0] != 0x10) {
554  keymap[scancode] = s[0];
555  }
556  }
557  SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
558  if (send_event) {
560  }
561  return;
562  }
563 
564 cleanup:
565  CFRelease(key_layout);
566 }
567 
568 void
570 {
572 
573  UpdateKeymap(data, SDL_FALSE);
574 
575  /* Set our own names for the platform-dependent but layout-independent keys */
576  /* This key is NumLock on the MacBook keyboard. :) */
577  /*SDL_SetScancodeName(SDL_SCANCODE_NUMLOCKCLEAR, "Clear");*/
578  SDL_SetScancodeName(SDL_SCANCODE_LALT, "Left Option");
579  SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Command");
580  SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
581  SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
582 
583  data->modifierFlags = [NSEvent modifierFlags];
584  SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
585 
586  InitHIDCallback();
587 }
588 
589 void
591 { @autoreleasepool
592 {
594  SDL_Window *window = SDL_GetKeyboardFocus();
595  NSWindow *nswindow = nil;
596  if (window) {
597  nswindow = ((SDL_WindowData*)window->driverdata)->nswindow;
598  }
599 
600  NSView *parentView = [nswindow contentView];
601 
602  /* We only keep one field editor per process, since only the front most
603  * window can receive text input events, so it make no sense to keep more
604  * than one copy. When we switched to another window and requesting for
605  * text input, simply remove the field editor from its superview then add
606  * it to the front most window's content view */
607  if (!data->fieldEdit) {
608  data->fieldEdit =
609  [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
610  }
611 
612  if (![[data->fieldEdit superview] isEqual:parentView]) {
613  /* DEBUG_IME(@"add fieldEdit to window contentView"); */
614  [data->fieldEdit removeFromSuperview];
615  [parentView addSubview: data->fieldEdit];
616  [nswindow makeFirstResponder: data->fieldEdit];
617  }
618 }}
619 
620 void
622 { @autoreleasepool
623 {
625 
626  if (data && data->fieldEdit) {
627  [data->fieldEdit removeFromSuperview];
628  [data->fieldEdit release];
629  data->fieldEdit = nil;
630  }
631 }}
632 
633 void
635 {
637 
638  if (!rect) {
639  SDL_InvalidParamError("rect");
640  return;
641  }
642 
643  [data->fieldEdit setInputRect:rect];
644 }
645 
646 void
648 {
650  if (!data) {
651  return; /* can happen when returning from fullscreen Space on shutdown */
652  }
653 
654  unsigned short scancode = [event keyCode];
655  SDL_Scancode code;
656 #if 0
657  const char *text;
658 #endif
659 
660  if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
661  /* see comments in SDL_cocoakeys.h */
662  scancode = 60 - scancode;
663  }
664 
665  if (scancode < SDL_arraysize(darwin_scancode_table)) {
666  code = darwin_scancode_table[scancode];
667  } else {
668  /* Hmm, does this ever happen? If so, need to extend the keymap... */
669  code = SDL_SCANCODE_UNKNOWN;
670  }
671 
672  switch ([event type]) {
673  case NSKeyDown:
674  if (![event isARepeat]) {
675  /* See if we need to rebuild the keyboard layout */
676  UpdateKeymap(data, SDL_TRUE);
677  }
678 
680 #if 1
681  if (code == SDL_SCANCODE_UNKNOWN) {
682  fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
683  }
684 #endif
686  /* 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. */
687  [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
688 #if 0
689  text = [[event characters] UTF8String];
690  if(text && *text) {
691  SDL_SendKeyboardText(text);
692  [data->fieldEdit setString:@""];
693  }
694 #endif
695  }
696  break;
697  case NSKeyUp:
699  break;
700  case NSFlagsChanged:
701  /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
702  HandleModifiers(_this, scancode, [event modifierFlags]);
703  break;
704  default: /* just to avoid compiler warnings */
705  break;
706  }
707 }
708 
709 void
711 {
712  QuitHIDCallback();
713 }
714 
715 #endif /* SDL_VIDEO_DRIVER_COCOA */
716 
717 /* vi: set ts=4 sw=4 expandtab: */
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
Definition: SDL_keyboard.c:580
void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
GLuint64EXT * result
GLdouble s
Definition: SDL_opengl.h:2056
SDLTranslatorResponder * fieldEdit
SDL_Rect rect
Definition: testrelative.c:27
static SDL_Window * window
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
#define SDLK_SCANCODE_MASK
Definition: SDL_keycode.h:44
#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:42
GLenum GLsizei len
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:661
void Cocoa_QuitKeyboard(_THIS)
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
Definition: SDL_keyboard.c:586
static const SDL_Scancode darwin_scancode_table[]
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1564
GLsizeiptr const void GLenum usage
GLsizei const GLfloat * value
#define _THIS
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:774
struct _cl_event * event
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
Definition: SDL_keyboard.c:598
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:850
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
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
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:654
The type used to identify a window.
Definition: SDL_sysvideo.h:71
#define SDL_EventState
void Cocoa_InitKeyboard(_THIS)
void Cocoa_StopTextInput(_THIS)
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:90
#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:797
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64