Fixed compiler warnings. "leftFingerDown" doesn't need to be an SDL_FingerID.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "SDL_config.h"
23 #if SDL_VIDEO_DRIVER_UIKIT
25 #include "SDL_uikitview.h"
27 #include "../../events/SDL_keyboard_c.h"
28 #include "../../events/SDL_mouse_c.h"
29 #include "../../events/SDL_touch_c.h"
31 #if SDL_IPHONE_KEYBOARD
32 #include "keyinfotable.h"
33 #include "SDL_uikitappdelegate.h"
34 #include "SDL_uikitmodes.h"
35 #include "SDL_uikitwindow.h"
38 @implementation SDL_uikitview
45 - (id)initWithFrame:(CGRect)frame
47 self = [super initWithFrame: frame];
49 #if SDL_IPHONE_KEYBOARD
50 [self initializeKeyboard];
53 self.multipleTouchEnabled = YES;
56 SDL_AddTouch(touchId, "");
62 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
64 CGPoint point = [touch locationInView: self];
66 // Get the display scale and apply that to the input coordinates
67 SDL_Window *window = self->viewcontroller.window;
68 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
69 SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
72 CGRect bounds = [self bounds];
73 point.x /= bounds.size.width;
74 point.y /= bounds.size.height;
76 point.x *= displaymodedata->scale;
77 point.y *= displaymodedata->scale;
82 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
84 NSEnumerator *enumerator = [touches objectEnumerator];
85 UITouch *touch = (UITouch*)[enumerator nextObject];
88 if (!leftFingerDown) {
89 CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
91 /* send moved event */
92 SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
94 /* send mouse down event */
95 SDL_SendMouseButton(NULL, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
97 leftFingerDown = touch;
100 CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
101 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
102 // FIXME: TODO: Using touch as the fingerId is potentially dangerous
103 // It is also much more efficient than storing the UITouch pointer
104 // and comparing it to the incoming event.
105 SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
106 SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
109 for(i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
110 if (finger[i] == NULL) {
112 SDL_SendTouch(touchId, i,
113 SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
118 touch = (UITouch*)[enumerator nextObject];
122 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
124 NSEnumerator *enumerator = [touches objectEnumerator];
125 UITouch *touch = (UITouch*)[enumerator nextObject];
128 if (touch == leftFingerDown) {
130 SDL_SendMouseButton(NULL, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
131 leftFingerDown = nil;
134 CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
135 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
136 SDL_SendTouch(touchId, (long)touch,
137 SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
140 for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
141 if (finger[i] == touch) {
142 SDL_SendTouch(touchId, i,
143 SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
149 touch = (UITouch*)[enumerator nextObject];
153 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
156 this can happen if the user puts more than 5 touches on the screen
157 at once, or perhaps in other circumstances. Usually (it seems)
158 all active touches are canceled.
160 [self touchesEnded: touches withEvent: event];
163 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
165 NSEnumerator *enumerator = [touches objectEnumerator];
166 UITouch *touch = (UITouch*)[enumerator nextObject];
169 if (touch == leftFingerDown) {
170 CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
172 /* send moved event */
173 SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
176 CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
177 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
178 SDL_SendTouchMotion(touchId, (long)touch,
179 locationInView.x, locationInView.y, 1.0f);
182 for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
183 if (finger[i] == touch) {
184 SDL_SendTouchMotion(touchId, i,
185 locationInView.x, locationInView.y, 1.0f);
190 touch = (UITouch*)[enumerator nextObject];
195 ---- Keyboard related functionality below this line ----
197 #if SDL_IPHONE_KEYBOARD
199 /* Is the iPhone virtual keyboard visible onscreen? */
200 - (BOOL)keyboardVisible
202 return keyboardVisible;
205 /* Set ourselves up as a UITextFieldDelegate */
206 - (void)initializeKeyboard
208 textField = [[UITextField alloc] initWithFrame: CGRectZero];
209 textField.delegate = self;
210 /* placeholder so there is something to delete! */
211 textField.text = @" ";
213 /* set UITextInputTrait properties, mostly to defaults */
214 textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
215 textField.autocorrectionType = UITextAutocorrectionTypeNo;
216 textField.enablesReturnKeyAutomatically = NO;
217 textField.keyboardAppearance = UIKeyboardAppearanceDefault;
218 textField.keyboardType = UIKeyboardTypeDefault;
219 textField.returnKeyType = UIReturnKeyDefault;
220 textField.secureTextEntry = NO;
222 textField.hidden = YES;
223 keyboardVisible = NO;
224 /* add the UITextField (hidden) to our view */
225 [self addSubview: textField];
229 /* reveal onscreen virtual keyboard */
232 keyboardVisible = YES;
233 [textField becomeFirstResponder];
236 /* hide onscreen virtual keyboard */
239 keyboardVisible = NO;
240 [textField resignFirstResponder];
243 /* UITextFieldDelegate method. Invoked when user types something. */
244 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
246 if ([string length] == 0) {
247 /* it wants to replace text with nothing, ie a delete */
248 SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE);
249 SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE);
252 /* go through all the characters in the string we've been sent
253 and convert them to key presses */
255 for (i = 0; i < [string length]; i++) {
257 unichar c = [string characterAtIndex: i];
263 /* figure out the SDL_Scancode and SDL_keymod for this unichar */
264 code = unicharToUIKeyInfoTable[c].code;
265 mod = unicharToUIKeyInfoTable[c].mod;
268 /* we only deal with ASCII right now */
269 code = SDL_SCANCODE_UNKNOWN;
273 if (mod & KMOD_SHIFT) {
274 /* If character uses shift, press shift down */
275 SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
277 /* send a keydown and keyup even for the character */
278 SDL_SendKeyboardKey(SDL_PRESSED, code);
279 SDL_SendKeyboardKey(SDL_RELEASED, code);
280 if (mod & KMOD_SHIFT) {
281 /* If character uses shift, press shift back up */
282 SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
285 SDL_SendKeyboardText([string UTF8String]);
287 return NO; /* don't allow the edit! (keep placeholder text there) */
290 /* Terminates the editing session */
291 - (BOOL)textFieldShouldReturn:(UITextField*)_textField
293 SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
294 SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN);
303 /* iPhone keyboard addition functions */
304 #if SDL_IPHONE_KEYBOARD
306 static SDL_uikitview * getWindowView(SDL_Window * window)
308 if (window == NULL) {
309 SDL_SetError("Window does not exist");
313 SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
314 SDL_uikitview *view = data != NULL ? data->view : nil;
317 SDL_SetError("Window has no view");
323 SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
328 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
330 SDL_uikitview *view = getWindowView(window);
336 void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
338 SDL_uikitview *view = getWindowView(window);
344 SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
346 SDL_uikitview *view = getWindowView(window);
351 return view.keyboardVisible;
354 #endif /* SDL_IPHONE_KEYBOARD */
356 #endif /* SDL_VIDEO_DRIVER_UIKIT */
358 /* vi: set ts=4 sw=4 expandtab: */