summaryrefslogtreecommitdiffstats
path: root/x11vnc/macosx_opengl.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/macosx_opengl.c')
-rw-r--r--x11vnc/macosx_opengl.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/x11vnc/macosx_opengl.c b/x11vnc/macosx_opengl.c
new file mode 100644
index 0000000..9788279
--- /dev/null
+++ b/x11vnc/macosx_opengl.c
@@ -0,0 +1,176 @@
+/*
+ Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
+ All rights reserved.
+
+This file is part of x11vnc.
+
+x11vnc is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+x11vnc is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with x11vnc; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
+or see <http://www.gnu.org/licenses/>.
+
+In addition, as a special exception, Karl J. Runge
+gives permission to link the code of its release of x11vnc with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables. You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL". If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so. If you do not wish to do
+so, delete this exception statement from your version.
+*/
+
+/* -- macosx_opengl.c -- */
+
+#if (defined(__MACH__) && defined(__APPLE__))
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+#include <rfb/rfb.h>
+#if LIBVNCSERVER_HAVE_MACOSX_OPENGL_H
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#endif
+
+extern int macosx_no_opengl, macosx_read_opengl;
+extern CGDirectDisplayID displayID;
+
+static CGLContextObj glContextObj;
+
+int macosx_opengl_width = 0;
+int macosx_opengl_height = 0;
+int macosx_opengl_bpp = 0;
+
+int macosx_opengl_get_width(void) {
+ GLint viewport[4];
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ return (int) viewport[2];
+}
+
+int macosx_opengl_get_height(void) {
+ GLint viewport[4];
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ return (int) viewport[3];
+}
+
+int macosx_opengl_get_bpp(void) {
+ return 32;
+}
+
+int macosx_opengl_get_bps(void) {
+ return 8;
+}
+
+int macosx_opengl_get_spp(void) {
+ return 3;
+}
+
+void macosx_opengl_init(void) {
+ CGLPixelFormatObj pixelFormatObj;
+ GLint numPixelFormats;
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFAFullScreen,
+ kCGLPFADisplayMask,
+ 0,
+ 0
+ };
+
+ if (macosx_no_opengl) {
+ return;
+ }
+
+ attribs[2] = CGDisplayIDToOpenGLDisplayMask(displayID);
+
+ CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
+ if (pixelFormatObj == NULL) {
+ rfbLog("macosx_opengl_init: CGLChoosePixelFormat failed. Not using OpenGL.\n");
+ return;
+ }
+
+ CGLCreateContext(pixelFormatObj, NULL, &glContextObj);
+ CGLDestroyPixelFormat(pixelFormatObj);
+
+ if (glContextObj == NULL) {
+ rfbLog("macosx_opengl_init: CGLCreateContext failed. Not using OpenGL.\n");
+ return;
+ }
+
+ CGLSetCurrentContext(glContextObj);
+ CGLSetFullScreen(glContextObj);
+
+ macosx_opengl_width = macosx_opengl_get_width();
+ macosx_opengl_height = macosx_opengl_get_height();
+
+ macosx_opengl_bpp = macosx_opengl_get_bpp();
+
+ glFinish();
+
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+
+ rfbLog("macosx_opengl_init: Using OpenGL for screen capture.\n");
+ macosx_read_opengl = 1;
+}
+
+void macosx_opengl_fini(void) {
+ if (!macosx_read_opengl) {
+ return;
+ }
+ CGLSetCurrentContext(NULL);
+ CGLClearDrawable(glContextObj);
+ CGLDestroyContext(glContextObj);
+}
+
+void macosx_copy_opengl(char *dest, int x, int y, unsigned int w, unsigned int h) {
+ int yflip = macosx_opengl_height - y - h;
+
+ CGLSetCurrentContext(glContextObj);
+
+ glReadPixels((GLint) x, (GLint) yflip, (int) w, (int) h,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, dest);
+
+ if (h > 1) {
+ static char *pbuf = NULL;
+ static int buflen = 0;
+ int top = 0, bot = h - 1, rowlen = w * macosx_opengl_bpp/8;
+ char *ptop, *pbot;
+
+ if (rowlen > buflen || buflen == 0) {
+ buflen = rowlen + 128;
+ if (pbuf) {
+ free(pbuf);
+ }
+ pbuf = (char *) malloc(buflen);
+ }
+ while (top < bot) {
+ ptop = dest + top * rowlen;
+ pbot = dest + bot * rowlen;
+ memcpy(pbuf, ptop, rowlen);
+ memcpy(ptop, pbot, rowlen);
+ memcpy(pbot, pbuf, rowlen);
+ top++;
+ bot--;
+ }
+ }
+}
+
+
+#else
+
+#endif /* __APPLE__ */
+
OpenPOWER on IntegriCloud