1 /* Darwin support via OpenGL */
4 #include <ApplicationServices/ApplicationServices.h>
5 #include "OpenGL/OpenGL.h"
7 #include "OpenGL/glu.h"
8 #include "OpenGL/glext.h"
11 imss_darwin(i_img_dim left, i_img_dim top, i_img_dim right, i_img_dim bottom) {
15 CGLPixelFormatObj pix;
19 CGDirectDisplayID disp;
20 i_img_dim screen_width, screen_height;
21 i_img_dim width, height;
23 CGLPixelFormatAttribute pix_attrs[] =
25 kCGLPFADisplayMask, 0, /* filled in later */
34 disp = CGMainDisplayID();
36 /* for now, only interested in the first display */
37 rect = CGDisplayBounds(disp);
38 screen_width = rect.size.width;
39 screen_height = rect.size.height;
41 /* adjust negative/zero values to window size */
47 right += screen_width;
49 bottom += screen_height;
54 if (right > screen_width)
58 if (bottom > screen_height)
59 bottom = screen_height;
62 if (right <= left || bottom <= top) {
63 i_push_error(0, "image would be empty");
68 height = bottom - top;
70 /* select a pixel format */
71 pix_attrs[1] = CGDisplayIDToOpenGLDisplayMask(disp);
72 err = CGLChoosePixelFormat(pix_attrs, &pix, &npix);
74 i_push_errorf(err, "CGLChoosePixelFormat: %d", (int)err);
78 i_push_error(0, "No pixel format found");
82 /* make ourselves a context */
83 err = CGLCreateContext(pix, NULL, &ctx);
84 CGLDestroyPixelFormat(pix);
86 i_push_errorf(err, "CGLCreateContext: %d", (int)err);
90 err = CGLSetCurrentContext(ctx);
92 i_push_errorf(err, "CGLSetCurrentContext: %d", (int)err);
96 err = CGLSetFullScreen(ctx);
98 i_push_errorf(err, "CGLSetFullScreen: %d", (int)err);
103 im = i_img_8_new(width, height, 3);
105 size_t line_size = width * 4;
106 size_t buf_size = line_size * height;
107 unsigned char *buf = malloc(buf_size);
108 i_img_dim y = height - 1;
109 i_color *bufp = (i_color *)buf; /* hackish */
111 /* GL has the vertical axis going from bottom to top, so translate it */
113 glReadBuffer(GL_FRONT);
114 glReadPixels(left, screen_height - top - height, width, height,
115 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);
119 i_plin(im, 0, width, y, bufp);
128 CGLSetCurrentContext(NULL);
129 CGLDestroyContext(ctx);