// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
// see below for copyright information on the second portion of this file
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-#include <X11/keysymdef.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xmu/StdCmap.h>
+#include "GCJ.cc"
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
#include <sys/types.h>
-#include <gcj/cni.h>
#include <signal.h>
+#include <java/lang/String.h>
+// FIXME: we don't need all these
#include <java/lang/String.h>
#include <org/xwt/Surface.h>
#include <org/xwt/Picture.h>
+#include <org/xwt/js/JS.h>
#include <org/xwt/Box.h>
-#include <org/xwt/plat/POSIX.h>
-#include <org/xwt/plat/POSIX$X11Surface.h>
-#include <org/xwt/plat/POSIX$X11Picture.h>
-#include <org/xwt/plat/POSIX$X11DoubleBuffer.h>
#include <org/xwt/util/Semaphore.h>
#include <org/xwt/Platform.h>
#include <java/lang/Long.h>
#include <java/util/Hashtable.h>
#include <org/xwt/util/Log.h>
-
+#include <org/xwt/plat/POSIX.h>
#include <java/lang/System.h>
#include <java/io/PrintStream.h>
-// static (per-xserver) data
-static Visual* visual;
-static Colormap s_colormap;
-static XStandardColormap* colormap_info;
-static XShmSegmentInfo shm_info;
-static Window selectionWindow;
-static int shm_supported;
-static int shm_pixmaps_supported;
-static int screen_num;
-static int colorDepth = 0;
-static Display* display;
-static int shm_size = 0;
-
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define max(a, b) ((a) < (b) ? (b) : (a))
-
-// X11DoubleBuffer //////////////////////////////////////////////////////////////////////
-
-// ensures that the shared memory is at least size bytes; if not, allocates 3/2 * size
-static void ensureShmSize(int size) {
- if (size > shm_size) {
- if (shm_size > 0) {
- XShmDetach(display, &shm_info);
- shmdt(shm_info.shmaddr);
- shmctl(shm_info.shmid, IPC_RMID, 0);
- }
- shm_size = 3 * size / 2;
- shm_info.shmid = shmget(IPC_PRIVATE, shm_size, IPC_CREAT | 0777 | IPC_EXCL);
- shm_info.shmaddr = (char*)shmat(shm_info.shmid, 0, 0);
- shm_info.readOnly = False;
- XSync(display, False);
- shmctl(shm_info.shmid, IPC_RMID, 0);
- XShmAttach(display, &shm_info);
- XSync(display, False);
- }
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::fastDrawPicture(org::xwt::Picture* s,
- jint dx1, jint dy1, jint dx2, jint dy2, jint sx1, jint sy1, jint sx2, jint sy2) {
- org::xwt::plat::POSIX$X11Picture* source = (org::xwt::plat::POSIX$X11Picture*)s;
-
- // it's safe to clip manually since we no that no scaling will be done
- if (dx1 < clipx) { sx1 += ((clipx - dx1) * (sx2 - sx1)) / (dx2 - dx1); dx1 = clipx; }
- if (dy1 < clipy) { sy1 += ((clipy - dy1) * (sy2 - sy1)) / (dy2 - dy1); dy1 = clipy; }
- if (dx2 > clipx + clipw) { sx2 -= ((dx2 - clipx - clipw) * (sx2 - sx1)) / (dx2 - dx1); dx2 = clipx + clipw; }
- if (dy2 > clipy + cliph) { sy2 -= ((dy2 - clipy - cliph) * (sy2 - sy1)) / (dy2 - dy1); dy2 = clipy + cliph; }
- if (dx1 > clipx + clipw) return;
- if (dy1 > clipy + cliph) return;
- if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0) return;
-
- if (source->doublebuf->stipple != NULL) {
- XSetClipMask(display, (*((GC*)clipped_gc)), *((Pixmap*)source->doublebuf->stipple));
- XSetClipOrigin(display, (*((GC*)clipped_gc)), dx1 - sx1, dy1 - sy1);
- } else {
- XSetClipMask(display, (*((GC*)clipped_gc)), None);
- }
- XCopyArea(display, *((Pixmap*)source->doublebuf->pm), (*((Pixmap*)pm)), (*((GC*)clipped_gc)), sx1, sy1, sx2 - sx1, sy2 - sy1, dx1, dy1);
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::slowDrawPicture(org::xwt::Picture* s,
- jint dx1, jint dy1, jint dx2, jint dy2, jint sx1, jint sy1, jint sx2, jint sy2) {
-
- org::xwt::plat::POSIX$X11Picture* source = (org::xwt::plat::POSIX$X11Picture*)s;
- XImage* xi;
-
- // FASTEST: shared pixmap; twiddle bits in video ram directly
- if (shared_pixmap) {
- XSync(display, False); // ensure that all pending operations have rendered
- xi = (XImage*)fake_ximage;
-
- // MEDIUM: write to a shared ximage, then ask the server to do the blit
- } else if (shm_supported) {
- xi = XShmCreateImage(display, visual, colorDepth, ZPixmap, NULL, &shm_info, dx2 - dx1, dy2 - dy1);
- ensureShmSize(xi->bytes_per_line * xi->height);
- xi->data = shm_info.shmaddr;
- XShmGetImage(display, (*((Pixmap*)pm)), xi, dx1, dy1, AllPlanes);
-
- // SLOWEST: write to an ximage, copy it through the TCP connection, ask the server to do the blit
- } else {
- xi = XGetImage(display, (*((Pixmap*)pm)), dx1, dy1, dx2 - dx1, dy2 - dy1, AllPlanes, ZPixmap);
- }
-
- int* sourcedata = (int*)elements(source->data);
- for(int y=max(dy1, clipy); y<min(dy2, clipy + cliph); y++) {
-
- char* current_pixel = (xi->data + y * xi->bytes_per_line) +
- (shared_pixmap ? max(dx1, clipx) * (xi->bits_per_pixel / 8) : - 1 * dy1 * xi->bytes_per_line);
-
- for(int x=max(dx1, clipx); x<min(dx2, clipx + clipw); x++, current_pixel += xi->bits_per_pixel / 8) {
- int source_x = ((x - dx1) * (sx2 - sx1)) / (dx2 - dx1) + sx1;
- int source_y = ((y - dy1) * (sy2 - sy1)) / (dy2 - dy1) + sy1;
-
- int sourcepixel = sourcedata[source_x + source_y * source->getWidth()];
- int alpha = (sourcepixel & 0xFF000000) >> 24;
- int source_red = (sourcepixel & 0x00FF0000) >> 16;
- int source_green = (sourcepixel & 0x0000FF00) >> 8;
- int source_blue = (sourcepixel & 0x000000FF);
- int red = 0, blue = 0, green = 0;
-
- if (alpha == 0x00) continue;
- if (alpha != 0xFF) {
- int targetpixel;
- switch (xi->bits_per_pixel) {
- case 8: targetpixel = (int)(*current_pixel); break;
- case 16: targetpixel = (int)(*((u_int16_t*)current_pixel)); break;
- case 24: targetpixel = (((int)*current_pixel) << 16) | (((int)*(current_pixel + 1)) << 8) | (((int)*(current_pixel + 2))); break;
- case 32: targetpixel = *((int*)current_pixel); break;
- default: org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: bpp not a multiple of 8!"));
- }
-
- targetpixel -= colormap_info->base_pixel;
-
- // if you're on some wierd display that isn't either RGB or BGR, that's your problem, not mine
- if (colormap_info->red_mult > colormap_info->green_mult && colormap_info->green_mult > colormap_info->blue_mult) {
- red = targetpixel / colormap_info->red_mult;
- green = (targetpixel - red * colormap_info->red_mult) / colormap_info->green_mult;
- blue = (targetpixel - red * colormap_info->red_mult - green * colormap_info->green_mult) / colormap_info->blue_mult;
- } else {
- blue = targetpixel / colormap_info->blue_mult;
- green = (targetpixel - blue * colormap_info->blue_mult) / colormap_info->green_mult;
- red = (targetpixel - blue * colormap_info->blue_mult - green * colormap_info->green_mult) / colormap_info->red_mult;
- }
- }
-
- red = ((source_red * colormap_info->red_max * alpha) + (red * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
- green = ((source_green * colormap_info->green_max * alpha) + (green * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
- blue = ((source_blue * colormap_info->blue_max * alpha) + (blue * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
- u_int32_t destpixel = red * colormap_info->red_mult + green * colormap_info->green_mult +
- blue * colormap_info->blue_mult + colormap_info->base_pixel;
-
- switch (xi->bits_per_pixel) {
- case 8: *current_pixel = (char)(destpixel & 0xFF); break;
- case 16: *((u_int16_t*)current_pixel) = (u_int16_t)destpixel; break;
- case 24: {
- int offset = (int)current_pixel & 0x3;
- u_int64_t dest = ((u_int64_t)destpixel) << (8 * offset);
- u_int64_t mask = ((u_int64_t)0xffffff) << (8 * offset);
- u_int64_t* base = (u_int64_t*)(current_pixel - offset);
- *base = (*base & ~mask) | dest;
- break;
- }
- case 32: *((u_int32_t*)current_pixel) = destpixel; break;
- default: org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: bpp not a multiple of 8!"));
- }
- }
- }
-
- if (shared_pixmap) {
- // do nothing, we wrote directly to video memory
-
- } else if (shm_supported) {
- XShmPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, dx1, dy1, dx2 - dx1, dy2 - dy1, False);
- XDestroyImage(xi);
-
- } else {
- XPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, dx1, dy1, dx2 - dx1, dy2 - dy1);
-
- }
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::finalize() {
- if (shared_pixmap) {
- XShmSegmentInfo *sinfo = (XShmSegmentInfo*)shm_segment;
- XShmDetach(display, sinfo);
- shmdt(sinfo->shmaddr);
- shmctl(sinfo->shmid, IPC_RMID, 0);
- XDestroyImage((XImage*)fake_ximage);
- free(sinfo);
- }
- if (stipple) {
- XFreePixmap(display, *((Pixmap*)stipple));
- free(stipple);
- }
- XFreePixmap(display, *((Pixmap*)pm));
- XFreeGC(display, *((GC*)gc));
- XFreeGC(display, *((GC*)clipped_gc));
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::natInit() {
-
- if (width == 0 || height == 0) return;
- shared_pixmap &= shm_supported & shm_pixmaps_supported; // refuse to use shared pixmaps if we don't have shm
- pm = (gnu::gcj::RawData*)malloc(sizeof(Pixmap));
-
- if (!shared_pixmap)
- (*((Pixmap*)pm)) = XCreatePixmap(display, RootWindow(display, screen_num), width, height, colorDepth);
- else {
- XShmSegmentInfo *sinfo = (XShmSegmentInfo*)malloc(sizeof(XShmSegmentInfo));
- shm_segment = (gnu::gcj::RawData*)sinfo;
- ((XImage*)fake_ximage) = XShmCreateImage(display, visual, colorDepth, ZPixmap, NULL, sinfo, width, height);
- sinfo->shmid = shmget(IPC_PRIVATE, ((XImage*)fake_ximage)->bytes_per_line * height, IPC_CREAT | 0777 | IPC_EXCL);
- ((XImage*)fake_ximage)->data = sinfo->shmaddr = (char*)shmat(sinfo->shmid, 0, 0);
- sinfo->readOnly = False;
- XShmAttach(display, sinfo);
- XSync(display, False);
- shmctl(sinfo->shmid, IPC_RMID, 0);
- (*((Pixmap*)pm)) = XShmCreatePixmap(display, RootWindow(display, screen_num), sinfo->shmaddr, sinfo, width, height, colorDepth);
- XSync(display, False);
- }
-
- gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
- clipped_gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
- (*((GC*)gc)) = XCreateGC(display, (*((Pixmap*)pm)), 0, 0);
- (*((GC*)clipped_gc)) = XCreateGC(display, (*((Pixmap*)pm)), 0, 0);
-
- XGCValues vm;
- vm.graphics_exposures = 0;
- XChangeGC(display, (*((GC*)gc)), GCGraphicsExposures, &vm);
- XChangeGC(display, (*((GC*)clipped_gc)), GCGraphicsExposures, &vm);
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::createStipple(org::xwt::plat::POSIX$X11Picture* xpi) {
-
- stipple = (gnu::gcj::RawData*)malloc(sizeof(Pixmap));
- (*((Pixmap*)stipple)) = XCreatePixmap(display, RootWindow(display, screen_num), width, height, 1);
-
- XImage xi;
- xi.data = (char*)malloc((width + 1) * height);
- xi.width = width;
- xi.height = height;
- xi.xoffset = 0;
- xi.format = ZPixmap;
- xi.bitmap_pad = 8;
- xi.bitmap_unit = 8;
- xi.byte_order = LSBFirst;
- xi.depth = 1;
- xi.bytes_per_line = (width / 8) + 1;
- xi.bits_per_pixel = 1;
-
- jint* d = (jint*)elements(xpi->data);
- memset(xi.data, 0xFF, (width + 1) * height);
- for(int x=0; x<width; x++)
- for (int y=0; y<height; y++)
- xi.data[y * xi.bytes_per_line + (x/8)] &= ~(((d[x + y * width] & 0xFF000000) != 0 ? 0 : 1) << (x % 8));
-
- GC stipple_gc = XCreateGC(display, (*((Pixmap*)stipple)), 0, 0);
-
- XGCValues vm;
- vm.graphics_exposures = 0;
- XChangeGC(display, stipple_gc, GCGraphicsExposures, &vm);
-
- XPutImage(display, (*((Pixmap*)stipple)), stipple_gc, &xi, 0, 0, 0, 0, width, height);
-}
-
-void org::xwt::plat::POSIX$X11Surface::blit(org::xwt::DoubleBuffer* db, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
- org::xwt::plat::POSIX$X11DoubleBuffer *xdb = (org::xwt::plat::POSIX$X11DoubleBuffer*)db;
- XCopyArea(display, *((Pixmap*)xdb->pm), *((Window*)window), *((GC*)gc), sx, sy, dx2 - dx, dy2 - dy, dx, dy);
- XFlush(display);
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::fillRect (jint x, jint y, jint x2, jint y2, jint argb) {
-
- jint w = x2 - x;
- jint h = y2 - y;
-
- if (x < clipx) { w -= (clipx - x); x = clipx; }
- if (y < clipy) { h -= (clipy - y); y = clipy; }
- if (x + w > clipx + clipw) w = (clipx + clipw - x);
- if (y + h > clipy + cliph) h = (cliph + clipy - y);
-
- XSetForeground(display, (*((GC*)gc)),
- ((((argb & 0x00FF0000) >> 16) * colormap_info->red_max) / 0xFF) * colormap_info->red_mult +
- ((((argb & 0x0000FF00) >> 8) * colormap_info->green_max) / 0xFF) * colormap_info->green_mult +
- ((((argb & 0x000000FF)) * colormap_info->blue_max) / 0xFF) * colormap_info->blue_mult +
- colormap_info->base_pixel
- );
-
- XFillRectangle(display, (*((Pixmap*)pm)), (*((GC*)gc)), x, y, w, h);
-}
-
-void org::xwt::plat::POSIX$X11DoubleBuffer::drawString(::java::lang::String* font, ::java::lang::String* text, jint x, jint y, jint argb) {
-
- XRectangle rect;
- rect.x = clipx, rect.y = clipy; rect.width = clipw; rect.height = cliph;
- XSetClipMask(display, (*((GC*)clipped_gc)), None);
- XSetClipRectangles(display, (*((GC*)clipped_gc)), 0, 0, &rect, 1, YSorted);
- XSetForeground(display, (*((GC*)clipped_gc)),
- ((((argb & 0x00FF0000) >> 16) * colormap_info->red_max) / 0xFF) * colormap_info->red_mult +
- ((((argb & 0x0000FF00) >> 8) * colormap_info->green_max) / 0xFF) * colormap_info->green_mult +
- ((((argb & 0x000000FF)) * colormap_info->blue_max) / 0xFF) * colormap_info->blue_mult +
- colormap_info->base_pixel
- );
-
- // Grab the string
- int len = min(1024, JvGetStringUTFLength(text));
+jstring org::xwt::plat::POSIX::_getEnv(jstring key) {
+ int len = JvGetStringUTFLength(key);
char buf[len + 1];
- JvGetStringUTFRegion(text, 0, len, buf);
+ JvGetStringUTFRegion(key, 0, len, buf);
buf[len] = '\0';
-
- // Build the XTextItem structure
- XTextItem textitem;
- textitem.chars = buf;
- textitem.nchars = len;
- textitem.delta = 0;
- textitem.font = ((XFontStruct*)org::xwt::plat::POSIX::fontToXFont(font))->fid;
-
- // Draw the text
- XDrawText(display, (*((Pixmap*)pm)), (*((GC*)clipped_gc)), x, y, &textitem, 1);
-}
-
-
-// X11Surface //////////////////////////////////////////////////////////////////////
-
-void org::xwt::plat::POSIX$X11Surface::setIcon(org::xwt::Picture* pic) {
- org::xwt::plat::POSIX$X11Picture* p = ((org::xwt::plat::POSIX$X11Picture*)pic);
- org::xwt::plat::POSIX$X11DoubleBuffer* old_dbuf = p->doublebuf;
- p->buildDoubleBuffer(1);
- XWMHints xwmh;
- memset(&xwmh, 0, sizeof(XWMHints));
- xwmh.flags |= IconPixmapHint | IconMaskHint;
- xwmh.icon_pixmap = *((Pixmap*)p->doublebuf->pm);
- xwmh.icon_mask = *((Pixmap*)p->doublebuf->stipple);
- XSetWMHints(display, (*((Window*)window)), &xwmh);
- p->doublebuf = old_dbuf;
-}
-
-void org::xwt::plat::POSIX$X11Surface::setTitleBarText(java::lang::String* s) {
- int len = min(JvGetStringUTFLength(s), 1024);
- char buf[len + 1];
- JvGetStringUTFRegion(s, 0, len, buf);
- buf[len] = '\0';
-
- XTextProperty tp;
- tp.value = (unsigned char*)buf;
- tp.nitems = len;
- tp.encoding = XA_STRING;
- tp.format = 8;
- XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_NAME);
- XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_ICON_NAME);
-}
-
-void org::xwt::plat::POSIX$X11Surface::setLimits(jint minw, jint minh, jint maxw, jint maxh) {
- XSizeHints hints;
- hints.min_width = minw;
- hints.min_height = minh;
- hints.max_width = maxw;
- hints.max_height = maxh;
- hints.flags = PMinSize | PMaxSize;
- XSetWMNormalHints(display, (*((Window*)window)), &hints);
-}
-
-void org::xwt::plat::POSIX$X11Surface::setSize (jint width, jint height) {
- if (width <= 0 || height <= 0) return;
- XResizeWindow(display, (*((Window*)window)), width, height);
- XFlush(display);
-}
-
-void org::xwt::plat::POSIX$X11Surface::_dispose() { XDestroyWindow(display, (*((Window*)window))); }
-void org::xwt::plat::POSIX$X11Surface::setLocation (jint x, jint y) { XMoveWindow(display, (*((Window*)window)), x, y); }
-void org::xwt::plat::POSIX$X11Surface::toFront() { XRaiseWindow(display, (*((Window*)window))); }
-void org::xwt::plat::POSIX$X11Surface::toBack() { XLowerWindow(display, (*((Window*)window))); }
-
-void org::xwt::plat::POSIX$X11Surface::setInvisible(jboolean i) {
- if (i) XUnmapWindow(display, (*((Window*)window)));
- else XMapRaised(display, (*((Window*)window)));
- XFlush(display);
-}
-
-void org::xwt::plat::POSIX$X11Surface::_setMinimized(jboolean b) {
- if (b) XIconifyWindow(display, (*((Window*)window)), screen_num);
- else XMapRaised(display, (*((Window*)window)));
- XFlush(display);
-}
-
-void org::xwt::plat::POSIX$X11Surface::natInit() {
- XSetWindowAttributes xswa;
- window = (gnu::gcj::RawData*)malloc(sizeof(Window));
- xswa.bit_gravity = NorthWestGravity;
- xswa.colormap = s_colormap;
- xswa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask |
- KeyPressMask | KeyReleaseMask | ButtonPressMask |
- ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
- PointerMotionMask | ButtonMotionMask | ConfigureNotify | FocusChangeMask;
- *((Window*)window) = XCreateWindow(display, RootWindow(display, screen_num), 10, 10, 500, 300, 0,
- colorDepth, InputOutput, CopyFromParent,
- CWColormap | CWBitGravity | CWEventMask, &xswa);
-
- if (!framed) {
- // I don't know why this works....
- int dat[5] = { 0x2, 0xbffff804, 0x0, 0x817f560, 0x8110694 };
- XChangeProperty(display, (*((Window*)window)),
- XInternAtom(display, "_MOTIF_WM_HINTS", False),
- XInternAtom(display, "_MOTIF_WM_HINTS", False),
- 32,
- PropModeReplace,
- (unsigned char*)dat,
- 5);
- }
-
- XTextProperty tp;
- tp.value = (unsigned char*)"XWT";
- tp.nitems = 3;
- tp.encoding = XA_STRING;
- tp.format = 8;
- XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_CLASS);
-
- Atom proto = XInternAtom(display, "WM_DELETE_WINDOW", False);
- XSetWMProtocols(display, (*((Window*)window)), &proto, 1);
-
- XSelectInput(display, (*((Window*)window)), StructureNotifyMask);
- org::xwt::plat::POSIX::windowToSurfaceMap->put(new java::lang::Long(*((Window*)window)), this);
-
- XEvent e;
- XMapRaised(display, (*((Window*)window)));
- XFlush(display);
-
- waitForCreation->block();
- XSelectInput(display, (*((Window*)window)), xswa.event_mask);
- XFlush(display);
-
- gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
- *((GC*)gc) = XCreateGC(display, (*((Window*)window)), 0, 0);
-
- XGCValues vm;
- vm.graphics_exposures = 0;
- XChangeGC(display, *((GC*)gc), GCGraphicsExposures, &vm);
-}
-
-
-void org::xwt::plat::POSIX$X11Surface::dispatchEvent(gnu::gcj::RawData* ev) {
-
- XEvent* e = (XEvent*)ev;
- if (e->type == Expose) {
- XExposeEvent *expose = (XExposeEvent*)(e);
- Dirty(expose->x, expose->y, expose->width, expose->height);
-
- } else if (e->type == ClientMessage) { if (((XClientMessageEvent*)(e))->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", False)) Close();
- } else if (e->type == MapNotify) { Minimized(0); waitForCreation->release();
- } else if (e->type == UnmapNotify) { Minimized(1);
- } else if (e->type == FocusIn) { Focused(1);
- } else if (e->type == FocusOut) { Focused(0);
-
- } else if (e->type == SelectionNotify) {
- XSelectionEvent* xsn = (XSelectionEvent*)(e);
- if (xsn->property == None) org::xwt::plat::POSIX::clipboard = JvNewStringLatin1("", 0);
- else {
- Atom returntype;
- int returnformat;
- unsigned long numitems;
- unsigned char* ret;
- unsigned long bytes_after;
- XGetWindowProperty(display, xsn->requestor, xsn->property, 0, 4096,
- True, AnyPropertyType, &returntype, &returnformat,
- &numitems, &bytes_after, &ret);
- org::xwt::plat::POSIX::clipboard =
- (returntype == None ? JvNewStringLatin1("", 0) : JvNewStringLatin1((char*)ret, strlen((char*)ret)));
- }
- org::xwt::plat::POSIX::waiting_for_selection_event->release();
-
- } else if (e->type == SelectionRequest) {
- XSelectionRequestEvent* xsr = (XSelectionRequestEvent*)(e);
- XSelectionEvent xsn;
- xsn.type = SelectionNotify;
- xsn.serial = xsr->serial;
- xsn.send_event = True;
- xsn.display = display;
- xsn.requestor = xsr->requestor;
- xsn.selection = xsr->selection;
- xsn.target = xsr->target;
- xsn.property = xsr->property;
- xsn.time = xsr->time;
-
- int len = min(1024, JvGetStringUTFLength(org::xwt::plat::POSIX::clipboard));
- char buf[len + 1];
- JvGetStringUTFRegion(org::xwt::plat::POSIX::clipboard, 0, len, buf);
- buf[len] = '\0';
-
- XChangeProperty(display, xsr->requestor, xsr->property, xsr->target, 8, PropModeReplace, (unsigned char*)buf, len + 1);
- XSendEvent(display, xsr->requestor, True, 0, (XEvent*)(&xsn));
-
- } else if (e->type == KeyPress || e->type == KeyRelease) {
- XKeyEvent *xbe = (XKeyEvent*)(e);
-
- // drop faked KeyRelease events generated by the X server's autorepeat
- if (e->type == KeyRelease) {
- char depressed[32];
- XQueryKeymap(display, depressed);
- if ((depressed[(xbe->keycode & 0xff) / 8] & (0x1 << (xbe->keycode % 8))) >> (xbe->keycode % 8)) return;
- }
-
- char ss[20];
- char* s = ss;
-
- unsigned int savestate = xbe->state;
- xbe->state = xbe->state & ShiftMask; // ignore everything except shiftmask
- XLookupString(xbe, s, 20, NULL, NULL);
- xbe->state = savestate;
-
- if (s != NULL && s[0] != '\0' && s[1] == '\0' && s[0] >= 0x20 && s[0] <= 0x7E) {
- int i = s[0];
-
- } else {
- KeySym ks = XKeycodeToKeysym(display, xbe->keycode, 0);
- switch (ks) {
- case XK_BackSpace: s = "back_space"; break;
- case XK_Tab: s = "tab"; break;
- case XK_Linefeed: s = "enter"; break;
- case XK_Return: s = "enter"; break;
- case XK_Scroll_Lock: s = "scroll_lock"; break;
- case XK_Escape: s = "escape"; break;
- case XK_Insert: s = "insert"; break;
- case XK_Delete: s = "delete"; break;
- case XK_Home: s = "home"; break;
- case XK_Left: s = "left"; break;
- case XK_Up: s = "up"; break;
- case XK_Right: s = "right"; break;
- case XK_Down: s = "down"; break;
- case XK_Page_Up: s = "page_up"; break;
- case XK_Page_Down: s = "page_down"; break;
- case XK_End: s = "end"; break;
- case XK_Num_Lock: s = "num_lock"; break;
- case XK_KP_Tab: s = "tab"; break;
- case XK_KP_Enter: s = "enter"; break;
- case XK_KP_F1: s = "f1"; break;
- case XK_KP_F2: s = "f2"; break;
- case XK_KP_F3: s = "f3"; break;
- case XK_KP_F4: s = "f4"; break;
- case XK_KP_Home: s = "home"; break;
- case XK_KP_Left: s = "left"; break;
- case XK_KP_Up: s = "up"; break;
- case XK_KP_Right: s = "right"; break;
- case XK_KP_Down: s = "down"; break;
- case XK_KP_Page_Up: s = "page_up"; break;
- case XK_KP_Page_Down: s = "page_down"; break;
- case XK_KP_End: s = "end"; break;
- case XK_KP_Insert: s = "insert"; break;
- case XK_KP_Delete: s = "delete"; break;
- case XK_F1: s = "f1"; break;
- case XK_F2: s = "f2"; break;
- case XK_F3: s = "f3"; break;
- case XK_F4: s = "f4"; break;
- case XK_F5: s = "f5"; break;
- case XK_F6: s = "f6"; break;
- case XK_F7: s = "f7"; break;
- case XK_F8: s = "f8"; break;
- case XK_F9: s = "f9"; break;
- case XK_F10: s = "f10"; break;
- case XK_F11: s = "f11"; break;
- case XK_F12: s = "f12"; break;
- case XK_Shift_L: s = "shift"; break;
- case XK_Shift_R: s = "shift"; break;
- case XK_Control_L: s = "control"; break;
- case XK_Control_R: s = "control"; break;
- case XK_Caps_Lock: s = "caps_lock"; break;
- case XK_Meta_L: s = "alt"; break;
- case XK_Meta_R: s = "alt"; break;
- case XK_Alt_L: s = "alt"; break;
- case XK_Alt_R: s = "alt"; break;
- default: return;
- }
- }
-
- if (e->type == KeyPress) KeyPressed(JvNewStringLatin1(s));
- if (e->type == KeyRelease) KeyReleased(JvNewStringLatin1(s));
-
- } else if (e->type == ButtonPress) {
- XButtonEvent* xbe = (XButtonEvent*)(e);
- if (xbe->button == 2) xbe->button = 3;
- else if (xbe->button == 3) xbe->button = 2;
- Press(xbe->button);
-
- } else if (e->type == ButtonRelease) {
- XButtonEvent* xbe = (XButtonEvent*)(e);
- if (xbe->button == 2) xbe->button = 3;
- else if (xbe->button == 3) xbe->button = 2;
- Release(xbe->button);
-
- } else if (e->type == MotionNotify) {
- XMotionEvent* xme = (XMotionEvent*)(e);
- Move(xme->x, xme->y);
-
- } else if (e->type == EnterNotify || e->type == LeaveNotify) {
- XCrossingEvent* xce = (XCrossingEvent*)(e);
- Move(xce->x, xce->y);
-
- } else if (e->type == ConfigureNotify) {
- Window child;
- int x_out, y_out;
- XConfigureEvent* xce = (XConfigureEvent*)(e);
- XTranslateCoordinates(display, (*((Window*)window)), RootWindow(display, screen_num), 0, 0, &x_out, &y_out, &child);
- if (xce->width != width || xce->height != height) SizeChange(xce->width, xce->height);
- if (x_out != root->abs(0) || y_out != root->abs(1)) PosChange(x_out, y_out);
-
- }
-}
-
-static jstring crosshair, east, hand, move, north, northeast, northwest,
- south, southeast, southwest, text, west, wait_string;
-static Cursor crosshair_cursor, east_cursor, hand_cursor, move_cursor, north_cursor,
- northeast_cursor, northwest_cursor, south_cursor, southeast_cursor,
- southwest_cursor, text_cursor, west_cursor, wait_cursor, default_cursor;
-
-void org::xwt::plat::POSIX$X11Surface::syncCursor() {
-
- Cursor curs;
- if (cursor->equals(crosshair)) curs = crosshair_cursor;
- else if (cursor->equals(east)) curs = east_cursor;
- else if (cursor->equals(hand)) curs = hand_cursor;
- else if (cursor->equals(move)) curs = move_cursor;
- else if (cursor->equals(north)) curs = north_cursor;
- else if (cursor->equals(northeast)) curs = northeast_cursor;
- else if (cursor->equals(northwest)) curs = northwest_cursor;
- else if (cursor->equals(south)) curs = south_cursor;
- else if (cursor->equals(southeast)) curs = southeast_cursor;
- else if (cursor->equals(southwest)) curs = southwest_cursor;
- else if (cursor->equals(text)) curs = text_cursor;
- else if (cursor->equals(west)) curs = west_cursor;
- else if (cursor->equals(wait_string)) curs = wait_cursor;
- else curs = default_cursor;
-
- XDefineCursor(display, (*((Window*)window)), curs);
-}
-
-
-
-// POSIX ///////////////////////////////////////////////////////////////////
-
-jint org::xwt::plat::POSIX::_getScreenWidth() { return WidthOfScreen(DefaultScreenOfDisplay(display)); }
-jint org::xwt::plat::POSIX::_getScreenHeight() { return HeightOfScreen(DefaultScreenOfDisplay(display)); }
-
-jstring org::xwt::plat::POSIX::getBrowserEnvString() {
- char* envstr = getenv("BROWSER");
+ char* envstr = getenv(buf);
return envstr == NULL ? NULL : JvNewStringLatin1(envstr);
}
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
- execvp(cmd2[0], cmd2);
- }
-}
-
-void org::xwt::plat::POSIX::eventThread() {
- XEvent e;
- while(true) {
- XNextEvent(display, &e);
- org::xwt::plat::POSIX$X11Surface* surface =
- (org::xwt::plat::POSIX$X11Surface*)windowToSurfaceMap->get(new java::lang::Long(((XAnyEvent*)&e)->window));
- if (surface != NULL) surface->dispatchEvent((gnu::gcj::RawData*)&e);
- }
-}
-
-jstring org::xwt::plat::POSIX::_getClipBoard() {
- XConvertSelection(display, XA_PRIMARY, XA_STRING, XInternAtom(display, "VT_SELECTION", False), selectionWindow, CurrentTime);
- XFlush(display);
- org::xwt::plat::POSIX::waiting_for_selection_event->block();
- return clipboard;
-}
-
-void org::xwt::plat::POSIX::_setClipBoard(jstring s) {
- clipboard = s;
- int len = JvGetStringUTFLength(clipboard);
- char buf[len + 1];
- JvGetStringUTFRegion(clipboard, 0, len, buf);
- buf[len] = '\0';
- XSetSelectionOwner(display, XInternAtom(display, "PRIMARY", 0), selectionWindow, CurrentTime);
-}
-
-typedef int (X11ErrorHandler)(Display*, XErrorEvent*);
-int errorHandler(Display* d, XErrorEvent* e) {
- // this error handler is only installed during the initial
- // test to see if shm is present
- shm_supported = 0;
-}
-
-void org::xwt::plat::POSIX::natInit() {
-
- if (!XInitThreads())
- org::xwt::Platform::criticalAbort(JvNewStringLatin1("Your X11 libraries do not support multithreaded programs"));
-
- display = XOpenDisplay(NULL);
- screen_num = XDefaultScreen(display);
- colorDepth = (jint)(DefaultDepth(((Display*)display), 0));
- shm_info.shmaddr = NULL;
-
- shm_supported = (XShmQueryExtension(display) == True);
- if (shm_supported) {
- X11ErrorHandler* oldHandler = XSetErrorHandler(errorHandler);
- XShmSegmentInfo sinfo;
- sinfo.shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT | 0777 | IPC_EXCL);
- sinfo.readOnly = False;
- // if the server is remote, this will trigger the error handler
- XShmAttach(display, &sinfo);
- XSync(display, False);
- XSetErrorHandler(oldHandler);
- }
-
- if (shm_supported)
- shm_pixmaps_supported = (XShmPixmapFormat(display) == ZPixmap);
-
- crosshair = JvNewStringLatin1("crosshair");
- east = JvNewStringLatin1("east");
- hand = JvNewStringLatin1("hand");
- move = JvNewStringLatin1("move");
- north = JvNewStringLatin1("north");
- northeast = JvNewStringLatin1("northeast");
- northwest = JvNewStringLatin1("northwest");
- south = JvNewStringLatin1("south");
- southeast = JvNewStringLatin1("southeast");
- southwest = JvNewStringLatin1("southwest");
- text = JvNewStringLatin1("text");
- west = JvNewStringLatin1("west");
- wait_string = JvNewStringLatin1("wait");
- crosshair_cursor = XCreateFontCursor(display, XC_tcross);
- east_cursor = XCreateFontCursor(display, XC_right_side);
- hand_cursor = XCreateFontCursor(display, XC_hand2);
- move_cursor = XCreateFontCursor(display, XC_fleur);
- north_cursor = XCreateFontCursor(display, XC_top_side);
- northeast_cursor = XCreateFontCursor(display, XC_top_right_corner);
- northwest_cursor = XCreateFontCursor(display, XC_left_side);
- south_cursor = XCreateFontCursor(display, XC_bottom_side);
- southeast_cursor = XCreateFontCursor(display, XC_bottom_right_corner);
- southwest_cursor = XCreateFontCursor(display, XC_bottom_left_corner);
- text_cursor = XCreateFontCursor(display, XC_xterm);
- west_cursor = XCreateFontCursor(display, XC_right_side);
- wait_cursor = XCreateFontCursor(display, XC_watch);
- default_cursor = XCreateFontCursor(display, XC_left_ptr);
-
- selectionWindow = XCreateWindow(display, RootWindow(display, screen_num), 0, 0, 1, 1, 0, colorDepth, InputOutput, CopyFromParent, 0, NULL);
- visual = DefaultVisual(display, screen_num);
- char buf[255];
- sprintf(buf, "X11 DISPLAY: %s", JvNewStringLatin1(XDisplayString(display)));
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
- sprintf(buf, "X11 SHM: %s", shm_supported ? "enabled" : "disabled");
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
- sprintf(buf, "X11 Visual: %x %x %x bits: %i visualid: %i depth: %i",
- visual->red_mask, visual->green_mask, visual->blue_mask, visual->bits_per_rgb, visual->visualid, colorDepth);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
-
- // FIXME: don't know why (True, False) is the best solution...
- if(XmuLookupStandardColormap(display, screen_num, visual->visualid, colorDepth, XA_RGB_BEST_MAP, True, False) == 0)
- org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: XmuLookupStandardColormap failed"));
-
- XStandardColormap* best_map_info = NULL;
- int count;
- if (XGetRGBColormaps(display, RootWindow(display, screen_num), &best_map_info, &count, XA_RGB_BEST_MAP) == 0)
- org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: couldn't allocate a standard colormap"));
- if (!best_map_info->colormap)
- org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: XmuLookupStandardColomap succeded, but no colormap was found on the root window"));
- if (best_map_info->red_max == 0)
- org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: standard colormap exists, but was improperly allocated"));
- s_colormap = best_map_info->colormap;
- colormap_info = best_map_info;
-
- sprintf(buf, " red_max / red_mult: %x %x", colormap_info->red_max, colormap_info->red_mult);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
- sprintf(buf, " green_max / green_mult: %x %x", colormap_info->green_max, colormap_info->green_mult);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
- sprintf(buf, " blue_max / blue_mult: %x %x", colormap_info->blue_max, colormap_info->blue_mult);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
- sprintf(buf, " base_pixel: %x", colormap_info->base_pixel);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
-}
-
-JArray<java::lang::String*>* org::xwt::plat::POSIX::listNativeFonts() {
- int numfonts;
- char** xfonts = XListFonts(display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0xFFFFFFFF, &numfonts);
- JArray<java::lang::String*>* fonts = (JArray<java::lang::String*>*)JvNewObjectArray(numfonts, &(::java::lang::String::class$), NULL);
- java::lang::String** jfonts = (java::lang::String**)(elements(fonts));
- for(int i=0; i<numfonts; i++)
- jfonts[i] = JvNewStringLatin1(xfonts[i], strlen(xfonts[i]));
- return fonts;
-}
-
-gnu::gcj::RawData* org::xwt::plat::POSIX::fontStringToStruct(jstring s) {
- int len = min(1024, JvGetStringUTFLength(s));
- char buf[len + 1];
- JvGetStringUTFRegion(s, 0, len, buf);
- buf[len] = '\0';
- return (gnu::gcj::RawData*)XLoadQueryFont(display, buf);
-}
-
-jint org::xwt::plat::POSIX::_getMaxAscent(::java::lang::String* font) { return ((XFontStruct*)fontToXFont(font))->max_bounds.ascent; }
-jint org::xwt::plat::POSIX::_getMaxDescent(::java::lang::String* font) { return ((XFontStruct*)fontToXFont(font))->max_bounds.descent; }
-jint org::xwt::plat::POSIX::_stringWidth(::java::lang::String* font, ::java::lang::String* text) {
- if (text == NULL) return 0;
- int len = JvGetStringUTFLength(text);
- char buf[len + 1];
- JvGetStringUTFRegion(text, 0, len, buf);
- buf[len] = '\0';
- return XTextWidth((XFontStruct*)fontToXFont(font), buf, len);
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-// //
-// Everything below this point was taken, cut-and-paste, from the //
-// source for libXmu. It implements the official 'standard colormap //
-// creation algorithm. I made some small changes to //
-// XmuDeleteStandardColormap //
-// //
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/* $Xorg: LookupCmap.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/LookupCmap.c,v 1.8 2001/12/14 19:55:47 dawes Exp $ */
-
-/*
- * Author: Donna Converse, MIT X Consortium
- */
-
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/StdCmap.h>
-#include <stdlib.h>
-
-/*
- * Prototypes
- */
-static Status lookup(Display*, int, VisualID, Atom, XStandardColormap*, Bool);
-
-/*
- * To create a standard colormap if one does not currently exist, or
- * replace the currently existing standard colormap, use
- * XmuLookupStandardColormap().
- *
- * Given a screen, a visual, and a property, XmuLookupStandardColormap()
- * will determine the best allocation for the property under the specified
- * visual, and determine the whether to create a new colormap or to use
- * the default colormap of the screen. It will call XmuStandardColormap()
- * to create the standard colormap.
- *
- * If replace is true, any previous definition of the property will be
- * replaced. If retain is true, the property and the colormap will be
- * made permanent for the duration of the server session. However,
- * pre-existing property definitions which are not replaced cannot be made
- * permanent by a call to XmuLookupStandardColormap(); a request to retain
- * resources pertains to newly created resources.
- *
- * Returns 0 on failure, non-zero on success. A request to create a
- * standard colormap upon a visual which cannot support such a map is
- * considered a failure. An example of this would be requesting any
- * standard colormap property on a monochrome visual, or, requesting an
- * RGB_BEST_MAP on a display whose colormap size is 16.
- */
-
-Status
-XmuLookupStandardColormap(Display *dpy, int screen, VisualID visualid,
- unsigned int depth, Atom property,
- Bool replace, Bool retain)
- /*
- * dpy - specifies X server connection
- * screen - specifies screen of display
- * visualid - specifies the visual type
- * depth - specifies the visual type
- * property - a standard colormap property
- * replace - specifies whether to replace
- * retain - specifies whether to retain
- */
-{
- Display *odpy; /* original display connection */
- XStandardColormap *colormap;
- XVisualInfo vinfo_template, *vinfo; /* visual */
- long vinfo_mask;
- unsigned long r_max, g_max, b_max; /* allocation */
- int count;
- Colormap cmap; /* colormap ID */
- Status status = 0;
-
-
- /* Match the requested visual */
-
- vinfo_template.visualid = visualid;
- vinfo_template.screen = screen;
- vinfo_template.depth = depth;
- vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
- if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
- NULL)
- return 0;
-
- /* Monochrome visuals have no standard maps */
-
- if (vinfo->colormap_size <= 2) {
- XFree((char *) vinfo);
- return 0;
- }
-
- /* If the requested property already exists on this screen, and,
- * if the replace flag has not been set to true, return success.
- * lookup() will remove a pre-existing map if replace is true.
- */
-
- if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
- replace) && !replace) {
- XFree((char *) vinfo);
- return 1;
- }
-
- /* Determine the best allocation for this property under the requested
- * visualid and depth, and determine whether or not to use the default
- * colormap of the screen.
- */
-
- if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
- XFree((char *) vinfo);
- return 0;
- }
-
- cmap = (property == XA_RGB_DEFAULT_MAP &&
- visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
- ? DefaultColormap(dpy, screen) : None;
-
- /* If retaining resources, open a new connection to the same server */
-
- if (retain) {
- odpy = dpy;
- if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
- XFree((char *) vinfo);
- return 0;
- }
- }
-
- /* Create the standard colormap */
-
- colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
- cmap, r_max, g_max, b_max);
-
- /* Set the standard colormap property */
-
- if (colormap) {
- XGrabServer(dpy);
-
- if (lookup(dpy, screen, visualid, property, colormap, replace) &&
- !replace) {
- /* Someone has defined the property since we last looked.
- * Since we will not replace it, release our own resources.
- * If this is the default map, our allocations will be freed
- * when this connection closes.
- */
- if (colormap->killid == ReleaseByFreeingColormap)
- XFreeColormap(dpy, colormap->colormap);
- } else if (retain) {
- XSetCloseDownMode(dpy, RetainPermanent);
- }
- XUngrabServer(dpy);
- XFree((char *) colormap);
- status = 1;
- }
-
- if (retain)
- XCloseDisplay(dpy);
- XFree((char *) vinfo);
- return status;
-}
-
-/***************************************************************************/
-
-/* Lookup a standard colormap property. If the property is RGB_DEFAULT_MAP,
- * the visualid is used to determine whether the indicated standard colormap
- * exists. If the map exists and replace is true, delete the resources used
- * by the map and remove the property. Return true if the map exists,
- * or did exist and was deleted; return false if the map was not found.
- *
- * Note that this is not the way that a Status return is normally used.
- *
- * If new is not NULL, new points to an XStandardColormap structure which
- * describes a standard colormap of the specified property. It will be made
- * a standard colormap of the screen if none already exists, or if replace
- * is true.
- */
-
-static Status
-lookup(Display *dpy, int screen, VisualID visualid, Atom property,
- XStandardColormap *cnew, Bool replace)
- /*
- * dpy - specifies display connection
- * screen - specifies screen number
- * visualid - specifies visualid for std map
- * property - specifies colormap property name
- * cnew - specifies a standard colormap
- * replace - specifies whether to replace
- */
-{
- register int i;
- int count;
- XStandardColormap *stdcmaps, *s;
- Window win = RootWindow(dpy, screen);
-
- /* The property does not already exist */
-
- if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
- if (cnew)
- XSetRGBColormaps(dpy, win, cnew, 1, property);
- return 0;
- }
-
- /* The property exists and is not describing the RGB_DEFAULT_MAP */
-
- if (property != XA_RGB_DEFAULT_MAP) {
- if (replace) {
- XmuDeleteStandardColormap(dpy, screen, property);
- if (cnew)
- XSetRGBColormaps(dpy, win, cnew, 1, property);
- }
- XFree((char *)stdcmaps);
- return 1;
- }
-
- /* The property exists and is RGB_DEFAULT_MAP */
-
- for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
- ;
-
- /* No RGB_DEFAULT_MAP property matches the given visualid */
-
- if (i == count) {
- if (cnew) {
- XStandardColormap *m, *maps;
-
- s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
- (XStandardColormap)));
-
- for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
- m->colormap = maps->colormap;
- m->red_max = maps->red_max;
- m->red_mult = maps->red_mult;
- m->green_max = maps->green_max;
- m->green_mult = maps->green_mult;
- m->blue_max = maps->blue_max;
- m->blue_mult = maps->blue_mult;
- m->base_pixel = maps->base_pixel;
- m->visualid = maps->visualid;
- m->killid = maps->killid;
- }
- m->colormap = cnew->colormap;
- m->red_max = cnew->red_max;
- m->red_mult = cnew->red_mult;
- m->green_max = cnew->green_max;
- m->green_mult = cnew->green_mult;
- m->blue_max = cnew->blue_max;
- m->blue_mult = cnew->blue_mult;
- m->base_pixel = cnew->base_pixel;
- m->visualid = cnew->visualid;
- m->killid = cnew->killid;
-
- XSetRGBColormaps(dpy, win, s, ++count, property);
- free((char *) s);
- }
- XFree((char *) stdcmaps);
- return 0;
- }
-
- /* Found an RGB_DEFAULT_MAP property with a matching visualid */
-
- if (replace) {
- /* Free old resources first - we may need them, particularly in
- * the default colormap of the screen. However, because of this,
- * it is possible that we will destroy the old resource and fail
- * to create a new one if XmuStandardColormap() fails.
- */
-
- if (count == 1) {
- XmuDeleteStandardColormap(dpy, screen, property);
- if (cnew)
- XSetRGBColormaps(dpy, win, cnew, 1, property);
- }
- else {
- XStandardColormap *map;
-
- /* s still points to the matching standard colormap */
-
- if (s->killid == ReleaseByFreeingColormap) {
- if ((s->colormap != None) &&
- (s->colormap != DefaultColormap(dpy, screen)))
- XFreeColormap(dpy, s->colormap);
- }
- else if (s->killid != None)
- XKillClient(dpy, s->killid);
-
- map = (cnew) ? cnew : stdcmaps + --count;
-
- s->colormap = map->colormap;
- s->red_max = map->red_max;
- s->red_mult = map->red_mult;
- s->green_max = map->green_max;
- s->green_mult = map->green_mult;
- s->blue_max = map->blue_max;
- s->blue_mult = map->blue_mult;
- s->visualid = map->visualid;
- s->killid = map->killid;
-
- XSetRGBColormaps(dpy, win, stdcmaps, count, property);
- }
- }
- XFree((char *) stdcmaps);
- return 1;
-}
-
-/* $Xorg: CmapAlloc.c,v 1.4 2001/02/09 02:03:51 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1994, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/CmapAlloc.c,v 1.7 2001/12/14 19:55:35 dawes Exp $ */
-/*
- * Author: Donna Converse, MIT X Consortium
- */
+ // ignore SIGPIPE in case we were launched from a browser and the browser closed
+ signal(SIGPIPE, SIG_IGN);
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/StdCmap.h>
-#include <stdio.h>
-
-#define lowbit(x) ((x) & (~(x) + 1))
-
-/*
- * Prototypes
- */
-static void best_allocation(XVisualInfo*, unsigned long*, unsigned long*,
- unsigned long*);
-static int default_allocation(XVisualInfo*, unsigned long*,
- unsigned long*, unsigned long*);
-static void gray_allocation(int, unsigned long*, unsigned long*,
- unsigned long*);
-static int icbrt(int);
-static int icbrt_with_bits(int, int);
-static int icbrt_with_guess(int, int);
-
-/* To determine the best allocation of reds, greens, and blues in a
- * standard colormap, use XmuGetColormapAllocation.
- * vinfo specifies visual information for a chosen visual
- * property specifies one of the standard colormap property names
- * red_max returns maximum red value
- * green_max returns maximum green value
- * blue_max returns maximum blue value
- *
- * XmuGetColormapAllocation returns 0 on failure, non-zero on success.
- * It is assumed that the visual is appropriate for the colormap property.
- */
-
-Status
-XmuGetColormapAllocation(XVisualInfo *vinfo, Atom property,
- unsigned long *red_max,
- unsigned long *green_max,
- unsigned long *blue_max)
-{
- Status status = 1;
-
- if (vinfo->colormap_size <= 2)
- return 0;
-
- switch (property)
- {
- case XA_RGB_DEFAULT_MAP:
- status = default_allocation(vinfo, red_max, green_max, blue_max);
- break;
- case XA_RGB_BEST_MAP:
- best_allocation(vinfo, red_max, green_max, blue_max);
- break;
- case XA_RGB_GRAY_MAP:
- gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
- break;
- case XA_RGB_RED_MAP:
- *red_max = vinfo->colormap_size - 1;
- *green_max = *blue_max = 0;
- break;
- case XA_RGB_GREEN_MAP:
- *green_max = vinfo->colormap_size - 1;
- *red_max = *blue_max = 0;
- break;
- case XA_RGB_BLUE_MAP:
- *blue_max = vinfo->colormap_size - 1;
- *red_max = *green_max = 0;
- break;
- default:
- status = 0;
- }
- return status;
-}
-
-/****************************************************************************/
-/* Determine the appropriate color allocations of a gray scale.
- *
- * Keith Packard, MIT X Consortium
- */
-
-static void
-gray_allocation(int n, unsigned long *red_max, unsigned long *green_max,
- unsigned long *blue_max)
-{
- *red_max = (n * 30) / 100;
- *green_max = (n * 59) / 100;
- *blue_max = (n * 11) / 100;
- *green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
-}
-
-/****************************************************************************/
-/* Determine an appropriate color allocation for the RGB_DEFAULT_MAP.
- * If a map has less than a minimum number of definable entries, we do not
- * produce an allocation for an RGB_DEFAULT_MAP.
- *
- * For 16 planes, the default colormap will have 27 each RGB; for 12 planes,
- * 12 each. For 8 planes, let n = the number of colormap entries, which may
- * be 256 or 254. Then, maximum red value = floor(cube_root(n - 125)) - 1.
- * Maximum green and maximum blue values are identical to maximum red.
- * This leaves at least 125 cells which clients can allocate.
- *
- * Return 0 if an allocation has been determined, non-zero otherwise.
- */
-
-static int
-default_allocation(XVisualInfo *vinfo, unsigned long *red,
- unsigned long *green, unsigned long *blue)
-{
- int ngrays; /* number of gray cells */
-
- switch (vinfo->c_class)
- {
- case PseudoColor:
-
- if (vinfo->colormap_size > 65000)
- /* intended for displays with 16 planes */
- *red = *green = *blue = (unsigned long) 27;
- else if (vinfo->colormap_size > 4000)
- /* intended for displays with 12 planes */
- *red = *green = *blue = (unsigned long) 12;
- else if (vinfo->colormap_size < 250)
- return 0;
- else
- /* intended for displays with 8 planes */
- *red = *green = *blue = (unsigned long)
- (icbrt(vinfo->colormap_size - 125) - 1);
- break;
-
- case DirectColor:
-
- if (vinfo->colormap_size < 10)
- return 0;
- *red = *green = *blue = vinfo->colormap_size / 2 - 1;
- break;
-
- case TrueColor:
-
- *red = vinfo->red_mask / lowbit(vinfo->red_mask);
- *green = vinfo->green_mask / lowbit(vinfo->green_mask);
- *blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
- break;
-
- case GrayScale:
-
- if (vinfo->colormap_size > 65000)
- ngrays = 4096;
- else if (vinfo->colormap_size > 4000)
- ngrays = 512;
- else if (vinfo->colormap_size < 250)
- return 0;
- else
- ngrays = 12;
- gray_allocation(ngrays, red, green, blue);
- break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-/****************************************************************************/
-/* Determine an appropriate color allocation for the RGB_BEST_MAP.
- *
- * For a DirectColor or TrueColor visual, the allocation is determined
- * by the red_mask, green_mask, and blue_mask members of the visual info.
- *
- * Otherwise, if the colormap size is an integral power of 2, determine
- * the allocation according to the number of bits given to each color,
- * with green getting more than red, and red more than blue, if there
- * are to be inequities in the distribution. If the colormap size is
- * not an integral power of 2, let n = the number of colormap entries.
- * Then maximum red value = floor(cube_root(n)) - 1;
- * maximum blue value = floor(cube_root(n)) - 1;
- * maximum green value = n / ((# red values) * (# blue values)) - 1;
- * Which, on a GPX, allows for 252 entries in the best map, out of 254
- * defineable colormap entries.
- */
-
-static void
-best_allocation(XVisualInfo *vinfo, unsigned long *red, unsigned long *green,
- unsigned long *blue)
-{
-
- if (vinfo->c_class == DirectColor || vinfo->c_class == TrueColor)
- {
- *red = vinfo->red_mask;
- while ((*red & 01) == 0)
- *red >>= 1;
- *green = vinfo->green_mask;
- while ((*green & 01) == 0)
- *green >>=1;
- *blue = vinfo->blue_mask;
- while ((*blue & 01) == 0)
- *blue >>= 1;
- }
- else
- {
- register int bits, n;
-
- /* Determine n such that n is the least integral power of 2 which is
- * greater than or equal to the number of entries in the colormap.
- */
- n = 1;
- bits = 0;
- while (vinfo->colormap_size > n)
- {
- n = n << 1;
- bits++;
- }
-
- /* If the number of entries in the colormap is a power of 2, determine
- * the allocation by "dealing" the bits, first to green, then red, then
- * blue. If not, find the maximum integral red, green, and blue values
- * which, when multiplied together, do not exceed the number of
-
- * colormap entries.
- */
- if (n == vinfo->colormap_size)
- {
- register int r, g, b;
- b = bits / 3;
- g = b + ((bits % 3) ? 1 : 0);
- r = b + (((bits % 3) == 2) ? 1 : 0);
- *red = 1 << r;
- *green = 1 << g;
- *blue = 1 << b;
- }
- else
- {
- *red = icbrt_with_bits(vinfo->colormap_size, bits);
- *blue = *red;
- *green = (vinfo->colormap_size / ((*red) * (*blue)));
- }
- (*red)--;
- (*green)--;
- (*blue)--;
- }
- return;
-}
-
-/*
- * integer cube roots by Newton's method
- *
- * Stephen Gildea, MIT X Consortium, July 1991
- */
-
-static int
-icbrt(int a)
-{
- register int bits = 0;
- register unsigned n = a;
-
- while (n)
- {
- bits++;
- n >>= 1;
- }
- return icbrt_with_bits(a, bits);
-}
-
-
-static int
-icbrt_with_bits(int a, int bits)
- /* bits - log 2 of a */
-{
- return icbrt_with_guess(a, a>>2*bits/3);
-}
-
-#ifdef _X_ROOT_STATS
-int icbrt_loopcount;
-#endif
-
-/* Newton's Method: x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */
-
-/* for cube roots, x^3 - a = 0, x_new = x - 1/3 (x - a/x^2) */
-
-/*
- * Quick and dirty cube roots. Nothing fancy here, just Newton's method.
- * Only works for positive integers (since that's all we need).
- * We actually return floor(cbrt(a)) because that's what we need here, too.
- */
-
-static int
-icbrt_with_guess(int a, int guess)
-{
- register int delta;
-
-#ifdef _X_ROOT_STATS
- icbrt_loopcount = 0;
-#endif
- if (a <= 0)
- return 0;
- if (guess < 1)
- guess = 1;
-
- do {
-#ifdef _X_ROOT_STATS
- icbrt_loopcount++;
-#endif
- delta = (guess - a/(guess*guess))/3;
-#ifdef DEBUG
- printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
-#endif
- guess -= delta;
- } while (delta != 0);
-
- if (guess*guess*guess > a)
- guess--;
-
- return guess;
-}
-
-
-/* $Xorg: StdCmap.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/StdCmap.c,v 1.6 2001/12/14 19:55:48 dawes Exp $ */
-
-/*
- * Author: Donna Converse, MIT X Consortium
- */
-
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/StdCmap.h>
-
-#define lowbit(x) ((x) & (~(x) + 1))
-
-/*
- * Prototypes
- */
-/* argument restrictions */
-static Status valid_args(XVisualInfo*, unsigned long, unsigned long,
- unsigned long, Atom);
-
-/*
- * To create any one standard colormap, use XmuStandardColormap().
- *
- * Create a standard colormap for the given screen, visualid, and visual
- * depth, with the given red, green, and blue maximum values, with the
- * given standard property name. Return a pointer to an XStandardColormap
- * structure which describes the newly created colormap, upon success.
- * Upon failure, return NULL.
- *
- * XmuStandardColormap() calls XmuCreateColormap() to create the map.
- *
- * Resources created by this function are not made permanent; that is the
- * caller's responsibility.
- */
-
-XStandardColormap *
-XmuStandardColormap(Display *dpy, int screen, VisualID visualid,
- unsigned int depth, Atom property, Colormap cmap,
- unsigned long red_max, unsigned long green_max,
- unsigned long blue_max)
- /*
- * dpy - specifies X server connection
- * screen - specifies display screen
- * visualid - identifies the visual type
- * depth - identifies the visual type
- * property - a standard colormap property
- * cmap - specifies colormap ID or None
- * red_max, green_max, blue_max - allocations
- */
-{
- XStandardColormap *stdcmap;
- Status status;
- XVisualInfo vinfo_template, *vinfo;
- long vinfo_mask;
- int n;
-
- /* Match the required visual information to an actual visual */
- vinfo_template.visualid = visualid;
- vinfo_template.screen = screen;
- vinfo_template.depth = depth;
- vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
- if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
- return 0;
-
- /* Check the validity of the combination of visual characteristics,
- * allocation, and colormap property. Create an XStandardColormap
- * structure.
- */
-
- if (! valid_args(vinfo, red_max, green_max, blue_max, property)
- || ((stdcmap = XAllocStandardColormap()) == NULL)) {
- XFree((char *) vinfo);
- return 0;
- }
-
- /* Fill in the XStandardColormap structure */
-
- if (cmap == DefaultColormap(dpy, screen)) {
- /* Allocating out of the default map, cannot use XFreeColormap() */
- Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
- 0, 0, InputOnly, vinfo->visual,
- (unsigned long) 0,
- (XSetWindowAttributes *)NULL);
- stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
- XDestroyWindow(dpy, win);
- stdcmap->colormap = cmap;
- } else {
- stdcmap->killid = ReleaseByFreeingColormap;
- stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
- vinfo->visual, AllocNone);
- }
- stdcmap->red_max = red_max;
- stdcmap->green_max = green_max;
- stdcmap->blue_max = blue_max;
- if (property == XA_RGB_GRAY_MAP)
- stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
- else if (vinfo->c_class == TrueColor || vinfo->c_class == DirectColor) {
- stdcmap->red_mult = lowbit(vinfo->red_mask);
- stdcmap->green_mult = lowbit(vinfo->green_mask);
- stdcmap->blue_mult = lowbit(vinfo->blue_mask);
- } else {
- stdcmap->red_mult = (red_max > 0)
- ? (green_max + 1) * (blue_max + 1) : 0;
- stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
- stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
- }
- stdcmap->base_pixel = 0; /* base pixel may change */
- stdcmap->visualid = vinfo->visualid;
-
- /* Make the colormap */
-
- status = XmuCreateColormap(dpy, stdcmap);
-
- /* Clean up */
-
- XFree((char *) vinfo);
- if (!status) {
-
- /* Free the colormap or the pixmap, if we created one */
- if (stdcmap->killid == ReleaseByFreeingColormap)
- XFreeColormap(dpy, stdcmap->colormap);
- else if (stdcmap->killid != None)
- XFreePixmap(dpy, stdcmap->killid);
-
- XFree((char *) stdcmap);
- return (XStandardColormap *) NULL;
- }
- return stdcmap;
-}
-
-/****************************************************************************/
-static Status
-valid_args(XVisualInfo *vinfo, unsigned long red_max, unsigned long green_max,
- unsigned long blue_max, Atom property)
- /*
- * vinfo - specifies visual
- * red_max, green_max, blue_max - specifies alloc
- * property - specifies property name
- */
-{
- unsigned long ncolors; /* number of colors requested */
-
- /* Determine that the number of colors requested is <= map size */
-
- if ((vinfo->c_class == DirectColor) || (vinfo->c_class == TrueColor)) {
- unsigned long mask;
-
- mask = vinfo->red_mask;
- while (!(mask & 1))
- mask >>= 1;
- if (red_max > mask)
- return 0;
- mask = vinfo->green_mask;
- while (!(mask & 1))
- mask >>= 1;
- if (green_max > mask)
- return 0;
- mask = vinfo->blue_mask;
- while (!(mask & 1))
- mask >>= 1;
- if (blue_max > mask)
- return 0;
- } else if (property == XA_RGB_GRAY_MAP) {
- ncolors = red_max + green_max + blue_max + 1;
- if (ncolors > vinfo->colormap_size)
- return 0;
- } else {
- ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
- if (ncolors > vinfo->colormap_size)
- return 0;
- }
-
- /* Determine that the allocation and visual make sense for the property */
-
- switch (property)
- {
- case XA_RGB_DEFAULT_MAP:
- if (red_max == 0 || green_max == 0 || blue_max == 0)
- return 0;
- break;
- case XA_RGB_RED_MAP:
- if (red_max == 0)
- return 0;
- break;
- case XA_RGB_GREEN_MAP:
- if (green_max == 0)
- return 0;
- break;
- case XA_RGB_BLUE_MAP:
- if (blue_max == 0)
- return 0;
- break;
- case XA_RGB_BEST_MAP:
- if (red_max == 0 || green_max == 0 || blue_max == 0)
- return 0;
- break;
- case XA_RGB_GRAY_MAP:
- if (red_max == 0 || blue_max == 0 || green_max == 0)
- return 0;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-
-/* $Xorg: CrCmap.c,v 1.4 2001/02/09 02:03:51 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/CrCmap.c,v 3.7 2001/12/14 19:55:36 dawes Exp $ */
-
-/*
- * Author: Donna Converse, MIT X Consortium
- */
-
-/*
- * CreateCmap.c - given a standard colormap description, make the map.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/StdCmap.h>
-
-/*
- * Prototypes
- */
-/* allocate entire map Read Only */
-static int ROmap(Display*, Colormap, unsigned long[], int, int);
-
-/* allocate a cell, prefer Read Only */
-static Status ROorRWcell(Display*, Colormap, unsigned long[], int,
- XColor*, unsigned long);
-
-/* allocate a cell Read Write */
-static Status RWcell(Display*, Colormap, XColor*, XColor*, unsigned long*);
-
-/* for quicksort */
-static int compare(_Xconst void*, _Xconst void*);
-
-/* find contiguous sequence of cells */
-static Status contiguous(unsigned long[], int, int, unsigned long, int*, int*);
-
-/* frees resources before quitting */
-static void free_cells(Display*, Colormap, unsigned long[], int, int);
-
-/* create a map in a RO visual type */
-static Status readonly_map(Display*, XVisualInfo*, XStandardColormap*);
-
-/* create a map in a RW visual type */
-static Status readwrite_map(Display*, XVisualInfo*, XStandardColormap*);
-
-#define lowbit(x) ((x) & (~(x) + 1))
-#define TRUEMATCH(mult,max,mask) \
- (colormap->max * colormap->mult <= vinfo->mask && \
- lowbit(vinfo->mask) == colormap->mult)
-
-/*
- * To create any one colormap which is described by an XStandardColormap
- * structure, use XmuCreateColormap().
- *
- * Return 0 on failure, non-zero on success.
- * Resources created by this function are not made permanent.
- * No argument error checking is provided. Use at your own risk.
- *
- * All colormaps are created with read only allocations, with the exception
- * of read only allocations of colors in the default map or otherwise
- * which fail to return the expected pixel value, and these are individually
- * defined as read/write allocations. This is done so that all the cells
- * defined in the default map are contiguous, for use in image processing.
- * This typically happens with White and Black in the default map.
- *
- * Colormaps of static visuals are considered to be successfully created if
- * the map of the static visual matches the definition given in the
- * standard colormap structure.
- */
-
-Status
-XmuCreateColormap(Display *dpy, XStandardColormap *colormap)
- /* dpy - specifies the connection under which the map is created
- * colormap - specifies the map to be created, and returns, particularly
- * if the map is created as a subset of the default colormap
- * of the screen, the base_pixel of the map.
- */
-{
- XVisualInfo vinfo_template; /* template visual information */
- XVisualInfo *vinfo; /* matching visual information */
- XVisualInfo *vpointer; /* for freeing the entire list */
- long vinfo_mask; /* specifies the visual mask value */
- int n; /* number of matching visuals */
- int status;
-
- vinfo_template.visualid = colormap->visualid;
- vinfo_mask = VisualIDMask;
- if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
- return 0;
-
- /* A visual id may be valid on multiple screens. Also, there may
- * be multiple visuals with identical visual ids at different depths.
- * If the colormap is the Default Colormap, use the Default Visual.
- * Otherwise, arbitrarily, use the deepest visual.
- */
- vpointer = vinfo;
- if (n > 1)
- {
- register int i;
- register int screen_number;
- Bool def_cmap;
-
- def_cmap = False;
- for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
- if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
- def_cmap = True;
- break;
- }
-
- if (def_cmap) {
- for (i=0; i < n; i++, vinfo++) {
- if (vinfo->visual == DefaultVisual(dpy, screen_number))
- break;
- }
- } else {
- int maxdepth = 0;
- XVisualInfo *v = NULL;
-
- for (i=0; i < n; i++, vinfo++)
- if (vinfo->depth > maxdepth) {
- maxdepth = vinfo->depth;
- v = vinfo;
- }
- vinfo = v;
- }
- }
-
- if (vinfo->c_class == PseudoColor || vinfo->c_class == DirectColor ||
- vinfo->c_class == GrayScale)
- status = readwrite_map(dpy, vinfo, colormap);
- else if (vinfo->c_class == TrueColor)
- status = TRUEMATCH(red_mult, red_max, red_mask) &&
- TRUEMATCH(green_mult, green_max, green_mask) &&
- TRUEMATCH(blue_mult, blue_max, blue_mask);
- else
- status = readonly_map(dpy, vinfo, colormap);
-
- XFree((char *) vpointer);
- return status;
-}
-
-/****************************************************************************/
-static Status
-readwrite_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
-{
- register unsigned long i, n; /* index counters */
- unsigned long ncolors; /* number of colors to be defined */
- int npixels; /* number of pixels allocated R/W */
- int first_index; /* first index of pixels to use */
- int remainder; /* first index of remainder */
- XColor color; /* the definition of a color */
- unsigned long *pixels; /* array of colormap pixels */
- unsigned long delta;
-
-
- /* Determine ncolors, the number of colors to be defined.
- * Insure that 1 < ncolors <= the colormap size.
- */
- if (vinfo->c_class == DirectColor) {
- ncolors = colormap->red_max;
- if (colormap->green_max > ncolors)
- ncolors = colormap->green_max;
- if (colormap->blue_max > ncolors)
- ncolors = colormap->blue_max;
- ncolors++;
- delta = lowbit(vinfo->red_mask) +
- lowbit(vinfo->green_mask) +
- lowbit(vinfo->blue_mask);
- } else {
- ncolors = colormap->red_max * colormap->red_mult +
- colormap->green_max * colormap->green_mult +
- colormap->blue_max * colormap->blue_mult + 1;
- delta = 1;
- }
- if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size) return 0;
-
- /* Allocate Read/Write as much of the colormap as we can possibly get.
- * Then insure that the pixels we were allocated are given in
- * monotonically increasing order, using a quicksort. Next, insure
- * that our allocation includes a subset of contiguous pixels at least
- * as long as the number of colors to be defined. Now we know that
- * these conditions are met:
- * 1) There are no free cells in the colormap.
- * 2) We have a contiguous sequence of pixels, monotonically
- * increasing, of length >= the number of colors requested.
- *
- * One cell at a time, we will free, compute the next color value,
- * then allocate read only. This takes a long time.
- * This is done to insure that cells are allocated read only in the
- * contiguous order which we prefer. If the server has a choice of
- * cells to grant to an allocation request, the server may give us any
- * cell, so that is why we do these slow gymnastics.
- */
-
- if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
- sizeof(unsigned long))) == NULL)
- return 0;
-
- if ((npixels = ROmap(dpy, colormap->colormap, pixels,
- vinfo->colormap_size, ncolors)) == 0) {
- free((char *) pixels);
- return 0;
- }
-
- qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
-
- if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
- {
- /* can't find enough contiguous cells, give up */
- XFreeColors(dpy, colormap->colormap, pixels, npixels,
- (unsigned long) 0);
- free((char *) pixels);
- return 0;
- }
- colormap->base_pixel = pixels[first_index];
-
- /* construct a gray map */
- if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
- colormap->blue_mult == 1)
- for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
- {
- color.pixel = n;
- color.blue = color.green = color.red =
- (unsigned short) ((i * 65535) / (colormap->red_max +
- colormap->green_max +
- colormap->blue_max));
-
- if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
- first_index + i))
- return 0;
- }
-
- /* construct a red ramp map */
- else if (colormap->green_max == 0 && colormap->blue_max == 0)
- for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
- {
- color.pixel = n;
- color.red = (unsigned short) ((i * 65535) / colormap->red_max);
- color.green = color.blue = 0;
-
- if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
- first_index + i))
- return 0;
- }
-
- /* construct a green ramp map */
- else if (colormap->red_max == 0 && colormap->blue_max == 0)
- for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
- {
- color.pixel = n;
- color.green = (unsigned short) ((i * 65535) / colormap->green_max);
- color.red = color.blue = 0;
-
- if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
- first_index + i))
- return 0;
- }
-
- /* construct a blue ramp map */
- else if (colormap->red_max == 0 && colormap->green_max == 0)
- for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
- {
- color.pixel = n;
- color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
- color.red = color.green = 0;
-
- if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
- first_index + i))
- return 0;
- }
-
- /* construct a standard red green blue cube map */
- else
- {
-#define calc(max,mult) (((n / colormap->mult) % \
- (colormap->max + 1)) * 65535) / colormap->max
-
- for (n=0, i=0; i < ncolors; i++, n += delta)
- {
- color.pixel = n + colormap->base_pixel;
- color.red = calc(red_max, red_mult);
- color.green = calc(green_max, green_mult);
- color.blue = calc(blue_max, blue_mult);
- if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
- first_index + i))
- return 0;
- }
-#undef calc
- }
- /* We have a read-only map defined. Now free unused cells,
- * first those occuring before the contiguous sequence begins,
- * then any following the contiguous sequence.
- */
-
- if (first_index)
- XFreeColors(dpy, colormap->colormap, pixels, first_index,
- (unsigned long) 0);
- if (remainder)
- XFreeColors(dpy, colormap->colormap,
- &(pixels[first_index + ncolors]), remainder,
- (unsigned long) 0);
-
- free((char *) pixels);
- return 1;
-}
-
-
-/****************************************************************************/
-static int
-ROmap(Display *dpy, Colormap cmap, unsigned long pixels[], int m, int n)
- /*
- * dpy - the X server connection
- * cmap - specifies colormap ID
- * pixels - returns pixel allocations
- * m - specifies colormap size
- * n - specifies number of colors
- */
-{
- register int p;
-
- /* first try to allocate the entire colormap */
- if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
- (unsigned) 0, pixels, (unsigned) m))
- return m;
-
- /* Allocate all available cells in the colormap, using a binary
- * algorithm to discover how many cells we can allocate in the colormap.
- */
- m--;
- while (n <= m) {
- p = n + ((m - n + 1) / 2);
- if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
- (unsigned) 0, pixels, (unsigned) p)) {
- if (p == m)
- return p;
- else {
- XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
- n = p;
- }
- }
- else
- m = p - 1;
- }
- return 0;
-}
-
-
-/****************************************************************************/
-static Status
-contiguous(unsigned long pixels[], int npixels, int ncolors,
- unsigned long delta, int *first, int *rem)
- /* pixels - specifies allocated pixels
- * npixels - specifies count of alloc'd pixels
- * ncolors - specifies needed sequence length
- * delta - between pixels
- * first - returns first index of sequence
- * rem - returns first index after sequence, or 0, if none follow
- */
-{
- register int i = 1; /* walking index into the pixel array */
- register int count = 1; /* length of sequence discovered so far */
-
- *first = 0;
- if (npixels == ncolors) {
- *rem = 0;
- return 1;
- }
- *rem = npixels - 1;
- while (count < ncolors && ncolors - count <= *rem)
- {
- if (pixels[i-1] + delta == pixels[i])
- count++;
- else {
- count = 1;
- *first = i;
- }
- i++;
- (*rem)--;
- }
- if (count != ncolors)
- return 0;
- return 1;
-}
-
-
-/****************************************************************************/
-static Status
-ROorRWcell(Display *dpy, Colormap cmap, unsigned long pixels[],
- int npixels, XColor *color, unsigned long p)
-{
- unsigned long pixel;
- XColor request;
-
- /* Free the read/write allocation of one cell in the colormap.
- * Request a read only allocation of one cell in the colormap.
- * If the read only allocation cannot be granted, give up, because
- * there must be no free cells in the colormap.
- * If the read only allocation is granted, but gives us a cell which
- * is not the one that we just freed, it is probably the case that
- * we are trying allocate White or Black or some other color which
- * already has a read-only allocation in the map. So we try to
- * allocate the previously freed cell with a read/write allocation,
- * because we want contiguous cells for image processing algorithms.
- */
-
- pixel = color->pixel;
- request.red = color->red;
- request.green = color->green;
- request.blue = color->blue;
-
- XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
- if (! XAllocColor(dpy, cmap, color)
- || (color->pixel != pixel &&
- (!RWcell(dpy, cmap, color, &request, &pixel))))
- {
- free_cells(dpy, cmap, pixels, npixels, (int)p);
- return 0;
- }
- return 1;
-}
-
-
-/****************************************************************************/
-static void
-free_cells(Display *dpy, Colormap cmap, unsigned long pixels[],
- int npixels, int p)
- /*
- * pixels - to be freed
- * npixels - original number allocated
- */
-{
- /* One of the npixels allocated has already been freed.
- * p is the index of the freed pixel.
- * First free the pixels preceeding p, and there are p of them;
- * then free the pixels following p, there are npixels - p - 1 of them.
- */
- XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
- XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
- free((char *) pixels);
-}
-
-
-/****************************************************************************/
-static Status
-RWcell(Display *dpy, Colormap cmap, XColor *color, XColor *request,
- unsigned long *pixel)
-{
- unsigned long n = *pixel;
-
- XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
- if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
- (unsigned) 0, pixel, (unsigned) 1))
- return 0;
- if (*pixel != n)
- {
- XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
- return 0;
- }
- color->pixel = *pixel;
- color->flags = DoRed | DoGreen | DoBlue;
- color->red = request->red;
- color->green = request->green;
- color->blue = request->blue;
- XStoreColors(dpy, cmap, color, 1);
- return 1;
-}
-
-
-/****************************************************************************/
-static int
-compare(_Xconst void *e1, _Xconst void *e2)
-{
- return ((int)(*(long *)e1 - *(long *)e2));
-}
-
-
-/****************************************************************************/
-static Status
-readonly_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
-{
- int i, last_pixel;
- XColor color;
-
- last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
- (colormap->blue_max + 1) + colormap->base_pixel - 1;
-
- for(i=colormap->base_pixel; i <= last_pixel; i++) {
-
- color.pixel = (unsigned long) i;
- color.red = (unsigned short)
- (((i/colormap->red_mult) * 65535) / colormap->red_max);
-
- if (vinfo->c_class == StaticColor) {
- color.green = (unsigned short)
- ((((i/colormap->green_mult) % (colormap->green_max + 1)) *
- 65535) / colormap->green_max);
- color.blue = (unsigned short)
- (((i%colormap->green_mult) * 65535) / colormap->blue_max);
- }
- else /* vinfo->c_class == GrayScale, old style allocation XXX */
- color.green = color.blue = color.red;
-
- XAllocColor(dpy, colormap->colormap, &color);
- if (color.pixel != (unsigned long) i)
- return 0;
+ execvp(cmd2[0], cmd2);
}
- return 1;
-}
-
-
-/* $Xorg: DelCmap.c,v 1.4 2001/02/09 02:03:52 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/DelCmap.c,v 1.7 2001/12/14 19:55:40 dawes Exp $ */
-
-/*
- * Author: Donna Converse, MIT X Consortium
- */
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/StdCmap.h>
-
-int ignoreErrorHandler(Display* d, XErrorEvent* e) { }
-
-/* To remove any standard colormap property, use XmuDeleteStandardColormap().
- * XmuDeleteStandardColormap() will remove the specified property from the
- * specified screen, releasing any resources used by the colormap(s) of the
- * property if possible.
- */
-
-void
-XmuDeleteStandardColormap(Display *dpy, int screen, Atom property)
- /* dpy; - specifies the X server to connect to
- * screen - specifies the screen of the display
- * property - specifies the standard colormap property
- */
-{
- XStandardColormap *stdcmaps, *s;
- int count = 0;
-
- if (XGetRGBColormaps(dpy, RootWindow(dpy, screen), &stdcmaps, &count,
- property))
- {
- for (s=stdcmaps; count > 0; count--, s++) {
- if ((s->killid == ReleaseByFreeingColormap) &&
- (s->colormap != None) &&
- (s->colormap != DefaultColormap(dpy, screen))) {
-
- // UGLY HACK written in by Adam Megacz -- sometimes s->colormap isn't valid, so we do some shuffling
- X11ErrorHandler* oldHandler = XSetErrorHandler(ignoreErrorHandler);
- XSync(dpy, False);
- XFreeColormap(dpy, s->colormap);
- XSync(dpy, False);
- XSetErrorHandler(oldHandler);
- XSync(dpy, False);
-
- } else if (s->killid != None) {
- XKillClient(dpy, s->killid);
- }
- }
- XDeleteProperty(dpy, RootWindow(dpy, screen), property);
- XFree((char *) stdcmaps);
- XSync(dpy, False);
- }
}