j2se/src/solaris/native/sun/awt/awt_GraphicsEnv.c
changeset 10: ce9dde984c21
parent 0:a4ed3fb96592
manifest: ce9dde984c21
author: xiomara
date: Fri Oct 12 20:19:08 2007 +0000 (8 months ago)
permissions: -rw-r--r--
[svn] Load openjdk/jdk7/b22 into jdk/trunk.
        1 /*
        2  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
        3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        4  *
        5  * This code is free software; you can redistribute it and/or modify it
        6  * under the terms of the GNU General Public License version 2 only, as
        7  * published by the Free Software Foundation.  Sun designates this
        8  * particular file as subject to the "Classpath" exception as provided
        9  * by Sun in the LICENSE file that accompanied this code.
       10  *
       11  * This code is distributed in the hope that it will be useful, but WITHOUT
       12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       14  * version 2 for more details (a copy is included in the LICENSE file that
       15  * accompanied this code).
       16  *
       17  * You should have received a copy of the GNU General Public License version
       18  * 2 along with this work; if not, write to the Free Software Foundation,
       19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       20  *
       21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       22  * CA 95054 USA or visit www.sun.com if you need additional information or
       23  * have any questions.
       24  */
       25 
       26 #include "awt_p.h"
       27 #include "awt.h"
       28 #include "color.h"
       29 #include <java_awt_DisplayMode.h>
       30 #include <sun_awt_X11GraphicsEnvironment.h>
       31 #include <sun_awt_X11GraphicsDevice.h>
       32 #include <sun_awt_X11GraphicsConfig.h>
       33 #ifndef HEADLESS
       34 #include <X11/extensions/Xdbe.h>
       35 #include <X11/XKBlib.h>
       36 #include "Xrandr.h"
       37 #include "GLXGraphicsConfig.h"
       38 #endif /* !HEADLESS */
       39 
       40 #include <jni.h>
       41 #include <jni_util.h>
       42 #include <jvm.h>
       43 #include <jlong.h>
       44 
       45 #include <stdlib.h>
       46 
       47 #include "awt_GraphicsEnv.h"
       48 #include "awt_Window.h"
       49 #include "awt_util.h"
       50 #include "gdefs.h"
       51 #include <dlfcn.h>
       52 #include "Trace.h"
       53 
       54 #ifdef NETSCAPE
       55 #include <signal.h>
       56 extern int awt_init_xt;
       57 #endif
       58 
       59 #ifndef HEADLESS
       60 
       61 int awt_numScreens;     /* Xinerama-aware number of screens */
       62 
       63 AwtScreenDataPtr x11Screens;
       64 
       65 /*
       66  * Set in initDisplay() to indicate whether we should attempt to initialize
       67  * GLX for the default configuration.
       68  */
       69 static jboolean glxRequested = JNI_FALSE;
       70 
       71 #endif /* !HEADLESS */
       72 
       73 #ifdef HEADLESS
       74 #define Display void
       75 #endif /* HEADLESS */
       76 
       77 Display *awt_display;
       78 
       79 jclass tkClass = NULL;
       80 jmethodID awtLockMID = NULL;
       81 jmethodID awtUnlockMID = NULL;
       82 jmethodID awtWaitMID = NULL;
       83 jmethodID awtNotifyMID = NULL;
       84 jmethodID awtNotifyAllMID = NULL;
       85 jboolean awtLockInited = JNI_FALSE;
       86 
       87 /** Convenience macro for loading the lock-related method IDs. */
       88 #define GET_STATIC_METHOD(klass, method_id, method_name, method_sig) \
       89     do { \
       90         method_id = (*env)->GetStaticMethodID(env, klass, \
       91                                               method_name, method_sig); \
       92         if (method_id == NULL) return NULL; \
       93     } while (0)
       94 
       95 struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
       96 struct X11GraphicsDeviceIDs x11GraphicsDeviceIDs;
       97 extern struct WindowIDs mWindowIDs;
       98 extern struct MWindowPeerIDs mWindowPeerIDs;
       99 
      100 #ifndef HEADLESS
      101 int awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata);
      102 #endif /* HEADLESS */
      103 
      104 static char *x11GraphicsConfigClassName = "sun/awt/X11GraphicsConfig";
      105 
      106 /* AWT and Xinerama
      107  *
      108  * As of fix 4356756, AWT is Xinerama-aware.  X11GraphicsDevices are created for
      109  * each screen of a Xinerama setup, though X11 itself still only sees a single
      110  * display.
      111  * In many places where we talk to X11, a xinawareScreen variable is used to
      112  * pass the correct Display value, depending on the circumstances (a single
      113  * X display, multiple X displays, or a single X display with multiple
      114  * Xinerama screens).
      115  *
      116  * Solaris and Linux differ in the functions used to access Xinerama-related
      117  * data.  This is in part because at this time, the X consortium has not
      118  * finalized the "official" Xinerama API.  Once this spec is available, and
      119  * both OSes are conformant, one code base should be sufficient for Xinerama
      120  * operation on both OSes.  Until then, some of the Xinerama-related code
      121  * is ifdef'd appropriately.  -bchristi, 7/12/01
      122  */
      123 
      124 #define MAXFRAMEBUFFERS 16
      125 #ifdef __linux__
      126 typedef struct {
      127    int   screen_number;
      128    short x_org;
      129    short y_org;
      130    short width;
      131    short height;
      132 } XineramaScreenInfo;
      133 
      134 typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);
      135 
      136 #else /* SOLARIS */
      137 typedef Status XineramaGetInfoFunc(Display* display, int screen_number,
      138          XRectangle* framebuffer_rects, unsigned char* framebuffer_hints,
      139          int* num_framebuffers);
      140 typedef Status XineramaGetCenterHintFunc(Display* display, int screen_number,
      141                                          int* x, int* y);
      142 
      143 XineramaGetCenterHintFunc* XineramaSolarisCenterFunc = NULL;
      144 #endif
      145 
      146 Bool usingXinerama = False;
      147 XRectangle fbrects[MAXFRAMEBUFFERS];
      148 
      149 JNIEXPORT void JNICALL
      150 Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls)
      151 {
      152     x11GraphicsConfigIDs.aData = NULL;
      153     x11GraphicsConfigIDs.bitsPerPixel = NULL;
      154     x11GraphicsConfigIDs.screen = NULL;
      155 
      156     x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J");
      157     x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I");
      158     x11GraphicsConfigIDs.screen = (*env)->GetFieldID (env, cls, "screen", "Lsun/awt/X11GraphicsDevice;");
      159 
      160     if (x11GraphicsConfigIDs.aData == NULL || 
      161 	    x11GraphicsConfigIDs.bitsPerPixel == NULL ||
      162         x11GraphicsConfigIDs.screen == NULL) {
      163 
      164 	    JNU_ThrowNoSuchFieldError(env, "Can't find a field");
      165 	    return;
      166 	}
      167 } 
      168 
      169 JNIEXPORT void JNICALL
      170 Java_sun_awt_X11GraphicsDevice_initIDs (JNIEnv *env, jclass cls)
      171 {
      172     x11GraphicsDeviceIDs.screen = NULL;
      173     x11GraphicsDeviceIDs.screen = (*env)->GetFieldID (env, cls, "screen", "I");
      174     DASSERT(x11GraphicsDeviceIDs.screen);
      175 }
      176 
      177 #ifndef HEADLESS
      178 /*
      179  * error handlers
      180  */
      181 
      182 int
      183 xerror_handler(Display * disp, XErrorEvent * err)
      184 {
      185 /* #ifdef DEBUG */
      186     char msg[128];
      187     char buf[128];
      188     char *ev = getenv("NOISY_AWT");
      189 
      190     if (!ev || !ev[0])
      191         return 0;
      192     XGetErrorText(disp, err->error_code, msg, sizeof(msg));
      193     jio_fprintf(stderr, "Xerror %s, XID %x, ser# %d\n", msg, err->resourceid, err->serial);
      194     jio_snprintf(buf, sizeof(buf), "%d", err->request_code);
      195     XGetErrorDatabaseText(disp, "XRequest", buf, "Unknown", msg, sizeof(msg));
      196     jio_fprintf(stderr, "Major opcode %d (%s)\n", err->request_code, msg);
      197     if (err->request_code > 128) {
      198         jio_fprintf(stderr, "Minor opcode %d\n", err->minor_code);
      199     }
      200     if (awtLockInited) {
      201         /*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", msg); */
      202     }
      203     if (strcasecmp(ev, "abort") == 0) {
      204         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
      205 
      206         (*env)->FatalError(env, "xerror_handler abort");
      207     }
      208 /* #endif */
      209     return 0;
      210 }
      211 
      212 static int 
      213 xioerror_handler(Display * disp)
      214 {
      215     if (awtLockInited) {
      216         if (errno == EPIPE) {
      217             jio_fprintf(stderr, "X connection to %s host broken (explicit kill or server shutdown)\n", XDisplayName(NULL));
      218         }
      219         /*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", "I/O error"); */
      220     }
      221     return 0;
      222 }
      223 
      224 static AwtGraphicsConfigDataPtr 
      225 findWithTemplate(XVisualInfo *vinfo,
      226 		 long mask)
      227 {
      228 
      229     XVisualInfo *visualList;
      230     XColor color;
      231     AwtGraphicsConfigDataPtr defaultConfig;
      232     int visualsMatched, i;
      233     
      234     visualList = XGetVisualInfo(awt_display,
      235 				mask, vinfo, &visualsMatched);
      236     if (visualList) {
      237 	defaultConfig = ZALLOC(_AwtGraphicsConfigData);
      238 	for (i = 0; i < visualsMatched; i++) {
      239 	    memcpy(&defaultConfig->awt_visInfo, &visualList[i], sizeof(XVisualInfo));
      240 	    defaultConfig->awt_depth = visualList[i].depth;
      241 
      242 	    /* we can't use awtJNI_CreateColorData here, because it'll pull,
      243 	       SystemColor, which in turn will cause toolkit to be reinitialized */
      244 	    if (awtCreateX11Colormap(defaultConfig)) {
      245 		/* Allocate white and black pixels for this visual */
      246 		color.flags = DoRed | DoGreen | DoBlue;
      247 		color.red = color.green = color.blue = 0x0000;
      248 		XAllocColor(awt_display, defaultConfig->awt_cmap, &color);
      249 		x11Screens[visualList[i].screen].blackpixel = color.pixel;
      250 		color.flags = DoRed | DoGreen | DoBlue;
      251 		color.red = color.green = color.blue = 0xffff;
      252 		XAllocColor(awt_display, defaultConfig->awt_cmap, &color);
      253 		x11Screens[visualList[i].screen].whitepixel = color.pixel;
      254 
      255 		XFree(visualList);
      256 		return defaultConfig;
      257 	    }
      258 	}
      259 	XFree(visualList);
      260 	free((void *)defaultConfig);
      261     }
      262     return NULL;
      263 }
      264 
      265 /* default config is based on X11 screen.  All Xinerama screens of that X11
      266    screen will have the same default config */
      267 /* Need more notes about which fields of the structure are based on the X
      268    screen, and which are based on the Xinerama screen */
      269 static AwtGraphicsConfigDataPtr
      270 makeDefaultConfig(JNIEnv *env, int screen) {
      271 
      272     AwtGraphicsConfigDataPtr defaultConfig;
      273     int xinawareScreen = 0;
      274     VisualID forcedVisualID, defaultVisualID;
      275     char *forcedVisualStr;
      276     XVisualInfo vinfo;
      277     long mask;
      278 
      279     xinawareScreen = usingXinerama ? 0 : screen;
      280     defaultVisualID = 
      281 	XVisualIDFromVisual(DefaultVisual(awt_display, xinawareScreen));
      282 
      283     memset(&vinfo, 0, sizeof(XVisualInfo));
      284     vinfo.screen = xinawareScreen;
      285 
      286     if ((forcedVisualStr = getenv("FORCEDEFVIS"))) {
      287 	mask = VisualIDMask | VisualScreenMask;
      288 	if (sscanf(forcedVisualStr, "%x", &forcedVisualID) > 0 &&
      289 	    forcedVisualID > 0) 
      290 	{
      291 	    vinfo.visualid = forcedVisualID;
      292 	} else {
      293 	    vinfo.visualid = defaultVisualID;
      294 	}
      295     } else {
      296         VisualID bestGLXVisualID;
      297         if (glxRequested &&
      298             (bestGLXVisualID = GLXGC_FindBestVisual(env, xinawareScreen)) > 0)
      299         {
      300             /* we've found the best visual for use with GLX, so use it */
      301             vinfo.visualid = bestGLXVisualID;
      302             mask = VisualIDMask | VisualScreenMask;
      303         } else {
      304             /* otherwise, continue looking for the best X11 visual */
      305             vinfo.depth = 24;
      306             vinfo.class = TrueColor;
      307             mask = VisualDepthMask | VisualScreenMask | VisualClassMask;
      308         }
      309     }
      310 
      311     /* try the best, or forced visual */
      312     defaultConfig = findWithTemplate(&vinfo, mask);
      313     if (defaultConfig) {
      314 	return defaultConfig;
      315     }
      316 
      317     /* try the default visual */
      318     vinfo.visualid = defaultVisualID;
      319     mask = VisualIDMask | VisualScreenMask;
      320     defaultConfig = findWithTemplate(&vinfo, mask);
      321     if (defaultConfig) {
      322         return defaultConfig;
      323     }
      324 
      325     /* try any TrueColor */
      326     vinfo.class = TrueColor;
      327     mask = VisualScreenMask | VisualClassMask;
      328     defaultConfig = findWithTemplate(&vinfo, mask);
      329     if (defaultConfig) {
      330 	return defaultConfig;
      331     }
      332 
      333     /* try 8-bit PseudoColor */
      334     vinfo.depth = 8;
      335     vinfo.class = PseudoColor;
      336     mask = VisualDepthMask | VisualScreenMask | VisualClassMask;
      337     defaultConfig = findWithTemplate(&vinfo, mask);
      338     if (defaultConfig) {
      339 	return defaultConfig;
      340     }
      341 
      342     /* try any 8-bit */
      343     vinfo.depth = 8;
      344     mask = VisualDepthMask | VisualScreenMask;
      345     defaultConfig = findWithTemplate(&vinfo, mask);
      346     if (defaultConfig) {
      347 	return defaultConfig;
      348     }
      349 
      350     /* we tried everything, give up */
      351     JNU_ThrowInternalError(env, "Can't find supported visual");
      352     XCloseDisplay(awt_display);
      353     awt_display = NULL;
      354     return NULL;
      355 }
      356 
      357 static void
      358 getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
      359 
      360     int i;
      361     int n8p=0, n12p=0, n8s=0, n8gs=0, n8sg=0, n1sg=0, nTrue=0;
      362     int nConfig;
      363     XVisualInfo *pVI8p, *pVI12p, *pVI8s, *pVITrue, *pVI8gs,
      364                 *pVI8sg, *pVI1sg = NULL, viTmp;
      365     AwtGraphicsConfigDataPtr *graphicsConfigs;
      366     AwtGraphicsConfigDataPtr defaultConfig;
      367     int ind;
      368     char errmsg[128];
      369     int xinawareScreen;
      370 
      371     if (usingXinerama) {
      372         xinawareScreen = 0;
      373     }
      374     else {
      375         xinawareScreen = screen;
      376     }
      377 
      378     AWT_LOCK ();
      379 
      380     viTmp.screen = xinawareScreen;
      381     
      382     viTmp.depth = 8;
      383     viTmp.class = PseudoColor;
      384     viTmp.colormap_size = 256;
      385     pVI8p = XGetVisualInfo (awt_display, 
      386                             VisualDepthMask | VisualClassMask |
      387                             VisualColormapSizeMask | VisualScreenMask, 
      388                             &viTmp, &n8p);
      389 
      390     viTmp.depth = 12;
      391     viTmp.class = PseudoColor;
      392     viTmp.colormap_size = 4096;
      393     pVI12p = XGetVisualInfo (awt_display, 
      394 			     VisualDepthMask | VisualClassMask |
      395 			     VisualColormapSizeMask | VisualScreenMask, 
      396 			     &viTmp, &n12p);
      397     
      398     viTmp.class = TrueColor;
      399     pVITrue = XGetVisualInfo (awt_display,
      400                               VisualClassMask |
      401                               VisualScreenMask,
      402                               &viTmp, &nTrue);
      403     
      404     viTmp.depth = 8;
      405     viTmp.class = StaticColor;
      406     pVI8s = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask |
      407                             VisualScreenMask, &viTmp, &n8s);
      408 
      409     viTmp.depth = 8;
      410     viTmp.class = GrayScale;
      411     viTmp.colormap_size = 256;
      412     pVI8gs = XGetVisualInfo (awt_display, 
      413                              VisualDepthMask | VisualClassMask |
      414                              VisualColormapSizeMask | VisualScreenMask,
      415                              &viTmp, &n8gs);
      416     viTmp.depth = 8;
      417     viTmp.class = StaticGray;
      418     viTmp.colormap_size = 256;
      419     pVI8sg = XGetVisualInfo (awt_display, 
      420                              VisualDepthMask | VisualClassMask |
      421                              VisualColormapSizeMask | VisualScreenMask,
      422                              &viTmp, &n8sg);
      423 
      424 /* REMIND.. remove when we have support for the color classes below */
      425 /*     viTmp.depth = 1; */
      426 /*     viTmp.class = StaticGray; */
      427 /*     pVI1sg = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask, */
      428 /*                              viTmp, &n1sg); */
      429     
      430     nConfig = n8p + n12p + n8s + n8gs + n8sg  + n1sg + nTrue + 1;
      431     graphicsConfigs = (AwtGraphicsConfigDataPtr *)
      432         calloc(nConfig, sizeof(AwtGraphicsConfigDataPtr));
      433     if (graphicsConfigs == NULL) {
      434 	JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),
      435                                   NULL);
      436         AWT_UNLOCK();
      437         return;
      438     }
      439 
      440     if (screenDataPtr->defaultConfig == NULL) {
      441         /*
      442          * After a display change event, the default config field will have
      443          * been reset, so we need to recreate the default config here.
      444          */
      445         screenDataPtr->defaultConfig = makeDefaultConfig(env, screen);
      446     }
      447 
      448     defaultConfig = screenDataPtr->defaultConfig;
      449     graphicsConfigs[0] = defaultConfig;
      450     nConfig = 1; /* reserve index 0 for default config */
      451 
      452     for (i = 0; i < nTrue; i++) {
      453         if (XVisualIDFromVisual(pVITrue[i].visual) ==
      454             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) ||
      455 	    pVITrue[i].depth == 12) {
      456 	    /* Skip the non-supported 12-bit TrueColor visual */
      457             continue;
      458         } else {
      459             ind = nConfig++;
      460         }
      461         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      462         graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
      463         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
      464                 sizeof (XVisualInfo));
      465     }
      466  
      467     for (i = 0; i < n8p; i++) {
      468         if (XVisualIDFromVisual(pVI8p[i].visual) ==
      469             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      470             continue;
      471         } else {
      472             ind = nConfig++;
      473         }
      474         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      475         graphicsConfigs [ind]->awt_depth = pVI8p [i].depth;
      476         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8p [i],
      477                 sizeof (XVisualInfo));
      478     }
      479        
      480     for (i = 0; i < n12p; i++) {
      481         if (XVisualIDFromVisual(pVI12p[i].visual) ==
      482             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      483             continue;
      484         } else {
      485             ind = nConfig++;
      486         }
      487         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      488         graphicsConfigs [ind]->awt_depth = pVI12p [i].depth;
      489         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI12p [i],
      490                 sizeof (XVisualInfo));
      491     }
      492        
      493     for (i = 0; i < n8s; i++) {
      494         if (XVisualIDFromVisual(pVI8s[i].visual) ==
      495             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      496             continue;
      497         } else {
      498             ind = nConfig++;
      499         }
      500         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      501         graphicsConfigs [ind]->awt_depth = pVI8s [i].depth;
      502         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8s [i],
      503                 sizeof (XVisualInfo));
      504     }
      505 
      506     for (i = 0; i < n8gs; i++) {
      507         if (XVisualIDFromVisual(pVI8gs[i].visual) ==
      508             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      509             continue;
      510         } else {
      511             ind = nConfig++;
      512         }
      513         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      514         graphicsConfigs [ind]->awt_depth = pVI8gs [i].depth;
      515         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8gs [i],
      516                 sizeof (XVisualInfo));
      517     }
      518 
      519     for (i = 0; i < n8sg; i++) {
      520         if (XVisualIDFromVisual(pVI8sg[i].visual) ==
      521             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      522             continue;
      523         } else {
      524             ind = nConfig++;
      525         }
      526         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      527         graphicsConfigs [ind]->awt_depth = pVI8sg [i].depth;
      528         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8sg [i],
      529                 sizeof (XVisualInfo));
      530     }
      531 
      532     for (i = 0; i < n1sg; i++) {
      533         if (XVisualIDFromVisual(pVI1sg[i].visual) ==
      534             XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {
      535             continue;
      536         } else {
      537             ind = nConfig++;
      538         }
      539         graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
      540         graphicsConfigs [ind]->awt_depth = pVI1sg [i].depth;
      541         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI1sg [i],
      542                 sizeof (XVisualInfo));
      543     }
      544 
      545     if (n8p != 0)
      546        XFree (pVI8p);
      547     if (n12p != 0)
      548        XFree (pVI12p);
      549     if (n8s != 0)
      550        XFree (pVI8s);
      551     if (n8gs != 0)
      552        XFree (pVI8gs);
      553     if (n8sg != 0)
      554        XFree (pVI8sg);
      555     if (n1sg != 0)
      556        XFree (pVI1sg);
      557 
      558     screenDataPtr->numConfigs = nConfig;
      559     screenDataPtr->configs = graphicsConfigs;
      560 
      561     AWT_UNLOCK ();
      562 }
      563 
      564 /*
      565  * Determing if this top-level has been moved onto another Xinerama screen.
      566  * Called from awt_TopLevel.c
      567  *
      568  * ASSUME: wdata != null
      569  */
      570 #ifndef HEADLESS
      571 void checkNewXineramaScreen(JNIEnv* env, jobject peer, struct FrameData* wdata,
      572                             int32_t newX, int32_t newY, 
      573                             int32_t newWidth, int32_t newHeight) {
      574     int i;
      575     int amt;
      576     int totAmt = 0;
      577     int largestAmt = 0;
      578     int largestAmtScr = 0;
      579 
      580     int horiz;
      581     int vert;
      582 
      583     if (!usingXinerama) { return; }
      584 
      585     totAmt = newWidth * newHeight;
      586 
      587     /* assert that peer implements WindowPeer */
      588     DASSERT(JNU_IsInstanceOfByName(env, peer, "java/awt/peer/WindowPeer"));
      589 
      590     DTRACE_PRINTLN4("checkNewXineramaScreen() x=%i y=%i w=%i h=%i\n",newX, newY, newWidth, newHeight);
      591 
      592     /* decide which screen we're on
      593      * if we're spanning, figure out which screen we're most on
      594      */
      595     for (i = 0; i < awt_numScreens; i++) {
      596         if (INTERSECTS(newX, newX + newWidth, newY, newY + newHeight,
      597                        fbrects[i].x, fbrects[i].x + fbrects[i].width,
      598                        fbrects[i].y, fbrects[i].y + fbrects[i].height)) {
      599 
      600             /* calc how much of window is on this screen */
      601             horiz = MIN(newX + newWidth, fbrects[i].x + fbrects[i].width) - 
      602                     MAX(newX, fbrects[i].x);
      603             vert =  MIN(newY + newHeight, fbrects[i].y + fbrects[i].height) - 
      604                     MAX(newY, fbrects[i].y);
      605             DASSERT(horiz > 0);
      606             DASSERT(vert > 0);
      607 
      608             amt = horiz * vert;
      609             if (amt == totAmt) {
      610                 /* completely on this screen - done! */
      611                 largestAmtScr = i;
      612                 break;
      613             }
      614             if (amt > largestAmt) {
      615                 largestAmt = amt;
      616                 largestAmtScr = i;
      617             }
      618         }
      619     }
      620 
      621 #ifndef XAWT
      622     /* check if we're on a new screen */
      623     if (largestAmtScr != wdata->screenNum) {
      624         wdata->screenNum = largestAmtScr;
      625         /* update peer, target Comp */
      626         (*env)->CallVoidMethod(env, peer,
      627                                mWindowPeerIDs.draggedToScreenMID, largestAmtScr);
      628     }
      629 #endif /* XAWT */
      630 }
      631 #endif /* HEADLESS */
      632 
      633 #ifndef HEADLESS
      634 #ifdef __linux__
      635 static void xinerama_init_linux()
      636 {
      637     void* libHandle = 0;
      638     char* XineramaLibName= "libXinerama.so.1";
      639     int32_t locNumScr = 0;
      640     XineramaScreenInfo *xinInfo;
      641     char* XineramaQueryScreensName = "XineramaQueryScreens";
      642     XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
      643 
      644     /* load library */
      645     libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL);
      646     if (libHandle != 0) {
      647         XineramaQueryScreens = (XineramaQueryScreensFunc*)
      648             dlsym(libHandle, XineramaQueryScreensName);
      649 
      650         if (XineramaQueryScreens != NULL) {
      651             DTRACE_PRINTLN("calling XineramaQueryScreens func on Linux");
      652             xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
      653             if (xinInfo != NULL) {
      654                 int32_t idx;
      655                 DTRACE_PRINTLN("Enabling Xinerama support");
      656                 usingXinerama = True;
      657                 /* set global number of screens */
      658                 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
      659                 awt_numScreens = locNumScr;
      660 
      661                 /* stuff values into fbrects */
      662                 for (idx = 0; idx < awt_numScreens; idx++) {
      663                     DASSERT(xinInfo[idx].screen_number == idx);
      664 
      665                     fbrects[idx].width = xinInfo[idx].width;
      666                     fbrects[idx].height = xinInfo[idx].height;
      667                     fbrects[idx].x = xinInfo[idx].x_org;
      668                     fbrects[idx].y = xinInfo[idx].y_org;
      669                 }
      670             } else {
      671                 DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
      672             }
      673         } else {
      674             DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");
      675         }
      676         dlclose(libHandle);
      677     } else {
      678         DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
      679     }
      680 }
      681 #endif
      682 #ifndef __linux__ /* Solaris */
      683 static void xinerama_init_solaris()
      684 {
      685     void* libHandle = 0;
      686     char* XineramaLibName= "libXext.so";
      687     unsigned char fbhints[MAXFRAMEBUFFERS];
      688     int32_t locNumScr = 0;
      689     /* load and run XineramaGetInfo */
      690     char* XineramaGetInfoName = "XineramaGetInfo";
      691     char* XineramaGetCenterHintName = "XineramaGetCenterHint";
      692     XineramaGetInfoFunc* XineramaSolarisFunc = NULL;
      693 
      694     /* load library */
      695     libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL);
      696     if (libHandle != 0) {
      697         XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName);
      698         XineramaSolarisCenterFunc =
      699             (XineramaGetCenterHintFunc*)dlsym(libHandle, XineramaGetCenterHintName);
      700 
      701         if (XineramaSolarisFunc != NULL) {
      702             DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");
      703             if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],
      704                                        &fbhints[0], &locNumScr) != 0)
      705             {
      706                 DTRACE_PRINTLN("Enabling Xinerama support");
      707                 usingXinerama = True;
      708                 /* set global number of screens */
      709                 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
      710                 awt_numScreens = locNumScr;
      711             } else {
      712                 DTRACE_PRINTLN("calling XineramaGetInfo didn't work");
      713             }
      714         } else {
      715             DTRACE_PRINTLN("couldn't load XineramaGetInfo symbol");
      716         }
      717         dlclose(libHandle);
      718     } else {
      719         DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
      720     }
      721 }
      722 #endif
      723 
      724 /*
      725  * Checks if Xinerama is running and perform Xinerama-related
      726  * platform dependent initialization.
      727  */
      728 static void xineramaInit(void) {
      729     char* XinExtName = "XINERAMA";
      730     int32_t major_opcode, first_event, first_error;
      731     Bool gotXinExt = False;
      732 
      733     gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
      734                                 &first_event, &first_error);