zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_uikitmodes.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.h"
22 
23 #if SDL_VIDEO_DRIVER_UIKIT
24 
25 #include "SDL_assert.h"
26 #include "SDL_uikitmodes.h"
27 
28 
30 
31 
32 static int
33 UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
34  UIScreenMode * uiscreenmode, CGFloat scale)
35 {
37 
38  if (uiscreenmode != nil) {
39  /* Allocate the display mode data */
40  data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
41  if (!data) {
42  return SDL_OutOfMemory();
43  }
44 
45  data->uiscreenmode = uiscreenmode;
46  [data->uiscreenmode retain];
47 
48  data->scale = scale;
49  }
50 
51  mode->driverdata = data;
52 
53  return 0;
54 }
55 
56 static void
57 UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
58 {
60  /* Not on at least iPhoneOS 3.2 (versions prior to iPad). */
61  SDL_assert(mode->driverdata == NULL);
62  } else if (mode->driverdata != NULL) {
64  [data->uiscreenmode release];
65  SDL_free(data);
66  mode->driverdata = NULL;
67  }
68 }
69 
70 static int
71 UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
72  UIScreenMode * uiscreenmode, CGFloat scale)
73 {
75  SDL_zero(mode);
76 
78  mode.refresh_rate = 0;
79  if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
80  return -1;
81  }
82 
83  mode.w = w;
84  mode.h = h;
85  if (SDL_AddDisplayMode(display, &mode)) {
86  return 0;
87  } else {
88  UIKit_FreeDisplayModeData(&mode);
89  return -1;
90  }
91 }
92 
93 static int
94 UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
95  UIScreenMode * uiscreenmode, SDL_bool addRotation)
96 {
97  if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
98  return -1;
99  }
100 
101  if (addRotation) {
102  /* Add the rotated version */
103  if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
104  return -1;
105  }
106  }
107 
108  return 0;
109 }
110 
111 static int
112 UIKit_AddDisplay(UIScreen *uiscreen)
113 {
114  CGSize size = [uiscreen bounds].size;
115 
116  /* Make sure the width/height are oriented correctly */
117  if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
118  CGFloat height = size.width;
119  size.width = size.height;
120  size.height = height;
121  }
122 
123  /* When dealing with UIKit all coordinates are specified in terms of
124  * what Apple refers to as points. On earlier devices without the
125  * so called "Retina" display, there is a one to one mapping between
126  * points and pixels. In other cases [UIScreen scale] indicates the
127  * relationship between points and pixels. Since SDL has no notion
128  * of points, we must compensate in all cases where dealing with such
129  * units.
130  */
131  CGFloat scale;
132  if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
133  scale = [uiscreen scale]; /* iOS >= 4.0 */
134  } else {
135  scale = 1.0f; /* iOS < 4.0 */
136  }
137 
140  SDL_zero(mode);
142  mode.w = (int)(size.width * scale);
143  mode.h = (int)(size.height * scale);
144 
145  UIScreenMode * uiscreenmode = nil;
146  /* UIScreenMode showed up in 3.2 (the iPad and later). We're
147  * misusing this supports_multiple_displays flag here for that.
148  */
150  uiscreenmode = [uiscreen currentMode];
151  }
152 
153  if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
154  return -1;
155  }
156 
157  SDL_zero(display);
158  display.desktop_mode = mode;
159  display.current_mode = mode;
160 
161  /* Allocate the display data */
162  SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
163  if (!data) {
164  UIKit_FreeDisplayModeData(&display.desktop_mode);
165  return SDL_OutOfMemory();
166  }
167 
168  [uiscreen retain];
169  data->uiscreen = uiscreen;
170  data->scale = scale;
171 
172  display.driverdata = data;
173  SDL_AddVideoDisplay(&display);
174 
175  return 0;
176 }
177 
178 SDL_bool
179 UIKit_IsDisplayLandscape(UIScreen *uiscreen)
180 {
181  if (uiscreen == [UIScreen mainScreen]) {
182  return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
183  } else {
184  CGSize size = [uiscreen bounds].size;
185  return (size.width > size.height);
186  }
187 }
188 
189 int
191 {
192  /* this tells us whether we are running on ios >= 3.2 */
193  SDL_UIKit_supports_multiple_displays = [UIScreen instancesRespondToSelector:@selector(currentMode)];
194 
195  /* Add the main screen. */
196  if (UIKit_AddDisplay([UIScreen mainScreen]) < 0) {
197  return -1;
198  }
199 
200  /* If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels. */
201  /* The iPad added both a larger main screen and the ability to use
202  * external displays. So, add the other displays (screens in UI speak).
203  */
205  for (UIScreen *uiscreen in [UIScreen screens]) {
206  /* Only add the other screens */
207  if (uiscreen != [UIScreen mainScreen]) {
208  if (UIKit_AddDisplay(uiscreen) < 0) {
209  return -1;
210  }
211  }
212  }
213  }
214 
215  /* We're done! */
216  return 0;
217 }
218 
219 void
221 {
222  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
223 
224  SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
225  SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
226 
228  /* availableModes showed up in 3.2 (the iPad and later). We should only
229  * land here for at least that version of the OS.
230  */
231  for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
232  CGSize size = [uimode size];
233  int w = (int)size.width;
234  int h = (int)size.height;
235 
236  /* Make sure the width/height are oriented correctly */
237  if (isLandscape != (w > h)) {
238  int tmp = w;
239  w = h;
240  h = tmp;
241  }
242 
243  /* Add the native screen resolution. */
244  UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
245 
246  if (data->scale != 1.0f) {
247  /* Add the native screen resolution divided by its scale.
248  * This is so devices capable of e.g. 640x960 also advertise 320x480.
249  */
250  UIKit_AddDisplayMode(display,
251  (int)(size.width / data->scale),
252  (int)(size.height / data->scale),
253  1.0f, uimode, addRotation);
254  }
255  }
256  } else {
257  const CGSize size = [data->uiscreen bounds].size;
258  int w = (int)size.width;
259  int h = (int)size.height;
260 
261  /* Make sure the width/height are oriented correctly */
262  if (isLandscape != (w > h)) {
263  int tmp = w;
264  w = h;
265  h = tmp;
266  }
267 
268  UIKit_AddDisplayMode(display, w, h, 1.0f, nil, addRotation);
269  }
270 }
271 
272 int
274 {
275  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
276 
278  /* Not on at least iPhoneOS 3.2 (versions prior to iPad). */
279  SDL_assert(mode->driverdata == NULL);
280  } else {
282  [data->uiscreen setCurrentMode:modedata->uiscreenmode];
283 
284  if (data->uiscreen == [UIScreen mainScreen]) {
285  if (mode->w > mode->h) {
286  if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
287  [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
288  }
289  } else if (mode->w < mode->h) {
290  if (UIKit_IsDisplayLandscape(data->uiscreen)) {
291  [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
292  }
293  }
294  }
295  }
296  return 0;
297 }
298 
299 void
301 {
302  /* Release Objective-C objects, so higher level doesn't free() them. */
303  int i, j;
304  for (i = 0; i < _this->num_displays; i++) {
305  SDL_VideoDisplay *display = &_this->displays[i];
306 
307  UIKit_FreeDisplayModeData(&display->desktop_mode);
308  for (j = 0; j < display->num_display_modes; j++) {
309  SDL_DisplayMode *mode = &display->display_modes[j];
310  UIKit_FreeDisplayModeData(mode);
311  }
312 
313  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
314  [data->uiscreen release];
315  SDL_free(data);
316  display->driverdata = NULL;
317  }
318 }
319 
320 #endif /* SDL_VIDEO_DRIVER_UIKIT */
321 
322 /* vi: set ts=4 sw=4 expandtab: */
int UIKit_InitModes(_THIS)
void UIKit_QuitModes(_THIS)
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen)
SDL_bool
Definition: SDL_stdinc.h:116
GLuint in
Definition: glew.h:10672
DECLSPEC void SDLCALL SDL_free(void *mem)
The structure that defines a display mode.
Definition: SDL_video.h:53
int32_t j
Definition: e_log.c:102
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
char * display
Definition: visualinfo.c:85
if(!yyg->yy_init)
void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
UIScreen * uiscreen
int
Definition: SDL_systhread.c:37
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define _THIS
void * driverdata
Definition: SDL_video.h:59
SDL_DisplayMode * display_modes
Definition: SDL_sysvideo.h:118
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:265
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12632
#define SDL_assert(condition)
Definition: SDL_assert.h:159
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
UIScreenMode * uiscreenmode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
BOOL SDL_UIKit_supports_multiple_displays
Uint32 format
Definition: SDL_video.h:55
int i
Definition: pngrutil.c:1377
GLenum mode
Definition: glew.h:2394
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC
GLsizei size
Definition: gl2ext.h:1467
int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)