-/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski <jwz@jwz.org>
-*
-* Permission to use, copy, modify, distribute, and sell this software and its
-* documentation for any purpose is hereby granted without fee, provided that
-* the above copyright notice appear in all copies and that both that
-* copyright notice and this permission notice appear in supporting
-* documentation. No representations are made about the suitability of this
-* software for any purpose. It is provided "as is" without express or
-* implied warranty.
-*/
+/* xscreensaver, Copyright (c) 2006-2014 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
/* This is a subclass of Apple's ScreenSaverView that knows how to run
xscreensaver programs without X11 via the dark magic of the "jwxyz"
# ifndef USE_IPHONE
[NSOpenGLContext clearCurrentContext];
# endif // !USE_IPHONE
+
+ clear_gl_error(); // This hack is defunct, don't let this linger.
}
}
+#ifdef USE_IPHONE
+/* With GL programs, drawing at full resolution isn't a problem.
+ */
+- (CGFloat) hackedContentScaleFactor
+{
+ NSSize ssize = [[[UIScreen mainScreen] currentMode] size];
+ NSSize bsize = [self bounds].size;
+
+ // Ratio of screen size in pixels to view size in points.
+ GLfloat s = ((ssize.width > ssize.height ? ssize.width : ssize.height) /
+ (bsize.width > bsize.height ? bsize.width : bsize.height));
+ return s;
+}
+#endif // USE_IPHONE
+
+
- (void) setOglContext: (NSOpenGLContext *) ctx
{
ogl_ctx = ctx;
# ifdef USE_IPHONE
[EAGLContext setCurrentContext: ogl_ctx];
- double s = self.contentScaleFactor;
- int w = s * [self frame].size.width;
- int h = s * [self frame].size.height;
+ double s = [self hackedContentScaleFactor];
+ int w = s * [self bounds].size.width;
+ int h = s * [self bounds].size.height;
if (gl_framebuffer) glDeleteFramebuffersOES (1, &gl_framebuffer);
if (gl_renderbuffer) glDeleteRenderbuffersOES (1, &gl_renderbuffer);
return [CAEAGLLayer class];
}
+- (void) swapBuffers
+{
+ glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
+ [ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES];
+}
+#endif // USE_IPHONE
+
+
+#ifdef USE_BACKBUFFER
+
+- (void) initLayer
+{
+ // Do nothing.
+}
-/* On MacOS: drawRect does nothing, and animateOneFrame renders.
- On iOS GL: drawRect does nothing, and animateOneFrame renders.
- On iOS X11: drawRect renders, and animateOneFrame marks the view dirty.
- */
- (void)drawRect:(NSRect)rect
{
}
- (void) animateOneFrame
{
+# ifdef USE_IPHONE
UIGraphicsPushContext (backbuffer);
+# endif
+
[self render_x11];
+
+# ifdef USE_IPHONE
UIGraphicsPopContext();
+# endif
}
and discarded. That's ok, though, because mostly it's just calls to
XClearWindow and housekeeping stuff like that. So we make a tiny one.
*/
-- (void) createBackbuffer
+- (void) createBackbuffer:(CGSize)new_size
{
- // Don't resize the X11 window to match rotation.
- // Rotation and scaling are handled in GL.
- //
- NSRect f = [self frame];
- double s = self.contentScaleFactor;
- backbuffer_size.width = (int) (s * f.size.width);
- backbuffer_size.height = (int) (s * f.size.height);
+ backbuffer_size = new_size;
if (! backbuffer) {
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
int w = 8;
int h = 8;
- backbuffer = CGBitmapContextCreate (NULL, w, h,
+ backbuffer = CGBitmapContextCreate (NULL, w, h, // yup, only 8px x 8px.
8, w*4, cs,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease (cs);
}
}
+# endif // USE_BACKBUFFER
-- (void) swapBuffers
+/* When changing the device orientation, leave the X11 Window and glViewport
+ in portrait configuration. OpenGL hacks examine current_device_rotation()
+ within the scene as needed.
+ */
+- (BOOL)reshapeRotatedWindow
{
- glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
- [ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES];
+ return NO;
}
-# endif // USE_IPHONE
- (void)dealloc {
*/
-// redefine these now since they don't work when not inside an ObjC method.
+// redefine NSAssert, etc. here since they don't work when not inside
+// an ObjC method.
#undef NSAssert
#undef NSAssert1
#undef NSAssert2
-#define NSAssert(CC,S) do { if (!(CC)) { NSLog(S); abort();}} while(0)
-#define NSAssert1(CC,S,A) do { if (!(CC)) { NSLog(S,A); abort();}} while(0)
-#define NSAssert2(CC,S,A,B) do { if (!(CC)) { NSLog(S,A,B);abort();}} while(0)
+#define NSASS(S) \
+ jwxyz_abort ("%s", [(S) cStringUsingEncoding:NSUTF8StringEncoding])
+#define NSAssert(CC,S) do { if (!(CC)) { NSASS((S)); }} while(0)
+#define NSAssert1(CC,S,A) do { if (!(CC)) { \
+ NSASS(([NSString stringWithFormat: S, A])); }} while(0)
+#define NSAssert2(CC,S,A,B) do { if (!(CC)) { \
+ NSASS(([NSString stringWithFormat: S, A, B])); }} while(0)
/* Called by OpenGL savers using the XLockmore API.
NSAssert (pixfmt, @"unable to create NSOpenGLPixelFormat");
+ // #### Analyze says: "Potential leak of an object stored into pixfmt"
ctx = [[NSOpenGLContext alloc]
initWithFormat:pixfmt
shareContext:nil];
[ctx setValues:&r forParameter:NSOpenGLCPSwapInterval];
// check_gl_error ("NSOpenGLCPSwapInterval"); // SEGV sometimes. Too early?
- // #### "Build and Analyze" says that ctx leaks, because it doesn't
- // seem to realize that makeCurrentContext retains it (right?)
- // Not sure what to do to make this warning go away.
+ // #### Analyze says: "Potential leak of an object stored into "ctx"
+ // But makeCurrentContext retains it (right?)
[ctx makeCurrentContext];
check_gl_error ("makeCurrentContext");
eagl_layer.opaque = TRUE;
eagl_layer.drawableProperties =
[NSDictionary dictionaryWithObjectsAndKeys:
- kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
- [NSNumber numberWithBool:!dbuf_p], kEAGLDrawablePropertyRetainedBacking,
- nil];
+ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+ [NSNumber numberWithBool:!dbuf_p], kEAGLDrawablePropertyRetainedBacking,
+ nil];
// Without this, the GL frame buffer is half the screen resolution!
eagl_layer.contentsScale = [UIScreen mainScreen].scale;
if (!ogl_ctx)
return 0;
[view setOglContext:ogl_ctx];
+ // #### Analyze says "Potential leak of an object stored into ogl_ctx"
check_gl_error ("OES_init");
+ jwzgles_reset ();
+
# endif // USE_IPHONE
+ // I don't know why this is necessary, but it beats randomly having some
+ // textures be upside down.
+ //
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+
// Caller expects a pointer to an opaque struct... which it dereferences.
// Don't ask me, it's historical...
static int blort = -1;