-/* Whether the shape of the X11 Window should be changed to HxW when the
- device is in a landscape orientation. X11 hacks want this, but OpenGL
- hacks do not.
- */
-- (BOOL)reshapeRotatedWindow
-{
- return YES;
-}
-
-
-/* Called after the device's orientation has changed.
-
- Rotation is complicated: the UI, X11 and OpenGL work in 3 different ways.
-
- The UI (list of savers, preferences panels) is rotated by the system,
- because its UIWindow is under a UINavigationController that does
- automatic rotation, using Core Animation.
-
- The savers are under a different UIWindow and a UINavigationController
- that does not do automatic rotation.
-
- We have to do it this way because using Core Animation on an EAGLContext
- causes the OpenGL pipeline used on both X11 and GL savers to fall back on
- software rendering and performance goes to hell.
-
- During and after rotation, the size/shape of the X11 window changes,
- and ConfigureNotify events are generated.
-
- X11 code (jwxyz) continues to draw into the (reshaped) backbuffer, which is
- rendered onto a rotating OpenGL quad.
-
- GL code always recieves a portrait-oriented X11 Window whose size never
- changes. The GL COLOR_BUFFER is displayed on the hardware directly and
- unrotated, so the GL hacks themselves are responsible for rotating the
- GL scene to match current_device_rotation().
-
- Touch events are converted to mouse clicks, and those XEvent coordinates
- are reported in the coordinate system currently in use by the X11 window.
- Again, GL must convert those.
- */
-- (void)didRotate:(NSNotification *)notification
-{
- UIDeviceOrientation current = [[UIDevice currentDevice] orientation];
-
- /* Sometimes UIDevice doesn't know the proper orientation, or the device is
- face up/face down, so in those cases fall back to the status bar
- orientation. The SaverViewController tries to set the status bar to the
- proper orientation before it creates the XScreenSaverView; see
- _storedOrientation in SaverViewController.
- */
- if (current == UIDeviceOrientationUnknown ||
- current == UIDeviceOrientationFaceUp ||
- current == UIDeviceOrientationFaceDown) {
- /* Mind the differences between UIInterfaceOrientation and
- UIDeviceOrientaiton:
- 1. UIInterfaceOrientation does not include FaceUp and FaceDown.
- 2. LandscapeLeft and LandscapeRight are swapped between the two. But
- converting between device and interface orientation doesn't need to
- take this into account, because (from the UIInterfaceOrientation
- description): "rotating the device requires rotating the content in
- the opposite direction."
- */
- current = [UIApplication sharedApplication].statusBarOrientation;
- }
-
- /* On the iPad (but not iPhone 3GS, or the simulator) sometimes we get
- an orientation change event with an unknown orientation. Those seem
- to always be immediately followed by another orientation change with
- a *real* orientation change, so let's try just ignoring those bogus
- ones and hoping that the real one comes in shortly...
- */
- if (current == UIDeviceOrientationUnknown)
- return;
-
- if (rotation_ratio >= 0) return; // in the midst of rotation animation
- if (orientation == current) return; // no change
-
- new_orientation = current; // current animation target
- rotation_ratio = 0; // start animating
- rot_start_time = double_time();
-
- switch (orientation) {
- case UIDeviceOrientationLandscapeLeft: angle_from = 90; break;
- case UIDeviceOrientationLandscapeRight: angle_from = 270; break;
- case UIDeviceOrientationPortraitUpsideDown: angle_from = 180; break;
- default: angle_from = 0; break;
- }
-
- switch (new_orientation) {
- case UIDeviceOrientationLandscapeLeft: angle_to = 90; break;
- case UIDeviceOrientationLandscapeRight: angle_to = 270; break;
- case UIDeviceOrientationPortraitUpsideDown: angle_to = 180; break;
- default: angle_to = 0; break;
- }
-
- switch (orientation) {
- case UIDeviceOrientationLandscapeRight: // from landscape
- case UIDeviceOrientationLandscapeLeft:
- rot_from.width = initial_bounds.height;
- rot_from.height = initial_bounds.width;
- break;
- default: // from portrait
- rot_from.width = initial_bounds.width;
- rot_from.height = initial_bounds.height;
- break;
- }
-
- switch (new_orientation) {
- case UIDeviceOrientationLandscapeRight: // to landscape
- case UIDeviceOrientationLandscapeLeft:
- rot_to.width = initial_bounds.height;
- rot_to.height = initial_bounds.width;
- break;
- default: // to portrait
- rot_to.width = initial_bounds.width;
- rot_to.height = initial_bounds.height;
- break;
- }
-
-# if TARGET_IPHONE_SIMULATOR
- NSLog (@"%srotation begun: %s %d -> %s %d; %d x %d",
- initted_p ? "" : "initial ",
- orientname(orientation), (int) rot_current_angle,
- orientname(new_orientation), (int) angle_to,
- (int) rot_current_size.width, (int) rot_current_size.height);
-# endif
-
- // Even though the status bar isn't on the screen, this still does two things:
- // 1. It fixes the orientation of the iOS simulator.
- // 2. It places the iOS notification center on the expected edge.
- // 3. It prevents the notification center from causing rotation events.
- [[UIApplication sharedApplication] setStatusBarOrientation:new_orientation
- animated:NO];
-
- if (! initted_p) {
- // If we've done a rotation but the saver hasn't been initialized yet,
- // don't bother going through an X11 resize, but just do it now.
- rot_start_time = 0; // dawn of time
- [self hackRotation];
- }
-}
-
-