src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54856 4fcc1f1d7dd8
child 58679 9c3209ff7550
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Oct 17 20:27:44 2019 +0100
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Oct 17 20:53:35 2019 +0100
@@ -119,9 +119,8 @@
 } XineramaScreenInfo;
 
 typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);
-
+static XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
 Bool usingXinerama = False;
-XRectangle fbrects[MAXFRAMEBUFFERS];
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls)
@@ -167,6 +166,10 @@
         int id = -1;
         VisualID defaultVisual = XVisualIDFromVisual(DefaultVisual(awt_display, vinfo->screen));
         defaultConfig = ZALLOC(_AwtGraphicsConfigData);
+        if (defaultConfig == NULL) {
+            XFree(visualList);
+            return NULL;
+        }
         for (i = 0; i < visualsMatched; i++) {
             memcpy(&defaultConfig->awt_visInfo, &visualList[i], sizeof(XVisualInfo));
             defaultConfig->awt_depth = visualList[i].depth;
@@ -448,8 +451,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVITrue [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
                 sizeof (XVisualInfo));
         if (xrenderFindVisualFormat != NULL) {
@@ -483,8 +490,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI8p [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI8p [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8p [i],
                 sizeof (XVisualInfo));
     }
@@ -496,8 +507,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI12p [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI12p [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI12p [i],
                 sizeof (XVisualInfo));
     }
@@ -509,8 +524,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI8s [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI8s [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8s [i],
                 sizeof (XVisualInfo));
     }
@@ -522,8 +541,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI8gs [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI8gs [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8gs [i],
                 sizeof (XVisualInfo));
     }
@@ -535,8 +558,12 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI8sg [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI8sg [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8sg [i],
                 sizeof (XVisualInfo));
     }
@@ -548,12 +575,20 @@
         } else {
             ind = nConfig++;
         }
-        graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
-        graphicsConfigs [ind]->awt_depth = pVI1sg [i].depth;
+        graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+        if (graphicsConfigs[ind] == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+            goto cleanup;
+        }
+        graphicsConfigs[ind]->awt_depth = pVI1sg [i].depth;
         memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI1sg [i],
                 sizeof (XVisualInfo));
     }
 
+    screenDataPtr->numConfigs = nConfig;
+    screenDataPtr->configs = graphicsConfigs;
+
+cleanup:
     if (n8p != 0)
        XFree (pVI8p);
     if (n12p != 0)
@@ -567,9 +602,6 @@
     if (n1sg != 0)
        XFree (pVI1sg);
 
-    screenDataPtr->numConfigs = nConfig;
-    screenDataPtr->configs = graphicsConfigs;
-
     AWT_UNLOCK ();
 }
 
@@ -586,7 +618,6 @@
     int32_t locNumScr = 0;
     XineramaScreenInfo *xinInfo;
     char* XineramaQueryScreensName = "XineramaQueryScreens";
-    XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
 
     gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
                                 &first_event, &first_error);
@@ -612,36 +643,27 @@
         XineramaQueryScreens = (XineramaQueryScreensFunc*)
             dlsym(libHandle, XineramaQueryScreensName);
 
-        if (XineramaQueryScreens != NULL) {
+        if (XineramaQueryScreens == NULL) {
+            DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");
+            dlclose(libHandle);
+        } else {
             DTRACE_PRINTLN("calling XineramaQueryScreens func");
             xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
-            if (xinInfo != NULL && locNumScr > XScreenCount(awt_display)) {
-                int32_t idx;
-                DTRACE_PRINTLN("Enabling Xinerama support");
-                usingXinerama = True;
-                /* set global number of screens */
-                DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
-                awt_numScreens = locNumScr;
-
-                /* stuff values into fbrects */
-                for (idx = 0; idx < awt_numScreens; idx++) {
-                    DASSERT(xinInfo[idx].screen_number == idx);
-
-                    fbrects[idx].width = xinInfo[idx].width;
-                    fbrects[idx].height = xinInfo[idx].height;
-                    fbrects[idx].x = xinInfo[idx].x_org;
-                    fbrects[idx].y = xinInfo[idx].y_org;
+            if (xinInfo != NULL) {
+                if (locNumScr > XScreenCount(awt_display)) {
+                    DTRACE_PRINTLN("Enabling Xinerama support");
+                    usingXinerama = True;
+                    /* set global number of screens */
+                    DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
+                    awt_numScreens = locNumScr;
+                } else {
+                    DTRACE_PRINTLN("XineramaQueryScreens <= XScreenCount");
                 }
+                XFree(xinInfo);
             } else {
-                DTRACE_PRINTLN((xinInfo == NULL) ?
-                               "calling XineramaQueryScreens didn't work" :
-                               "XineramaQueryScreens <= XScreenCount"
-                               );
+                DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
             }
-        } else {
-            DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");
         }
-        dlclose(libHandle);
     } else {
         DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
     }
@@ -1303,6 +1325,8 @@
     jmethodID mid;
     jobject bounds = NULL;
     AwtGraphicsConfigDataPtr adata;
+    int32_t locNumScr = 0;
+    XineramaScreenInfo *xinInfo;
 
     adata = (AwtGraphicsConfigDataPtr)
         JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData);
@@ -1313,17 +1337,30 @@
     if (mid != NULL) {
         if (usingXinerama) {
             if (0 <= screen && screen < awt_numScreens) {
-                bounds = (*env)->NewObject(env, clazz, mid, fbrects[screen].x,
-                                                            fbrects[screen].y,
-                                                            fbrects[screen].width,
-                                                            fbrects[screen].height);
+                AWT_LOCK();
+                xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
+                AWT_UNLOCK();
+                if (xinInfo != NULL && locNumScr > 0) {
+                    if (screen >= locNumScr) {
+                        screen = 0; // fallback to the main screen
+                    }
+                    DASSERT(xinInfo[screen].screen_number == screen);
+                    bounds = (*env)->NewObject(env, clazz, mid,
+                                               xinInfo[screen].x_org,
+                                               xinInfo[screen].y_org,
+                                               xinInfo[screen].width,
+                                               xinInfo[screen].height);
+                    XFree(xinInfo);
+                }
             } else {
                 jclass exceptionClass = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
                 if (exceptionClass != NULL) {
                     (*env)->ThrowNew(env, exceptionClass, "Illegal screen index");
                 }
             }
-        } else {
+        }
+        if (!bounds) {
+            // Xinerama cannot provide correct bounds, will try X11
             XWindowAttributes xwa;
             memset(&xwa, 0, sizeof(xwa));