// 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 "POSIX.cc"
+
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <X11/keysymdef.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xmu/StdCmap.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <gcj/cni.h>
-#include <signal.h>
#include <java/lang/String.h>
#include <org/xwt/Surface.h>
#include <org/xwt/plat/X11.h>
#include <org/xwt/plat/X11$X11Surface.h>
#include <org/xwt/plat/X11$X11Picture.h>
-#include <org/xwt/plat/X11$X11DoubleBuffer.h>
+#include <org/xwt/plat/X11$X11PixelBuffer.h>
#include <org/xwt/util/Semaphore.h>
#include <org/xwt/Platform.h>
#include <java/lang/Long.h>
#include <java/lang/System.h>
#include <java/io/PrintStream.h>
-#include "POSIX.cc"
-
// 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_supported = 0;
static int shm_pixmaps_supported;
static int screen_num;
static int colorDepth = 0;
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) < (b) ? (b) : (a))
-// X11DoubleBuffer //////////////////////////////////////////////////////////////////////
+// X11PixelBuffer //////////////////////////////////////////////////////////////////////
// ensures that the shared memory is at least size bytes; if not, allocates 3/2 * size
static void ensureShmSize(int size) {
}
}
-void org::xwt::plat::X11$X11DoubleBuffer::fastDrawPicture(org::xwt::Picture* s,
- jint dx1, jint dy1, jint dx2, jint dy2, jint sx1, jint sy1, jint sx2, jint sy2) {
+void org::xwt::plat::X11$X11PixelBuffer::fastDrawPicture(org::xwt::Picture* s,
+ jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
org::xwt::plat::X11$X11Picture* source = (org::xwt::plat::X11$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);
+ XSetClipOrigin(display, (*((GC*)clipped_gc)), dx, dy);
} 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);
+
+ XCopyArea(display,
+ *((Pixmap*)source->doublebuf->pm), (*((Pixmap*)pm)), (*((GC*)clipped_gc)),
+ cx1 - dx, cy1 - dy, cx2 - cx1, cy2 - cy1, cx1, cy1);
}
-void org::xwt::plat::X11$X11DoubleBuffer::slowDrawPicture(org::xwt::Picture* s,
- jint dx1, jint dy1, jint dx2, jint dy2, jint sx1, jint sy1, jint sx2, jint sy2) {
+void org::xwt::plat::X11$X11PixelBuffer::slowDrawPicture(org::xwt::Picture* s,
+ jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2,
+ jint rgb, jboolean alphaOnly) {
org::xwt::plat::X11$X11Picture* source = (org::xwt::plat::X11$X11Picture*)s;
XImage* xi;
// 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);
+ xi = XShmCreateImage(display, visual, colorDepth, ZPixmap, NULL, &shm_info, cx2 - cx1, cy2 - cy1);
ensureShmSize(xi->bytes_per_line * xi->height);
xi->data = shm_info.shmaddr;
- XShmGetImage(display, (*((Pixmap*)pm)), xi, dx1, dy1, AllPlanes);
+ XShmGetImage(display, (*((Pixmap*)pm)), xi, cx1, cy1, 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);
+ xi = XGetImage(display, (*((Pixmap*)pm)), cx1, cy1, cx2 - cx1, cy2 - cy1, AllPlanes, ZPixmap);
}
int* sourcedata = (int*)elements(source->data);
- for(int y=max(dy1, clipy); y<min(dy2, clipy + cliph); y++) {
-
+ for(int y=cy1; y < cy2; 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);
+ (shared_pixmap ? cx1 * (xi->bits_per_pixel / 8) : - 1 * cy1 * 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;
-
+ for(int x=cx1; x < cx2; x++, current_pixel += xi->bits_per_pixel / 8) {
+ int source_x = x - dx;
+ int source_y = y - dy;
+
+ // FEATURE: be smarter here; can we do something better for the alphaonly case?
int sourcepixel = sourcedata[source_x + source_y * source->getWidth()];
int alpha = (sourcepixel & 0xFF000000) >> 24;
+ if (alphaOnly) sourcepixel = rgb;
int source_red = (sourcepixel & 0x00FF0000) >> 16;
int source_green = (sourcepixel & 0x0000FF00) >> 8;
int source_blue = (sourcepixel & 0x000000FF);
int red = 0, blue = 0, green = 0;
-
+ int targetpixel;
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 15:
+ case 16: targetpixel = (int)(*((uint16_t*)current_pixel)); break;
+
+ // FIXME assumes endianness...
+ 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;
+ 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 = (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;
-
+ 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);
+ uint32_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 16: *((uint16_t*)current_pixel) = (uint16_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);
+ uint64_t dest = ((uint64_t)destpixel) << (8 * offset);
+ uint64_t mask = ((uint64_t)0xffffff) << (8 * offset);
+ uint64_t* base = (uint64_t*)(current_pixel - offset);
*base = (*base & ~mask) | dest;
break;
}
- case 32: *((u_int32_t*)current_pixel) = destpixel; break;
+ case 32: *((uint32_t*)current_pixel) = destpixel; break;
default: org::xwt::Platform::criticalAbort(JvNewStringLatin1("ERROR: bpp not a multiple of 8!"));
}
}
// 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);
+ XShmPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, cx1, cy1, cx2 - cx1, cy2 - cy1, False);
XDestroyImage(xi);
} else {
- XPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, dx1, dy1, dx2 - dx1, dy2 - dy1);
+ XPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, cx1, cy1, cx2 - cx1, cy2 - cy1);
}
}
-void org::xwt::plat::X11$X11DoubleBuffer::finalize() {
+void org::xwt::plat::X11$X11PixelBuffer::finalize() {
if (shared_pixmap) {
XShmSegmentInfo *sinfo = (XShmSegmentInfo*)shm_segment;
XShmDetach(display, sinfo);
XFreeGC(display, *((GC*)clipped_gc));
}
-void org::xwt::plat::X11$X11DoubleBuffer::natInit() {
+void org::xwt::plat::X11$X11PixelBuffer::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
XChangeGC(display, (*((GC*)clipped_gc)), GCGraphicsExposures, &vm);
}
-void org::xwt::plat::X11$X11DoubleBuffer::createStipple(org::xwt::plat::X11$X11Picture* xpi) {
+void org::xwt::plat::X11$X11PixelBuffer::createStipple(org::xwt::plat::X11$X11Picture* xpi) {
stipple = (gnu::gcj::RawData*)malloc(sizeof(Pixmap));
(*((Pixmap*)stipple)) = XCreatePixmap(display, RootWindow(display, screen_num), width, height, 1);
XPutImage(display, (*((Pixmap*)stipple)), stipple_gc, &xi, 0, 0, 0, 0, width, height);
}
-void org::xwt::plat::X11$X11Surface::blit(org::xwt::DoubleBuffer* db, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
- org::xwt::plat::X11$X11DoubleBuffer *xdb = (org::xwt::plat::X11$X11DoubleBuffer*)db;
+void org::xwt::plat::X11$X11Surface::blit(org::xwt::PixelBuffer* db, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
+ org::xwt::plat::X11$X11PixelBuffer *xdb = (org::xwt::plat::X11$X11PixelBuffer*)db;
XCopyArea(display, *((Pixmap*)xdb->pm), *((Window*)window), *((GC*)gc), sx, sy, dx2 - dx, dy2 - dy, dx, dy);
XFlush(display);
}
-void org::xwt::plat::X11$X11DoubleBuffer::fillRect (jint x, jint y, jint x2, jint y2, jint argb) {
+void org::xwt::plat::X11$X11PixelBuffer::fillRect (jint x, jint y, jint x2, jint y2, jint argb) {
jint w = x2 - x;
jint h = y2 - y;
XFillRectangle(display, (*((Pixmap*)pm)), (*((GC*)gc)), x, y, w, h);
}
-void org::xwt::plat::X11$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::X11::fontToXFont(font))->fid;
-
- // Draw the text
- XDrawText(display, (*((Pixmap*)pm)), (*((GC*)clipped_gc)), x, y, &textitem, 1);
-}
-
// X11Surface //////////////////////////////////////////////////////////////////////
void org::xwt::plat::X11$X11Surface::setIcon(org::xwt::Picture* pic) {
org::xwt::plat::X11$X11Picture* p = ((org::xwt::plat::X11$X11Picture*)pic);
- org::xwt::plat::X11$X11DoubleBuffer* old_dbuf = p->doublebuf;
- p->buildDoubleBuffer(1);
+ org::xwt::plat::X11$X11PixelBuffer* old_dbuf = p->doublebuf;
+ p->buildPixelBuffer(1);
XWMHints xwmh;
memset(&xwmh, 0, sizeof(XWMHints));
xwmh.flags |= IconPixmapHint | IconMaskHint;
XSetWMNormalHints(display, (*((Window*)window)), &hints);
}
-void org::xwt::plat::X11$X11Surface::setSize (jint width, jint height) {
+void org::xwt::plat::X11$X11Surface::_setSize (jint width, jint height) {
if (width <= 0 || height <= 0) return;
XResizeWindow(display, (*((Window*)window)), width, height);
XFlush(display);
}
-void org::xwt::plat::X11$X11Surface::setLocation (jint x, jint y) { XMoveWindow(display, (*((Window*)window)), x, y); }
+void org::xwt::plat::X11$X11Surface::setLocation () { XMoveWindow(display, (*((Window*)window)), root->x, root->y); }
void org::xwt::plat::X11$X11Surface::toFront() { XRaiseWindow(display, (*((Window*)window))); }
void org::xwt::plat::X11$X11Surface::toBack() { XLowerWindow(display, (*((Window*)window))); }
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);
+ if (xce->width != root->width || xce->height != root->height) SizeChange(xce->width, xce->height);
+ if (x_out != root->x || y_out != root->y) PosChange(x_out, y_out);
}
}
if (!XInitThreads())
org::xwt::Platform::criticalAbort(JvNewStringLatin1("Your X11 libraries do not support multithreaded programs"));
- display = XOpenDisplay(NULL);
+ char* DISPLAY = getenv("DISPLAY");
+ if (DISPLAY == NULL || strlen(DISPLAY) == 0) DISPLAY = ":0.0";
+ display = XOpenDisplay(DISPLAY);
+
+ if (display == 0)
+ org::xwt::Platform::criticalAbort(JvNewStringLatin1("Unable to connect to X11 display server"));
+
screen_num = XDefaultScreen(display);
colorDepth = (jint)(DefaultDepth(((Display*)display), 0));
shm_info.shmaddr = NULL;
- shm_supported = (XShmQueryExtension(display) == True);
+ // FIXME: SHM doesn't work on Darwin
+ //shm_supported = (XShmQueryExtension(display) == True);
if (shm_supported) {
X11ErrorHandler* oldHandler = XSetErrorHandler(errorHandler);
XShmSegmentInfo sinfo;
visual = DefaultVisual(display, screen_num);
char buf[255];
sprintf(buf, "X11 DISPLAY: %s", XDisplayString(display));
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
+ org::xwt::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
sprintf(buf, "X11 SHM: %s", shm_supported ? "enabled" : "disabled");
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
+ org::xwt::util::Log::info(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));
+ org::xwt::util::Log::info(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)
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));
+ org::xwt::util::Log::info(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));
+ org::xwt::util::Log::info(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));
+ org::xwt::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
sprintf(buf, " base_pixel: %x", colormap_info->base_pixel);
- org::xwt::util::Log::log(this->getClass(), JvNewStringLatin1(buf));
+ org::xwt::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
}
-JArray<java::lang::String*>* org::xwt::plat::X11::listNativeFonts() {
- int numfonts;
- char** xfonts = XListFonts(display, "-*-*-*-*-normal-*-*-*-*-*-*-*-*-*", 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::X11::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::X11::_getMaxAscent(::java::lang::String* font) { return ((XFontStruct*)fontToXFont(font))->max_bounds.ascent; }
-jint org::xwt::plat::X11::_getMaxDescent(::java::lang::String* font) { return ((XFontStruct*)fontToXFont(font))->max_bounds.descent; }
-jint org::xwt::plat::X11::_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);
-}
//////////////////////////////////////////////////////////////////////////////