| /* Copyright (C) 2000 Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| // Needed to avoid linking in libstdc++ |
| #ifndef __STL_USE_EXCEPTIONS |
| # include <java/lang/OutOfMemoryError.h> |
| # define __THROW_BAD_ALLOC throw new java::lang::OutOfMemoryError() |
| #endif |
| |
| #include <vector> |
| |
| #include <X11/Xlib.h> |
| |
| #include <gcj/cni.h> |
| #include <java/lang/RuntimeException.h> |
| #include <gnu/gcj/xlib/Display.h> |
| #include <gnu/gcj/xlib/Screen.h> |
| #include <gnu/gcj/xlib/Colormap.h> |
| #include <gnu/gcj/xlib/XColor.h> |
| #include <gnu/gcj/RawData.h> |
| |
| jlong gnu::gcj::xlib::Colormap::allocateColorPixel(XColor* color) |
| { |
| ::Display* dpy = (::Display*) (screen->getDisplay()->display); |
| ::XColor* col = (::XColor*) (color->structure); |
| Status result = XAllocColor(dpy, xid, col); |
| if (result == 0) |
| throw new java::lang::RuntimeException( |
| JvNewStringLatin1("Unable to allocate color pixel.")); |
| |
| return col->pixel; |
| } |
| |
| typedef JArray<gnu::gcj::xlib::XColor*>* xcolorarray; |
| |
| xcolorarray gnu::gcj::xlib::Colormap::getSharedColors() |
| { |
| ::Display* dpy = (::Display*) (screen->getDisplay()->display); |
| unsigned int nCells = CellsOfScreen(ScreenOfDisplay(dpy, screen->screenNumber)); |
| |
| typedef ::XColor xcolor; |
| std::vector<xcolor> colors(nCells); |
| for (unsigned int i=0; i<nCells; i++) |
| colors[i].pixel = i; |
| ::XColor* cols = colors.get_allocator().address(colors.front()); |
| XQueryColors(dpy, xid, cols, |
| nCells); |
| |
| int nShared = 0; |
| for (unsigned int i=0; i<nCells; i++) |
| { |
| ::XColor color = colors[i]; |
| |
| if (!XAllocColor(dpy, xid, &color)) |
| continue; |
| |
| /* FIXME: In some cases this algorithm may identify a free |
| color cell as a shared one. */ |
| if (color.pixel != i) |
| { |
| // Oops, the color wasn't shared. Free it. |
| XFreeColors(dpy, xid, &(color.pixel), 1, 0); |
| colors[i].flags = FLAG_NOT_SHARED; |
| continue; |
| } |
| |
| // FIXME: Shared or free? |
| |
| nShared++; |
| colors[i].flags = FLAG_SHARED; |
| } |
| |
| JArray<XColor*>* shared = newXColorArray(nShared); |
| int si=0; |
| for (unsigned int i=0; i<nCells; i++) |
| { |
| if (colors[i].flags != FLAG_SHARED) |
| continue; |
| |
| XColor* col = elements(shared)[si++]; |
| gnu::gcj::RawData* colorData = col->structure; |
| ::XColor* colStruct = reinterpret_cast<xcolor*>(colorData); |
| *colStruct = colors[i]; |
| } |
| |
| return shared; |
| } |
| |
| xcolorarray gnu::gcj::xlib::Colormap::getXColors() |
| { |
| ::Display* dpy = (::Display*) (screen->getDisplay()->display); |
| unsigned int nCells = |
| CellsOfScreen(ScreenOfDisplay(dpy, screen->screenNumber)); |
| |
| typedef ::XColor xcolor; |
| std::vector<xcolor> colors(nCells); |
| |
| JArray<XColor*>* colArray = newXColorArray(nCells); |
| |
| for (unsigned int i=0; i<nCells; i++) |
| colors[i].pixel = i; |
| |
| XQueryColors(dpy, xid, &(colors.front()), nCells); |
| |
| /* TODO: The current problem with this code is that it relies on |
| (color.pixel == i) as an indicator that the color is |
| shared. However, (color.pixel == i), may also occur simply |
| because color cell i simply was the next free in the list of |
| unallocated color cells. IDEA: run through the list both |
| backwards and forwards, and only pick out the colorcells that |
| have been identified as shared during both passes. Reversing the |
| traversal direction might prevent i from corresponding to the |
| next free colorcell, atleast in one of the passes. */ |
| for (unsigned int i=0; i<nCells; i++) |
| { |
| ::XColor color = colors[i]; |
| |
| char flag = FLAG_NOT_SHARED; |
| if (XAllocColor(dpy, xid, &color)) |
| { |
| if (color.pixel == i) |
| { |
| flag = FLAG_SHARED; |
| } |
| else |
| { |
| // Oops, the color wasn't shared. Free it. |
| XFreeColors(dpy, xid, &(color.pixel), 1, 0); |
| } |
| } |
| |
| // Copy color data into object in array |
| XColor* col = elements(colArray)[i]; |
| gnu::gcj::RawData* colorData = col->structure; |
| ::XColor* colStruct = reinterpret_cast<xcolor*>(colorData); |
| *colStruct = colors[i]; |
| colStruct->flags = flag; |
| } |
| |
| return colArray; |
| } |
| |