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 i_push_error(0, "No main display");
40 /* for now, only interested in the first display */
41 rect = CGDisplayBounds(disp);
42 screen_width = rect.size.width;
43 screen_height = rect.size.height;
45 /* adjust negative/zero values to window size */
51 right += screen_width;
53 bottom += screen_height;
58 if (right > screen_width)
62 if (bottom > screen_height)
63 bottom = screen_height;
66 if (right <= left || bottom <= top) {
67 i_push_error(0, "image would be empty");
72 height = bottom - top;
74 /* select a pixel format */
75 pix_attrs[1] = CGDisplayIDToOpenGLDisplayMask(disp);
76 err = CGLChoosePixelFormat(pix_attrs, &pix, &npix);
78 i_push_errorf(err, "CGLChoosePixelFormat: %d", (int)err);
82 i_push_error(0, "No pixel format found - hidden display?");
86 /* make ourselves a context */
87 err = CGLCreateContext(pix, NULL, &ctx);
88 CGLDestroyPixelFormat(pix);
90 i_push_errorf(err, "CGLCreateContext: %d", (int)err);
94 err = CGLSetCurrentContext(ctx);
96 i_push_errorf(err, "CGLSetCurrentContext: %d", (int)err);
100 err = CGLSetFullScreen(ctx);
102 i_push_errorf(err, "CGLSetFullScreen: %d", (int)err);
107 im = i_img_8_new(width, height, 3);
109 size_t line_size = width * 4;
110 size_t buf_size = line_size * height;
111 unsigned char *buf = malloc(buf_size);
112 i_img_dim y = height - 1;
113 i_color *bufp = (i_color *)buf; /* hackish */
115 /* GL has the vertical axis going from bottom to top, so translate it */
117 glReadBuffer(GL_FRONT);
118 glReadPixels(left, screen_height - top - height, width, height,
119 GL_RGBA, GL_UNSIGNED_BYTE, buf);
123 i_plin(im, 0, width, y, bufp);
130 i_tags_setn(&im->tags, "ss_window_width", width);
131 i_tags_setn(&im->tags, "ss_window_height", height);
132 i_tags_set(&im->tags, "ss_type", "Darwin", 6);
133 i_tags_set(&im->tags, "ss_variant", "<11", 3);
134 i_tags_setn(&im->tags, "ss_left", left);
135 i_tags_setn(&im->tags, "ss_top", top);
139 CGLSetCurrentContext(NULL);
140 CGLDestroyContext(ctx);