6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include "jni_util.h"
27 #include "awt_p.h"
28 #include "awt.h"
29 #include "color.h"
30 #include <java_awt_DisplayMode.h>
31 #include <sun_awt_X11GraphicsEnvironment.h>
32 #include <sun_awt_X11GraphicsDevice.h>
33 #include <sun_awt_X11GraphicsConfig.h>
34 #ifndef HEADLESS
35 #include <X11/extensions/Xdbe.h>
36 #include <X11/XKBlib.h>
37 #ifndef NO_XRANDR
38 #include <X11/extensions/Xrandr.h>
39 #endif
40 #include "GLXGraphicsConfig.h"
41 #endif /* !HEADLESS */
42
43 #include <jni.h>
44 #include <jni_util.h>
45 #include <jvm.h>
46 #include <jvm_md.h>
47 #include <jlong.h>
48 #include "systemScale.h"
49 #include <stdlib.h>
50
51 #include "awt_GraphicsEnv.h"
52 #include "awt_util.h"
53 #include "gdefs.h"
54 #include <dlfcn.h>
55 #include "Trace.h"
56
57 #ifndef HEADLESS
58
59 int awt_numScreens; /* Xinerama-aware number of screens */
60
61 AwtScreenDataPtr x11Screens;
62
63 /*
64 * Set in initDisplay() to indicate whether we should attempt to initialize
65 * GLX for the default configuration.
66 */
67 static jboolean glxRequested = JNI_FALSE;
68
69 #endif /* !HEADLESS */
70
71 #ifdef HEADLESS
72 #define Display void
73 #endif /* HEADLESS */
74
75 Display *awt_display;
76
77 jclass tkClass = NULL;
78 jmethodID awtLockMID = NULL;
79 jmethodID awtUnlockMID = NULL;
80 jmethodID awtWaitMID = NULL;
81 jmethodID awtNotifyMID = NULL;
82 jmethodID awtNotifyAllMID = NULL;
83 jboolean awtLockInited = JNI_FALSE;
84
85 /** Convenience macro for loading the lock-related method IDs. */
86 #define GET_STATIC_METHOD(klass, method_id, method_name, method_sig) \
87 do { \
88 method_id = (*env)->GetStaticMethodID(env, klass, \
89 method_name, method_sig); \
90 if (method_id == NULL) return NULL; \
91 } while (0)
92
93 struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
94
95 #ifndef HEADLESS
96 int awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata);
97 #endif /* HEADLESS */
98
99 static char *x11GraphicsConfigClassName = "sun/awt/X11GraphicsConfig";
100
101 /* AWT and Xinerama
102 *
103 * As of fix 4356756, AWT is Xinerama-aware. X11GraphicsDevices are created for
104 * each screen of a Xinerama setup, though X11 itself still only sees a single
105 * display.
106 * In many places where we talk to X11, a xinawareScreen variable is used to
107 * pass the correct Display value, depending on the circumstances (a single
108 * X display, multiple X displays, or a single X display with multiple
109 * Xinerama screens).
110 */
111
112 #define MAXFRAMEBUFFERS 16
113 typedef struct {
114 int screen_number;
115 short x_org;
116 short y_org;
117 short width;
118 short height;
119 } XineramaScreenInfo;
120
121 typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);
122 static XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
123 Bool usingXinerama = False;
124
125 JNIEXPORT void JNICALL
126 Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls)
127 {
128 x11GraphicsConfigIDs.aData = NULL;
129 x11GraphicsConfigIDs.bitsPerPixel = NULL;
130
131 x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J");
132 CHECK_NULL(x11GraphicsConfigIDs.aData);
133 x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I");
134 CHECK_NULL(x11GraphicsConfigIDs.bitsPerPixel);
135 }
136
137 #ifndef HEADLESS
138
139 /*
140 * XIOErrorHandler
141 */
142 static int xioerror_handler(Display *disp)
143 {
144 if (awtLockInited) {
145 if (errno == EPIPE) {
146 jio_fprintf(stderr, "X connection to %s host broken (explicit kill or server shutdown)\n", XDisplayName(NULL));
147 }
148 /*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", "I/O error"); */
149 }
150 return 0;
151 }
152
153 static AwtGraphicsConfigDataPtr
154 findWithTemplate(XVisualInfo *vinfo,
155 long mask)
156 {
157
158 XVisualInfo *visualList;
388
389 if (screenDataPtr->defaultConfig == NULL) {
390 /*
391 * After a display change event, the default config field will have
392 * been reset, so we need to recreate the default config here.
393 */
394 screenDataPtr->defaultConfig = makeDefaultConfig(env, screen);
395 }
396
397 defaultConfig = screenDataPtr->defaultConfig;
398 graphicsConfigs[0] = defaultConfig;
399 nConfig = 1; /* reserve index 0 for default config */
400
401 // Only use the RENDER extension if it is available on the X server
402 if (XQueryExtension(awt_display, "RENDER",
403 &major_opcode, &first_event, &first_error))
404 {
405 DTRACE_PRINTLN("RENDER extension available");
406 xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
407
408 #ifdef MACOSX
409 #define XRENDER_LIB "/usr/X11/lib/libXrender.dylib"
410 #else
411 #define XRENDER_LIB "libXrender.so"
412 #endif
413
414 if (xrenderLibHandle == NULL) {
415 xrenderLibHandle = dlopen(XRENDER_LIB,
416 RTLD_LAZY | RTLD_GLOBAL);
417 }
418
419 #if defined(__solaris__)
420 if (xrenderLibHandle == NULL) {
421 xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1",
422 RTLD_LAZY | RTLD_GLOBAL);
423 }
424 #elif defined(_AIX)
425 if (xrenderLibHandle == NULL) {
426 xrenderLibHandle = dlopen("libXrender.a(libXrender.so.0)",
427 RTLD_MEMBER | RTLD_LAZY | RTLD_GLOBAL);
428 }
429 #endif
430 if (xrenderLibHandle != NULL) {
431 DTRACE_PRINTLN("Loaded libXrender");
432 xrenderFindVisualFormat =
433 (XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,
434 "XRenderFindVisualFormat");
435 if (xrenderFindVisualFormat == NULL) {
436 DTRACE_PRINTLN1("Can't find 'XRenderFindVisualFormat' in libXrender (%s)", dlerror());
588 screenDataPtr->numConfigs = nConfig;
589 screenDataPtr->configs = graphicsConfigs;
590
591 cleanup:
592 if (n8p != 0)
593 XFree (pVI8p);
594 if (n12p != 0)
595 XFree (pVI12p);
596 if (n8s != 0)
597 XFree (pVI8s);
598 if (n8gs != 0)
599 XFree (pVI8gs);
600 if (n8sg != 0)
601 XFree (pVI8sg);
602 if (n1sg != 0)
603 XFree (pVI1sg);
604
605 AWT_UNLOCK ();
606 }
607
608 #ifndef HEADLESS
609
610 /*
611 * Checks if Xinerama is running and perform Xinerama-related initialization.
612 */
613 static void xineramaInit(void) {
614 char* XinExtName = "XINERAMA";
615 int32_t major_opcode, first_event, first_error;
616 Bool gotXinExt = False;
617 void* libHandle = NULL;
618 int32_t locNumScr = 0;
619 XineramaScreenInfo *xinInfo;
620 char* XineramaQueryScreensName = "XineramaQueryScreens";
621
622 gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
623 &first_event, &first_error);
624
625 if (!gotXinExt) {
626 DTRACE_PRINTLN("Xinerama extension is not available");
627 return;
628 }
629
651 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
652 if (xinInfo != NULL) {
653 if (locNumScr > XScreenCount(awt_display)) {
654 DTRACE_PRINTLN("Enabling Xinerama support");
655 usingXinerama = True;
656 /* set global number of screens */
657 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
658 awt_numScreens = locNumScr;
659 } else {
660 DTRACE_PRINTLN("XineramaQueryScreens <= XScreenCount");
661 }
662 XFree(xinInfo);
663 } else {
664 DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
665 }
666 }
667 } else {
668 DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
669 }
670 }
671 #endif /* HEADLESS */
672
673 Display *
674 awt_init_Display(JNIEnv *env, jobject this)
675 {
676 jclass klass;
677 Display *dpy;
678 char errmsg[128];
679 int i;
680
681 if (awt_display) {
682 return awt_display;
683 }
684
685 /* Load AWT lock-related methods in SunToolkit */
686 klass = (*env)->FindClass(env, "sun/awt/SunToolkit");
687 if (klass == NULL) return NULL;
688 GET_STATIC_METHOD(klass, awtLockMID, "awtLock", "()V");
689 GET_STATIC_METHOD(klass, awtUnlockMID, "awtUnlock", "()V");
690 GET_STATIC_METHOD(klass, awtWaitMID, "awtLockWait", "(J)V");
691 GET_STATIC_METHOD(klass, awtNotifyMID, "awtLockNotify", "()V");
728 if (x11Screens == NULL) {
729 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),
730 NULL);
731 return NULL;
732 }
733
734 for (i = 0; i < awt_numScreens; i++) {
735 if (usingXinerama) {
736 /* All Xinerama screens use the same X11 root for now */
737 x11Screens[i].root = RootWindow(awt_display, 0);
738 }
739 else {
740 x11Screens[i].root = RootWindow(awt_display, i);
741 }
742 x11Screens[i].defaultConfig = makeDefaultConfig(env, i);
743 JNU_CHECK_EXCEPTION_RETURN(env, NULL);
744 }
745
746 return dpy;
747 }
748 #endif /* !HEADLESS */
749
750 /*
751 * Class: sun_awt_X11GraphicsEnvironment
752 * Method: getDefaultScreenNum
753 * Signature: ()I
754 */
755 JNIEXPORT jint JNICALL
756 Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum(
757 JNIEnv *env, jobject this)
758 {
759 #ifdef HEADLESS
760 return (jint)0;
761 #else
762 return DefaultScreen(awt_display);
763 #endif /* !HEADLESS */
764 }
765
766 #ifndef HEADLESS
767 static void ensureConfigsInited(JNIEnv* env, int screen) {
768 if (x11Screens[screen].numConfigs == 0) {
769 if (env == NULL) {
770 env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
771 }
772 getAllConfigs (env, screen, &(x11Screens[screen]));
773 }
774 }
775 #endif
776
777 #ifdef HEADLESS
778 void* getDefaultConfig(int screen) {
779 return NULL;
780 }
781 #else
782 AwtGraphicsConfigDataPtr
783 getDefaultConfig(int screen) {
784 ensureConfigsInited(NULL, screen);
785 return x11Screens[screen].defaultConfig;
786 }
787 #endif /* !HEADLESS */
788
789 /*
790 * Class: sun_awt_X11GraphicsEnvironment
791 * Method: initDisplay
792 * Signature: (Z)V
793 */
794 JNIEXPORT void JNICALL
795 Java_sun_awt_X11GraphicsEnvironment_initDisplay(JNIEnv *env, jobject this,
796 jboolean glxReq)
797 {
798 #ifndef HEADLESS
799 glxRequested = glxReq;
800 (void) awt_init_Display(env, this);
801 #endif /* !HEADLESS */
802 }
803
804 /*
805 * Class: sun_awt_X11GraphicsEnvironment
806 * Method: initGLX
807 * Signature: ()Z
808 */
809 JNIEXPORT jboolean JNICALL
810 Java_sun_awt_X11GraphicsEnvironment_initGLX(JNIEnv *env, jclass x11ge)
811 {
812 #ifndef HEADLESS
813 jboolean glxAvailable;
814
815 AWT_LOCK();
816 glxAvailable = GLXGC_IsGLXAvailable();
817 AWT_UNLOCK();
818
819 return glxAvailable;
820 #else
821 return JNI_FALSE;
822 #endif /* !HEADLESS */
823 }
824
825 /*
826 * Class: sun_awt_X11GraphicsEnvironment
827 * Method: getNumScreens
828 * Signature: ()I
829 */
830 JNIEXPORT jint JNICALL
831 Java_sun_awt_X11GraphicsEnvironment_getNumScreens(JNIEnv *env, jobject this)
832 {
833 #ifdef HEADLESS
834 return (jint)0;
835 #else
836 return awt_numScreens;
837 #endif /* !HEADLESS */
838 }
839
840 /*
841 * Class: sun_awt_X11GraphicsDevice
842 * Method: getDisplay
843 * Signature: ()J
844 */
845 JNIEXPORT jlong JNICALL
846 Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)
847 {
848 #ifdef HEADLESS
849 return NULL;
850 #else
851 return ptr_to_jlong(awt_display);
852 #endif /* !HEADLESS */
853 }
854
855 #ifdef MITSHM
856
857 static jint canUseShmExt = UNSET_MITSHM;
858 static jint canUseShmExtPixmaps = UNSET_MITSHM;
859 static jboolean xshmAttachFailed = JNI_FALSE;
860
861 int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr) {
862 if (xerr->minor_code == X_ShmAttach) {
863 xshmAttachFailed = JNI_TRUE;
864 }
865 return 0;
866 }
867 jboolean isXShmAttachFailed() {
868 return xshmAttachFailed;
869 }
870 void resetXShmAttachFailed() {
871 xshmAttachFailed = JNI_FALSE;
872 }
959 JNIEXPORT jint JNICALL
960 Java_sun_awt_X11GraphicsEnvironment_checkShmExt(JNIEnv *env, jobject this)
961 {
962
963 int shmExt = NOEXT_MITSHM, shmPixmaps;
964 #ifdef MITSHM
965 TryInitMITShm(env, &shmExt, &shmPixmaps);
966 #endif
967 return shmExt;
968 }
969
970 /*
971 * Class: sun_awt_X11GraphicsEnvironment
972 * Method: getDisplayString
973 * Signature: ()Ljava/lang/String
974 */
975 JNIEXPORT jstring JNICALL
976 Java_sun_awt_X11GraphicsEnvironment_getDisplayString
977 (JNIEnv *env, jobject this)
978 {
979 #ifdef HEADLESS
980 return (jstring)NULL;
981 #else
982 return (*env)->NewStringUTF(env, DisplayString(awt_display));
983 #endif /* HEADLESS */
984 }
985
986
987 /*
988 * Class: sun_awt_X11GraphicsDevice
989 * Method: getNumConfigs
990 * Signature: ()I
991 */
992 JNIEXPORT jint JNICALL
993 Java_sun_awt_X11GraphicsDevice_getNumConfigs(
994 JNIEnv *env, jobject this, jint screen)
995 {
996 #ifdef HEADLESS
997 return (jint)0;
998 #else
999 ensureConfigsInited(env, screen);
1000 return x11Screens[screen].numConfigs;
1001 #endif /* !HEADLESS */
1002 }
1003
1004 /*
1005 * Class: sun_awt_X11GraphicsDevice
1006 * Method: getConfigVisualId
1007 * Signature: (I)I
1008 */
1009 JNIEXPORT jint JNICALL
1010 Java_sun_awt_X11GraphicsDevice_getConfigVisualId(
1011 JNIEnv *env, jobject this, jint index, jint screen)
1012 {
1013 #ifdef HEADLESS
1014 return (jint)0;
1015 #else
1016 int visNum;
1017
1018 ensureConfigsInited(env, screen);
1019 if (index == 0) {
1020 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.visualid);
1021 } else {
1022 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.visualid);
1023 }
1024 #endif /* !HEADLESS */
1025 }
1026
1027 /*
1028 * Class: sun_awt_X11GraphicsDevice
1029 * Method: getConfigDepth
1030 * Signature: (I)I
1031 */
1032 JNIEXPORT jint JNICALL
1033 Java_sun_awt_X11GraphicsDevice_getConfigDepth(
1034 JNIEnv *env, jobject this, jint index, jint screen)
1035 {
1036 #ifdef HEADLESS
1037 return (jint)0;
1038 #else
1039 int visNum;
1040
1041 ensureConfigsInited(env, screen);
1042 if (index == 0) {
1043 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.depth);
1044 } else {
1045 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.depth);
1046 }
1047 #endif /* !HEADLESS */
1048 }
1049
1050 /*
1051 * Class: sun_awt_X11GraphicsDevice
1052 * Method: getConfigColormap
1053 * Signature: (I)I
1054 */
1055 JNIEXPORT jint JNICALL
1056 Java_sun_awt_X11GraphicsDevice_getConfigColormap(
1057 JNIEnv *env, jobject this, jint index, jint screen)
1058 {
1059 #ifdef HEADLESS
1060 return (jint)0;
1061 #else
1062 int visNum;
1063
1064 ensureConfigsInited(env, screen);
1065 if (index == 0) {
1066 return ((jint)x11Screens[screen].defaultConfig->awt_cmap);
1067 } else {
1068 return ((jint)x11Screens[screen].configs[index]->awt_cmap);
1069 }
1070 #endif /* !HEADLESS */
1071 }
1072
1073 /*
1074 * Class: sun_awt_X11GraphicsDevice
1075 * Method: resetNativeData
1076 * Signature: (I)V
1077 */
1078 JNIEXPORT void JNICALL
1079 Java_sun_awt_X11GraphicsDevice_resetNativeData
1080 (JNIEnv *env, jclass x11gd, jint screen)
1081 {
1082 #ifndef HEADLESS
1083 /*
1084 * Reset references to the various configs; the actual native config data
1085 * will be free'd later by the Disposer mechanism when the Java-level
1086 * X11GraphicsConfig objects go away. By setting these values to NULL,
1087 * we ensure that they will be reinitialized as necessary (for example,
1088 * see the getNumConfigs() method).
1089 */
1090 if (x11Screens[screen].configs) {
1091 free(x11Screens[screen].configs);
1092 x11Screens[screen].configs = NULL;
1093 }
1094 x11Screens[screen].defaultConfig = NULL;
1095 x11Screens[screen].numConfigs = 0;
1096 #endif /* !HEADLESS */
1097 }
1098
1099 /*
1100 * Class: sun_awt_X11GraphicsConfig
1101 * Method: dispose
1102 * Signature: (J)V
1103 */
1104 JNIEXPORT void JNICALL
1105 Java_sun_awt_X11GraphicsConfig_dispose
1106 (JNIEnv *env, jclass x11gc, jlong configData)
1107 {
1108 #ifndef HEADLESS
1109 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)
1110 jlong_to_ptr(configData);
1111
1112 if (aData == NULL) {
1113 return;
1114 }
1115
1116 AWT_LOCK();
1117 if (aData->awt_cmap) {
1118 XFreeColormap(awt_display, aData->awt_cmap);
1119 }
1120 if (aData->awtImage) {
1121 free(aData->awtImage);
1122 }
1123 if (aData->monoImage) {
1124 XFree(aData->monoImage);
1125 }
1126 if (aData->monoPixmap) {
1127 XFreePixmap(awt_display, aData->monoPixmap);
1128 }
1130 XFreeGC(awt_display, aData->monoPixmapGC);
1131 }
1132 if (aData->color_data) {
1133 free(aData->color_data);
1134 }
1135 AWT_UNLOCK();
1136
1137 if (aData->glxInfo) {
1138 /*
1139 * The native GLXGraphicsConfig data needs to be disposed separately
1140 * on the OGL queue flushing thread (should not be called while
1141 * the AWT lock is held).
1142 */
1143 JNU_CallStaticMethodByName(env, NULL,
1144 "sun/java2d/opengl/OGLRenderQueue",
1145 "disposeGraphicsConfig", "(J)V",
1146 ptr_to_jlong(aData->glxInfo));
1147 }
1148
1149 free(aData);
1150 #endif /* !HEADLESS */
1151 }
1152
1153 /*
1154 * Class: sun_awt_X11GraphicsConfig
1155 * Method: getXResolution
1156 * Signature: ()I
1157 */
1158 JNIEXPORT jdouble JNICALL
1159 Java_sun_awt_X11GraphicsConfig_getXResolution(
1160 JNIEnv *env, jobject this, jint screen)
1161 {
1162 #ifdef HEADLESS
1163 return (jdouble)0;
1164 #else
1165 return ((DisplayWidth(awt_display, screen) * 25.4) /
1166 DisplayWidthMM(awt_display, screen));
1167 #endif /* !HEADLESS */
1168 }
1169
1170 /*
1171 * Class: sun_awt_X11GraphicsConfig
1172 * Method: getYResolution
1173 * Signature: ()I
1174 */
1175 JNIEXPORT jdouble JNICALL
1176 Java_sun_awt_X11GraphicsConfig_getYResolution(
1177 JNIEnv *env, jobject this, jint screen)
1178 {
1179 #ifdef HEADLESS
1180 return (jdouble)0;
1181 #else
1182 return ((DisplayHeight(awt_display, screen) * 25.4) /
1183 DisplayHeightMM(awt_display, screen));
1184 #endif /* !HEADLESS */
1185 }
1186
1187
1188 /*
1189 * Class: sun_awt_X11GraphicsConfig
1190 * Method: getNumColors
1191 * Signature: ()I
1192 */
1193 JNIEXPORT jint JNICALL
1194 Java_sun_awt_X11GraphicsConfig_getNumColors(
1195 JNIEnv *env, jobject this)
1196 {
1197 #ifdef HEADLESS
1198 return (jint)0;
1199 #else
1200 AwtGraphicsConfigData *adata;
1201
1202 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1203 x11GraphicsConfigIDs.aData);
1204
1205 return adata->awt_num_colors;
1206 #endif /* !HEADLESS */
1207 }
1208
1209 /*
1210 * Class: sun_awt_X11GraphicsConfig
1211 * Method: init
1212 * Signature: (I)V
1213 */
1214 JNIEXPORT void JNICALL
1215 Java_sun_awt_X11GraphicsConfig_init(
1216 JNIEnv *env, jobject this, jint visualNum, jint screen)
1217 {
1218 #ifndef HEADLESS
1219 AwtGraphicsConfigData *adata = NULL;
1220 AwtScreenData asd = x11Screens[screen];
1221 int i, n;
1222 int depth;
1223 XImage * tempImage;
1224
1225 /* If haven't gotten all of the configs yet, do it now. */
1226 if (asd.numConfigs == 0) {
1227 getAllConfigs (env, screen, &asd);
1228 }
1229
1230 /* Check the graphicsConfig for this visual */
1231 for (i = 0; i < asd.numConfigs; i++) {
1232 AwtGraphicsConfigDataPtr agcPtr = asd.configs[i];
1233 if ((jint)agcPtr->awt_visInfo.visualid == visualNum) {
1234 adata = agcPtr;
1235 break;
1236 }
1237 }
1238
1239 /* If didn't find the visual, throw an exception... */
1240 if (adata == (AwtGraphicsConfigData *) NULL) {
1241 JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified");
1242 return;
1243 }
1244
1245 /* adata->awt_cmap initialization has been deferred to
1246 * makeColorModel call
1247 */
1248
1249 JNU_SetLongFieldFromPtr(env, this, x11GraphicsConfigIDs.aData, adata);
1250
1251 depth = adata->awt_visInfo.depth;
1252 tempImage = XCreateImage(awt_display,
1253 adata->awt_visInfo.visual,
1254 depth, ZPixmap, 0, NULL, 1, 1, 32, 0);
1255 adata->pixelStride = (tempImage->bits_per_pixel + 7) / 8;
1256 (*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel,
1257 (jint)tempImage->bits_per_pixel);
1258 XDestroyImage(tempImage);
1259 #endif /* !HEADLESS */
1260 }
1261
1262
1263
1264 /*
1265 * Class: sun_awt_X11GraphicsConfig
1266 * Method: makeColorModel
1267 * Signature: ()Ljava/awt/image/ColorModel
1268 */
1269 JNIEXPORT jobject JNICALL
1270 Java_sun_awt_X11GraphicsConfig_makeColorModel(
1271 JNIEnv *env, jobject this)
1272 {
1273 #ifdef HEADLESS
1274 return NULL;
1275 #else
1276 AwtGraphicsConfigData *adata;
1277 jobject colorModel;
1278
1279 /*
1280 * If awt is not locked yet, return null since the toolkit is not
1281 * initialized yet.
1282 */
1283 if (!awtLockInited) {
1284 return NULL;
1285 }
1286
1287 AWT_LOCK ();
1288
1289 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1290 x11GraphicsConfigIDs.aData);
1291
1292 /* If colormap entry of adata is NULL, need to create it now */
1293 if (adata->awt_cmap == (Colormap) NULL) {
1294 awtJNI_CreateColorData (env, adata, 1);
1295 }
1296
1297 /* Make Color Model object for this GraphicsConfiguration */
1298 colorModel = (*env)->ExceptionCheck(env)
1299 ? NULL : awtJNI_GetColorModel (env, adata);
1300
1301 AWT_UNLOCK ();
1302
1303 return colorModel;
1304 #endif /* !HEADLESS */
1305 }
1306
1307
1308 /*
1309 * Class: sun_awt_X11GraphicsConfig
1310 * Method: getBounds
1311 * Signature: ()Ljava/awt/Rectangle
1312 */
1313 JNIEXPORT jobject JNICALL
1314 Java_sun_awt_X11GraphicsConfig_pGetBounds(JNIEnv *env, jobject this, jint screen)
1315 {
1316 #ifdef HEADLESS
1317 return NULL;
1318 #else
1319 jclass clazz;
1320 jmethodID mid;
1321 jobject bounds = NULL;
1322 AwtGraphicsConfigDataPtr adata;
1323 int32_t locNumScr = 0;
1324 XineramaScreenInfo *xinInfo;
1325
1326 adata = (AwtGraphicsConfigDataPtr)
1327 JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData);
1328
1329 clazz = (*env)->FindClass(env, "java/awt/Rectangle");
1330 CHECK_NULL_RETURN(clazz, NULL);
1331 mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V");
1332 if (mid != NULL) {
1333 if (usingXinerama) {
1334 if (0 <= screen && screen < awt_numScreens) {
1335 AWT_LOCK();
1336 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
1337 AWT_UNLOCK();
1338 if (xinInfo != NULL && locNumScr > 0) {
1357 if (!bounds) {
1358 // Xinerama cannot provide correct bounds, will try X11
1359 XWindowAttributes xwa;
1360 memset(&xwa, 0, sizeof(xwa));
1361
1362 AWT_LOCK ();
1363 XGetWindowAttributes(awt_display,
1364 RootWindow(awt_display, adata->awt_visInfo.screen),
1365 &xwa);
1366 AWT_UNLOCK ();
1367
1368 bounds = (*env)->NewObject(env, clazz, mid, 0, 0,
1369 xwa.width, xwa.height);
1370 }
1371
1372 if ((*env)->ExceptionOccurred(env)) {
1373 return NULL;
1374 }
1375 }
1376 return bounds;
1377 #endif /* !HEADLESS */
1378 }
1379
1380 /*
1381 * Class: sun_awt_X11GraphicsConfig
1382 * Method: createBackBuffer
1383 * Signature: (JI)J
1384 */
1385 JNIEXPORT jlong JNICALL
1386 Java_sun_awt_X11GraphicsConfig_createBackBuffer
1387 (JNIEnv *env, jobject this, jlong window, jint swapAction)
1388 {
1389 int32_t v1, v2;
1390 XdbeBackBuffer ret = (unsigned long) 0;
1391 Window w = (Window)window;
1392 AWT_LOCK();
1393 if (!XdbeQueryExtension(awt_display, &v1, &v2)) {
1394 JNU_ThrowByName(env, "java/lang/Exception",
1395 "Could not query double-buffer extension");
1396 AWT_UNLOCK();
1397 return (jlong)0;
1433 XdbeBeginIdiom(awt_display);
1434 swapInfo.swap_window = (Window)window;
1435 swapInfo.swap_action = (XdbeSwapAction)swapAction;
1436 if (!XdbeSwapBuffers(awt_display, &swapInfo, 1)) {
1437 JNU_ThrowInternalError(env, "Could not swap buffers");
1438 }
1439 XdbeEndIdiom(awt_display);
1440
1441 AWT_FLUSH_UNLOCK();
1442 }
1443
1444 /*
1445 * Class: sun_awt_X11GraphicsConfig
1446 * Method: isTranslucencyCapable
1447 * Signature: (J)V
1448 */
1449 JNIEXPORT jboolean JNICALL
1450 Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable
1451 (JNIEnv *env, jobject this, jlong configData)
1452 {
1453 #ifdef HEADLESS
1454 return JNI_FALSE;
1455 #else
1456 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);
1457 if (aData == NULL) {
1458 return JNI_FALSE;
1459 }
1460 return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE;
1461 #endif
1462 }
1463
1464 /*
1465 * Class: sun_awt_X11GraphicsDevice
1466 * Method: isDBESupported
1467 * Signature: ()Z
1468 */
1469 JNIEXPORT jboolean JNICALL
1470 Java_sun_awt_X11GraphicsDevice_isDBESupported(JNIEnv *env, jobject this)
1471 {
1472 #ifdef HEADLESS
1473 return JNI_FALSE;
1474 #else
1475 int opcode = 0, firstEvent = 0, firstError = 0;
1476 jboolean ret;
1477
1478 AWT_LOCK();
1479 ret = (jboolean)XQueryExtension(awt_display, "DOUBLE-BUFFER",
1480 &opcode, &firstEvent, &firstError);
1481 AWT_FLUSH_UNLOCK();
1482 return ret;
1483 #endif /* !HEADLESS */
1484 }
1485
1486 /*
1487 * Class: sun_awt_X11GraphicsDevice
1488 * Method: getDoubleBufferVisuals
1489 * Signature: (I)V
1490 */
1491 JNIEXPORT void JNICALL
1492 Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env,
1493 jobject this, jint screen)
1494 {
1495 #ifndef HEADLESS
1496 jclass clazz;
1497 jmethodID midAddVisual;
1498 Window rootWindow;
1499 int i, n = 1;
1500 XdbeScreenVisualInfo* visScreenInfo;
1501 int xinawareScreen;
1502
1503 if (usingXinerama) {
1504 xinawareScreen = 0;
1505 }
1506 else {
1507 xinawareScreen = screen;
1508 }
1509
1510 clazz = (*env)->GetObjectClass(env, this);
1511 midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual",
1512 "(I)V");
1513 CHECK_NULL(midAddVisual);
1514 AWT_LOCK();
1515 rootWindow = RootWindow(awt_display, xinawareScreen);
1516 visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n);
1517 if (visScreenInfo == NULL) {
1518 JNU_ThrowInternalError(env, "Could not get visual info");
1519 AWT_UNLOCK();
1520 return;
1521 }
1522 AWT_FLUSH_UNLOCK();
1523 for (i = 0; i < visScreenInfo->count; i++) {
1524 XdbeVisualInfo* visInfo = visScreenInfo->visinfo;
1525 (*env)->CallVoidMethod(env, this, midAddVisual, (visInfo[i]).visual);
1526 if ((*env)->ExceptionCheck(env)) {
1527 break;
1528 }
1529 }
1530 #endif /* !HEADLESS */
1531 }
1532
1533 /*
1534 * Class: sun_awt_X11GraphicsEnvironment
1535 * Method: pRunningXinerama
1536 * Signature: ()Z
1537 */
1538 JNIEXPORT jboolean JNICALL
1539 Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama(JNIEnv *env,
1540 jobject this)
1541 {
1542 #ifdef HEADLESS
1543 return JNI_FALSE;
1544 #else
1545 return usingXinerama ? JNI_TRUE : JNI_FALSE;
1546 #endif /* HEADLESS */
1547 }
1548
1549 /**
1550 * Begin DisplayMode/FullScreen support
1551 */
1552
1553 #ifndef HEADLESS
1554
1555 #ifndef NO_XRANDR
1556
1557 #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
1558 #define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
1559
1560 typedef Status
1561 (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
1562 typedef XRRScreenConfiguration*
1563 (*XRRGetScreenInfoType)(Display *dpy, Drawable root);
1564 typedef void
1565 (*XRRFreeScreenConfigInfoType)(XRRScreenConfiguration *config);
1566 typedef short*
1567 (*XRRConfigRatesType)(XRRScreenConfiguration *config,
1568 int sizeID, int *nrates);
1569 typedef short
1570 (*XRRConfigCurrentRateType)(XRRScreenConfiguration *config);
1571 typedef XRRScreenSize*
1572 (*XRRConfigSizesType)(XRRScreenConfiguration *config,
1573 int *nsizes);
1574 typedef SizeID
1772
1773 if (wmState == None || wmStateFs == None
1774 || !XGetWindowAttributes(awt_display, win, &attr)) {
1775 return;
1776 }
1777
1778 memset(&event, 0, sizeof(event));
1779 event.xclient.type = ClientMessage;
1780 event.xclient.message_type = wmState;
1781 event.xclient.display = awt_display;
1782 event.xclient.window = win;
1783 event.xclient.format = 32;
1784 event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove
1785 event.xclient.data.l[1] = wmStateFs;
1786
1787 XSendEvent(awt_display, attr.root, False,
1788 SubstructureRedirectMask | SubstructureNotifyMask,
1789 &event);
1790 XSync(awt_display, False);
1791 }
1792 #endif /* !HEADLESS */
1793
1794 /*
1795 * Class: sun_awt_X11GraphicsDevice
1796 * Method: initXrandrExtension
1797 * Signature: ()Z
1798 */
1799 JNIEXPORT jboolean JNICALL
1800 Java_sun_awt_X11GraphicsDevice_initXrandrExtension
1801 (JNIEnv *env, jclass x11gd)
1802 {
1803 #if defined(HEADLESS) || defined(NO_XRANDR)
1804 return JNI_FALSE;
1805 #else
1806 int opcode = 0, firstEvent = 0, firstError = 0;
1807 jboolean ret;
1808
1809 AWT_LOCK();
1810 ret = (jboolean)XQueryExtension(awt_display, "RANDR",
1811 &opcode, &firstEvent, &firstError);
1812 if (ret) {
1813 ret = X11GD_InitXrandrFuncs(env);
1814 }
1815 AWT_FLUSH_UNLOCK();
1816
1817 return ret;
1818 #endif /* HEADLESS */
1819 }
1820
1821 /*
1822 * Class: sun_awt_X11GraphicsDevice
1823 * Method: getCurrentDisplayMode
1824 * Signature: (I)Ljava/awt/DisplayMode;
1825 */
1826 JNIEXPORT jobject JNICALL
1827 Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
1828 (JNIEnv* env, jclass x11gd, jint screen)
1829 {
1830 #if defined(HEADLESS) || defined(NO_XRANDR)
1831 return NULL;
1832 #else
1833 XRRScreenConfiguration *config;
1834 jobject displayMode = NULL;
1835
1836 AWT_LOCK();
1837
1838 if (usingXinerama && XScreenCount(awt_display) > 0) {
1839 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
1840 RootWindow(awt_display, 0));
1841 if (res) {
1842 if (res->noutput > screen) {
1843 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
1844 res, res->outputs[screen]);
1845 if (output_info) {
1846 if (output_info->crtc) {
1847 XRRCrtcInfo *crtc_info =
1848 awt_XRRGetCrtcInfo (awt_display, res,
1849 output_info->crtc);
1850 if (crtc_info) {
1893 curRate = awt_XRRConfigCurrentRate(config);
1894
1895 if ((sizes != NULL) &&
1896 (curSizeIndex < nsizes))
1897 {
1898 XRRScreenSize curSize = sizes[curSizeIndex];
1899 displayMode = X11GD_CreateDisplayMode(env,
1900 curSize.width,
1901 curSize.height,
1902 BIT_DEPTH_MULTI,
1903 curRate);
1904 }
1905
1906 awt_XRRFreeScreenConfigInfo(config);
1907 }
1908 }
1909
1910 AWT_FLUSH_UNLOCK();
1911
1912 return displayMode;
1913 #endif /* HEADLESS */
1914 }
1915
1916 /*
1917 * Class: sun_awt_X11GraphicsDevice
1918 * Method: enumDisplayModes
1919 * Signature: (ILjava/util/ArrayList;)V
1920 */
1921 JNIEXPORT void JNICALL
1922 Java_sun_awt_X11GraphicsDevice_enumDisplayModes
1923 (JNIEnv* env, jclass x11gd,
1924 jint screen, jobject arrayList)
1925 {
1926 #if !defined(HEADLESS) && !defined(NO_XRANDR)
1927
1928 AWT_LOCK();
1929
1930 if (usingXinerama && XScreenCount(awt_display) > 0) {
1931 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
1932 RootWindow(awt_display, 0));
1933 if (res) {
1934 if (res->noutput > screen) {
1935 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
1936 res, res->outputs[screen]);
1937 if (output_info) {
1938 int i;
1939 for (i = 0; i < output_info->nmode; i++) {
1940 RRMode m = output_info->modes[i];
1941 int j;
1942 XRRModeInfo *mode;
1943 for (j = 0; j < res->nmode; j++) {
1944 mode = &res->modes[j];
1945 if (mode->id == m) {
1946 float rate = 0;
1981 short *rates = awt_XRRConfigRates(config, i, &nrates);
1982
1983 for (j = 0; j < nrates; j++) {
1984 X11GD_AddDisplayMode(env, arrayList,
1985 size.width,
1986 size.height,
1987 BIT_DEPTH_MULTI,
1988 rates[j]);
1989 if ((*env)->ExceptionCheck(env)) {
1990 goto ret1;
1991 }
1992 }
1993 }
1994 }
1995 ret1:
1996 awt_XRRFreeScreenConfigInfo(config);
1997 }
1998 }
1999
2000 AWT_FLUSH_UNLOCK();
2001 #endif /* !HEADLESS */
2002 }
2003
2004 /*
2005 * Class: sun_awt_X11GraphicsDevice
2006 * Method: configDisplayMode
2007 * Signature: (IIII)V
2008 */
2009 JNIEXPORT void JNICALL
2010 Java_sun_awt_X11GraphicsDevice_configDisplayMode
2011 (JNIEnv* env, jclass x11gd,
2012 jint screen, jint width, jint height, jint refreshRate)
2013 {
2014 #if !defined(HEADLESS) && !defined(NO_XRANDR)
2015 jboolean success = JNI_FALSE;
2016 XRRScreenConfiguration *config;
2017 Drawable root;
2018 Rotation currentRotation = RR_Rotate_0;
2019
2020 AWT_LOCK();
2021
2022 root = RootWindow(awt_display, screen);
2023 config = awt_XRRGetScreenInfo(awt_display, root);
2024 if (config != NULL) {
2025 jboolean foundConfig = JNI_FALSE;
2026 int chosenSizeIndex = -1;
2027 short chosenRate = -1;
2028 int nsizes;
2029 XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
2030 awt_XRRConfigRotations(config, ¤tRotation);
2031
2032 if (sizes != NULL) {
2033 int i, j;
2034
2064 currentRotation,
2065 chosenRate,
2066 CurrentTime);
2067
2068 /* issue XSync to ensure immediate mode change */
2069 XSync(awt_display, False);
2070
2071 if (status == RRSetConfigSuccess) {
2072 success = JNI_TRUE;
2073 }
2074 }
2075
2076 awt_XRRFreeScreenConfigInfo(config);
2077 }
2078
2079 AWT_FLUSH_UNLOCK();
2080
2081 if (!success && !(*env)->ExceptionCheck(env)) {
2082 JNU_ThrowInternalError(env, "Could not set display mode");
2083 }
2084 #endif /* !HEADLESS */
2085 }
2086
2087 /*
2088 * Class: sun_awt_X11GraphicsDevice
2089 * Method: enterFullScreenExclusive
2090 * Signature: (J)V
2091 */
2092 JNIEXPORT void JNICALL
2093 Java_sun_awt_X11GraphicsDevice_enterFullScreenExclusive
2094 (JNIEnv* env, jclass x11gd,
2095 jlong window)
2096 {
2097 #ifndef HEADLESS
2098 Window win = (Window)window;
2099
2100 AWT_LOCK();
2101 XSync(awt_display, False); /* ensures window is visible first */
2102 X11GD_SetFullscreenMode(win, JNI_TRUE);
2103 AWT_UNLOCK();
2104 #endif /* !HEADLESS */
2105 }
2106
2107 /*
2108 * Class: sun_awt_X11GraphicsDevice
2109 * Method: exitFullScreenExclusive
2110 * Signature: (J)V
2111 */
2112 JNIEXPORT void JNICALL
2113 Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive
2114 (JNIEnv* env, jclass x11gd,
2115 jlong window)
2116 {
2117 #ifndef HEADLESS
2118 Window win = (Window)window;
2119
2120 AWT_LOCK();
2121 X11GD_SetFullscreenMode(win, JNI_FALSE);
2122 AWT_UNLOCK();
2123 #endif /* !HEADLESS */
2124 }
2125
2126 /**
2127 * End DisplayMode/FullScreen support
2128 */
2129
2130 static char *get_output_screen_name(JNIEnv *env, int screen) {
2131 #ifdef NO_XRANDR
2132 return NULL;
2133 #else
2134 if (!awt_XRRGetScreenResources || !awt_XRRGetOutputInfo) {
2135 return NULL;
2136 }
2137 char *name = NULL;
2138 AWT_LOCK();
2139 int scr = 0, out = 0;
2140 if (usingXinerama && XScreenCount(awt_display) > 0) {
2141 out = screen;
2142 } else {
2143 scr = screen;
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #ifdef HEADLESS
27 #error This file should not be included in headless library
28 #endif
29
30 #include "jni_util.h"
31 #include "awt_p.h"
32 #include "awt.h"
33 #include "color.h"
34 #include <java_awt_DisplayMode.h>
35 #include <sun_awt_X11GraphicsEnvironment.h>
36 #include <sun_awt_X11GraphicsDevice.h>
37 #include <sun_awt_X11GraphicsConfig.h>
38
39 #include <X11/extensions/Xdbe.h>
40 #include <X11/XKBlib.h>
41 #ifndef NO_XRANDR
42 #include <X11/extensions/Xrandr.h>
43 #endif
44 #include "GLXGraphicsConfig.h"
45
46 #include <jni.h>
47 #include <jni_util.h>
48 #include <jvm.h>
49 #include <jvm_md.h>
50 #include <jlong.h>
51 #include "systemScale.h"
52 #include <stdlib.h>
53
54 #include "awt_GraphicsEnv.h"
55 #include "awt_util.h"
56 #include "gdefs.h"
57 #include <dlfcn.h>
58 #include "Trace.h"
59
60 int awt_numScreens; /* Xinerama-aware number of screens */
61
62 AwtScreenDataPtr x11Screens;
63
64 /*
65 * Set in initDisplay() to indicate whether we should attempt to initialize
66 * GLX for the default configuration.
67 */
68 static jboolean glxRequested = JNI_FALSE;
69
70 Display *awt_display;
71
72 jclass tkClass = NULL;
73 jmethodID awtLockMID = NULL;
74 jmethodID awtUnlockMID = NULL;
75 jmethodID awtWaitMID = NULL;
76 jmethodID awtNotifyMID = NULL;
77 jmethodID awtNotifyAllMID = NULL;
78 jboolean awtLockInited = JNI_FALSE;
79
80 /** Convenience macro for loading the lock-related method IDs. */
81 #define GET_STATIC_METHOD(klass, method_id, method_name, method_sig) \
82 do { \
83 method_id = (*env)->GetStaticMethodID(env, klass, \
84 method_name, method_sig); \
85 if (method_id == NULL) return NULL; \
86 } while (0)
87
88 struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
89
90 int awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata);
91
92 static char *x11GraphicsConfigClassName = "sun/awt/X11GraphicsConfig";
93
94 /* AWT and Xinerama
95 *
96 * As of fix 4356756, AWT is Xinerama-aware. X11GraphicsDevices are created for
97 * each screen of a Xinerama setup, though X11 itself still only sees a single
98 * display.
99 * In many places where we talk to X11, a xinawareScreen variable is used to
100 * pass the correct Display value, depending on the circumstances (a single
101 * X display, multiple X displays, or a single X display with multiple
102 * Xinerama screens).
103 */
104
105 #define MAXFRAMEBUFFERS 16
106 typedef struct {
107 int screen_number;
108 short x_org;
109 short y_org;
110 short width;
111 short height;
112 } XineramaScreenInfo;
113
114 typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);
115 static XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
116 Bool usingXinerama = False;
117
118 JNIEXPORT void JNICALL
119 Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls)
120 {
121 x11GraphicsConfigIDs.aData = NULL;
122 x11GraphicsConfigIDs.bitsPerPixel = NULL;
123
124 x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J");
125 CHECK_NULL(x11GraphicsConfigIDs.aData);
126 x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I");
127 CHECK_NULL(x11GraphicsConfigIDs.bitsPerPixel);
128 }
129
130 /*
131 * XIOErrorHandler
132 */
133 static int xioerror_handler(Display *disp)
134 {
135 if (awtLockInited) {
136 if (errno == EPIPE) {
137 jio_fprintf(stderr, "X connection to %s host broken (explicit kill or server shutdown)\n", XDisplayName(NULL));
138 }
139 /*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", "I/O error"); */
140 }
141 return 0;
142 }
143
144 static AwtGraphicsConfigDataPtr
145 findWithTemplate(XVisualInfo *vinfo,
146 long mask)
147 {
148
149 XVisualInfo *visualList;
379
380 if (screenDataPtr->defaultConfig == NULL) {
381 /*
382 * After a display change event, the default config field will have
383 * been reset, so we need to recreate the default config here.
384 */
385 screenDataPtr->defaultConfig = makeDefaultConfig(env, screen);
386 }
387
388 defaultConfig = screenDataPtr->defaultConfig;
389 graphicsConfigs[0] = defaultConfig;
390 nConfig = 1; /* reserve index 0 for default config */
391
392 // Only use the RENDER extension if it is available on the X server
393 if (XQueryExtension(awt_display, "RENDER",
394 &major_opcode, &first_event, &first_error))
395 {
396 DTRACE_PRINTLN("RENDER extension available");
397 xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
398
399 if (xrenderLibHandle == NULL) {
400 xrenderLibHandle = dlopen("libXrender.so", RTLD_LAZY | RTLD_GLOBAL);
401 }
402
403 #if defined(__solaris__)
404 if (xrenderLibHandle == NULL) {
405 xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1",
406 RTLD_LAZY | RTLD_GLOBAL);
407 }
408 #elif defined(_AIX)
409 if (xrenderLibHandle == NULL) {
410 xrenderLibHandle = dlopen("libXrender.a(libXrender.so.0)",
411 RTLD_MEMBER | RTLD_LAZY | RTLD_GLOBAL);
412 }
413 #endif
414 if (xrenderLibHandle != NULL) {
415 DTRACE_PRINTLN("Loaded libXrender");
416 xrenderFindVisualFormat =
417 (XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,
418 "XRenderFindVisualFormat");
419 if (xrenderFindVisualFormat == NULL) {
420 DTRACE_PRINTLN1("Can't find 'XRenderFindVisualFormat' in libXrender (%s)", dlerror());
572 screenDataPtr->numConfigs = nConfig;
573 screenDataPtr->configs = graphicsConfigs;
574
575 cleanup:
576 if (n8p != 0)
577 XFree (pVI8p);
578 if (n12p != 0)
579 XFree (pVI12p);
580 if (n8s != 0)
581 XFree (pVI8s);
582 if (n8gs != 0)
583 XFree (pVI8gs);
584 if (n8sg != 0)
585 XFree (pVI8sg);
586 if (n1sg != 0)
587 XFree (pVI1sg);
588
589 AWT_UNLOCK ();
590 }
591
592 /*
593 * Checks if Xinerama is running and perform Xinerama-related initialization.
594 */
595 static void xineramaInit(void) {
596 char* XinExtName = "XINERAMA";
597 int32_t major_opcode, first_event, first_error;
598 Bool gotXinExt = False;
599 void* libHandle = NULL;
600 int32_t locNumScr = 0;
601 XineramaScreenInfo *xinInfo;
602 char* XineramaQueryScreensName = "XineramaQueryScreens";
603
604 gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
605 &first_event, &first_error);
606
607 if (!gotXinExt) {
608 DTRACE_PRINTLN("Xinerama extension is not available");
609 return;
610 }
611
633 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
634 if (xinInfo != NULL) {
635 if (locNumScr > XScreenCount(awt_display)) {
636 DTRACE_PRINTLN("Enabling Xinerama support");
637 usingXinerama = True;
638 /* set global number of screens */
639 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
640 awt_numScreens = locNumScr;
641 } else {
642 DTRACE_PRINTLN("XineramaQueryScreens <= XScreenCount");
643 }
644 XFree(xinInfo);
645 } else {
646 DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
647 }
648 }
649 } else {
650 DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
651 }
652 }
653
654 Display *
655 awt_init_Display(JNIEnv *env, jobject this)
656 {
657 jclass klass;
658 Display *dpy;
659 char errmsg[128];
660 int i;
661
662 if (awt_display) {
663 return awt_display;
664 }
665
666 /* Load AWT lock-related methods in SunToolkit */
667 klass = (*env)->FindClass(env, "sun/awt/SunToolkit");
668 if (klass == NULL) return NULL;
669 GET_STATIC_METHOD(klass, awtLockMID, "awtLock", "()V");
670 GET_STATIC_METHOD(klass, awtUnlockMID, "awtUnlock", "()V");
671 GET_STATIC_METHOD(klass, awtWaitMID, "awtLockWait", "(J)V");
672 GET_STATIC_METHOD(klass, awtNotifyMID, "awtLockNotify", "()V");
709 if (x11Screens == NULL) {
710 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),
711 NULL);
712 return NULL;
713 }
714
715 for (i = 0; i < awt_numScreens; i++) {
716 if (usingXinerama) {
717 /* All Xinerama screens use the same X11 root for now */
718 x11Screens[i].root = RootWindow(awt_display, 0);
719 }
720 else {
721 x11Screens[i].root = RootWindow(awt_display, i);
722 }
723 x11Screens[i].defaultConfig = makeDefaultConfig(env, i);
724 JNU_CHECK_EXCEPTION_RETURN(env, NULL);
725 }
726
727 return dpy;
728 }
729
730 /*
731 * Class: sun_awt_X11GraphicsEnvironment
732 * Method: getDefaultScreenNum
733 * Signature: ()I
734 */
735 JNIEXPORT jint JNICALL
736 Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum(
737 JNIEnv *env, jobject this)
738 {
739 return DefaultScreen(awt_display);
740 }
741
742 static void ensureConfigsInited(JNIEnv* env, int screen) {
743 if (x11Screens[screen].numConfigs == 0) {
744 if (env == NULL) {
745 env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
746 }
747 getAllConfigs (env, screen, &(x11Screens[screen]));
748 }
749 }
750
751 AwtGraphicsConfigDataPtr
752 getDefaultConfig(int screen) {
753 ensureConfigsInited(NULL, screen);
754 return x11Screens[screen].defaultConfig;
755 }
756
757 /*
758 * Class: sun_awt_X11GraphicsEnvironment
759 * Method: initDisplay
760 * Signature: (Z)V
761 */
762 JNIEXPORT void JNICALL
763 Java_sun_awt_X11GraphicsEnvironment_initDisplay(JNIEnv *env, jobject this,
764 jboolean glxReq)
765 {
766 glxRequested = glxReq;
767 (void) awt_init_Display(env, this);
768 }
769
770 /*
771 * Class: sun_awt_X11GraphicsEnvironment
772 * Method: initGLX
773 * Signature: ()Z
774 */
775 JNIEXPORT jboolean JNICALL
776 Java_sun_awt_X11GraphicsEnvironment_initGLX(JNIEnv *env, jclass x11ge)
777 {
778 jboolean glxAvailable;
779
780 AWT_LOCK();
781 glxAvailable = GLXGC_IsGLXAvailable();
782 AWT_UNLOCK();
783
784 return glxAvailable;
785 }
786
787 /*
788 * Class: sun_awt_X11GraphicsEnvironment
789 * Method: getNumScreens
790 * Signature: ()I
791 */
792 JNIEXPORT jint JNICALL
793 Java_sun_awt_X11GraphicsEnvironment_getNumScreens(JNIEnv *env, jobject this)
794 {
795 return awt_numScreens;
796 }
797
798 /*
799 * Class: sun_awt_X11GraphicsDevice
800 * Method: getDisplay
801 * Signature: ()J
802 */
803 JNIEXPORT jlong JNICALL
804 Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)
805 {
806 return ptr_to_jlong(awt_display);
807 }
808
809 #ifdef MITSHM
810
811 static jint canUseShmExt = UNSET_MITSHM;
812 static jint canUseShmExtPixmaps = UNSET_MITSHM;
813 static jboolean xshmAttachFailed = JNI_FALSE;
814
815 int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr) {
816 if (xerr->minor_code == X_ShmAttach) {
817 xshmAttachFailed = JNI_TRUE;
818 }
819 return 0;
820 }
821 jboolean isXShmAttachFailed() {
822 return xshmAttachFailed;
823 }
824 void resetXShmAttachFailed() {
825 xshmAttachFailed = JNI_FALSE;
826 }
913 JNIEXPORT jint JNICALL
914 Java_sun_awt_X11GraphicsEnvironment_checkShmExt(JNIEnv *env, jobject this)
915 {
916
917 int shmExt = NOEXT_MITSHM, shmPixmaps;
918 #ifdef MITSHM
919 TryInitMITShm(env, &shmExt, &shmPixmaps);
920 #endif
921 return shmExt;
922 }
923
924 /*
925 * Class: sun_awt_X11GraphicsEnvironment
926 * Method: getDisplayString
927 * Signature: ()Ljava/lang/String
928 */
929 JNIEXPORT jstring JNICALL
930 Java_sun_awt_X11GraphicsEnvironment_getDisplayString
931 (JNIEnv *env, jobject this)
932 {
933 return (*env)->NewStringUTF(env, DisplayString(awt_display));
934 }
935
936
937 /*
938 * Class: sun_awt_X11GraphicsDevice
939 * Method: getNumConfigs
940 * Signature: ()I
941 */
942 JNIEXPORT jint JNICALL
943 Java_sun_awt_X11GraphicsDevice_getNumConfigs(
944 JNIEnv *env, jobject this, jint screen)
945 {
946 ensureConfigsInited(env, screen);
947 return x11Screens[screen].numConfigs;
948 }
949
950 /*
951 * Class: sun_awt_X11GraphicsDevice
952 * Method: getConfigVisualId
953 * Signature: (I)I
954 */
955 JNIEXPORT jint JNICALL
956 Java_sun_awt_X11GraphicsDevice_getConfigVisualId(
957 JNIEnv *env, jobject this, jint index, jint screen)
958 {
959 int visNum;
960
961 ensureConfigsInited(env, screen);
962 if (index == 0) {
963 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.visualid);
964 } else {
965 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.visualid);
966 }
967 }
968
969 /*
970 * Class: sun_awt_X11GraphicsDevice
971 * Method: getConfigDepth
972 * Signature: (I)I
973 */
974 JNIEXPORT jint JNICALL
975 Java_sun_awt_X11GraphicsDevice_getConfigDepth(
976 JNIEnv *env, jobject this, jint index, jint screen)
977 {
978 int visNum;
979
980 ensureConfigsInited(env, screen);
981 if (index == 0) {
982 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.depth);
983 } else {
984 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.depth);
985 }
986 }
987
988 /*
989 * Class: sun_awt_X11GraphicsDevice
990 * Method: getConfigColormap
991 * Signature: (I)I
992 */
993 JNIEXPORT jint JNICALL
994 Java_sun_awt_X11GraphicsDevice_getConfigColormap(
995 JNIEnv *env, jobject this, jint index, jint screen)
996 {
997 int visNum;
998
999 ensureConfigsInited(env, screen);
1000 if (index == 0) {
1001 return ((jint)x11Screens[screen].defaultConfig->awt_cmap);
1002 } else {
1003 return ((jint)x11Screens[screen].configs[index]->awt_cmap);
1004 }
1005 }
1006
1007 /*
1008 * Class: sun_awt_X11GraphicsDevice
1009 * Method: resetNativeData
1010 * Signature: (I)V
1011 */
1012 JNIEXPORT void JNICALL
1013 Java_sun_awt_X11GraphicsDevice_resetNativeData
1014 (JNIEnv *env, jclass x11gd, jint screen)
1015 {
1016 /*
1017 * Reset references to the various configs; the actual native config data
1018 * will be free'd later by the Disposer mechanism when the Java-level
1019 * X11GraphicsConfig objects go away. By setting these values to NULL,
1020 * we ensure that they will be reinitialized as necessary (for example,
1021 * see the getNumConfigs() method).
1022 */
1023 if (x11Screens[screen].configs) {
1024 free(x11Screens[screen].configs);
1025 x11Screens[screen].configs = NULL;
1026 }
1027 x11Screens[screen].defaultConfig = NULL;
1028 x11Screens[screen].numConfigs = 0;
1029 }
1030
1031 /*
1032 * Class: sun_awt_X11GraphicsConfig
1033 * Method: dispose
1034 * Signature: (J)V
1035 */
1036 JNIEXPORT void JNICALL
1037 Java_sun_awt_X11GraphicsConfig_dispose
1038 (JNIEnv *env, jclass x11gc, jlong configData)
1039 {
1040 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)
1041 jlong_to_ptr(configData);
1042
1043 if (aData == NULL) {
1044 return;
1045 }
1046
1047 AWT_LOCK();
1048 if (aData->awt_cmap) {
1049 XFreeColormap(awt_display, aData->awt_cmap);
1050 }
1051 if (aData->awtImage) {
1052 free(aData->awtImage);
1053 }
1054 if (aData->monoImage) {
1055 XFree(aData->monoImage);
1056 }
1057 if (aData->monoPixmap) {
1058 XFreePixmap(awt_display, aData->monoPixmap);
1059 }
1061 XFreeGC(awt_display, aData->monoPixmapGC);
1062 }
1063 if (aData->color_data) {
1064 free(aData->color_data);
1065 }
1066 AWT_UNLOCK();
1067
1068 if (aData->glxInfo) {
1069 /*
1070 * The native GLXGraphicsConfig data needs to be disposed separately
1071 * on the OGL queue flushing thread (should not be called while
1072 * the AWT lock is held).
1073 */
1074 JNU_CallStaticMethodByName(env, NULL,
1075 "sun/java2d/opengl/OGLRenderQueue",
1076 "disposeGraphicsConfig", "(J)V",
1077 ptr_to_jlong(aData->glxInfo));
1078 }
1079
1080 free(aData);
1081 }
1082
1083 /*
1084 * Class: sun_awt_X11GraphicsConfig
1085 * Method: getXResolution
1086 * Signature: ()I
1087 */
1088 JNIEXPORT jdouble JNICALL
1089 Java_sun_awt_X11GraphicsConfig_getXResolution(
1090 JNIEnv *env, jobject this, jint screen)
1091 {
1092 return ((DisplayWidth(awt_display, screen) * 25.4) /
1093 DisplayWidthMM(awt_display, screen));
1094 }
1095
1096 /*
1097 * Class: sun_awt_X11GraphicsConfig
1098 * Method: getYResolution
1099 * Signature: ()I
1100 */
1101 JNIEXPORT jdouble JNICALL
1102 Java_sun_awt_X11GraphicsConfig_getYResolution(
1103 JNIEnv *env, jobject this, jint screen)
1104 {
1105 return ((DisplayHeight(awt_display, screen) * 25.4) /
1106 DisplayHeightMM(awt_display, screen));
1107 }
1108
1109
1110 /*
1111 * Class: sun_awt_X11GraphicsConfig
1112 * Method: getNumColors
1113 * Signature: ()I
1114 */
1115 JNIEXPORT jint JNICALL
1116 Java_sun_awt_X11GraphicsConfig_getNumColors(
1117 JNIEnv *env, jobject this)
1118 {
1119 AwtGraphicsConfigData *adata;
1120
1121 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1122 x11GraphicsConfigIDs.aData);
1123
1124 return adata->awt_num_colors;
1125 }
1126
1127 /*
1128 * Class: sun_awt_X11GraphicsConfig
1129 * Method: init
1130 * Signature: (I)V
1131 */
1132 JNIEXPORT void JNICALL
1133 Java_sun_awt_X11GraphicsConfig_init(
1134 JNIEnv *env, jobject this, jint visualNum, jint screen)
1135 {
1136 AwtGraphicsConfigData *adata = NULL;
1137 AwtScreenData asd = x11Screens[screen];
1138 int i, n;
1139 int depth;
1140 XImage * tempImage;
1141
1142 /* If haven't gotten all of the configs yet, do it now. */
1143 if (asd.numConfigs == 0) {
1144 getAllConfigs (env, screen, &asd);
1145 }
1146
1147 /* Check the graphicsConfig for this visual */
1148 for (i = 0; i < asd.numConfigs; i++) {
1149 AwtGraphicsConfigDataPtr agcPtr = asd.configs[i];
1150 if ((jint)agcPtr->awt_visInfo.visualid == visualNum) {
1151 adata = agcPtr;
1152 break;
1153 }
1154 }
1155
1156 /* If didn't find the visual, throw an exception... */
1157 if (adata == (AwtGraphicsConfigData *) NULL) {
1158 JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified");
1159 return;
1160 }
1161
1162 /* adata->awt_cmap initialization has been deferred to
1163 * makeColorModel call
1164 */
1165
1166 JNU_SetLongFieldFromPtr(env, this, x11GraphicsConfigIDs.aData, adata);
1167
1168 depth = adata->awt_visInfo.depth;
1169 tempImage = XCreateImage(awt_display,
1170 adata->awt_visInfo.visual,
1171 depth, ZPixmap, 0, NULL, 1, 1, 32, 0);
1172 adata->pixelStride = (tempImage->bits_per_pixel + 7) / 8;
1173 (*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel,
1174 (jint)tempImage->bits_per_pixel);
1175 XDestroyImage(tempImage);
1176 }
1177
1178 /*
1179 * Class: sun_awt_X11GraphicsConfig
1180 * Method: makeColorModel
1181 * Signature: ()Ljava/awt/image/ColorModel
1182 */
1183 JNIEXPORT jobject JNICALL
1184 Java_sun_awt_X11GraphicsConfig_makeColorModel(
1185 JNIEnv *env, jobject this)
1186 {
1187 AwtGraphicsConfigData *adata;
1188 jobject colorModel;
1189
1190 /*
1191 * If awt is not locked yet, return null since the toolkit is not
1192 * initialized yet.
1193 */
1194 if (!awtLockInited) {
1195 return NULL;
1196 }
1197
1198 AWT_LOCK ();
1199
1200 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1201 x11GraphicsConfigIDs.aData);
1202
1203 /* If colormap entry of adata is NULL, need to create it now */
1204 if (adata->awt_cmap == (Colormap) NULL) {
1205 awtJNI_CreateColorData (env, adata, 1);
1206 }
1207
1208 /* Make Color Model object for this GraphicsConfiguration */
1209 colorModel = (*env)->ExceptionCheck(env)
1210 ? NULL : awtJNI_GetColorModel (env, adata);
1211
1212 AWT_UNLOCK ();
1213
1214 return colorModel;
1215 }
1216
1217 /*
1218 * Class: sun_awt_X11GraphicsConfig
1219 * Method: getBounds
1220 * Signature: ()Ljava/awt/Rectangle
1221 */
1222 JNIEXPORT jobject JNICALL
1223 Java_sun_awt_X11GraphicsConfig_pGetBounds(JNIEnv *env, jobject this, jint screen)
1224 {
1225 jclass clazz;
1226 jmethodID mid;
1227 jobject bounds = NULL;
1228 AwtGraphicsConfigDataPtr adata;
1229 int32_t locNumScr = 0;
1230 XineramaScreenInfo *xinInfo;
1231
1232 adata = (AwtGraphicsConfigDataPtr)
1233 JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData);
1234
1235 clazz = (*env)->FindClass(env, "java/awt/Rectangle");
1236 CHECK_NULL_RETURN(clazz, NULL);
1237 mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V");
1238 if (mid != NULL) {
1239 if (usingXinerama) {
1240 if (0 <= screen && screen < awt_numScreens) {
1241 AWT_LOCK();
1242 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
1243 AWT_UNLOCK();
1244 if (xinInfo != NULL && locNumScr > 0) {
1263 if (!bounds) {
1264 // Xinerama cannot provide correct bounds, will try X11
1265 XWindowAttributes xwa;
1266 memset(&xwa, 0, sizeof(xwa));
1267
1268 AWT_LOCK ();
1269 XGetWindowAttributes(awt_display,
1270 RootWindow(awt_display, adata->awt_visInfo.screen),
1271 &xwa);
1272 AWT_UNLOCK ();
1273
1274 bounds = (*env)->NewObject(env, clazz, mid, 0, 0,
1275 xwa.width, xwa.height);
1276 }
1277
1278 if ((*env)->ExceptionOccurred(env)) {
1279 return NULL;
1280 }
1281 }
1282 return bounds;
1283 }
1284
1285 /*
1286 * Class: sun_awt_X11GraphicsConfig
1287 * Method: createBackBuffer
1288 * Signature: (JI)J
1289 */
1290 JNIEXPORT jlong JNICALL
1291 Java_sun_awt_X11GraphicsConfig_createBackBuffer
1292 (JNIEnv *env, jobject this, jlong window, jint swapAction)
1293 {
1294 int32_t v1, v2;
1295 XdbeBackBuffer ret = (unsigned long) 0;
1296 Window w = (Window)window;
1297 AWT_LOCK();
1298 if (!XdbeQueryExtension(awt_display, &v1, &v2)) {
1299 JNU_ThrowByName(env, "java/lang/Exception",
1300 "Could not query double-buffer extension");
1301 AWT_UNLOCK();
1302 return (jlong)0;
1338 XdbeBeginIdiom(awt_display);
1339 swapInfo.swap_window = (Window)window;
1340 swapInfo.swap_action = (XdbeSwapAction)swapAction;
1341 if (!XdbeSwapBuffers(awt_display, &swapInfo, 1)) {
1342 JNU_ThrowInternalError(env, "Could not swap buffers");
1343 }
1344 XdbeEndIdiom(awt_display);
1345
1346 AWT_FLUSH_UNLOCK();
1347 }
1348
1349 /*
1350 * Class: sun_awt_X11GraphicsConfig
1351 * Method: isTranslucencyCapable
1352 * Signature: (J)V
1353 */
1354 JNIEXPORT jboolean JNICALL
1355 Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable
1356 (JNIEnv *env, jobject this, jlong configData)
1357 {
1358 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);
1359 if (aData == NULL) {
1360 return JNI_FALSE;
1361 }
1362 return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE;
1363 }
1364
1365 /*
1366 * Class: sun_awt_X11GraphicsDevice
1367 * Method: isDBESupported
1368 * Signature: ()Z
1369 */
1370 JNIEXPORT jboolean JNICALL
1371 Java_sun_awt_X11GraphicsDevice_isDBESupported(JNIEnv *env, jobject this)
1372 {
1373 int opcode = 0, firstEvent = 0, firstError = 0;
1374 jboolean ret;
1375
1376 AWT_LOCK();
1377 ret = (jboolean)XQueryExtension(awt_display, "DOUBLE-BUFFER",
1378 &opcode, &firstEvent, &firstError);
1379 AWT_FLUSH_UNLOCK();
1380 return ret;
1381 }
1382
1383 /*
1384 * Class: sun_awt_X11GraphicsDevice
1385 * Method: getDoubleBufferVisuals
1386 * Signature: (I)V
1387 */
1388 JNIEXPORT void JNICALL
1389 Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env,
1390 jobject this, jint screen)
1391 {
1392 jclass clazz;
1393 jmethodID midAddVisual;
1394 Window rootWindow;
1395 int i, n = 1;
1396 XdbeScreenVisualInfo* visScreenInfo;
1397 int xinawareScreen;
1398
1399 if (usingXinerama) {
1400 xinawareScreen = 0;
1401 }
1402 else {
1403 xinawareScreen = screen;
1404 }
1405
1406 clazz = (*env)->GetObjectClass(env, this);
1407 midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual",
1408 "(I)V");
1409 CHECK_NULL(midAddVisual);
1410 AWT_LOCK();
1411 rootWindow = RootWindow(awt_display, xinawareScreen);
1412 visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n);
1413 if (visScreenInfo == NULL) {
1414 JNU_ThrowInternalError(env, "Could not get visual info");
1415 AWT_UNLOCK();
1416 return;
1417 }
1418 AWT_FLUSH_UNLOCK();
1419 for (i = 0; i < visScreenInfo->count; i++) {
1420 XdbeVisualInfo* visInfo = visScreenInfo->visinfo;
1421 (*env)->CallVoidMethod(env, this, midAddVisual, (visInfo[i]).visual);
1422 if ((*env)->ExceptionCheck(env)) {
1423 break;
1424 }
1425 }
1426 }
1427
1428 /*
1429 * Class: sun_awt_X11GraphicsEnvironment
1430 * Method: pRunningXinerama
1431 * Signature: ()Z
1432 */
1433 JNIEXPORT jboolean JNICALL
1434 Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama(JNIEnv *env,
1435 jobject this)
1436 {
1437 return usingXinerama ? JNI_TRUE : JNI_FALSE;
1438 }
1439
1440 /**
1441 * Begin DisplayMode/FullScreen support
1442 */
1443
1444 #ifndef NO_XRANDR
1445
1446 #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
1447 #define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
1448
1449 typedef Status
1450 (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
1451 typedef XRRScreenConfiguration*
1452 (*XRRGetScreenInfoType)(Display *dpy, Drawable root);
1453 typedef void
1454 (*XRRFreeScreenConfigInfoType)(XRRScreenConfiguration *config);
1455 typedef short*
1456 (*XRRConfigRatesType)(XRRScreenConfiguration *config,
1457 int sizeID, int *nrates);
1458 typedef short
1459 (*XRRConfigCurrentRateType)(XRRScreenConfiguration *config);
1460 typedef XRRScreenSize*
1461 (*XRRConfigSizesType)(XRRScreenConfiguration *config,
1462 int *nsizes);
1463 typedef SizeID
1661
1662 if (wmState == None || wmStateFs == None
1663 || !XGetWindowAttributes(awt_display, win, &attr)) {
1664 return;
1665 }
1666
1667 memset(&event, 0, sizeof(event));
1668 event.xclient.type = ClientMessage;
1669 event.xclient.message_type = wmState;
1670 event.xclient.display = awt_display;
1671 event.xclient.window = win;
1672 event.xclient.format = 32;
1673 event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove
1674 event.xclient.data.l[1] = wmStateFs;
1675
1676 XSendEvent(awt_display, attr.root, False,
1677 SubstructureRedirectMask | SubstructureNotifyMask,
1678 &event);
1679 XSync(awt_display, False);
1680 }
1681
1682 /*
1683 * Class: sun_awt_X11GraphicsDevice
1684 * Method: initXrandrExtension
1685 * Signature: ()Z
1686 */
1687 JNIEXPORT jboolean JNICALL
1688 Java_sun_awt_X11GraphicsDevice_initXrandrExtension
1689 (JNIEnv *env, jclass x11gd)
1690 {
1691 #if defined(NO_XRANDR)
1692 return JNI_FALSE;
1693 #else
1694 int opcode = 0, firstEvent = 0, firstError = 0;
1695 jboolean ret;
1696
1697 AWT_LOCK();
1698 ret = (jboolean)XQueryExtension(awt_display, "RANDR",
1699 &opcode, &firstEvent, &firstError);
1700 if (ret) {
1701 ret = X11GD_InitXrandrFuncs(env);
1702 }
1703 AWT_FLUSH_UNLOCK();
1704
1705 return ret;
1706 #endif /* NO_XRANDR */
1707 }
1708
1709 /*
1710 * Class: sun_awt_X11GraphicsDevice
1711 * Method: getCurrentDisplayMode
1712 * Signature: (I)Ljava/awt/DisplayMode;
1713 */
1714 JNIEXPORT jobject JNICALL
1715 Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
1716 (JNIEnv* env, jclass x11gd, jint screen)
1717 {
1718 #if defined(NO_XRANDR)
1719 return NULL;
1720 #else
1721 XRRScreenConfiguration *config;
1722 jobject displayMode = NULL;
1723
1724 AWT_LOCK();
1725
1726 if (usingXinerama && XScreenCount(awt_display) > 0) {
1727 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
1728 RootWindow(awt_display, 0));
1729 if (res) {
1730 if (res->noutput > screen) {
1731 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
1732 res, res->outputs[screen]);
1733 if (output_info) {
1734 if (output_info->crtc) {
1735 XRRCrtcInfo *crtc_info =
1736 awt_XRRGetCrtcInfo (awt_display, res,
1737 output_info->crtc);
1738 if (crtc_info) {
1781 curRate = awt_XRRConfigCurrentRate(config);
1782
1783 if ((sizes != NULL) &&
1784 (curSizeIndex < nsizes))
1785 {
1786 XRRScreenSize curSize = sizes[curSizeIndex];
1787 displayMode = X11GD_CreateDisplayMode(env,
1788 curSize.width,
1789 curSize.height,
1790 BIT_DEPTH_MULTI,
1791 curRate);
1792 }
1793
1794 awt_XRRFreeScreenConfigInfo(config);
1795 }
1796 }
1797
1798 AWT_FLUSH_UNLOCK();
1799
1800 return displayMode;
1801 #endif /* NO_XRANDR */
1802 }
1803
1804 /*
1805 * Class: sun_awt_X11GraphicsDevice
1806 * Method: enumDisplayModes
1807 * Signature: (ILjava/util/ArrayList;)V
1808 */
1809 JNIEXPORT void JNICALL
1810 Java_sun_awt_X11GraphicsDevice_enumDisplayModes
1811 (JNIEnv* env, jclass x11gd,
1812 jint screen, jobject arrayList)
1813 {
1814 #if !defined(NO_XRANDR)
1815
1816 AWT_LOCK();
1817
1818 if (usingXinerama && XScreenCount(awt_display) > 0) {
1819 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
1820 RootWindow(awt_display, 0));
1821 if (res) {
1822 if (res->noutput > screen) {
1823 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
1824 res, res->outputs[screen]);
1825 if (output_info) {
1826 int i;
1827 for (i = 0; i < output_info->nmode; i++) {
1828 RRMode m = output_info->modes[i];
1829 int j;
1830 XRRModeInfo *mode;
1831 for (j = 0; j < res->nmode; j++) {
1832 mode = &res->modes[j];
1833 if (mode->id == m) {
1834 float rate = 0;
1869 short *rates = awt_XRRConfigRates(config, i, &nrates);
1870
1871 for (j = 0; j < nrates; j++) {
1872 X11GD_AddDisplayMode(env, arrayList,
1873 size.width,
1874 size.height,
1875 BIT_DEPTH_MULTI,
1876 rates[j]);
1877 if ((*env)->ExceptionCheck(env)) {
1878 goto ret1;
1879 }
1880 }
1881 }
1882 }
1883 ret1:
1884 awt_XRRFreeScreenConfigInfo(config);
1885 }
1886 }
1887
1888 AWT_FLUSH_UNLOCK();
1889 #endif /* !NO_XRANDR */
1890 }
1891
1892 /*
1893 * Class: sun_awt_X11GraphicsDevice
1894 * Method: configDisplayMode
1895 * Signature: (IIII)V
1896 */
1897 JNIEXPORT void JNICALL
1898 Java_sun_awt_X11GraphicsDevice_configDisplayMode
1899 (JNIEnv* env, jclass x11gd,
1900 jint screen, jint width, jint height, jint refreshRate)
1901 {
1902 #if !defined(NO_XRANDR)
1903 jboolean success = JNI_FALSE;
1904 XRRScreenConfiguration *config;
1905 Drawable root;
1906 Rotation currentRotation = RR_Rotate_0;
1907
1908 AWT_LOCK();
1909
1910 root = RootWindow(awt_display, screen);
1911 config = awt_XRRGetScreenInfo(awt_display, root);
1912 if (config != NULL) {
1913 jboolean foundConfig = JNI_FALSE;
1914 int chosenSizeIndex = -1;
1915 short chosenRate = -1;
1916 int nsizes;
1917 XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
1918 awt_XRRConfigRotations(config, ¤tRotation);
1919
1920 if (sizes != NULL) {
1921 int i, j;
1922
1952 currentRotation,
1953 chosenRate,
1954 CurrentTime);
1955
1956 /* issue XSync to ensure immediate mode change */
1957 XSync(awt_display, False);
1958
1959 if (status == RRSetConfigSuccess) {
1960 success = JNI_TRUE;
1961 }
1962 }
1963
1964 awt_XRRFreeScreenConfigInfo(config);
1965 }
1966
1967 AWT_FLUSH_UNLOCK();
1968
1969 if (!success && !(*env)->ExceptionCheck(env)) {
1970 JNU_ThrowInternalError(env, "Could not set display mode");
1971 }
1972 #endif /* !NO_XRANDR */
1973 }
1974
1975 /*
1976 * Class: sun_awt_X11GraphicsDevice
1977 * Method: enterFullScreenExclusive
1978 * Signature: (J)V
1979 */
1980 JNIEXPORT void JNICALL
1981 Java_sun_awt_X11GraphicsDevice_enterFullScreenExclusive
1982 (JNIEnv* env, jclass x11gd,
1983 jlong window)
1984 {
1985 Window win = (Window)window;
1986
1987 AWT_LOCK();
1988 XSync(awt_display, False); /* ensures window is visible first */
1989 X11GD_SetFullscreenMode(win, JNI_TRUE);
1990 AWT_UNLOCK();
1991 }
1992
1993 /*
1994 * Class: sun_awt_X11GraphicsDevice
1995 * Method: exitFullScreenExclusive
1996 * Signature: (J)V
1997 */
1998 JNIEXPORT void JNICALL
1999 Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive
2000 (JNIEnv* env, jclass x11gd,
2001 jlong window)
2002 {
2003 Window win = (Window)window;
2004
2005 AWT_LOCK();
2006 X11GD_SetFullscreenMode(win, JNI_FALSE);
2007 AWT_UNLOCK();
2008 }
2009
2010 /**
2011 * End DisplayMode/FullScreen support
2012 */
2013
2014 static char *get_output_screen_name(JNIEnv *env, int screen) {
2015 #ifdef NO_XRANDR
2016 return NULL;
2017 #else
2018 if (!awt_XRRGetScreenResources || !awt_XRRGetOutputInfo) {
2019 return NULL;
2020 }
2021 char *name = NULL;
2022 AWT_LOCK();
2023 int scr = 0, out = 0;
2024 if (usingXinerama && XScreenCount(awt_display) > 0) {
2025 out = screen;
2026 } else {
2027 scr = screen;
|