148 lines
4.1 KiB
C++
148 lines
4.1 KiB
C++
/* 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;
|
|
}
|
|
|