aboutsummaryrefslogtreecommitdiffstats
path: root/x11.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-10-25 14:47:11 +0000
committerkraxel <kraxel>2006-10-25 14:47:11 +0000
commit397fcd38d34e02a73dc0d05e41562a82e608e203 (patch)
tree051bfb9d033634e8d6832cfb754a1be6a777c2e6 /x11.c
parent75e722fc76c56c56a14546ba2dc7418fec08a558 (diff)
downloadxenwatch-397fcd38d34e02a73dc0d05e41562a82e608e203.tar.gz
add cvs viewer
Diffstat (limited to 'x11.c')
-rw-r--r--x11.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/x11.c b/x11.c
new file mode 100644
index 0000000..fb75c2d
--- /dev/null
+++ b/x11.c
@@ -0,0 +1,226 @@
+/*
+ * some X11 ximage / pixmaps rotines
+ *
+ * (c) 2006 Gerd Hoffmann <kraxel@suse.de>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "x11.h"
+
+/* ------------------------------------------------------------------------ */
+
+XVisualInfo *x11_info;
+int have_shmem = 0;
+
+int x11_red_bits = 0;
+int x11_red_shift = 0;
+int x11_green_bits = 0;
+int x11_green_shift = 0;
+int x11_blue_bits = 0;
+int x11_blue_shift = 0;
+
+static void
+x11_find_bits(unsigned long red_mask,
+ unsigned long green_mask,
+ unsigned long blue_mask)
+{
+ int i;
+ unsigned long mask;
+
+ for (i = 0; i < 24; i++) {
+ mask = (1 << i);
+ if (red_mask & mask)
+ x11_red_bits++;
+ else if (!x11_red_bits)
+ x11_red_shift++;
+ if (green_mask & mask)
+ x11_green_bits++;
+ else if (!x11_green_bits)
+ x11_green_shift++;
+ if (blue_mask & mask)
+ x11_blue_bits++;
+ else if (!x11_blue_bits)
+ x11_blue_shift++;
+ }
+
+#if 1
+ printf("color: bits shift\n");
+ printf("red : %04i %05i\n", x11_red_bits, x11_red_shift);
+ printf("green: %04i %05i\n", x11_green_bits, x11_green_shift);
+ printf("blue : %04i %05i\n", x11_blue_bits, x11_blue_shift);
+#endif
+}
+
+int x11_color_init(Display *dpy)
+{
+ Screen *scr;
+ XVisualInfo template;
+ int found;
+
+ scr = DefaultScreenOfDisplay(dpy);
+
+ /* Ask for visual type */
+ template.screen = XDefaultScreen(dpy);
+ template.visualid =
+ XVisualIDFromVisual(DefaultVisualOfScreen(scr));
+ x11_info = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &template,
+ &found);
+ if (XShmQueryExtension(dpy))
+ have_shmem = 1;
+
+ if (x11_info->class != TrueColor) {
+ fprintf(stderr, "sorry, can't handle visual\n");
+ return -1;
+ }
+ x11_find_bits(x11_info->red_mask, x11_info->green_mask, x11_info->blue_mask);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mitshm_bang = 0;
+
+static int x11_error_dev_null(Display *dpy, XErrorEvent *event)
+{
+ mitshm_bang = 1;
+ return 0;
+}
+
+XImage* x11_create_ximage(Display *dpy, int width, int height, void **shm)
+{
+ XImage *ximage = NULL;
+ char *ximage_data;
+ XShmSegmentInfo *shminfo = NULL;
+ void *old_handler;
+ Screen *scr = DefaultScreenOfDisplay(dpy);
+
+ if (have_shmem) {
+ old_handler = XSetErrorHandler(x11_error_dev_null);
+ (*shm) = shminfo = malloc(sizeof(XShmSegmentInfo));
+ memset(shminfo, 0, sizeof(XShmSegmentInfo));
+ ximage = XShmCreateImage(dpy,
+ DefaultVisualOfScreen(scr),
+ DefaultDepthOfScreen(scr),
+ ZPixmap, NULL,
+ shminfo, width, height);
+ if (ximage) {
+ shminfo->shmid = shmget(IPC_PRIVATE,
+ ximage->bytes_per_line * ximage->height,
+ IPC_CREAT | 0777);
+ if (-1 == shminfo->shmid) {
+ fprintf(stderr,"shmget(%dMB): %s\n",
+ ximage->bytes_per_line * ximage->height / 1024 / 1024,
+ strerror(errno));
+ goto oom;
+ }
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+ if ((void *) -1 == shminfo->shmaddr) {
+ perror("shmat");
+ goto oom;
+ }
+ ximage->data = shminfo->shmaddr;
+ shminfo->readOnly = False;
+
+ XShmAttach(dpy, shminfo);
+ XSync(dpy, False);
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ if (mitshm_bang) {
+ have_shmem = 0;
+ shmdt(shminfo->shmaddr);
+ free(shminfo);
+ shminfo = *shm = NULL;
+ XDestroyImage(ximage);
+ ximage = NULL;
+ }
+ } else {
+ have_shmem = 0;
+ free(shminfo);
+ shminfo = *shm = NULL;
+ }
+ XSetErrorHandler(old_handler);
+ }
+
+ if (ximage == NULL) {
+ (*shm) = NULL;
+ if (NULL == (ximage_data = malloc(width * height * 4))) {
+ fprintf(stderr,"Oops: out of memory\n");
+ goto oom;
+ }
+ ximage = XCreateImage(dpy,
+ DefaultVisualOfScreen(scr),
+ DefaultDepthOfScreen(scr),
+ ZPixmap, 0, ximage_data,
+ width, height,
+ 8, 0);
+ }
+ memset(ximage->data, 0, ximage->bytes_per_line * ximage->height);
+
+ return ximage;
+
+ oom:
+ if (shminfo) {
+ if (shminfo->shmid && shminfo->shmid != -1)
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ free(shminfo);
+ }
+ if (ximage)
+ XDestroyImage(ximage);
+ return NULL;
+}
+
+void x11_destroy_ximage(Display *dpy, XImage *ximage, void *shm)
+{
+ XShmSegmentInfo *shminfo = shm;
+
+ if (shminfo) {
+ XShmDetach(dpy, shminfo);
+ XDestroyImage(ximage);
+ shmdt(shminfo->shmaddr);
+ free(shminfo);
+ } else
+ XDestroyImage(ximage);
+}
+
+Pixmap x11_create_pixmap(Display *dpy, unsigned char *byte_data,
+ int width, int height)
+{
+ Pixmap pixmap;
+ XImage *ximage;
+ XGCValues values;
+ GC gc;
+ unsigned long *long_data = (unsigned long *)byte_data;
+ int x, y;
+ void *shm;
+
+ Screen *scr = DefaultScreenOfDisplay(dpy);
+
+ pixmap = XCreatePixmap(dpy,
+ RootWindowOfScreen(scr),
+ width, height,
+ DefaultDepthOfScreen(scr));
+ gc = XCreateGC(dpy, pixmap, 0, &values);
+
+ if (NULL == (ximage = x11_create_ximage(dpy, width, height, &shm))) {
+ XFreePixmap(dpy, pixmap);
+ XFreeGC(dpy, gc);
+ return 0;
+ }
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ XPutPixel(ximage, x, y, *(long_data++));
+
+ XPUTIMAGE(dpy, pixmap, gc, ximage, 0, 0, 0, 0, width, height);
+
+ x11_destroy_ximage(dpy, ximage, shm);
+ XFreeGC(dpy, gc);
+ return pixmap;
+}