X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FPOSIX.cc;fp=src%2Forg%2Fxwt%2Fplat%2FPOSIX.cc;h=203ac8af519ef636799b4317d2fe45036aaba2aa;hb=fa437b8b1bdf01b3bbdabec990b60833cd6c68f0;hp=f34fbdfadeb80b70a52f1aeafbea50c947623cad;hpb=f2406eab74a5cb0e918cda876409b46dd563d63e;p=org.ibex.core.git diff --git a/src/org/xwt/plat/POSIX.cc b/src/org/xwt/plat/POSIX.cc index f34fbdf..203ac8a 100644 --- a/src/org/xwt/plat/POSIX.cc +++ b/src/org/xwt/plat/POSIX.cc @@ -1,16 +1,6 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL] // see below for copyright information on the second portion of this file -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -18,610 +8,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -// 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); ydata + 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); xbits_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; xpm), *((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)); - char buf[len + 1]; - JvGetStringUTFRegion(text, 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::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::_dispose() { - // without this we get phantom messages after the window is gone - org::xwt::plat::POSIX::windowToSurfaceMap->remove(new java::lang::Long(*((Window*)window))); - XDestroyWindow(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, 10, 10, 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 == 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_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; - } - } - - jstring s2 = JvNewStringLatin1(s); - if (e->type == KeyPress) KeyPressed((xbe->state & LockMask) ? s2->toUpperCase() : s2); - if (e->type == KeyRelease) KeyReleased(s2); - - } 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::_getEnv(jstring key) { int len = JvGetStringUTFLength(key); char buf[len + 1]; @@ -653,1735 +39,3 @@ void org::xwt::plat::POSIX::spawnChildProcess(JArray* cmd) { } } -static void dispatchSelectionEvent(XEvent* e) { - 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)); - } -} - -void org::xwt::plat::POSIX::eventThread() { - XEvent e; - while(true) { - XNextEvent(display, &e); - if (e.type == SelectionNotify || e.type == SelectionRequest) { - dispatchSelectionEvent(&e); - } else { - 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", 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* org::xwt::plat::POSIX::listNativeFonts() { - int numfonts; - char** xfonts = XListFonts(display, "-*-*-*-*-normal-*-*-*-*-*-*-*-*-*", 0xFFFFFFFF, &numfonts); - JArray* fonts = (JArray*)JvNewObjectArray(numfonts, &(::java::lang::String::class$), NULL); - java::lang::String** jfonts = (java::lang::String**)(elements(fonts)); - for(int i=0; imax_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 -#include -#include -#include -#include -#include - -/* - * 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 - */ - -#include -#include -#include -#include -#include - -#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 -#include -#include -#include -#include - -#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 -#include -#include -#include -#include - -/* - * 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; - } - 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 -#include -#include - -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); - } -} -