Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c
32287 views
/*1* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "jni_util.h"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 HEADLESS34#include <X11/extensions/Xdbe.h>35#include <X11/XKBlib.h>36#include "Xrandr.h"37#include "GLXGraphicsConfig.h"38#endif /* !HEADLESS */3940#include <jni.h>41#include <jni_util.h>42#include <jvm.h>43#include <jvm_md.h>44#include <jlong.h>4546#include <stdlib.h>4748#include "awt_GraphicsEnv.h"49#include "awt_util.h"50#include "gdefs.h"51#include <dlfcn.h>52#include "Trace.h"5354#ifdef NETSCAPE55#include <signal.h>56extern int awt_init_xt;57#endif5859#ifndef HEADLESS6061int awt_numScreens; /* Xinerama-aware number of screens */6263AwtScreenDataPtr x11Screens;6465/*66* Set in initDisplay() to indicate whether we should attempt to initialize67* GLX for the default configuration.68*/69static jboolean glxRequested = JNI_FALSE;7071#endif /* !HEADLESS */7273#ifdef HEADLESS74#define Display void75#endif /* HEADLESS */7677Display *awt_display;7879jclass tkClass = NULL;80jmethodID awtLockMID = NULL;81jmethodID awtUnlockMID = NULL;82jmethodID awtWaitMID = NULL;83jmethodID awtNotifyMID = NULL;84jmethodID awtNotifyAllMID = NULL;85jboolean awtLockInited = JNI_FALSE;8687/** Convenience macro for loading the lock-related method IDs. */88#define GET_STATIC_METHOD(klass, method_id, method_name, method_sig) \89do { \90method_id = (*env)->GetStaticMethodID(env, klass, \91method_name, method_sig); \92if (method_id == NULL) return NULL; \93} while (0)9495struct X11GraphicsConfigIDs x11GraphicsConfigIDs;96struct X11GraphicsDeviceIDs x11GraphicsDeviceIDs;9798#ifndef HEADLESS99int awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata);100#endif /* HEADLESS */101102static char *x11GraphicsConfigClassName = "sun/awt/X11GraphicsConfig";103104/* AWT and Xinerama105*106* As of fix 4356756, AWT is Xinerama-aware. X11GraphicsDevices are created for107* each screen of a Xinerama setup, though X11 itself still only sees a single108* display.109* In many places where we talk to X11, a xinawareScreen variable is used to110* pass the correct Display value, depending on the circumstances (a single111* X display, multiple X displays, or a single X display with multiple112* Xinerama screens).113*114* Solaris and Linux differ in the functions used to access Xinerama-related115* data. This is in part because at this time, the X consortium has not116* finalized the "official" Xinerama API. Once this spec is available, and117* both OSes are conformant, one code base should be sufficient for Xinerama118* operation on both OSes. Until then, some of the Xinerama-related code119* is ifdef'd appropriately. -bchristi, 7/12/01120*/121122#define MAXFRAMEBUFFERS 16123#if defined(__linux__) || defined(MACOSX)124typedef struct {125int screen_number;126short x_org;127short y_org;128short width;129short height;130} XineramaScreenInfo;131132typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);133134#else /* SOLARIS */135typedef Status XineramaGetInfoFunc(Display* display, int screen_number,136XRectangle* framebuffer_rects, unsigned char* framebuffer_hints,137int* num_framebuffers);138typedef Status XineramaGetCenterHintFunc(Display* display, int screen_number,139int* x, int* y);140141XineramaGetCenterHintFunc* XineramaSolarisCenterFunc = NULL;142#endif143144Bool usingXinerama = False;145XRectangle fbrects[MAXFRAMEBUFFERS];146147JNIEXPORT void JNICALL148Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls)149{150x11GraphicsConfigIDs.aData = NULL;151x11GraphicsConfigIDs.bitsPerPixel = NULL;152x11GraphicsConfigIDs.screen = NULL;153154x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J");155CHECK_NULL(x11GraphicsConfigIDs.aData);156x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I");157CHECK_NULL(x11GraphicsConfigIDs.bitsPerPixel);158x11GraphicsConfigIDs.screen = (*env)->GetFieldID (env, cls, "screen", "Lsun/awt/X11GraphicsDevice;");159CHECK_NULL(x11GraphicsConfigIDs.screen);160161if (x11GraphicsConfigIDs.aData == NULL ||162x11GraphicsConfigIDs.bitsPerPixel == NULL ||163x11GraphicsConfigIDs.screen == NULL) {164165JNU_ThrowNoSuchFieldError(env, "Can't find a field");166return;167}168}169170JNIEXPORT void JNICALL171Java_sun_awt_X11GraphicsDevice_initIDs (JNIEnv *env, jclass cls)172{173x11GraphicsDeviceIDs.screen = NULL;174x11GraphicsDeviceIDs.screen = (*env)->GetFieldID (env, cls, "screen", "I");175DASSERT(x11GraphicsDeviceIDs.screen);176}177178#ifndef HEADLESS179180/*181* XIOErrorHandler182*/183static int xioerror_handler(Display *disp)184{185if (awtLockInited) {186if (errno == EPIPE) {187jio_fprintf(stderr, "X connection to %s host broken (explicit kill or server shutdown)\n", XDisplayName(NULL));188}189/*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", "I/O error"); */190}191return 0;192}193194static AwtGraphicsConfigDataPtr195findWithTemplate(XVisualInfo *vinfo,196long mask)197{198199XVisualInfo *visualList;200XColor color;201AwtGraphicsConfigDataPtr defaultConfig;202int visualsMatched, i;203204visualList = XGetVisualInfo(awt_display,205mask, vinfo, &visualsMatched);206if (visualList) {207defaultConfig = ZALLOC(_AwtGraphicsConfigData);208for (i = 0; i < visualsMatched; i++) {209memcpy(&defaultConfig->awt_visInfo, &visualList[i], sizeof(XVisualInfo));210defaultConfig->awt_depth = visualList[i].depth;211212/* we can't use awtJNI_CreateColorData here, because it'll pull,213SystemColor, which in turn will cause toolkit to be reinitialized */214if (awtCreateX11Colormap(defaultConfig)) {215/* Allocate white and black pixels for this visual */216color.flags = DoRed | DoGreen | DoBlue;217color.red = color.green = color.blue = 0x0000;218XAllocColor(awt_display, defaultConfig->awt_cmap, &color);219x11Screens[visualList[i].screen].blackpixel = color.pixel;220color.flags = DoRed | DoGreen | DoBlue;221color.red = color.green = color.blue = 0xffff;222XAllocColor(awt_display, defaultConfig->awt_cmap, &color);223x11Screens[visualList[i].screen].whitepixel = color.pixel;224225XFree(visualList);226return defaultConfig;227}228}229XFree(visualList);230free((void *)defaultConfig);231}232return NULL;233}234235/* default config is based on X11 screen. All Xinerama screens of that X11236screen will have the same default config */237/* Need more notes about which fields of the structure are based on the X238screen, and which are based on the Xinerama screen */239static AwtGraphicsConfigDataPtr240makeDefaultConfig(JNIEnv *env, int screen) {241242AwtGraphicsConfigDataPtr defaultConfig;243int xinawareScreen = 0;244VisualID forcedVisualID = 0, defaultVisualID;245char *forcedVisualStr;246XVisualInfo vinfo;247long mask;248249xinawareScreen = usingXinerama ? 0 : screen;250defaultVisualID =251XVisualIDFromVisual(DefaultVisual(awt_display, xinawareScreen));252253memset(&vinfo, 0, sizeof(XVisualInfo));254vinfo.screen = xinawareScreen;255256if ((forcedVisualStr = getenv("FORCEDEFVIS"))) {257mask = VisualIDMask | VisualScreenMask;258if (sscanf(forcedVisualStr, "%lx", &forcedVisualID) > 0 &&259forcedVisualID > 0)260{261vinfo.visualid = forcedVisualID;262} else {263vinfo.visualid = defaultVisualID;264}265} else {266VisualID bestGLXVisualID;267if (glxRequested &&268(bestGLXVisualID = GLXGC_FindBestVisual(env, xinawareScreen)) > 0)269{270/* we've found the best visual for use with GLX, so use it */271vinfo.visualid = bestGLXVisualID;272mask = VisualIDMask | VisualScreenMask;273} else {274/* otherwise, continue looking for the best X11 visual */275vinfo.depth = 24;276vinfo.class = TrueColor;277mask = VisualDepthMask | VisualScreenMask | VisualClassMask;278}279}280281/* try the best, or forced visual */282defaultConfig = findWithTemplate(&vinfo, mask);283if (defaultConfig) {284return defaultConfig;285}286287/* try the default visual */288vinfo.visualid = defaultVisualID;289mask = VisualIDMask | VisualScreenMask;290defaultConfig = findWithTemplate(&vinfo, mask);291if (defaultConfig) {292return defaultConfig;293}294295/* try any TrueColor */296vinfo.class = TrueColor;297mask = VisualScreenMask | VisualClassMask;298defaultConfig = findWithTemplate(&vinfo, mask);299if (defaultConfig) {300return defaultConfig;301}302303/* try 8-bit PseudoColor */304vinfo.depth = 8;305vinfo.class = PseudoColor;306mask = VisualDepthMask | VisualScreenMask | VisualClassMask;307defaultConfig = findWithTemplate(&vinfo, mask);308if (defaultConfig) {309return defaultConfig;310}311312/* try any 8-bit */313vinfo.depth = 8;314mask = VisualDepthMask | VisualScreenMask;315defaultConfig = findWithTemplate(&vinfo, mask);316if (defaultConfig) {317return defaultConfig;318}319320/* we tried everything, give up */321JNU_ThrowInternalError(env, "Can't find supported visual");322XCloseDisplay(awt_display);323awt_display = NULL;324return NULL;325}326327static void328getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {329330int i;331int n8p=0, n12p=0, n8s=0, n8gs=0, n8sg=0, n1sg=0, nTrue=0;332int nConfig;333XVisualInfo *pVI8p, *pVI12p, *pVI8s, *pVITrue, *pVI8gs,334*pVI8sg, *pVI1sg = NULL, viTmp;335AwtGraphicsConfigDataPtr *graphicsConfigs;336AwtGraphicsConfigDataPtr defaultConfig;337int ind;338char errmsg[128];339int xinawareScreen;340void* xrenderLibHandle = NULL;341XRenderFindVisualFormatFunc* xrenderFindVisualFormat = NULL;342int major_opcode, first_event, first_error;343344if (usingXinerama) {345xinawareScreen = 0;346}347else {348xinawareScreen = screen;349}350351AWT_LOCK ();352353viTmp.screen = xinawareScreen;354355viTmp.depth = 8;356viTmp.class = PseudoColor;357viTmp.colormap_size = 256;358pVI8p = XGetVisualInfo (awt_display,359VisualDepthMask | VisualClassMask |360VisualColormapSizeMask | VisualScreenMask,361&viTmp, &n8p);362363viTmp.depth = 12;364viTmp.class = PseudoColor;365viTmp.colormap_size = 4096;366pVI12p = XGetVisualInfo (awt_display,367VisualDepthMask | VisualClassMask |368VisualColormapSizeMask | VisualScreenMask,369&viTmp, &n12p);370371viTmp.class = TrueColor;372pVITrue = XGetVisualInfo (awt_display,373VisualClassMask |374VisualScreenMask,375&viTmp, &nTrue);376377viTmp.depth = 8;378viTmp.class = StaticColor;379pVI8s = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask |380VisualScreenMask, &viTmp, &n8s);381382viTmp.depth = 8;383viTmp.class = GrayScale;384viTmp.colormap_size = 256;385pVI8gs = XGetVisualInfo (awt_display,386VisualDepthMask | VisualClassMask |387VisualColormapSizeMask | VisualScreenMask,388&viTmp, &n8gs);389viTmp.depth = 8;390viTmp.class = StaticGray;391viTmp.colormap_size = 256;392pVI8sg = XGetVisualInfo (awt_display,393VisualDepthMask | VisualClassMask |394VisualColormapSizeMask | VisualScreenMask,395&viTmp, &n8sg);396397/* REMIND.. remove when we have support for the color classes below */398/* viTmp.depth = 1; */399/* viTmp.class = StaticGray; */400/* pVI1sg = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask, */401/* viTmp, &n1sg); */402403nConfig = n8p + n12p + n8s + n8gs + n8sg + n1sg + nTrue + 1;404graphicsConfigs = (AwtGraphicsConfigDataPtr *)405calloc(nConfig, sizeof(AwtGraphicsConfigDataPtr));406if (graphicsConfigs == NULL) {407JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),408NULL);409AWT_UNLOCK();410return;411}412413if (screenDataPtr->defaultConfig == NULL) {414/*415* After a display change event, the default config field will have416* been reset, so we need to recreate the default config here.417*/418screenDataPtr->defaultConfig = makeDefaultConfig(env, screen);419}420421defaultConfig = screenDataPtr->defaultConfig;422graphicsConfigs[0] = defaultConfig;423nConfig = 1; /* reserve index 0 for default config */424425// Only use the RENDER extension if it is available on the X server426if (XQueryExtension(awt_display, "RENDER",427&major_opcode, &first_event, &first_error))428{429xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);430431#ifdef MACOSX432#define XRENDER_LIB "/usr/X11/lib/libXrender.dylib"433#else434#define XRENDER_LIB "libXrender.so"435#endif436437if (xrenderLibHandle == NULL) {438xrenderLibHandle = dlopen(XRENDER_LIB,439RTLD_LAZY | RTLD_GLOBAL);440}441442#ifndef __linux__ /* SOLARIS */443if (xrenderLibHandle == NULL) {444xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1",445RTLD_LAZY | RTLD_GLOBAL);446}447#endif448449if (xrenderLibHandle != NULL) {450xrenderFindVisualFormat =451(XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,452"XRenderFindVisualFormat");453}454}455456for (i = 0; i < nTrue; i++) {457if (XVisualIDFromVisual(pVITrue[i].visual) ==458XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) ||459pVITrue[i].depth == 12) {460/* Skip the non-supported 12-bit TrueColor visual */461continue;462} else {463ind = nConfig++;464}465graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);466graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;467memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],468sizeof (XVisualInfo));469if (xrenderFindVisualFormat != NULL) {470XRenderPictFormat *format = xrenderFindVisualFormat (awt_display,471pVITrue [i].visual);472if (format &&473format->type == PictTypeDirect &&474format->direct.alphaMask)475{476graphicsConfigs [ind]->isTranslucencySupported = 1;477memcpy(&graphicsConfigs [ind]->renderPictFormat, format,478sizeof(*format));479}480}481}482483if (xrenderLibHandle != NULL) {484dlclose(xrenderLibHandle);485xrenderLibHandle = NULL;486}487488for (i = 0; i < n8p; i++) {489if (XVisualIDFromVisual(pVI8p[i].visual) ==490XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {491continue;492} else {493ind = nConfig++;494}495graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);496graphicsConfigs [ind]->awt_depth = pVI8p [i].depth;497memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8p [i],498sizeof (XVisualInfo));499}500501for (i = 0; i < n12p; i++) {502if (XVisualIDFromVisual(pVI12p[i].visual) ==503XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {504continue;505} else {506ind = nConfig++;507}508graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);509graphicsConfigs [ind]->awt_depth = pVI12p [i].depth;510memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI12p [i],511sizeof (XVisualInfo));512}513514for (i = 0; i < n8s; i++) {515if (XVisualIDFromVisual(pVI8s[i].visual) ==516XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {517continue;518} else {519ind = nConfig++;520}521graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);522graphicsConfigs [ind]->awt_depth = pVI8s [i].depth;523memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8s [i],524sizeof (XVisualInfo));525}526527for (i = 0; i < n8gs; i++) {528if (XVisualIDFromVisual(pVI8gs[i].visual) ==529XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {530continue;531} else {532ind = nConfig++;533}534graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);535graphicsConfigs [ind]->awt_depth = pVI8gs [i].depth;536memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8gs [i],537sizeof (XVisualInfo));538}539540for (i = 0; i < n8sg; i++) {541if (XVisualIDFromVisual(pVI8sg[i].visual) ==542XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {543continue;544} else {545ind = nConfig++;546}547graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);548graphicsConfigs [ind]->awt_depth = pVI8sg [i].depth;549memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8sg [i],550sizeof (XVisualInfo));551}552553for (i = 0; i < n1sg; i++) {554if (XVisualIDFromVisual(pVI1sg[i].visual) ==555XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) {556continue;557} else {558ind = nConfig++;559}560graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);561graphicsConfigs [ind]->awt_depth = pVI1sg [i].depth;562memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI1sg [i],563sizeof (XVisualInfo));564}565566if (n8p != 0)567XFree (pVI8p);568if (n12p != 0)569XFree (pVI12p);570if (n8s != 0)571XFree (pVI8s);572if (n8gs != 0)573XFree (pVI8gs);574if (n8sg != 0)575XFree (pVI8sg);576if (n1sg != 0)577XFree (pVI1sg);578579screenDataPtr->numConfigs = nConfig;580screenDataPtr->configs = graphicsConfigs;581582AWT_UNLOCK ();583}584585#ifndef HEADLESS586#if defined(__linux__) || defined(MACOSX)587static void xinerama_init_linux()588{589void* libHandle = NULL;590int32_t locNumScr = 0;591XineramaScreenInfo *xinInfo;592char* XineramaQueryScreensName = "XineramaQueryScreens";593XineramaQueryScreensFunc* XineramaQueryScreens = NULL;594595/* load library */596libHandle = dlopen(VERSIONED_JNI_LIB_NAME("Xinerama", "1"),597RTLD_LAZY | RTLD_GLOBAL);598if (libHandle == NULL) {599libHandle = dlopen(JNI_LIB_NAME("Xinerama"), RTLD_LAZY | RTLD_GLOBAL);600}601if (libHandle != NULL) {602XineramaQueryScreens = (XineramaQueryScreensFunc*)603dlsym(libHandle, XineramaQueryScreensName);604605if (XineramaQueryScreens != NULL) {606DTRACE_PRINTLN("calling XineramaQueryScreens func on Linux");607xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);608if (xinInfo != NULL && locNumScr > XScreenCount(awt_display)) {609int32_t idx;610DTRACE_PRINTLN("Enabling Xinerama support");611usingXinerama = True;612/* set global number of screens */613DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);614awt_numScreens = locNumScr;615616/* stuff values into fbrects */617for (idx = 0; idx < awt_numScreens; idx++) {618DASSERT(xinInfo[idx].screen_number == idx);619620fbrects[idx].width = xinInfo[idx].width;621fbrects[idx].height = xinInfo[idx].height;622fbrects[idx].x = xinInfo[idx].x_org;623fbrects[idx].y = xinInfo[idx].y_org;624}625} else {626DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");627}628} else {629DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");630}631dlclose(libHandle);632} else {633DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());634}635}636#endif637#if !defined(__linux__) && !defined(MACOSX) /* Solaris */638static void xinerama_init_solaris()639{640void* libHandle = NULL;641unsigned char fbhints[MAXFRAMEBUFFERS];642int32_t locNumScr = 0;643/* load and run XineramaGetInfo */644char* XineramaGetInfoName = "XineramaGetInfo";645char* XineramaGetCenterHintName = "XineramaGetCenterHint";646XineramaGetInfoFunc* XineramaSolarisFunc = NULL;647648/* load library */649libHandle = dlopen(JNI_LIB_NAME("Xext"), RTLD_LAZY | RTLD_GLOBAL);650if (libHandle != NULL) {651XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName);652XineramaSolarisCenterFunc =653(XineramaGetCenterHintFunc*)dlsym(libHandle, XineramaGetCenterHintName);654655if (XineramaSolarisFunc != NULL) {656DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");657if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],658&fbhints[0], &locNumScr) != 0 &&659locNumScr > XScreenCount(awt_display))660{661DTRACE_PRINTLN("Enabling Xinerama support");662usingXinerama = True;663/* set global number of screens */664DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);665awt_numScreens = locNumScr;666} else {667DTRACE_PRINTLN("calling XineramaGetInfo didn't work");668}669} else {670DTRACE_PRINTLN("couldn't load XineramaGetInfo symbol");671}672dlclose(libHandle);673} else {674DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());675}676}677#endif678679/*680* Checks if Xinerama is running and perform Xinerama-related681* platform dependent initialization.682*/683static void xineramaInit(void) {684char* XinExtName = "XINERAMA";685int32_t major_opcode, first_event, first_error;686Bool gotXinExt = False;687688gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,689&first_event, &first_error);690691if (!gotXinExt) {692DTRACE_PRINTLN("Xinerama extension is not available");693return;694}695696DTRACE_PRINTLN("Xinerama extension is available");697#if defined(__linux__) || defined(MACOSX)698xinerama_init_linux();699#else /* Solaris */700xinerama_init_solaris();701#endif /* __linux__ || MACOSX */702}703#endif /* HEADLESS */704705Display *706awt_init_Display(JNIEnv *env, jobject this)707{708jclass klass;709Display *dpy;710char errmsg[128];711int i;712#ifdef NETSCAPE713sigset_t alarm_set, oldset;714#endif715716if (awt_display) {717return awt_display;718}719720#ifdef NETSCAPE721/* Disable interrupts during XtOpenDisplay to avoid bugs in unix os select722code: some unix systems don't implement SA_RESTART properly and723because of this, select returns with EINTR. Most implementations of724gethostbyname don't cope with EINTR properly and as a result we get725stuck (forever) in the gethostbyname code726*/727sigemptyset(&alarm_set);728sigaddset(&alarm_set, SIGALRM);729sigprocmask(SIG_BLOCK, &alarm_set, &oldset);730#endif731732/* Load AWT lock-related methods in SunToolkit */733klass = (*env)->FindClass(env, "sun/awt/SunToolkit");734if (klass == NULL) return NULL;735GET_STATIC_METHOD(klass, awtLockMID, "awtLock", "()V");736GET_STATIC_METHOD(klass, awtUnlockMID, "awtUnlock", "()V");737GET_STATIC_METHOD(klass, awtWaitMID, "awtLockWait", "(J)V");738GET_STATIC_METHOD(klass, awtNotifyMID, "awtLockNotify", "()V");739GET_STATIC_METHOD(klass, awtNotifyAllMID, "awtLockNotifyAll", "()V");740tkClass = (*env)->NewGlobalRef(env, klass);741awtLockInited = JNI_TRUE;742743if (getenv("_AWT_IGNORE_XKB") != NULL &&744strlen(getenv("_AWT_IGNORE_XKB")) > 0) {745if (XkbIgnoreExtension(True)) {746printf("Ignoring XKB.\n");747}748}749750dpy = awt_display = XOpenDisplay(NULL);751#ifdef NETSCAPE752sigprocmask(SIG_SETMASK, &oldset, NULL);753#endif754if (!dpy) {755jio_snprintf(errmsg,756sizeof(errmsg),757"Can't connect to X11 window server using '%s' as the value of the DISPLAY variable.",758(getenv("DISPLAY") == NULL) ? ":0.0" : getenv("DISPLAY"));759JNU_ThrowByName(env, "java/awt/AWTError", errmsg);760return NULL;761}762763XSetIOErrorHandler(xioerror_handler);764JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "init", "(J)V",765ptr_to_jlong(awt_display));766JNU_CHECK_EXCEPTION_RETURN(env, NULL);767768/* set awt_numScreens, and whether or not we're using Xinerama */769xineramaInit();770771if (!usingXinerama) {772awt_numScreens = XScreenCount(awt_display);773}774775DTRACE_PRINTLN1("allocating %i screens\n", awt_numScreens);776/* Allocate screen data structure array */777x11Screens = calloc(awt_numScreens, sizeof(AwtScreenData));778if (x11Screens == NULL) {779JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),780NULL);781return NULL;782}783784for (i = 0; i < awt_numScreens; i++) {785if (usingXinerama) {786/* All Xinerama screens use the same X11 root for now */787x11Screens[i].root = RootWindow(awt_display, 0);788}789else {790x11Screens[i].root = RootWindow(awt_display, i);791}792x11Screens[i].defaultConfig = makeDefaultConfig(env, i);793JNU_CHECK_EXCEPTION_RETURN(env, NULL);794}795796return dpy;797}798#endif /* !HEADLESS */799800/*801* Class: sun_awt_X11GraphicsEnvironment802* Method: getDefaultScreenNum803* Signature: ()I804*/805JNIEXPORT jint JNICALL806Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum(807JNIEnv *env, jobject this)808{809#ifdef HEADLESS810return (jint)0;811#else812return DefaultScreen(awt_display);813#endif /* !HEADLESS */814}815816#ifndef HEADLESS817static void ensureConfigsInited(JNIEnv* env, int screen) {818if (x11Screens[screen].numConfigs == 0) {819if (env == NULL) {820env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);821}822getAllConfigs (env, screen, &(x11Screens[screen]));823}824}825#endif826827#ifdef HEADLESS828void* getDefaultConfig(int screen) {829return NULL;830}831#else832AwtGraphicsConfigDataPtr833getDefaultConfig(int screen) {834ensureConfigsInited(NULL, screen);835return x11Screens[screen].defaultConfig;836}837838AwtScreenDataPtr839getScreenData(int screen) {840return &(x11Screens[screen]);841}842#endif /* !HEADLESS */843844/*845* Class: sun_awt_X11GraphicsEnvironment846* Method: initDisplay847* Signature: (Z)V848*/849JNIEXPORT void JNICALL850Java_sun_awt_X11GraphicsEnvironment_initDisplay(JNIEnv *env, jobject this,851jboolean glxReq)852{853#ifndef HEADLESS854glxRequested = glxReq;855(void) awt_init_Display(env, this);856#endif /* !HEADLESS */857}858859/*860* Class: sun_awt_X11GraphicsEnvironment861* Method: initGLX862* Signature: ()Z863*/864JNIEXPORT jboolean JNICALL865Java_sun_awt_X11GraphicsEnvironment_initGLX(JNIEnv *env, jclass x11ge)866{867#ifndef HEADLESS868jboolean glxAvailable;869870AWT_LOCK();871glxAvailable = GLXGC_IsGLXAvailable();872AWT_UNLOCK();873874return glxAvailable;875#elif defined(__ANDROID)876return JNI_TRUE;877#else878return JNI_FALSE;879#endif /* !HEADLESS */880}881882/*883* Class: sun_awt_X11GraphicsEnvironment884* Method: getNumScreens885* Signature: ()I886*/887JNIEXPORT jint JNICALL888Java_sun_awt_X11GraphicsEnvironment_getNumScreens(JNIEnv *env, jobject this)889{890#ifdef HEADLESS891return (jint)1;892#else893return awt_numScreens;894#endif /* !HEADLESS */895}896897/*898* Class: sun_awt_X11GraphicsDevice899* Method: getDisplay900* Signature: ()J901*/902JNIEXPORT jlong JNICALL903Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)904{905#ifdef HEADLESS906return NULL;907#else908return ptr_to_jlong(awt_display);909#endif /* !HEADLESS */910}911912#ifdef MITSHM913914static jint canUseShmExt = UNSET_MITSHM;915static jint canUseShmExtPixmaps = UNSET_MITSHM;916static jboolean xshmAttachFailed = JNI_FALSE;917918int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr) {919if (xerr->minor_code == X_ShmAttach) {920xshmAttachFailed = JNI_TRUE;921}922return 0;923}924jboolean isXShmAttachFailed() {925return xshmAttachFailed;926}927void resetXShmAttachFailed() {928xshmAttachFailed = JNI_FALSE;929}930931extern int mitShmPermissionMask;932933void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) {934XShmSegmentInfo shminfo;935int XShmMajor, XShmMinor;936int a, b, c;937938AWT_LOCK();939if (canUseShmExt != UNSET_MITSHM) {940*shmExt = canUseShmExt;941*shmPixmaps = canUseShmExtPixmaps;942AWT_UNLOCK();943return;944}945946*shmExt = canUseShmExt = CANT_USE_MITSHM;947*shmPixmaps = canUseShmExtPixmaps = CANT_USE_MITSHM;948949if (awt_display == (Display *)NULL) {950AWT_NOFLUSH_UNLOCK();951return;952}953954/**955* XShmQueryExtension returns False in remote server case.956* Unfortunately it also returns True in ssh case, so957* we need to test that we can actually do XShmAttach.958*/959if (XShmQueryExtension(awt_display)) {960shminfo.shmid = shmget(IPC_PRIVATE, 0x10000,961IPC_CREAT|mitShmPermissionMask);962if (shminfo.shmid < 0) {963AWT_UNLOCK();964J2dRlsTraceLn1(J2D_TRACE_ERROR,965"TryInitMITShm: shmget has failed: %s",966strerror(errno));967return;968}969shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0);970if (shminfo.shmaddr == ((char *) -1)) {971shmctl(shminfo.shmid, IPC_RMID, 0);972AWT_UNLOCK();973J2dRlsTraceLn1(J2D_TRACE_ERROR,974"TryInitMITShm: shmat has failed: %s",975strerror(errno));976return;977}978shminfo.readOnly = True;979980resetXShmAttachFailed();981/**982* The J2DXErrHandler handler will set xshmAttachFailed983* to JNI_TRUE if any Shm error has occured.984*/985EXEC_WITH_XERROR_HANDLER(XShmAttachXErrHandler,986XShmAttach(awt_display, &shminfo));987988/**989* Get rid of the id now to reduce chances of leaking990* system resources.991*/992shmctl(shminfo.shmid, IPC_RMID, 0);993994if (isXShmAttachFailed() == JNI_FALSE) {995canUseShmExt = CAN_USE_MITSHM;996/* check if we can use shared pixmaps */997XShmQueryVersion(awt_display, &XShmMajor, &XShmMinor,998(Bool*)&canUseShmExtPixmaps);999canUseShmExtPixmaps = canUseShmExtPixmaps &&1000(XShmPixmapFormat(awt_display) == ZPixmap);1001XShmDetach(awt_display, &shminfo);1002}1003shmdt(shminfo.shmaddr);1004*shmExt = canUseShmExt;1005*shmPixmaps = canUseShmExtPixmaps;1006}1007AWT_UNLOCK();1008}1009#endif /* MITSHM */10101011/*1012* Class: sun_awt_X11GraphicsEnvironment1013* Method: checkShmExt1014* Signature: ()I1015*/1016JNIEXPORT jint JNICALL1017Java_sun_awt_X11GraphicsEnvironment_checkShmExt(JNIEnv *env, jobject this)1018{10191020int shmExt = NOEXT_MITSHM, shmPixmaps;1021#ifdef MITSHM1022TryInitMITShm(env, &shmExt, &shmPixmaps);1023#endif1024return shmExt;1025}10261027/*1028* Class: sun_awt_X11GraphicsEnvironment1029* Method: getDisplayString1030* Signature: ()Ljava/lang/String1031*/1032JNIEXPORT jstring JNICALL1033Java_sun_awt_X11GraphicsEnvironment_getDisplayString1034(JNIEnv *env, jobject this)1035{1036#ifdef HEADLESS1037return (jstring)NULL;1038#else1039return (*env)->NewStringUTF(env, DisplayString(awt_display));1040#endif /* HEADLESS */1041}104210431044/*1045* Class: sun_awt_X11GraphicsDevice1046* Method: getNumConfigs1047* Signature: ()I1048*/1049JNIEXPORT jint JNICALL1050Java_sun_awt_X11GraphicsDevice_getNumConfigs(1051JNIEnv *env, jobject this, jint screen)1052{1053#ifdef HEADLESS1054return (jint)0;1055#else1056ensureConfigsInited(env, screen);1057return x11Screens[screen].numConfigs;1058#endif /* !HEADLESS */1059}10601061/*1062* Class: sun_awt_X11GraphicsDevice1063* Method: getConfigVisualId1064* Signature: (I)I1065*/1066JNIEXPORT jint JNICALL1067Java_sun_awt_X11GraphicsDevice_getConfigVisualId(1068JNIEnv *env, jobject this, jint index, jint screen)1069{1070#ifdef HEADLESS1071return (jint)0;1072#else1073int visNum;10741075ensureConfigsInited(env, screen);1076if (index == 0) {1077return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.visualid);1078} else {1079return ((jint)x11Screens[screen].configs[index]->awt_visInfo.visualid);1080}1081#endif /* !HEADLESS */1082}10831084/*1085* Class: sun_awt_X11GraphicsDevice1086* Method: getConfigDepth1087* Signature: (I)I1088*/1089JNIEXPORT jint JNICALL1090Java_sun_awt_X11GraphicsDevice_getConfigDepth(1091JNIEnv *env, jobject this, jint index, jint screen)1092{1093#ifdef HEADLESS1094return (jint)0;1095#else1096int visNum;10971098ensureConfigsInited(env, screen);1099if (index == 0) {1100return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.depth);1101} else {1102return ((jint)x11Screens[screen].configs[index]->awt_visInfo.depth);1103}1104#endif /* !HEADLESS */1105}11061107/*1108* Class: sun_awt_X11GraphicsDevice1109* Method: getConfigColormap1110* Signature: (I)I1111*/1112JNIEXPORT jint JNICALL1113Java_sun_awt_X11GraphicsDevice_getConfigColormap(1114JNIEnv *env, jobject this, jint index, jint screen)1115{1116#ifdef HEADLESS1117return (jint)0;1118#else1119int visNum;11201121ensureConfigsInited(env, screen);1122if (index == 0) {1123return ((jint)x11Screens[screen].defaultConfig->awt_cmap);1124} else {1125return ((jint)x11Screens[screen].configs[index]->awt_cmap);1126}1127#endif /* !HEADLESS */1128}11291130/*1131* Class: sun_awt_X11GraphicsDevice1132* Method: resetNativeData1133* Signature: (I)V1134*/1135JNIEXPORT void JNICALL1136Java_sun_awt_X11GraphicsDevice_resetNativeData1137(JNIEnv *env, jclass x11gd, jint screen)1138{1139#ifndef HEADLESS1140/*1141* Reset references to the various configs; the actual native config data1142* will be free'd later by the Disposer mechanism when the Java-level1143* X11GraphicsConfig objects go away. By setting these values to NULL,1144* we ensure that they will be reinitialized as necessary (for example,1145* see the getNumConfigs() method).1146*/1147if (x11Screens[screen].configs) {1148free(x11Screens[screen].configs);1149x11Screens[screen].configs = NULL;1150}1151x11Screens[screen].defaultConfig = NULL;1152x11Screens[screen].numConfigs = 0;1153#endif /* !HEADLESS */1154}11551156/*1157* Class: sun_awt_X11GraphicsConfig1158* Method: dispose1159* Signature: (J)V1160*/1161JNIEXPORT void JNICALL1162Java_sun_awt_X11GraphicsConfig_dispose1163(JNIEnv *env, jclass x11gc, jlong configData)1164{1165#ifndef HEADLESS1166AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)1167jlong_to_ptr(configData);11681169if (aData == NULL) {1170return;1171}11721173AWT_LOCK();1174if (aData->awt_cmap) {1175XFreeColormap(awt_display, aData->awt_cmap);1176}1177if (aData->awtImage) {1178free(aData->awtImage);1179}1180if (aData->monoImage) {1181XFree(aData->monoImage);1182}1183if (aData->monoPixmap) {1184XFreePixmap(awt_display, aData->monoPixmap);1185}1186if (aData->monoPixmapGC) {1187XFreeGC(awt_display, aData->monoPixmapGC);1188}1189if (aData->color_data) {1190free(aData->color_data);1191}1192AWT_UNLOCK();11931194if (aData->glxInfo) {1195/*1196* The native GLXGraphicsConfig data needs to be disposed separately1197* on the OGL queue flushing thread (should not be called while1198* the AWT lock is held).1199*/1200JNU_CallStaticMethodByName(env, NULL,1201"sun/java2d/opengl/OGLRenderQueue",1202"disposeGraphicsConfig", "(J)V",1203ptr_to_jlong(aData->glxInfo));1204}12051206free(aData);1207#endif /* !HEADLESS */1208}12091210/*1211* Class: sun_awt_X11GraphicsConfig1212* Method: getXResolution1213* Signature: ()I1214*/1215JNIEXPORT jdouble JNICALL1216Java_sun_awt_X11GraphicsConfig_getXResolution(1217JNIEnv *env, jobject this, jint screen)1218{1219#ifdef HEADLESS1220return (jdouble)0;1221#else1222return ((DisplayWidth(awt_display, screen) * 25.4) /1223DisplayWidthMM(awt_display, screen));1224#endif /* !HEADLESS */1225}12261227/*1228* Class: sun_awt_X11GraphicsConfig1229* Method: getYResolution1230* Signature: ()I1231*/1232JNIEXPORT jdouble JNICALL1233Java_sun_awt_X11GraphicsConfig_getYResolution(1234JNIEnv *env, jobject this, jint screen)1235{1236#ifdef HEADLESS1237return (jdouble)0;1238#else1239return ((DisplayHeight(awt_display, screen) * 25.4) /1240DisplayHeightMM(awt_display, screen));1241#endif /* !HEADLESS */1242}124312441245/*1246* Class: sun_awt_X11GraphicsConfig1247* Method: getNumColors1248* Signature: ()I1249*/1250JNIEXPORT jint JNICALL1251Java_sun_awt_X11GraphicsConfig_getNumColors(1252JNIEnv *env, jobject this)1253{1254#ifdef HEADLESS1255return (jint)0;1256#else1257AwtGraphicsConfigData *adata;12581259adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,1260x11GraphicsConfigIDs.aData);12611262return adata->awt_num_colors;1263#endif /* !HEADLESS */1264}12651266/*1267* Class: sun_awt_X11GraphicsConfig1268* Method: init1269* Signature: (I)V1270*/1271JNIEXPORT void JNICALL1272Java_sun_awt_X11GraphicsConfig_init(1273JNIEnv *env, jobject this, jint visualNum, jint screen)1274{1275#ifndef HEADLESS1276AwtGraphicsConfigData *adata = NULL;1277AwtScreenData asd = x11Screens[screen];1278int i, n;1279int depth;1280XImage * tempImage;12811282/* If haven't gotten all of the configs yet, do it now. */1283if (asd.numConfigs == 0) {1284getAllConfigs (env, screen, &asd);1285}12861287/* Check the graphicsConfig for this visual */1288for (i = 0; i < asd.numConfigs; i++) {1289AwtGraphicsConfigDataPtr agcPtr = asd.configs[i];1290if ((jint)agcPtr->awt_visInfo.visualid == visualNum) {1291adata = agcPtr;1292break;1293}1294}12951296/* If didn't find the visual, throw an exception... */1297if (adata == (AwtGraphicsConfigData *) NULL) {1298JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified");1299return;1300}13011302/* adata->awt_cmap initialization has been deferred to1303* makeColorModel call1304*/13051306JNU_SetLongFieldFromPtr(env, this, x11GraphicsConfigIDs.aData, adata);13071308depth = adata->awt_visInfo.depth;1309tempImage = XCreateImage(awt_display,1310adata->awt_visInfo.visual,1311depth, ZPixmap, 0, NULL, 1, 1, 32, 0);1312adata->pixelStride = (tempImage->bits_per_pixel + 7) / 8;1313(*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel,1314(jint)tempImage->bits_per_pixel);1315XDestroyImage(tempImage);1316#endif /* !HEADLESS */1317}1318131913201321/*1322* Class: sun_awt_X11GraphicsConfig1323* Method: makeColorModel1324* Signature: ()Ljava/awt/image/ColorModel1325*/1326JNIEXPORT jobject JNICALL1327Java_sun_awt_X11GraphicsConfig_makeColorModel(1328JNIEnv *env, jobject this)1329{1330#ifdef HEADLESS1331return NULL;1332#else1333AwtGraphicsConfigData *adata;1334jobject colorModel;13351336/*1337* If awt is not locked yet, return null since the toolkit is not1338* initialized yet.1339*/1340if (!awtLockInited) {1341return NULL;1342}13431344AWT_LOCK ();13451346adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,1347x11GraphicsConfigIDs.aData);13481349/* If colormap entry of adata is NULL, need to create it now */1350if (adata->awt_cmap == (Colormap) NULL) {1351awtJNI_CreateColorData (env, adata, 1);1352}13531354/* Make Color Model object for this GraphicsConfiguration */1355colorModel = (*env)->ExceptionCheck(env)1356? NULL : awtJNI_GetColorModel (env, adata);13571358AWT_UNLOCK ();13591360return colorModel;1361#endif /* !HEADLESS */1362}136313641365/*1366* Class: sun_awt_X11GraphicsConfig1367* Method: getBounds1368* Signature: ()Ljava/awt/Rectangle1369*/1370JNIEXPORT jobject JNICALL1371Java_sun_awt_X11GraphicsConfig_pGetBounds(JNIEnv *env, jobject this, jint screen)1372{1373#ifdef HEADLESS1374return NULL;1375#else1376jclass clazz;1377jmethodID mid;1378jobject bounds = NULL;1379AwtGraphicsConfigDataPtr adata;13801381adata = (AwtGraphicsConfigDataPtr)1382JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData);13831384clazz = (*env)->FindClass(env, "java/awt/Rectangle");1385CHECK_NULL_RETURN(clazz, NULL);1386mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V");1387if (mid != NULL) {1388if (usingXinerama) {1389if (0 <= screen && screen < awt_numScreens) {1390bounds = (*env)->NewObject(env, clazz, mid, fbrects[screen].x,1391fbrects[screen].y,1392fbrects[screen].width,1393fbrects[screen].height);1394} else {1395jclass exceptionClass = (*env)->FindClass(env, "java/lang/IllegalArgumentException");1396if (exceptionClass != NULL) {1397(*env)->ThrowNew(env, exceptionClass, "Illegal screen index");1398}1399}1400} else {1401XWindowAttributes xwa;1402memset(&xwa, 0, sizeof(xwa));14031404AWT_LOCK ();1405XGetWindowAttributes(awt_display,1406RootWindow(awt_display, adata->awt_visInfo.screen),1407&xwa);1408AWT_UNLOCK ();14091410bounds = (*env)->NewObject(env, clazz, mid, 0, 0,1411xwa.width, xwa.height);1412}14131414if ((*env)->ExceptionOccurred(env)) {1415return NULL;1416}1417}1418return bounds;1419#endif /* !HEADLESS */1420}14211422/*1423* Class: sun_awt_X11GraphicsConfig1424* Method: createBackBuffer1425* Signature: (JI)J1426*/1427JNIEXPORT jlong JNICALL1428Java_sun_awt_X11GraphicsConfig_createBackBuffer1429(JNIEnv *env, jobject this, jlong window, jint swapAction)1430{1431int32_t v1, v2;1432XdbeBackBuffer ret = (unsigned long) 0;1433Window w = (Window)window;1434AWT_LOCK();1435if (!XdbeQueryExtension(awt_display, &v1, &v2)) {1436JNU_ThrowByName(env, "java/lang/Exception",1437"Could not query double-buffer extension");1438AWT_UNLOCK();1439return (jlong)0;1440}1441ret = XdbeAllocateBackBufferName(awt_display, w,1442(XdbeSwapAction)swapAction);1443AWT_FLUSH_UNLOCK();1444return (jlong)ret;1445}14461447/*1448* Class: sun_awt_X11GraphicsConfig1449* Method: destroyBackBuffer1450* Signature: (J)V1451*/1452JNIEXPORT void JNICALL1453Java_sun_awt_X11GraphicsConfig_destroyBackBuffer1454(JNIEnv *env, jobject this, jlong backBuffer)1455{1456AWT_LOCK();1457XdbeDeallocateBackBufferName(awt_display, (XdbeBackBuffer)backBuffer);1458AWT_FLUSH_UNLOCK();1459}14601461/*1462* Class: sun_awt_X11GraphicsConfig1463* Method: swapBuffers1464* Signature: (JI)V1465*/1466JNIEXPORT void JNICALL1467Java_sun_awt_X11GraphicsConfig_swapBuffers1468(JNIEnv *env, jobject this,1469jlong window, jint swapAction)1470{1471XdbeSwapInfo swapInfo;14721473AWT_LOCK();14741475XdbeBeginIdiom(awt_display);1476swapInfo.swap_window = (Window)window;1477swapInfo.swap_action = (XdbeSwapAction)swapAction;1478if (!XdbeSwapBuffers(awt_display, &swapInfo, 1)) {1479JNU_ThrowInternalError(env, "Could not swap buffers");1480}1481XdbeEndIdiom(awt_display);14821483AWT_FLUSH_UNLOCK();1484}14851486/*1487* Class: sun_awt_X11GraphicsConfig1488* Method: isTranslucencyCapable1489* Signature: (J)V1490*/1491JNIEXPORT jboolean JNICALL1492Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable1493(JNIEnv *env, jobject this, jlong configData)1494{1495#ifdef HEADLESS1496return JNI_FALSE;1497#else1498AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);1499if (aData == NULL) {1500return JNI_FALSE;1501}1502return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE;1503#endif1504}15051506/*1507* Class: sun_awt_X11GraphicsDevice1508* Method: isDBESupported1509* Signature: ()Z1510*/1511JNIEXPORT jboolean JNICALL1512Java_sun_awt_X11GraphicsDevice_isDBESupported(JNIEnv *env, jobject this)1513{1514#ifdef HEADLESS1515return JNI_FALSE;1516#else1517int opcode = 0, firstEvent = 0, firstError = 0;1518jboolean ret;15191520AWT_LOCK();1521ret = (jboolean)XQueryExtension(awt_display, "DOUBLE-BUFFER",1522&opcode, &firstEvent, &firstError);1523AWT_FLUSH_UNLOCK();1524return ret;1525#endif /* !HEADLESS */1526}15271528/*1529* Class: sun_awt_X11GraphicsDevice1530* Method: getDoubleBufferVisuals1531* Signature: (I)V1532*/1533JNIEXPORT void JNICALL1534Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env,1535jobject this, jint screen)1536{1537#ifndef HEADLESS1538jclass clazz;1539jmethodID midAddVisual;1540Window rootWindow;1541int i, n = 1;1542XdbeScreenVisualInfo* visScreenInfo;1543int xinawareScreen;15441545if (usingXinerama) {1546xinawareScreen = 0;1547}1548else {1549xinawareScreen = screen;1550}15511552clazz = (*env)->GetObjectClass(env, this);1553midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual",1554"(I)V");1555CHECK_NULL(midAddVisual);1556AWT_LOCK();1557rootWindow = RootWindow(awt_display, xinawareScreen);1558visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n);1559if (visScreenInfo == NULL) {1560JNU_ThrowInternalError(env, "Could not get visual info");1561AWT_UNLOCK();1562return;1563}1564AWT_FLUSH_UNLOCK();1565for (i = 0; i < visScreenInfo->count; i++) {1566XdbeVisualInfo* visInfo = visScreenInfo->visinfo;1567(*env)->CallVoidMethod(env, this, midAddVisual, (visInfo[i]).visual);1568}1569#endif /* !HEADLESS */1570}15711572/*1573* Class: sun_awt_X11GraphicsEnvironment1574* Method: pRunningXinerama1575* Signature: ()Z1576*/1577JNIEXPORT jboolean JNICALL1578Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama(JNIEnv *env,1579jobject this)1580{1581#ifdef HEADLESS1582return JNI_FALSE;1583#else1584return usingXinerama ? JNI_TRUE : JNI_FALSE;1585#endif /* HEADLESS */1586}15871588/*1589* Can return NULL.1590*1591* Class: sun_awt_X11GraphicsEnvironment1592* Method: getXineramaCenterPoint1593* Signature: ()Ljava/awt/Point1594*/1595JNIEXPORT jobject JNICALL1596Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env,1597jobject this)1598{1599jobject point = NULL;1600#ifndef HEADLESS /* return NULL in HEADLESS, Linux */1601#if !defined(__linux__) && !defined(MACOSX)1602int x,y;16031604AWT_LOCK();1605DASSERT(usingXinerama);1606if (XineramaSolarisCenterFunc != NULL) {1607(XineramaSolarisCenterFunc)(awt_display, 0, &x, &y);1608point = JNU_NewObjectByName(env, "java/awt/Point","(II)V", x, y);1609DASSERT(point);1610} else {1611DTRACE_PRINTLN("unable to call XineramaSolarisCenterFunc: symbol is null");1612}1613AWT_FLUSH_UNLOCK();1614#endif /* __linux __ || MACOSX */1615#endif /* HEADLESS */1616return point;1617}161816191620/**1621* Begin DisplayMode/FullScreen support1622*/16231624#ifndef HEADLESS16251626#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI1627#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN16281629typedef Status1630(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);1631typedef XRRScreenConfiguration*1632(*XRRGetScreenInfoType)(Display *dpy, Drawable root);1633typedef void1634(*XRRFreeScreenConfigInfoType)(XRRScreenConfiguration *config);1635typedef short*1636(*XRRConfigRatesType)(XRRScreenConfiguration *config,1637int sizeID, int *nrates);1638typedef short1639(*XRRConfigCurrentRateType)(XRRScreenConfiguration *config);1640typedef XRRScreenSize*1641(*XRRConfigSizesType)(XRRScreenConfiguration *config,1642int *nsizes);1643typedef SizeID1644(*XRRConfigCurrentConfigurationType)(XRRScreenConfiguration *config,1645Rotation *rotation);1646typedef Status1647(*XRRSetScreenConfigAndRateType)(Display *dpy,1648XRRScreenConfiguration *config,1649Drawable draw,1650int size_index,1651Rotation rotation,1652short rate,1653Time timestamp);1654typedef Rotation1655(*XRRConfigRotationsType)(XRRScreenConfiguration *config,1656Rotation *current_rotation);16571658static XRRQueryVersionType awt_XRRQueryVersion;1659static XRRGetScreenInfoType awt_XRRGetScreenInfo;1660static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;1661static XRRConfigRatesType awt_XRRConfigRates;1662static XRRConfigCurrentRateType awt_XRRConfigCurrentRate;1663static XRRConfigSizesType awt_XRRConfigSizes;1664static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;1665static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;1666static XRRConfigRotationsType awt_XRRConfigRotations;16671668#define LOAD_XRANDR_FUNC(f) \1669do { \1670awt_##f = (f##Type)dlsym(pLibRandR, #f); \1671if (awt_##f == NULL) { \1672J2dRlsTraceLn1(J2D_TRACE_ERROR, \1673"X11GD_InitXrandrFuncs: Could not load %s", #f); \1674dlclose(pLibRandR); \1675return JNI_FALSE; \1676} \1677} while (0)16781679static jboolean1680X11GD_InitXrandrFuncs(JNIEnv *env)1681{1682int rr_maj_ver = 0, rr_min_ver = 0;16831684void *pLibRandR = dlopen(VERSIONED_JNI_LIB_NAME("Xrandr", "2"),1685RTLD_LAZY | RTLD_LOCAL);1686if (pLibRandR == NULL) {1687pLibRandR = dlopen(JNI_LIB_NAME("Xrandr"), RTLD_LAZY | RTLD_LOCAL);1688}1689if (pLibRandR == NULL) {1690J2dRlsTraceLn(J2D_TRACE_ERROR,1691"X11GD_InitXrandrFuncs: Could not open libXrandr.so.2");1692return JNI_FALSE;1693}16941695LOAD_XRANDR_FUNC(XRRQueryVersion);16961697if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) {1698J2dRlsTraceLn(J2D_TRACE_ERROR,1699"X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status");1700dlclose(pLibRandR);1701return JNI_FALSE;1702}17031704if (usingXinerama) {1705/*1706* We can proceed as long as this is RANDR 1.2 or above.1707* As of Xorg server 1.3 onwards the Xinerama backend may actually be1708* a fake one provided by RANDR itself. See Java bug 6636469 for info.1709*/1710if (!(rr_maj_ver > 1 || (rr_maj_ver == 1 && rr_min_ver >= 2))) {1711J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "1712"Xinerama is active and Xrandr version is %d.%d",1713rr_maj_ver, rr_min_ver);1714dlclose(pLibRandR);1715return JNI_FALSE;1716}17171718/*1719* REMIND: Fullscreen mode doesn't work quite right with multi-monitor1720* setups and RANDR 1.2.1721*/1722if ((rr_maj_ver == 1 && rr_min_ver <= 2) && awt_numScreens > 1) {1723J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "1724"Multiple screens in use");1725dlclose(pLibRandR);1726return JNI_FALSE;1727}1728}17291730LOAD_XRANDR_FUNC(XRRGetScreenInfo);1731LOAD_XRANDR_FUNC(XRRFreeScreenConfigInfo);1732LOAD_XRANDR_FUNC(XRRConfigRates);1733LOAD_XRANDR_FUNC(XRRConfigCurrentRate);1734LOAD_XRANDR_FUNC(XRRConfigSizes);1735LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);1736LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);1737LOAD_XRANDR_FUNC(XRRConfigRotations);17381739return JNI_TRUE;1740}17411742static jobject1743X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,1744jint bitDepth, jint refreshRate)1745{1746jclass displayModeClass;1747jmethodID cid;1748jint validRefreshRate = refreshRate;17491750displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");1751CHECK_NULL_RETURN(displayModeClass, NULL);1752if (JNU_IsNull(env, displayModeClass)) {1753JNU_ThrowInternalError(env,1754"Could not get display mode class");1755return NULL;1756}17571758cid = (*env)->GetMethodID(env, displayModeClass, "<init>", "(IIII)V");1759CHECK_NULL_RETURN(cid, NULL);1760if (cid == NULL) {1761JNU_ThrowInternalError(env,1762"Could not get display mode constructor");1763return NULL;1764}17651766// early versions of xrandr may report "empty" rates (6880694)1767if (validRefreshRate <= 0) {1768validRefreshRate = REFRESH_RATE_UNKNOWN;1769}17701771return (*env)->NewObject(env, displayModeClass, cid,1772width, height, bitDepth, validRefreshRate);1773}17741775static void1776X11GD_AddDisplayMode(JNIEnv *env, jobject arrayList,1777jint width, jint height,1778jint bitDepth, jint refreshRate)1779{1780jobject displayMode = X11GD_CreateDisplayMode(env, width, height,1781bitDepth, refreshRate);1782if (!JNU_IsNull(env, displayMode)) {1783jclass arrayListClass;1784jmethodID mid;1785arrayListClass = (*env)->GetObjectClass(env, arrayList);1786if (JNU_IsNull(env, arrayListClass)) {1787JNU_ThrowInternalError(env,1788"Could not get class java.util.ArrayList");1789return;1790}1791mid = (*env)->GetMethodID(env, arrayListClass, "add",1792"(Ljava/lang/Object;)Z");1793CHECK_NULL(mid);1794if (mid == NULL) {1795JNU_ThrowInternalError(env,1796"Could not get method java.util.ArrayList.add()");1797return;1798}1799(*env)->CallObjectMethod(env, arrayList, mid, displayMode);1800(*env)->DeleteLocalRef(env, displayMode);1801}1802}18031804static void1805X11GD_SetFullscreenMode(Window win, jboolean enabled)1806{1807Atom wmState = XInternAtom(awt_display, "_NET_WM_STATE", False);1808Atom wmStateFs = XInternAtom(awt_display,1809"_NET_WM_STATE_FULLSCREEN", False);1810XWindowAttributes attr;1811XEvent event;18121813if (wmState == None || wmStateFs == None1814|| !XGetWindowAttributes(awt_display, win, &attr)) {1815return;1816}18171818memset(&event, 0, sizeof(event));1819event.xclient.type = ClientMessage;1820event.xclient.message_type = wmState;1821event.xclient.display = awt_display;1822event.xclient.window = win;1823event.xclient.format = 32;1824event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove1825event.xclient.data.l[1] = wmStateFs;18261827XSendEvent(awt_display, attr.root, False,1828SubstructureRedirectMask | SubstructureNotifyMask,1829&event);1830XSync(awt_display, False);1831}1832#endif /* !HEADLESS */18331834/*1835* Class: sun_awt_X11GraphicsDevice1836* Method: initXrandrExtension1837* Signature: ()Z1838*/1839JNIEXPORT jboolean JNICALL1840Java_sun_awt_X11GraphicsDevice_initXrandrExtension1841(JNIEnv *env, jclass x11gd)1842{1843#ifdef HEADLESS1844return JNI_FALSE;1845#else1846int opcode = 0, firstEvent = 0, firstError = 0;1847jboolean ret;18481849AWT_LOCK();1850ret = (jboolean)XQueryExtension(awt_display, "RANDR",1851&opcode, &firstEvent, &firstError);1852if (ret) {1853ret = X11GD_InitXrandrFuncs(env);1854}1855AWT_FLUSH_UNLOCK();18561857return ret;1858#endif /* HEADLESS */1859}18601861/*1862* Class: sun_awt_X11GraphicsDevice1863* Method: getCurrentDisplayMode1864* Signature: (I)Ljava/awt/DisplayMode;1865*/1866JNIEXPORT jobject JNICALL1867Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode1868(JNIEnv* env, jclass x11gd, jint screen)1869{1870#ifdef HEADLESS1871return NULL;1872#else1873XRRScreenConfiguration *config;1874jobject displayMode = NULL;18751876AWT_LOCK();18771878config = awt_XRRGetScreenInfo(awt_display,1879RootWindow(awt_display, screen));1880if (config != NULL) {1881Rotation rotation;1882short curRate;1883SizeID curSizeIndex;1884XRRScreenSize *sizes;1885int nsizes;18861887curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);1888sizes = awt_XRRConfigSizes(config, &nsizes);1889curRate = awt_XRRConfigCurrentRate(config);18901891if ((sizes != NULL) &&1892(curSizeIndex < nsizes))1893{1894XRRScreenSize curSize = sizes[curSizeIndex];1895displayMode = X11GD_CreateDisplayMode(env,1896curSize.width,1897curSize.height,1898BIT_DEPTH_MULTI,1899curRate);1900}19011902awt_XRRFreeScreenConfigInfo(config);1903}19041905AWT_FLUSH_UNLOCK();19061907return displayMode;1908#endif /* HEADLESS */1909}19101911/*1912* Class: sun_awt_X11GraphicsDevice1913* Method: enumDisplayModes1914* Signature: (ILjava/util/ArrayList;)V1915*/1916JNIEXPORT void JNICALL1917Java_sun_awt_X11GraphicsDevice_enumDisplayModes1918(JNIEnv* env, jclass x11gd,1919jint screen, jobject arrayList)1920{1921#ifndef HEADLESS1922XRRScreenConfiguration *config;19231924AWT_LOCK();19251926config = awt_XRRGetScreenInfo(awt_display,1927RootWindow(awt_display, screen));1928if (config != NULL) {1929int nsizes, i, j;1930XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);19311932if (sizes != NULL) {1933for (i = 0; i < nsizes; i++) {1934int nrates;1935XRRScreenSize size = sizes[i];1936short *rates = awt_XRRConfigRates(config, i, &nrates);19371938for (j = 0; j < nrates; j++) {1939X11GD_AddDisplayMode(env, arrayList,1940size.width,1941size.height,1942BIT_DEPTH_MULTI,1943rates[j]);1944if ((*env)->ExceptionCheck(env)) {1945break;1946}1947}1948}1949}19501951awt_XRRFreeScreenConfigInfo(config);1952}19531954AWT_FLUSH_UNLOCK();1955#endif /* !HEADLESS */1956}19571958/*1959* Class: sun_awt_X11GraphicsDevice1960* Method: configDisplayMode1961* Signature: (IIII)V1962*/1963JNIEXPORT void JNICALL1964Java_sun_awt_X11GraphicsDevice_configDisplayMode1965(JNIEnv* env, jclass x11gd,1966jint screen, jint width, jint height, jint refreshRate)1967{1968#ifndef HEADLESS1969jboolean success = JNI_FALSE;1970XRRScreenConfiguration *config;1971Drawable root;1972Rotation currentRotation = RR_Rotate_0;19731974AWT_LOCK();19751976root = RootWindow(awt_display, screen);1977config = awt_XRRGetScreenInfo(awt_display, root);1978if (config != NULL) {1979jboolean foundConfig = JNI_FALSE;1980int chosenSizeIndex = -1;1981short chosenRate = -1;1982int nsizes;1983XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);1984awt_XRRConfigRotations(config, ¤tRotation);19851986if (sizes != NULL) {1987int i, j;19881989/* find the size index that matches the requested dimensions */1990for (i = 0; i < nsizes; i++) {1991XRRScreenSize size = sizes[i];19921993if ((size.width == width) && (size.height == height)) {1994/* we've found our size index... */1995int nrates;1996short *rates = awt_XRRConfigRates(config, i, &nrates);19971998/* now find rate that matches requested refresh rate */1999for (j = 0; j < nrates; j++) {2000if (rates[j] == refreshRate) {2001/* we've found our rate; break out of the loop */2002chosenSizeIndex = i;2003chosenRate = rates[j];2004foundConfig = JNI_TRUE;2005break;2006}2007}20082009break;2010}2011}2012}20132014if (foundConfig) {2015Status status =2016awt_XRRSetScreenConfigAndRate(awt_display, config, root,2017chosenSizeIndex,2018currentRotation,2019chosenRate,2020CurrentTime);20212022/* issue XSync to ensure immediate mode change */2023XSync(awt_display, False);20242025if (status == RRSetConfigSuccess) {2026success = JNI_TRUE;2027}2028}20292030awt_XRRFreeScreenConfigInfo(config);2031}20322033AWT_FLUSH_UNLOCK();20342035if (!success && !(*env)->ExceptionCheck(env)) {2036JNU_ThrowInternalError(env, "Could not set display mode");2037}2038#endif /* !HEADLESS */2039}20402041/*2042* Class: sun_awt_X11GraphicsDevice2043* Method: enterFullScreenExclusive2044* Signature: (J)V2045*/2046JNIEXPORT void JNICALL2047Java_sun_awt_X11GraphicsDevice_enterFullScreenExclusive2048(JNIEnv* env, jclass x11gd,2049jlong window)2050{2051#ifndef HEADLESS2052Window win = (Window)window;20532054AWT_LOCK();2055XSync(awt_display, False); /* ensures window is visible first */2056X11GD_SetFullscreenMode(win, JNI_TRUE);2057AWT_UNLOCK();2058#endif /* !HEADLESS */2059}20602061/*2062* Class: sun_awt_X11GraphicsDevice2063* Method: exitFullScreenExclusive2064* Signature: (J)V2065*/2066JNIEXPORT void JNICALL2067Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive2068(JNIEnv* env, jclass x11gd,2069jlong window)2070{2071#ifndef HEADLESS2072Window win = (Window)window;20732074AWT_LOCK();2075X11GD_SetFullscreenMode(win, JNI_FALSE);2076AWT_UNLOCK();2077#endif /* !HEADLESS */2078}20792080/**2081* End DisplayMode/FullScreen support2082*/208320842085