1 /* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 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 #include "Xrandr.h" 38 #include "GLXGraphicsConfig.h" 39 #endif /* !HEADLESS */ 40 41 #include <jni.h> 42 #include <jni_util.h> 43 #include <jvm.h> 44 #include <jvm_md.h> 45 #include <jlong.h> 46 #include "systemScale.h" 47 #include <stdlib.h> 48 49 #include "awt_GraphicsEnv.h" 50 #include "awt_util.h" 51 #include "gdefs.h" 52 #include <dlfcn.h> 53 #include "Trace.h" 54 55 #ifdef NETSCAPE 56 #include <signal.h> 57 extern int awt_init_xt; 58 #endif 59 60 #ifndef HEADLESS 61 62 int awt_numScreens; /* Xinerama-aware number of screens */ 63 64 AwtScreenDataPtr x11Screens; 65 66 /* 67 * Set in initDisplay() to indicate whether we should attempt to initialize 68 * GLX for the default configuration. 69 */ 70 static jboolean glxRequested = JNI_FALSE; 71 72 #endif /* !HEADLESS */ 73 74 #ifdef HEADLESS 75 #define Display void 76 #endif /* HEADLESS */ 77 78 Display *awt_display; 79 80 jclass tkClass = NULL; 81 jmethodID awtLockMID = NULL; 82 jmethodID awtUnlockMID = NULL; 83 jmethodID awtWaitMID = NULL; 84 jmethodID awtNotifyMID = NULL; 85 jmethodID awtNotifyAllMID = NULL; 86 jboolean awtLockInited = JNI_FALSE; 87 88 /** Convenience macro for loading the lock-related method IDs. */ 89 #define GET_STATIC_METHOD(klass, method_id, method_name, method_sig) \ 90 do { \ 91 method_id = (*env)->GetStaticMethodID(env, klass, \ 92 method_name, method_sig); \ 93 if (method_id == NULL) return NULL; \ 94 } while (0) 95 96 struct X11GraphicsConfigIDs x11GraphicsConfigIDs; 97 struct X11GraphicsDeviceIDs x11GraphicsDeviceIDs; 98 99 #ifndef HEADLESS 100 int awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata); 101 #endif /* HEADLESS */ 102 103 static char *x11GraphicsConfigClassName = "sun/awt/X11GraphicsConfig"; 104 105 /* AWT and Xinerama 106 * 107 * As of fix 4356756, AWT is Xinerama-aware. X11GraphicsDevices are created for 108 * each screen of a Xinerama setup, though X11 itself still only sees a single 109 * display. 110 * In many places where we talk to X11, a xinawareScreen variable is used to 111 * pass the correct Display value, depending on the circumstances (a single 112 * X display, multiple X displays, or a single X display with multiple 113 * Xinerama screens). 114 * 115 * Solaris and Linux differ in the functions used to access Xinerama-related 116 * data. This is in part because at this time, the X consortium has not 117 * finalized the "official" Xinerama API. Once this spec is available, and 118 * both OSes are conformant, one code base should be sufficient for Xinerama 119 * operation on both OSes. Until then, some of the Xinerama-related code 120 * is ifdef'd appropriately. -bchristi, 7/12/01 121 */ 122 123 #define MAXFRAMEBUFFERS 16 124 #if defined(__linux__) || defined(MACOSX) 125 typedef struct { 126 int screen_number; 127 short x_org; 128 short y_org; 129 short width; 130 short height; 131 } XineramaScreenInfo; 132 133 typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*); 134 135 #else /* SOLARIS */ 136 typedef Status XineramaGetInfoFunc(Display* display, int screen_number, 137 XRectangle* framebuffer_rects, unsigned char* framebuffer_hints, 138 int* num_framebuffers); 139 typedef Status XineramaGetCenterHintFunc(Display* display, int screen_number, 140 int* x, int* y); 141 142 XineramaGetCenterHintFunc* XineramaSolarisCenterFunc = NULL; 143 #endif 144 145 Bool usingXinerama = False; 146 XRectangle fbrects[MAXFRAMEBUFFERS]; 147 148 JNIEXPORT void JNICALL 149 Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls) 150 { 151 x11GraphicsConfigIDs.aData = NULL; 152 x11GraphicsConfigIDs.bitsPerPixel = NULL; 153 x11GraphicsConfigIDs.screen = NULL; 154 155 x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J"); 156 CHECK_NULL(x11GraphicsConfigIDs.aData); 157 x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I"); 158 CHECK_NULL(x11GraphicsConfigIDs.bitsPerPixel); 159 x11GraphicsConfigIDs.screen = (*env)->GetFieldID (env, cls, "screen", "Lsun/awt/X11GraphicsDevice;"); 160 CHECK_NULL(x11GraphicsConfigIDs.screen); 161 162 if (x11GraphicsConfigIDs.aData == NULL || 163 x11GraphicsConfigIDs.bitsPerPixel == NULL || 164 x11GraphicsConfigIDs.screen == NULL) { 165 166 JNU_ThrowNoSuchFieldError(env, "Can't find a field"); 167 return; 168 } 169 } 170 171 JNIEXPORT void JNICALL 172 Java_sun_awt_X11GraphicsDevice_initIDs (JNIEnv *env, jclass cls) 173 { 174 x11GraphicsDeviceIDs.screen = NULL; 175 x11GraphicsDeviceIDs.screen = (*env)->GetFieldID (env, cls, "screen", "I"); 176 DASSERT(x11GraphicsDeviceIDs.screen); 177 } 178 179 #ifndef HEADLESS 180 181 /* 182 * XIOErrorHandler 183 */ 184 static int xioerror_handler(Display *disp) 185 { 186 if (awtLockInited) { 187 if (errno == EPIPE) { 188 jio_fprintf(stderr, "X connection to %s host broken (explicit kill or server shutdown)\n", XDisplayName(NULL)); 189 } 190 /*SignalError(lockedee->lastpc, lockedee, "fp/ade/gui/GUIException", "I/O error"); */ 191 } 192 return 0; 193 } 194 195 static AwtGraphicsConfigDataPtr 196 findWithTemplate(XVisualInfo *vinfo, 197 long mask) 198 { 199 200 XVisualInfo *visualList; 201 XColor color; 202 AwtGraphicsConfigDataPtr defaultConfig; 203 int visualsMatched, i; 204 205 visualList = XGetVisualInfo(awt_display, 206 mask, vinfo, &visualsMatched); 207 if (visualList) { 208 defaultConfig = ZALLOC(_AwtGraphicsConfigData); 209 for (i = 0; i < visualsMatched; i++) { 210 memcpy(&defaultConfig->awt_visInfo, &visualList[i], sizeof(XVisualInfo)); 211 defaultConfig->awt_depth = visualList[i].depth; 212 213 /* we can't use awtJNI_CreateColorData here, because it'll pull, 214 SystemColor, which in turn will cause toolkit to be reinitialized */ 215 if (awtCreateX11Colormap(defaultConfig)) { 216 /* Allocate white and black pixels for this visual */ 217 color.flags = DoRed | DoGreen | DoBlue; 218 color.red = color.green = color.blue = 0x0000; 219 XAllocColor(awt_display, defaultConfig->awt_cmap, &color); 220 x11Screens[visualList[i].screen].blackpixel = color.pixel; 221 color.flags = DoRed | DoGreen | DoBlue; 222 color.red = color.green = color.blue = 0xffff; 223 XAllocColor(awt_display, defaultConfig->awt_cmap, &color); 224 x11Screens[visualList[i].screen].whitepixel = color.pixel; 225 226 XFree(visualList); 227 return defaultConfig; 228 } 229 } 230 XFree(visualList); 231 free((void *)defaultConfig); 232 } 233 return NULL; 234 } 235 236 /* default config is based on X11 screen. All Xinerama screens of that X11 237 screen will have the same default config */ 238 /* Need more notes about which fields of the structure are based on the X 239 screen, and which are based on the Xinerama screen */ 240 static AwtGraphicsConfigDataPtr 241 makeDefaultConfig(JNIEnv *env, int screen) { 242 243 AwtGraphicsConfigDataPtr defaultConfig; 244 int xinawareScreen = 0; 245 VisualID forcedVisualID = 0, defaultVisualID; 246 char *forcedVisualStr; 247 XVisualInfo vinfo; 248 long mask; 249 250 xinawareScreen = usingXinerama ? 0 : screen; 251 defaultVisualID = 252 XVisualIDFromVisual(DefaultVisual(awt_display, xinawareScreen)); 253 254 memset(&vinfo, 0, sizeof(XVisualInfo)); 255 vinfo.screen = xinawareScreen; 256 257 if ((forcedVisualStr = getenv("FORCEDEFVIS"))) { 258 mask = VisualIDMask | VisualScreenMask; 259 if (sscanf(forcedVisualStr, "%lx", &forcedVisualID) > 0 && 260 forcedVisualID > 0) 261 { 262 vinfo.visualid = forcedVisualID; 263 } else { 264 vinfo.visualid = defaultVisualID; 265 } 266 } else { 267 VisualID bestGLXVisualID; 268 if (glxRequested && 269 (bestGLXVisualID = GLXGC_FindBestVisual(env, xinawareScreen)) > 0) 270 { 271 /* we've found the best visual for use with GLX, so use it */ 272 vinfo.visualid = bestGLXVisualID; 273 mask = VisualIDMask | VisualScreenMask; 274 } else { 275 /* otherwise, continue looking for the best X11 visual */ 276 vinfo.depth = 24; 277 vinfo.class = TrueColor; 278 mask = VisualDepthMask | VisualScreenMask | VisualClassMask; 279 } 280 } 281 282 /* try the best, or forced visual */ 283 defaultConfig = findWithTemplate(&vinfo, mask); 284 if (defaultConfig) { 285 return defaultConfig; 286 } 287 288 /* try the default visual */ 289 vinfo.visualid = defaultVisualID; 290 mask = VisualIDMask | VisualScreenMask; 291 defaultConfig = findWithTemplate(&vinfo, mask); 292 if (defaultConfig) { 293 return defaultConfig; 294 } 295 296 /* try any TrueColor */ 297 vinfo.class = TrueColor; 298 mask = VisualScreenMask | VisualClassMask; 299 defaultConfig = findWithTemplate(&vinfo, mask); 300 if (defaultConfig) { 301 return defaultConfig; 302 } 303 304 /* try 8-bit PseudoColor */ 305 vinfo.depth = 8; 306 vinfo.class = PseudoColor; 307 mask = VisualDepthMask | VisualScreenMask | VisualClassMask; 308 defaultConfig = findWithTemplate(&vinfo, mask); 309 if (defaultConfig) { 310 return defaultConfig; 311 } 312 313 /* try any 8-bit */ 314 vinfo.depth = 8; 315 mask = VisualDepthMask | VisualScreenMask; 316 defaultConfig = findWithTemplate(&vinfo, mask); 317 if (defaultConfig) { 318 return defaultConfig; 319 } 320 321 /* we tried everything, give up */ 322 JNU_ThrowInternalError(env, "Can't find supported visual"); 323 XCloseDisplay(awt_display); 324 awt_display = NULL; 325 return NULL; 326 } 327 328 static void 329 getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { 330 331 int i; 332 int n8p=0, n12p=0, n8s=0, n8gs=0, n8sg=0, n1sg=0, nTrue=0; 333 int nConfig; 334 XVisualInfo *pVI8p, *pVI12p, *pVI8s, *pVITrue, *pVI8gs, 335 *pVI8sg, *pVI1sg = NULL, viTmp; 336 AwtGraphicsConfigDataPtr *graphicsConfigs; 337 AwtGraphicsConfigDataPtr defaultConfig; 338 int ind; 339 char errmsg[128]; 340 int xinawareScreen; 341 void* xrenderLibHandle = NULL; 342 XRenderFindVisualFormatFunc* xrenderFindVisualFormat = NULL; 343 int major_opcode, first_event, first_error; 344 345 if (usingXinerama) { 346 xinawareScreen = 0; 347 } 348 else { 349 xinawareScreen = screen; 350 } 351 352 AWT_LOCK (); 353 354 viTmp.screen = xinawareScreen; 355 356 viTmp.depth = 8; 357 viTmp.class = PseudoColor; 358 viTmp.colormap_size = 256; 359 pVI8p = XGetVisualInfo (awt_display, 360 VisualDepthMask | VisualClassMask | 361 VisualColormapSizeMask | VisualScreenMask, 362 &viTmp, &n8p); 363 364 viTmp.depth = 12; 365 viTmp.class = PseudoColor; 366 viTmp.colormap_size = 4096; 367 pVI12p = XGetVisualInfo (awt_display, 368 VisualDepthMask | VisualClassMask | 369 VisualColormapSizeMask | VisualScreenMask, 370 &viTmp, &n12p); 371 372 viTmp.class = TrueColor; 373 pVITrue = XGetVisualInfo (awt_display, 374 VisualClassMask | 375 VisualScreenMask, 376 &viTmp, &nTrue); 377 378 viTmp.depth = 8; 379 viTmp.class = StaticColor; 380 pVI8s = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask | 381 VisualScreenMask, &viTmp, &n8s); 382 383 viTmp.depth = 8; 384 viTmp.class = GrayScale; 385 viTmp.colormap_size = 256; 386 pVI8gs = XGetVisualInfo (awt_display, 387 VisualDepthMask | VisualClassMask | 388 VisualColormapSizeMask | VisualScreenMask, 389 &viTmp, &n8gs); 390 viTmp.depth = 8; 391 viTmp.class = StaticGray; 392 viTmp.colormap_size = 256; 393 pVI8sg = XGetVisualInfo (awt_display, 394 VisualDepthMask | VisualClassMask | 395 VisualColormapSizeMask | VisualScreenMask, 396 &viTmp, &n8sg); 397 398 /* REMIND.. remove when we have support for the color classes below */ 399 /* viTmp.depth = 1; */ 400 /* viTmp.class = StaticGray; */ 401 /* pVI1sg = XGetVisualInfo (awt_display, VisualDepthMask | VisualClassMask, */ 402 /* viTmp, &n1sg); */ 403 404 nConfig = n8p + n12p + n8s + n8gs + n8sg + n1sg + nTrue + 1; 405 graphicsConfigs = (AwtGraphicsConfigDataPtr *) 406 calloc(nConfig, sizeof(AwtGraphicsConfigDataPtr)); 407 if (graphicsConfigs == NULL) { 408 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), 409 NULL); 410 AWT_UNLOCK(); 411 return; 412 } 413 414 if (screenDataPtr->defaultConfig == NULL) { 415 /* 416 * After a display change event, the default config field will have 417 * been reset, so we need to recreate the default config here. 418 */ 419 screenDataPtr->defaultConfig = makeDefaultConfig(env, screen); 420 } 421 422 defaultConfig = screenDataPtr->defaultConfig; 423 graphicsConfigs[0] = defaultConfig; 424 nConfig = 1; /* reserve index 0 for default config */ 425 426 // Only use the RENDER extension if it is available on the X server 427 if (XQueryExtension(awt_display, "RENDER", 428 &major_opcode, &first_event, &first_error)) 429 { 430 xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL); 431 432 #ifdef MACOSX 433 #define XRENDER_LIB "/usr/X11/lib/libXrender.dylib" 434 #else 435 #define XRENDER_LIB "libXrender.so" 436 #endif 437 438 if (xrenderLibHandle == NULL) { 439 xrenderLibHandle = dlopen(XRENDER_LIB, 440 RTLD_LAZY | RTLD_GLOBAL); 441 } 442 443 #ifndef __linux__ /* SOLARIS */ 444 if (xrenderLibHandle == NULL) { 445 xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1", 446 RTLD_LAZY | RTLD_GLOBAL); 447 } 448 #endif 449 450 if (xrenderLibHandle != NULL) { 451 xrenderFindVisualFormat = 452 (XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle, 453 "XRenderFindVisualFormat"); 454 } 455 } 456 457 for (i = 0; i < nTrue; i++) { 458 if (XVisualIDFromVisual(pVITrue[i].visual) == 459 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) || 460 pVITrue[i].depth == 12) { 461 /* Skip the non-supported 12-bit TrueColor visual */ 462 continue; 463 } else { 464 ind = nConfig++; 465 } 466 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 467 graphicsConfigs [ind]->awt_depth = pVITrue [i].depth; 468 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i], 469 sizeof (XVisualInfo)); 470 if (xrenderFindVisualFormat != NULL) { 471 XRenderPictFormat *format = xrenderFindVisualFormat (awt_display, 472 pVITrue [i].visual); 473 if (format && 474 format->type == PictTypeDirect && 475 format->direct.alphaMask) 476 { 477 graphicsConfigs [ind]->isTranslucencySupported = 1; 478 memcpy(&graphicsConfigs [ind]->renderPictFormat, format, 479 sizeof(*format)); 480 } 481 } 482 } 483 484 if (xrenderLibHandle != NULL) { 485 dlclose(xrenderLibHandle); 486 xrenderLibHandle = NULL; 487 } 488 489 for (i = 0; i < n8p; i++) { 490 if (XVisualIDFromVisual(pVI8p[i].visual) == 491 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 492 continue; 493 } else { 494 ind = nConfig++; 495 } 496 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 497 graphicsConfigs [ind]->awt_depth = pVI8p [i].depth; 498 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8p [i], 499 sizeof (XVisualInfo)); 500 } 501 502 for (i = 0; i < n12p; i++) { 503 if (XVisualIDFromVisual(pVI12p[i].visual) == 504 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 505 continue; 506 } else { 507 ind = nConfig++; 508 } 509 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 510 graphicsConfigs [ind]->awt_depth = pVI12p [i].depth; 511 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI12p [i], 512 sizeof (XVisualInfo)); 513 } 514 515 for (i = 0; i < n8s; i++) { 516 if (XVisualIDFromVisual(pVI8s[i].visual) == 517 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 518 continue; 519 } else { 520 ind = nConfig++; 521 } 522 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 523 graphicsConfigs [ind]->awt_depth = pVI8s [i].depth; 524 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8s [i], 525 sizeof (XVisualInfo)); 526 } 527 528 for (i = 0; i < n8gs; i++) { 529 if (XVisualIDFromVisual(pVI8gs[i].visual) == 530 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 531 continue; 532 } else { 533 ind = nConfig++; 534 } 535 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 536 graphicsConfigs [ind]->awt_depth = pVI8gs [i].depth; 537 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8gs [i], 538 sizeof (XVisualInfo)); 539 } 540 541 for (i = 0; i < n8sg; i++) { 542 if (XVisualIDFromVisual(pVI8sg[i].visual) == 543 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 544 continue; 545 } else { 546 ind = nConfig++; 547 } 548 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 549 graphicsConfigs [ind]->awt_depth = pVI8sg [i].depth; 550 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8sg [i], 551 sizeof (XVisualInfo)); 552 } 553 554 for (i = 0; i < n1sg; i++) { 555 if (XVisualIDFromVisual(pVI1sg[i].visual) == 556 XVisualIDFromVisual(defaultConfig->awt_visInfo.visual)) { 557 continue; 558 } else { 559 ind = nConfig++; 560 } 561 graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData); 562 graphicsConfigs [ind]->awt_depth = pVI1sg [i].depth; 563 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI1sg [i], 564 sizeof (XVisualInfo)); 565 } 566 567 if (n8p != 0) 568 XFree (pVI8p); 569 if (n12p != 0) 570 XFree (pVI12p); 571 if (n8s != 0) 572 XFree (pVI8s); 573 if (n8gs != 0) 574 XFree (pVI8gs); 575 if (n8sg != 0) 576 XFree (pVI8sg); 577 if (n1sg != 0) 578 XFree (pVI1sg); 579 580 screenDataPtr->numConfigs = nConfig; 581 screenDataPtr->configs = graphicsConfigs; 582 583 AWT_UNLOCK (); 584 } 585 586 #ifndef HEADLESS 587 #if defined(__linux__) || defined(MACOSX) 588 static void xinerama_init_linux() 589 { 590 void* libHandle = NULL; 591 int32_t locNumScr = 0; 592 XineramaScreenInfo *xinInfo; 593 char* XineramaQueryScreensName = "XineramaQueryScreens"; 594 XineramaQueryScreensFunc* XineramaQueryScreens = NULL; 595 596 /* load library */ 597 libHandle = dlopen(VERSIONED_JNI_LIB_NAME("Xinerama", "1"), 598 RTLD_LAZY | RTLD_GLOBAL); 599 if (libHandle == NULL) { 600 libHandle = dlopen(JNI_LIB_NAME("Xinerama"), RTLD_LAZY | RTLD_GLOBAL); 601 } 602 if (libHandle != NULL) { 603 XineramaQueryScreens = (XineramaQueryScreensFunc*) 604 dlsym(libHandle, XineramaQueryScreensName); 605 606 if (XineramaQueryScreens != NULL) { 607 DTRACE_PRINTLN("calling XineramaQueryScreens func on Linux"); 608 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr); 609 if (xinInfo != NULL && locNumScr > XScreenCount(awt_display)) { 610 int32_t idx; 611 DTRACE_PRINTLN("Enabling Xinerama support"); 612 usingXinerama = True; 613 /* set global number of screens */ 614 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr); 615 awt_numScreens = locNumScr; 616 617 /* stuff values into fbrects */ 618 for (idx = 0; idx < awt_numScreens; idx++) { 619 DASSERT(xinInfo[idx].screen_number == idx); 620 621 fbrects[idx].width = xinInfo[idx].width; 622 fbrects[idx].height = xinInfo[idx].height; 623 fbrects[idx].x = xinInfo[idx].x_org; 624 fbrects[idx].y = xinInfo[idx].y_org; 625 } 626 } else { 627 DTRACE_PRINTLN("calling XineramaQueryScreens didn't work"); 628 } 629 } else { 630 DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol"); 631 } 632 dlclose(libHandle); 633 } else { 634 DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror()); 635 } 636 } 637 #endif 638 #if !defined(__linux__) && !defined(MACOSX) /* Solaris */ 639 static void xinerama_init_solaris() 640 { 641 void* libHandle = NULL; 642 unsigned char fbhints[MAXFRAMEBUFFERS]; 643 int32_t locNumScr = 0; 644 /* load and run XineramaGetInfo */ 645 char* XineramaGetInfoName = "XineramaGetInfo"; 646 char* XineramaGetCenterHintName = "XineramaGetCenterHint"; 647 XineramaGetInfoFunc* XineramaSolarisFunc = NULL; 648 649 /* load library */ 650 libHandle = dlopen(JNI_LIB_NAME("Xext"), RTLD_LAZY | RTLD_GLOBAL); 651 if (libHandle != NULL) { 652 XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName); 653 XineramaSolarisCenterFunc = 654 (XineramaGetCenterHintFunc*)dlsym(libHandle, XineramaGetCenterHintName); 655 656 if (XineramaSolarisFunc != NULL) { 657 DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris"); 658 if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0], 659 &fbhints[0], &locNumScr) != 0 && 660 locNumScr > XScreenCount(awt_display)) 661 { 662 DTRACE_PRINTLN("Enabling Xinerama support"); 663 usingXinerama = True; 664 /* set global number of screens */ 665 DTRACE_PRINTLN1(" num screens = %i\n", locNumScr); 666 awt_numScreens = locNumScr; 667 } else { 668 DTRACE_PRINTLN("calling XineramaGetInfo didn't work"); 669 } 670 } else { 671 DTRACE_PRINTLN("couldn't load XineramaGetInfo symbol"); 672 } 673 dlclose(libHandle); 674 } else { 675 DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror()); 676 } 677 } 678 #endif 679 680 /* 681 * Checks if Xinerama is running and perform Xinerama-related 682 * platform dependent initialization. 683 */ 684 static void xineramaInit(void) { 685 char* XinExtName = "XINERAMA"; 686 int32_t major_opcode, first_event, first_error; 687 Bool gotXinExt = False; 688 689 gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode, 690 &first_event, &first_error); 691 692 if (!gotXinExt) { 693 DTRACE_PRINTLN("Xinerama extension is not available"); 694 return; 695 } 696 697 DTRACE_PRINTLN("Xinerama extension is available"); 698 #if defined(__linux__) || defined(MACOSX) 699 xinerama_init_linux(); 700 #else /* Solaris */ 701 xinerama_init_solaris(); 702 #endif /* __linux__ || MACOSX */ 703 } 704 #endif /* HEADLESS */ 705 706 Display * 707 awt_init_Display(JNIEnv *env, jobject this) 708 { 709 jclass klass; 710 Display *dpy; 711 char errmsg[128]; 712 int i; 713 #ifdef NETSCAPE 714 sigset_t alarm_set, oldset; 715 #endif 716 717 if (awt_display) { 718 return awt_display; 719 } 720 721 #ifdef NETSCAPE 722 /* Disable interrupts during XtOpenDisplay to avoid bugs in unix os select 723 code: some unix systems don't implement SA_RESTART properly and 724 because of this, select returns with EINTR. Most implementations of 725 gethostbyname don't cope with EINTR properly and as a result we get 726 stuck (forever) in the gethostbyname code 727 */ 728 sigemptyset(&alarm_set); 729 sigaddset(&alarm_set, SIGALRM); 730 sigprocmask(SIG_BLOCK, &alarm_set, &oldset); 731 #endif 732 733 /* Load AWT lock-related methods in SunToolkit */ 734 klass = (*env)->FindClass(env, "sun/awt/SunToolkit"); 735 if (klass == NULL) return NULL; 736 GET_STATIC_METHOD(klass, awtLockMID, "awtLock", "()V"); 737 GET_STATIC_METHOD(klass, awtUnlockMID, "awtUnlock", "()V"); 738 GET_STATIC_METHOD(klass, awtWaitMID, "awtLockWait", "(J)V"); 739 GET_STATIC_METHOD(klass, awtNotifyMID, "awtLockNotify", "()V"); 740 GET_STATIC_METHOD(klass, awtNotifyAllMID, "awtLockNotifyAll", "()V"); 741 tkClass = (*env)->NewGlobalRef(env, klass); 742 awtLockInited = JNI_TRUE; 743 744 if (getenv("_AWT_IGNORE_XKB") != NULL && 745 strlen(getenv("_AWT_IGNORE_XKB")) > 0) { 746 if (XkbIgnoreExtension(True)) { 747 printf("Ignoring XKB.\n"); 748 } 749 } 750 751 dpy = awt_display = XOpenDisplay(NULL); 752 #ifdef NETSCAPE 753 sigprocmask(SIG_SETMASK, &oldset, NULL); 754 #endif 755 if (!dpy) { 756 jio_snprintf(errmsg, 757 sizeof(errmsg), 758 "Can't connect to X11 window server using '%s' as the value of the DISPLAY variable.", 759 (getenv("DISPLAY") == NULL) ? ":0.0" : getenv("DISPLAY")); 760 JNU_ThrowByName(env, "java/awt/AWTError", errmsg); 761 return NULL; 762 } 763 764 XSetIOErrorHandler(xioerror_handler); 765 JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "init", "(J)V", 766 ptr_to_jlong(awt_display)); 767 JNU_CHECK_EXCEPTION_RETURN(env, NULL); 768 769 /* set awt_numScreens, and whether or not we're using Xinerama */ 770 xineramaInit(); 771 772 if (!usingXinerama) { 773 awt_numScreens = XScreenCount(awt_display); 774 } 775 776 DTRACE_PRINTLN1("allocating %i screens\n", awt_numScreens); 777 /* Allocate screen data structure array */ 778 x11Screens = calloc(awt_numScreens, sizeof(AwtScreenData)); 779 if (x11Screens == NULL) { 780 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), 781 NULL); 782 return NULL; 783 } 784 785 for (i = 0; i < awt_numScreens; i++) { 786 if (usingXinerama) { 787 /* All Xinerama screens use the same X11 root for now */ 788 x11Screens[i].root = RootWindow(awt_display, 0); 789 } 790 else { 791 x11Screens[i].root = RootWindow(awt_display, i); 792 } 793 x11Screens[i].defaultConfig = makeDefaultConfig(env, i); 794 JNU_CHECK_EXCEPTION_RETURN(env, NULL); 795 } 796 797 return dpy; 798 } 799 #endif /* !HEADLESS */ 800 801 /* 802 * Class: sun_awt_X11GraphicsEnvironment 803 * Method: getDefaultScreenNum 804 * Signature: ()I 805 */ 806 JNIEXPORT jint JNICALL 807 Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum( 808 JNIEnv *env, jobject this) 809 { 810 #ifdef HEADLESS 811 return (jint)0; 812 #else 813 return DefaultScreen(awt_display); 814 #endif /* !HEADLESS */ 815 } 816 817 #ifndef HEADLESS 818 static void ensureConfigsInited(JNIEnv* env, int screen) { 819 if (x11Screens[screen].numConfigs == 0) { 820 if (env == NULL) { 821 env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 822 } 823 getAllConfigs (env, screen, &(x11Screens[screen])); 824 } 825 } 826 #endif 827 828 #ifdef HEADLESS 829 void* getDefaultConfig(int screen) { 830 return NULL; 831 } 832 #else 833 AwtGraphicsConfigDataPtr 834 getDefaultConfig(int screen) { 835 ensureConfigsInited(NULL, screen); 836 return x11Screens[screen].defaultConfig; 837 } 838 839 AwtScreenDataPtr 840 getScreenData(int screen) { 841 return &(x11Screens[screen]); 842 } 843 #endif /* !HEADLESS */ 844 845 /* 846 * Class: sun_awt_X11GraphicsEnvironment 847 * Method: initDisplay 848 * Signature: (Z)V 849 */ 850 JNIEXPORT void JNICALL 851 Java_sun_awt_X11GraphicsEnvironment_initDisplay(JNIEnv *env, jobject this, 852 jboolean glxReq) 853 { 854 #ifndef HEADLESS 855 glxRequested = glxReq; 856 (void) awt_init_Display(env, this); 857 #endif /* !HEADLESS */ 858 } 859 860 /* 861 * Class: sun_awt_X11GraphicsEnvironment 862 * Method: initGLX 863 * Signature: ()Z 864 */ 865 JNIEXPORT jboolean JNICALL 866 Java_sun_awt_X11GraphicsEnvironment_initGLX(JNIEnv *env, jclass x11ge) 867 { 868 #ifndef HEADLESS 869 jboolean glxAvailable; 870 871 AWT_LOCK(); 872 glxAvailable = GLXGC_IsGLXAvailable(); 873 AWT_UNLOCK(); 874 875 return glxAvailable; 876 #else 877 return JNI_FALSE; 878 #endif /* !HEADLESS */ 879 } 880 881 /* 882 * Class: sun_awt_X11GraphicsEnvironment 883 * Method: getNumScreens 884 * Signature: ()I 885 */ 886 JNIEXPORT jint JNICALL 887 Java_sun_awt_X11GraphicsEnvironment_getNumScreens(JNIEnv *env, jobject this) 888 { 889 #ifdef HEADLESS 890 return (jint)0; 891 #else 892 return awt_numScreens; 893 #endif /* !HEADLESS */ 894 } 895 896 /* 897 * Class: sun_awt_X11GraphicsDevice 898 * Method: getDisplay 899 * Signature: ()J 900 */ 901 JNIEXPORT jlong JNICALL 902 Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this) 903 { 904 #ifdef HEADLESS 905 return NULL; 906 #else 907 return ptr_to_jlong(awt_display); 908 #endif /* !HEADLESS */ 909 } 910 911 #ifdef MITSHM 912 913 static jint canUseShmExt = UNSET_MITSHM; 914 static jint canUseShmExtPixmaps = UNSET_MITSHM; 915 static jboolean xshmAttachFailed = JNI_FALSE; 916 917 int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr) { 918 if (xerr->minor_code == X_ShmAttach) { 919 xshmAttachFailed = JNI_TRUE; 920 } 921 return 0; 922 } 923 jboolean isXShmAttachFailed() { 924 return xshmAttachFailed; 925 } 926 void resetXShmAttachFailed() { 927 xshmAttachFailed = JNI_FALSE; 928 } 929 930 extern int mitShmPermissionMask; 931 932 void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) { 933 XShmSegmentInfo shminfo; 934 int XShmMajor, XShmMinor; 935 int a, b, c; 936 937 AWT_LOCK(); 938 if (canUseShmExt != UNSET_MITSHM) { 939 *shmExt = canUseShmExt; 940 *shmPixmaps = canUseShmExtPixmaps; 941 AWT_UNLOCK(); 942 return; 943 } 944 945 *shmExt = canUseShmExt = CANT_USE_MITSHM; 946 *shmPixmaps = canUseShmExtPixmaps = CANT_USE_MITSHM; 947 948 if (awt_display == (Display *)NULL) { 949 AWT_NOFLUSH_UNLOCK(); 950 return; 951 } 952 953 /** 954 * XShmQueryExtension returns False in remote server case. 955 * Unfortunately it also returns True in ssh case, so 956 * we need to test that we can actually do XShmAttach. 957 */ 958 if (XShmQueryExtension(awt_display)) { 959 shminfo.shmid = shmget(IPC_PRIVATE, 0x10000, 960 IPC_CREAT|mitShmPermissionMask); 961 if (shminfo.shmid < 0) { 962 AWT_UNLOCK(); 963 J2dRlsTraceLn1(J2D_TRACE_ERROR, 964 "TryInitMITShm: shmget has failed: %s", 965 strerror(errno)); 966 return; 967 } 968 shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0); 969 if (shminfo.shmaddr == ((char *) -1)) { 970 shmctl(shminfo.shmid, IPC_RMID, 0); 971 AWT_UNLOCK(); 972 J2dRlsTraceLn1(J2D_TRACE_ERROR, 973 "TryInitMITShm: shmat has failed: %s", 974 strerror(errno)); 975 return; 976 } 977 shminfo.readOnly = True; 978 979 resetXShmAttachFailed(); 980 /** 981 * The J2DXErrHandler handler will set xshmAttachFailed 982 * to JNI_TRUE if any Shm error has occured. 983 */ 984 EXEC_WITH_XERROR_HANDLER(XShmAttachXErrHandler, 985 XShmAttach(awt_display, &shminfo)); 986 987 /** 988 * Get rid of the id now to reduce chances of leaking 989 * system resources. 990 */ 991 shmctl(shminfo.shmid, IPC_RMID, 0); 992 993 if (isXShmAttachFailed() == JNI_FALSE) { 994 canUseShmExt = CAN_USE_MITSHM; 995 /* check if we can use shared pixmaps */ 996 XShmQueryVersion(awt_display, &XShmMajor, &XShmMinor, 997 (Bool*)&canUseShmExtPixmaps); 998 canUseShmExtPixmaps = canUseShmExtPixmaps && 999 (XShmPixmapFormat(awt_display) == ZPixmap); 1000 XShmDetach(awt_display, &shminfo); 1001 } 1002 shmdt(shminfo.shmaddr); 1003 *shmExt = canUseShmExt; 1004 *shmPixmaps = canUseShmExtPixmaps; 1005 } 1006 AWT_UNLOCK(); 1007 } 1008 #endif /* MITSHM */ 1009 1010 /* 1011 * Class: sun_awt_X11GraphicsEnvironment 1012 * Method: checkShmExt 1013 * Signature: ()I 1014 */ 1015 JNIEXPORT jint JNICALL 1016 Java_sun_awt_X11GraphicsEnvironment_checkShmExt(JNIEnv *env, jobject this) 1017 { 1018 1019 int shmExt = NOEXT_MITSHM, shmPixmaps; 1020 #ifdef MITSHM 1021 TryInitMITShm(env, &shmExt, &shmPixmaps); 1022 #endif 1023 return shmExt; 1024 } 1025 1026 /* 1027 * Class: sun_awt_X11GraphicsEnvironment 1028 * Method: getDisplayString 1029 * Signature: ()Ljava/lang/String 1030 */ 1031 JNIEXPORT jstring JNICALL 1032 Java_sun_awt_X11GraphicsEnvironment_getDisplayString 1033 (JNIEnv *env, jobject this) 1034 { 1035 #ifdef HEADLESS 1036 return (jstring)NULL; 1037 #else 1038 return (*env)->NewStringUTF(env, DisplayString(awt_display)); 1039 #endif /* HEADLESS */ 1040 } 1041 1042 1043 /* 1044 * Class: sun_awt_X11GraphicsDevice 1045 * Method: getNumConfigs 1046 * Signature: ()I 1047 */ 1048 JNIEXPORT jint JNICALL 1049 Java_sun_awt_X11GraphicsDevice_getNumConfigs( 1050 JNIEnv *env, jobject this, jint screen) 1051 { 1052 #ifdef HEADLESS 1053 return (jint)0; 1054 #else 1055 ensureConfigsInited(env, screen); 1056 return x11Screens[screen].numConfigs; 1057 #endif /* !HEADLESS */ 1058 } 1059 1060 /* 1061 * Class: sun_awt_X11GraphicsDevice 1062 * Method: getConfigVisualId 1063 * Signature: (I)I 1064 */ 1065 JNIEXPORT jint JNICALL 1066 Java_sun_awt_X11GraphicsDevice_getConfigVisualId( 1067 JNIEnv *env, jobject this, jint index, jint screen) 1068 { 1069 #ifdef HEADLESS 1070 return (jint)0; 1071 #else 1072 int visNum; 1073 1074 ensureConfigsInited(env, screen); 1075 if (index == 0) { 1076 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.visualid); 1077 } else { 1078 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.visualid); 1079 } 1080 #endif /* !HEADLESS */ 1081 } 1082 1083 /* 1084 * Class: sun_awt_X11GraphicsDevice 1085 * Method: getConfigDepth 1086 * Signature: (I)I 1087 */ 1088 JNIEXPORT jint JNICALL 1089 Java_sun_awt_X11GraphicsDevice_getConfigDepth( 1090 JNIEnv *env, jobject this, jint index, jint screen) 1091 { 1092 #ifdef HEADLESS 1093 return (jint)0; 1094 #else 1095 int visNum; 1096 1097 ensureConfigsInited(env, screen); 1098 if (index == 0) { 1099 return ((jint)x11Screens[screen].defaultConfig->awt_visInfo.depth); 1100 } else { 1101 return ((jint)x11Screens[screen].configs[index]->awt_visInfo.depth); 1102 } 1103 #endif /* !HEADLESS */ 1104 } 1105 1106 /* 1107 * Class: sun_awt_X11GraphicsDevice 1108 * Method: getConfigColormap 1109 * Signature: (I)I 1110 */ 1111 JNIEXPORT jint JNICALL 1112 Java_sun_awt_X11GraphicsDevice_getConfigColormap( 1113 JNIEnv *env, jobject this, jint index, jint screen) 1114 { 1115 #ifdef HEADLESS 1116 return (jint)0; 1117 #else 1118 int visNum; 1119 1120 ensureConfigsInited(env, screen); 1121 if (index == 0) { 1122 return ((jint)x11Screens[screen].defaultConfig->awt_cmap); 1123 } else { 1124 return ((jint)x11Screens[screen].configs[index]->awt_cmap); 1125 } 1126 #endif /* !HEADLESS */ 1127 } 1128 1129 /* 1130 * Class: sun_awt_X11GraphicsDevice 1131 * Method: resetNativeData 1132 * Signature: (I)V 1133 */ 1134 JNIEXPORT void JNICALL 1135 Java_sun_awt_X11GraphicsDevice_resetNativeData 1136 (JNIEnv *env, jclass x11gd, jint screen) 1137 { 1138 #ifndef HEADLESS 1139 /* 1140 * Reset references to the various configs; the actual native config data 1141 * will be free'd later by the Disposer mechanism when the Java-level 1142 * X11GraphicsConfig objects go away. By setting these values to NULL, 1143 * we ensure that they will be reinitialized as necessary (for example, 1144 * see the getNumConfigs() method). 1145 */ 1146 if (x11Screens[screen].configs) { 1147 free(x11Screens[screen].configs); 1148 x11Screens[screen].configs = NULL; 1149 } 1150 x11Screens[screen].defaultConfig = NULL; 1151 x11Screens[screen].numConfigs = 0; 1152 #endif /* !HEADLESS */ 1153 } 1154 1155 /* 1156 * Class: sun_awt_X11GraphicsConfig 1157 * Method: dispose 1158 * Signature: (J)V 1159 */ 1160 JNIEXPORT void JNICALL 1161 Java_sun_awt_X11GraphicsConfig_dispose 1162 (JNIEnv *env, jclass x11gc, jlong configData) 1163 { 1164 #ifndef HEADLESS 1165 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr) 1166 jlong_to_ptr(configData); 1167 1168 if (aData == NULL) { 1169 return; 1170 } 1171 1172 AWT_LOCK(); 1173 if (aData->awt_cmap) { 1174 XFreeColormap(awt_display, aData->awt_cmap); 1175 } 1176 if (aData->awtImage) { 1177 free(aData->awtImage); 1178 } 1179 if (aData->monoImage) { 1180 XFree(aData->monoImage); 1181 } 1182 if (aData->monoPixmap) { 1183 XFreePixmap(awt_display, aData->monoPixmap); 1184 } 1185 if (aData->monoPixmapGC) { 1186 XFreeGC(awt_display, aData->monoPixmapGC); 1187 } 1188 if (aData->color_data) { 1189 free(aData->color_data); 1190 } 1191 AWT_UNLOCK(); 1192 1193 if (aData->glxInfo) { 1194 /* 1195 * The native GLXGraphicsConfig data needs to be disposed separately 1196 * on the OGL queue flushing thread (should not be called while 1197 * the AWT lock is held). 1198 */ 1199 JNU_CallStaticMethodByName(env, NULL, 1200 "sun/java2d/opengl/OGLRenderQueue", 1201 "disposeGraphicsConfig", "(J)V", 1202 ptr_to_jlong(aData->glxInfo)); 1203 } 1204 1205 free(aData); 1206 #endif /* !HEADLESS */ 1207 } 1208 1209 /* 1210 * Class: sun_awt_X11GraphicsConfig 1211 * Method: getXResolution 1212 * Signature: ()I 1213 */ 1214 JNIEXPORT jdouble JNICALL 1215 Java_sun_awt_X11GraphicsConfig_getXResolution( 1216 JNIEnv *env, jobject this, jint screen) 1217 { 1218 #ifdef HEADLESS 1219 return (jdouble)0; 1220 #else 1221 return ((DisplayWidth(awt_display, screen) * 25.4) / 1222 DisplayWidthMM(awt_display, screen)); 1223 #endif /* !HEADLESS */ 1224 } 1225 1226 /* 1227 * Class: sun_awt_X11GraphicsConfig 1228 * Method: getYResolution 1229 * Signature: ()I 1230 */ 1231 JNIEXPORT jdouble JNICALL 1232 Java_sun_awt_X11GraphicsConfig_getYResolution( 1233 JNIEnv *env, jobject this, jint screen) 1234 { 1235 #ifdef HEADLESS 1236 return (jdouble)0; 1237 #else 1238 return ((DisplayHeight(awt_display, screen) * 25.4) / 1239 DisplayHeightMM(awt_display, screen)); 1240 #endif /* !HEADLESS */ 1241 } 1242 1243 1244 /* 1245 * Class: sun_awt_X11GraphicsConfig 1246 * Method: getNumColors 1247 * Signature: ()I 1248 */ 1249 JNIEXPORT jint JNICALL 1250 Java_sun_awt_X11GraphicsConfig_getNumColors( 1251 JNIEnv *env, jobject this) 1252 { 1253 #ifdef HEADLESS 1254 return (jint)0; 1255 #else 1256 AwtGraphicsConfigData *adata; 1257 1258 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this, 1259 x11GraphicsConfigIDs.aData); 1260 1261 return adata->awt_num_colors; 1262 #endif /* !HEADLESS */ 1263 } 1264 1265 /* 1266 * Class: sun_awt_X11GraphicsConfig 1267 * Method: init 1268 * Signature: (I)V 1269 */ 1270 JNIEXPORT void JNICALL 1271 Java_sun_awt_X11GraphicsConfig_init( 1272 JNIEnv *env, jobject this, jint visualNum, jint screen) 1273 { 1274 #ifndef HEADLESS 1275 AwtGraphicsConfigData *adata = NULL; 1276 AwtScreenData asd = x11Screens[screen]; 1277 int i, n; 1278 int depth; 1279 XImage * tempImage; 1280 1281 /* If haven't gotten all of the configs yet, do it now. */ 1282 if (asd.numConfigs == 0) { 1283 getAllConfigs (env, screen, &asd); 1284 } 1285 1286 /* Check the graphicsConfig for this visual */ 1287 for (i = 0; i < asd.numConfigs; i++) { 1288 AwtGraphicsConfigDataPtr agcPtr = asd.configs[i]; 1289 if ((jint)agcPtr->awt_visInfo.visualid == visualNum) { 1290 adata = agcPtr; 1291 break; 1292 } 1293 } 1294 1295 /* If didn't find the visual, throw an exception... */ 1296 if (adata == (AwtGraphicsConfigData *) NULL) { 1297 JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified"); 1298 return; 1299 } 1300 1301 /* adata->awt_cmap initialization has been deferred to 1302 * makeColorModel call 1303 */ 1304 1305 JNU_SetLongFieldFromPtr(env, this, x11GraphicsConfigIDs.aData, adata); 1306 1307 depth = adata->awt_visInfo.depth; 1308 tempImage = XCreateImage(awt_display, 1309 adata->awt_visInfo.visual, 1310 depth, ZPixmap, 0, NULL, 1, 1, 32, 0); 1311 adata->pixelStride = (tempImage->bits_per_pixel + 7) / 8; 1312 (*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel, 1313 (jint)tempImage->bits_per_pixel); 1314 XDestroyImage(tempImage); 1315 #endif /* !HEADLESS */ 1316 } 1317 1318 1319 1320 /* 1321 * Class: sun_awt_X11GraphicsConfig 1322 * Method: makeColorModel 1323 * Signature: ()Ljava/awt/image/ColorModel 1324 */ 1325 JNIEXPORT jobject JNICALL 1326 Java_sun_awt_X11GraphicsConfig_makeColorModel( 1327 JNIEnv *env, jobject this) 1328 { 1329 #ifdef HEADLESS 1330 return NULL; 1331 #else 1332 AwtGraphicsConfigData *adata; 1333 jobject colorModel; 1334 1335 /* 1336 * If awt is not locked yet, return null since the toolkit is not 1337 * initialized yet. 1338 */ 1339 if (!awtLockInited) { 1340 return NULL; 1341 } 1342 1343 AWT_LOCK (); 1344 1345 adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this, 1346 x11GraphicsConfigIDs.aData); 1347 1348 /* If colormap entry of adata is NULL, need to create it now */ 1349 if (adata->awt_cmap == (Colormap) NULL) { 1350 awtJNI_CreateColorData (env, adata, 1); 1351 } 1352 1353 /* Make Color Model object for this GraphicsConfiguration */ 1354 colorModel = (*env)->ExceptionCheck(env) 1355 ? NULL : awtJNI_GetColorModel (env, adata); 1356 1357 AWT_UNLOCK (); 1358 1359 return colorModel; 1360 #endif /* !HEADLESS */ 1361 } 1362 1363 1364 /* 1365 * Class: sun_awt_X11GraphicsConfig 1366 * Method: getBounds 1367 * Signature: ()Ljava/awt/Rectangle 1368 */ 1369 JNIEXPORT jobject JNICALL 1370 Java_sun_awt_X11GraphicsConfig_pGetBounds(JNIEnv *env, jobject this, jint screen) 1371 { 1372 #ifdef HEADLESS 1373 return NULL; 1374 #else 1375 jclass clazz; 1376 jmethodID mid; 1377 jobject bounds = NULL; 1378 AwtGraphicsConfigDataPtr adata; 1379 1380 adata = (AwtGraphicsConfigDataPtr) 1381 JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData); 1382 1383 clazz = (*env)->FindClass(env, "java/awt/Rectangle"); 1384 CHECK_NULL_RETURN(clazz, NULL); 1385 mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V"); 1386 if (mid != NULL) { 1387 if (usingXinerama) { 1388 if (0 <= screen && screen < awt_numScreens) { 1389 bounds = (*env)->NewObject(env, clazz, mid, fbrects[screen].x, 1390 fbrects[screen].y, 1391 fbrects[screen].width, 1392 fbrects[screen].height); 1393 } else { 1394 jclass exceptionClass = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); 1395 if (exceptionClass != NULL) { 1396 (*env)->ThrowNew(env, exceptionClass, "Illegal screen index"); 1397 } 1398 } 1399 } else { 1400 XWindowAttributes xwa; 1401 memset(&xwa, 0, sizeof(xwa)); 1402 1403 AWT_LOCK (); 1404 XGetWindowAttributes(awt_display, 1405 RootWindow(awt_display, adata->awt_visInfo.screen), 1406 &xwa); 1407 AWT_UNLOCK (); 1408 1409 bounds = (*env)->NewObject(env, clazz, mid, 0, 0, 1410 xwa.width, xwa.height); 1411 } 1412 1413 if ((*env)->ExceptionOccurred(env)) { 1414 return NULL; 1415 } 1416 } 1417 return bounds; 1418 #endif /* !HEADLESS */ 1419 } 1420 1421 /* 1422 * Class: sun_awt_X11GraphicsConfig 1423 * Method: createBackBuffer 1424 * Signature: (JI)J 1425 */ 1426 JNIEXPORT jlong JNICALL 1427 Java_sun_awt_X11GraphicsConfig_createBackBuffer 1428 (JNIEnv *env, jobject this, jlong window, jint swapAction) 1429 { 1430 int32_t v1, v2; 1431 XdbeBackBuffer ret = (unsigned long) 0; 1432 Window w = (Window)window; 1433 AWT_LOCK(); 1434 if (!XdbeQueryExtension(awt_display, &v1, &v2)) { 1435 JNU_ThrowByName(env, "java/lang/Exception", 1436 "Could not query double-buffer extension"); 1437 AWT_UNLOCK(); 1438 return (jlong)0; 1439 } 1440 ret = XdbeAllocateBackBufferName(awt_display, w, 1441 (XdbeSwapAction)swapAction); 1442 AWT_FLUSH_UNLOCK(); 1443 return (jlong)ret; 1444 } 1445 1446 /* 1447 * Class: sun_awt_X11GraphicsConfig 1448 * Method: destroyBackBuffer 1449 * Signature: (J)V 1450 */ 1451 JNIEXPORT void JNICALL 1452 Java_sun_awt_X11GraphicsConfig_destroyBackBuffer 1453 (JNIEnv *env, jobject this, jlong backBuffer) 1454 { 1455 AWT_LOCK(); 1456 XdbeDeallocateBackBufferName(awt_display, (XdbeBackBuffer)backBuffer); 1457 AWT_FLUSH_UNLOCK(); 1458 } 1459 1460 /* 1461 * Class: sun_awt_X11GraphicsConfig 1462 * Method: swapBuffers 1463 * Signature: (JI)V 1464 */ 1465 JNIEXPORT void JNICALL 1466 Java_sun_awt_X11GraphicsConfig_swapBuffers 1467 (JNIEnv *env, jobject this, 1468 jlong window, jint swapAction) 1469 { 1470 XdbeSwapInfo swapInfo; 1471 1472 AWT_LOCK(); 1473 1474 XdbeBeginIdiom(awt_display); 1475 swapInfo.swap_window = (Window)window; 1476 swapInfo.swap_action = (XdbeSwapAction)swapAction; 1477 if (!XdbeSwapBuffers(awt_display, &swapInfo, 1)) { 1478 JNU_ThrowInternalError(env, "Could not swap buffers"); 1479 } 1480 XdbeEndIdiom(awt_display); 1481 1482 AWT_FLUSH_UNLOCK(); 1483 } 1484 1485 /* 1486 * Class: sun_awt_X11GraphicsConfig 1487 * Method: isTranslucencyCapable 1488 * Signature: (J)V 1489 */ 1490 JNIEXPORT jboolean JNICALL 1491 Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable 1492 (JNIEnv *env, jobject this, jlong configData) 1493 { 1494 #ifdef HEADLESS 1495 return JNI_FALSE; 1496 #else 1497 AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData); 1498 if (aData == NULL) { 1499 return JNI_FALSE; 1500 } 1501 return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE; 1502 #endif 1503 } 1504 1505 /* 1506 * Class: sun_awt_X11GraphicsDevice 1507 * Method: isDBESupported 1508 * Signature: ()Z 1509 */ 1510 JNIEXPORT jboolean JNICALL 1511 Java_sun_awt_X11GraphicsDevice_isDBESupported(JNIEnv *env, jobject this) 1512 { 1513 #ifdef HEADLESS 1514 return JNI_FALSE; 1515 #else 1516 int opcode = 0, firstEvent = 0, firstError = 0; 1517 jboolean ret; 1518 1519 AWT_LOCK(); 1520 ret = (jboolean)XQueryExtension(awt_display, "DOUBLE-BUFFER", 1521 &opcode, &firstEvent, &firstError); 1522 AWT_FLUSH_UNLOCK(); 1523 return ret; 1524 #endif /* !HEADLESS */ 1525 } 1526 1527 /* 1528 * Class: sun_awt_X11GraphicsDevice 1529 * Method: getDoubleBufferVisuals 1530 * Signature: (I)V 1531 */ 1532 JNIEXPORT void JNICALL 1533 Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env, 1534 jobject this, jint screen) 1535 { 1536 #ifndef HEADLESS 1537 jclass clazz; 1538 jmethodID midAddVisual; 1539 Window rootWindow; 1540 int i, n = 1; 1541 XdbeScreenVisualInfo* visScreenInfo; 1542 int xinawareScreen; 1543 1544 if (usingXinerama) { 1545 xinawareScreen = 0; 1546 } 1547 else { 1548 xinawareScreen = screen; 1549 } 1550 1551 clazz = (*env)->GetObjectClass(env, this); 1552 midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual", 1553 "(I)V"); 1554 CHECK_NULL(midAddVisual); 1555 AWT_LOCK(); 1556 rootWindow = RootWindow(awt_display, xinawareScreen); 1557 visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n); 1558 if (visScreenInfo == NULL) { 1559 JNU_ThrowInternalError(env, "Could not get visual info"); 1560 AWT_UNLOCK(); 1561 return; 1562 } 1563 AWT_FLUSH_UNLOCK(); 1564 for (i = 0; i < visScreenInfo->count; i++) { 1565 XdbeVisualInfo* visInfo = visScreenInfo->visinfo; 1566 (*env)->CallVoidMethod(env, this, midAddVisual, (visInfo[i]).visual); 1567 if ((*env)->ExceptionCheck(env)) { 1568 break; 1569 } 1570 } 1571 #endif /* !HEADLESS */ 1572 } 1573 1574 /* 1575 * Class: sun_awt_X11GraphicsEnvironment 1576 * Method: pRunningXinerama 1577 * Signature: ()Z 1578 */ 1579 JNIEXPORT jboolean JNICALL 1580 Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama(JNIEnv *env, 1581 jobject this) 1582 { 1583 #ifdef HEADLESS 1584 return JNI_FALSE; 1585 #else 1586 return usingXinerama ? JNI_TRUE : JNI_FALSE; 1587 #endif /* HEADLESS */ 1588 } 1589 1590 /* 1591 * Can return NULL. 1592 * 1593 * Class: sun_awt_X11GraphicsEnvironment 1594 * Method: getXineramaCenterPoint 1595 * Signature: ()Ljava/awt/Point 1596 */ 1597 JNIEXPORT jobject JNICALL 1598 Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env, 1599 jobject this) 1600 { 1601 jobject point = NULL; 1602 #ifndef HEADLESS /* return NULL in HEADLESS, Linux */ 1603 #if !defined(__linux__) && !defined(MACOSX) 1604 int x,y; 1605 1606 AWT_LOCK(); 1607 DASSERT(usingXinerama); 1608 if (XineramaSolarisCenterFunc != NULL) { 1609 (XineramaSolarisCenterFunc)(awt_display, 0, &x, &y); 1610 point = JNU_NewObjectByName(env, "java/awt/Point","(II)V", x, y); 1611 DASSERT(point); 1612 } else { 1613 DTRACE_PRINTLN("unable to call XineramaSolarisCenterFunc: symbol is null"); 1614 } 1615 AWT_FLUSH_UNLOCK(); 1616 #endif /* __linux __ || MACOSX */ 1617 #endif /* HEADLESS */ 1618 return point; 1619 } 1620 1621 1622 /** 1623 * Begin DisplayMode/FullScreen support 1624 */ 1625 1626 #ifndef HEADLESS 1627 1628 #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI 1629 #define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN 1630 1631 typedef Status 1632 (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp); 1633 typedef XRRScreenConfiguration* 1634 (*XRRGetScreenInfoType)(Display *dpy, Drawable root); 1635 typedef void 1636 (*XRRFreeScreenConfigInfoType)(XRRScreenConfiguration *config); 1637 typedef short* 1638 (*XRRConfigRatesType)(XRRScreenConfiguration *config, 1639 int sizeID, int *nrates); 1640 typedef short 1641 (*XRRConfigCurrentRateType)(XRRScreenConfiguration *config); 1642 typedef XRRScreenSize* 1643 (*XRRConfigSizesType)(XRRScreenConfiguration *config, 1644 int *nsizes); 1645 typedef SizeID 1646 (*XRRConfigCurrentConfigurationType)(XRRScreenConfiguration *config, 1647 Rotation *rotation); 1648 typedef Status 1649 (*XRRSetScreenConfigAndRateType)(Display *dpy, 1650 XRRScreenConfiguration *config, 1651 Drawable draw, 1652 int size_index, 1653 Rotation rotation, 1654 short rate, 1655 Time timestamp); 1656 typedef Rotation 1657 (*XRRConfigRotationsType)(XRRScreenConfiguration *config, 1658 Rotation *current_rotation); 1659 1660 typedef XRRScreenResources* (*XRRGetScreenResourcesType)(Display *dpy, 1661 Window window); 1662 1663 typedef void (*XRRFreeScreenResourcesType)(XRRScreenResources *resources); 1664 1665 typedef XRROutputInfo * (*XRRGetOutputInfoType)(Display *dpy, 1666 XRRScreenResources *resources, RROutput output); 1667 1668 typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo); 1669 1670 typedef XRRCrtcInfo* (*XRRGetCrtcInfoType)(Display *dpy, 1671 XRRScreenResources *resources, RRCrtc crtc); 1672 1673 typedef void (*XRRFreeCrtcInfoType)(XRRCrtcInfo *crtcInfo); 1674 1675 static XRRQueryVersionType awt_XRRQueryVersion; 1676 static XRRGetScreenInfoType awt_XRRGetScreenInfo; 1677 static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo; 1678 static XRRConfigRatesType awt_XRRConfigRates; 1679 static XRRConfigCurrentRateType awt_XRRConfigCurrentRate; 1680 static XRRConfigSizesType awt_XRRConfigSizes; 1681 static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration; 1682 static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate; 1683 static XRRConfigRotationsType awt_XRRConfigRotations; 1684 static XRRGetScreenResourcesType awt_XRRGetScreenResources; 1685 static XRRFreeScreenResourcesType awt_XRRFreeScreenResources; 1686 static XRRGetOutputInfoType awt_XRRGetOutputInfo; 1687 static XRRFreeOutputInfoType awt_XRRFreeOutputInfo; 1688 static XRRGetCrtcInfoType awt_XRRGetCrtcInfo; 1689 static XRRFreeCrtcInfoType awt_XRRFreeCrtcInfo; 1690 1691 #define LOAD_XRANDR_FUNC(f) \ 1692 do { \ 1693 awt_##f = (f##Type)dlsym(pLibRandR, #f); \ 1694 if (awt_##f == NULL) { \ 1695 J2dRlsTraceLn1(J2D_TRACE_ERROR, \ 1696 "X11GD_InitXrandrFuncs: Could not load %s", #f); \ 1697 dlclose(pLibRandR); \ 1698 return JNI_FALSE; \ 1699 } \ 1700 } while (0) 1701 1702 static jboolean 1703 X11GD_InitXrandrFuncs(JNIEnv *env) 1704 { 1705 int rr_maj_ver = 0, rr_min_ver = 0; 1706 1707 void *pLibRandR = dlopen(VERSIONED_JNI_LIB_NAME("Xrandr", "2"), 1708 RTLD_LAZY | RTLD_LOCAL); 1709 if (pLibRandR == NULL) { 1710 pLibRandR = dlopen(JNI_LIB_NAME("Xrandr"), RTLD_LAZY | RTLD_LOCAL); 1711 } 1712 if (pLibRandR == NULL) { 1713 J2dRlsTraceLn(J2D_TRACE_ERROR, 1714 "X11GD_InitXrandrFuncs: Could not open libXrandr.so.2"); 1715 return JNI_FALSE; 1716 } 1717 1718 LOAD_XRANDR_FUNC(XRRQueryVersion); 1719 1720 if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) { 1721 J2dRlsTraceLn(J2D_TRACE_ERROR, 1722 "X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status"); 1723 dlclose(pLibRandR); 1724 return JNI_FALSE; 1725 } 1726 1727 if (usingXinerama) { 1728 /* 1729 * We can proceed as long as this is RANDR 1.2 or above. 1730 * As of Xorg server 1.3 onwards the Xinerama backend may actually be 1731 * a fake one provided by RANDR itself. See Java bug 6636469 for info. 1732 */ 1733 if (!(rr_maj_ver > 1 || (rr_maj_ver == 1 && rr_min_ver >= 2))) { 1734 J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. " 1735 "Xinerama is active and Xrandr version is %d.%d", 1736 rr_maj_ver, rr_min_ver); 1737 dlclose(pLibRandR); 1738 return JNI_FALSE; 1739 } 1740 1741 /* 1742 * REMIND: Fullscreen mode doesn't work quite right with multi-monitor 1743 * setups and RANDR 1.2. 1744 */ 1745 if ((rr_maj_ver == 1 && rr_min_ver <= 2) && awt_numScreens > 1) { 1746 J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. " 1747 "Multiple screens in use"); 1748 dlclose(pLibRandR); 1749 return JNI_FALSE; 1750 } 1751 } 1752 1753 LOAD_XRANDR_FUNC(XRRGetScreenInfo); 1754 LOAD_XRANDR_FUNC(XRRFreeScreenConfigInfo); 1755 LOAD_XRANDR_FUNC(XRRConfigRates); 1756 LOAD_XRANDR_FUNC(XRRConfigCurrentRate); 1757 LOAD_XRANDR_FUNC(XRRConfigSizes); 1758 LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration); 1759 LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate); 1760 LOAD_XRANDR_FUNC(XRRConfigRotations); 1761 LOAD_XRANDR_FUNC(XRRGetScreenResources); 1762 LOAD_XRANDR_FUNC(XRRFreeScreenResources); 1763 LOAD_XRANDR_FUNC(XRRGetOutputInfo); 1764 LOAD_XRANDR_FUNC(XRRFreeOutputInfo); 1765 LOAD_XRANDR_FUNC(XRRGetCrtcInfo); 1766 LOAD_XRANDR_FUNC(XRRFreeCrtcInfo); 1767 1768 return JNI_TRUE; 1769 } 1770 1771 static jobject 1772 X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height, 1773 jint bitDepth, jint refreshRate) 1774 { 1775 jclass displayModeClass; 1776 jmethodID cid; 1777 jint validRefreshRate = refreshRate; 1778 1779 displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode"); 1780 CHECK_NULL_RETURN(displayModeClass, NULL); 1781 if (JNU_IsNull(env, displayModeClass)) { 1782 JNU_ThrowInternalError(env, 1783 "Could not get display mode class"); 1784 return NULL; 1785 } 1786 1787 cid = (*env)->GetMethodID(env, displayModeClass, "<init>", "(IIII)V"); 1788 CHECK_NULL_RETURN(cid, NULL); 1789 if (cid == NULL) { 1790 JNU_ThrowInternalError(env, 1791 "Could not get display mode constructor"); 1792 return NULL; 1793 } 1794 1795 // early versions of xrandr may report "empty" rates (6880694) 1796 if (validRefreshRate <= 0) { 1797 validRefreshRate = REFRESH_RATE_UNKNOWN; 1798 } 1799 1800 return (*env)->NewObject(env, displayModeClass, cid, 1801 width, height, bitDepth, validRefreshRate); 1802 } 1803 1804 static void 1805 X11GD_AddDisplayMode(JNIEnv *env, jobject arrayList, 1806 jint width, jint height, 1807 jint bitDepth, jint refreshRate) 1808 { 1809 jobject displayMode = X11GD_CreateDisplayMode(env, width, height, 1810 bitDepth, refreshRate); 1811 if (!JNU_IsNull(env, displayMode)) { 1812 jclass arrayListClass; 1813 jmethodID mid; 1814 arrayListClass = (*env)->GetObjectClass(env, arrayList); 1815 if (JNU_IsNull(env, arrayListClass)) { 1816 JNU_ThrowInternalError(env, 1817 "Could not get class java.util.ArrayList"); 1818 return; 1819 } 1820 mid = (*env)->GetMethodID(env, arrayListClass, "add", 1821 "(Ljava/lang/Object;)Z"); 1822 CHECK_NULL(mid); 1823 if (mid == NULL) { 1824 JNU_ThrowInternalError(env, 1825 "Could not get method java.util.ArrayList.add()"); 1826 return; 1827 } 1828 (*env)->CallObjectMethod(env, arrayList, mid, displayMode); 1829 (*env)->DeleteLocalRef(env, displayMode); 1830 } 1831 } 1832 1833 static void 1834 X11GD_SetFullscreenMode(Window win, jboolean enabled) 1835 { 1836 Atom wmState = XInternAtom(awt_display, "_NET_WM_STATE", False); 1837 Atom wmStateFs = XInternAtom(awt_display, 1838 "_NET_WM_STATE_FULLSCREEN", False); 1839 XWindowAttributes attr; 1840 XEvent event; 1841 1842 if (wmState == None || wmStateFs == None 1843 || !XGetWindowAttributes(awt_display, win, &attr)) { 1844 return; 1845 } 1846 1847 memset(&event, 0, sizeof(event)); 1848 event.xclient.type = ClientMessage; 1849 event.xclient.message_type = wmState; 1850 event.xclient.display = awt_display; 1851 event.xclient.window = win; 1852 event.xclient.format = 32; 1853 event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove 1854 event.xclient.data.l[1] = wmStateFs; 1855 1856 XSendEvent(awt_display, attr.root, False, 1857 SubstructureRedirectMask | SubstructureNotifyMask, 1858 &event); 1859 XSync(awt_display, False); 1860 } 1861 #endif /* !HEADLESS */ 1862 1863 /* 1864 * Class: sun_awt_X11GraphicsDevice 1865 * Method: initXrandrExtension 1866 * Signature: ()Z 1867 */ 1868 JNIEXPORT jboolean JNICALL 1869 Java_sun_awt_X11GraphicsDevice_initXrandrExtension 1870 (JNIEnv *env, jclass x11gd) 1871 { 1872 #ifdef HEADLESS 1873 return JNI_FALSE; 1874 #else 1875 int opcode = 0, firstEvent = 0, firstError = 0; 1876 jboolean ret; 1877 1878 AWT_LOCK(); 1879 ret = (jboolean)XQueryExtension(awt_display, "RANDR", 1880 &opcode, &firstEvent, &firstError); 1881 if (ret) { 1882 ret = X11GD_InitXrandrFuncs(env); 1883 } 1884 AWT_FLUSH_UNLOCK(); 1885 1886 return ret; 1887 #endif /* HEADLESS */ 1888 } 1889 1890 /* 1891 * Class: sun_awt_X11GraphicsDevice 1892 * Method: getCurrentDisplayMode 1893 * Signature: (I)Ljava/awt/DisplayMode; 1894 */ 1895 JNIEXPORT jobject JNICALL 1896 Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode 1897 (JNIEnv* env, jclass x11gd, jint screen) 1898 { 1899 #ifdef HEADLESS 1900 return NULL; 1901 #else 1902 XRRScreenConfiguration *config; 1903 jobject displayMode = NULL; 1904 1905 AWT_LOCK(); 1906 1907 if (usingXinerama && XScreenCount(awt_display) > 0) { 1908 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display, 1909 RootWindow(awt_display, 0)); 1910 if (res) { 1911 if (res->noutput > screen) { 1912 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display, 1913 res, res->outputs[screen]); 1914 if (output_info) { 1915 if (output_info->crtc) { 1916 XRRCrtcInfo *crtc_info = 1917 awt_XRRGetCrtcInfo (awt_display, res, 1918 output_info->crtc); 1919 if (crtc_info) { 1920 if (crtc_info->mode) { 1921 int i; 1922 for (i = 0; i < res->nmode; i++) { 1923 XRRModeInfo *mode = &res->modes[i]; 1924 if (mode->id == crtc_info->mode) { 1925 float rate = 0; 1926 if (mode->hTotal && mode->vTotal) { 1927 rate = ((float)mode->dotClock / 1928 ((float)mode->hTotal * 1929 (float)mode->vTotal)); 1930 } 1931 displayMode = X11GD_CreateDisplayMode( 1932 env, 1933 mode->width, 1934 mode->height, 1935 BIT_DEPTH_MULTI, 1936 (int)(rate +.2)); 1937 break; 1938 } 1939 } 1940 } 1941 awt_XRRFreeCrtcInfo(crtc_info); 1942 } 1943 } 1944 awt_XRRFreeOutputInfo(output_info); 1945 } 1946 } 1947 awt_XRRFreeScreenResources(res); 1948 } 1949 } else { 1950 1951 config = awt_XRRGetScreenInfo(awt_display, 1952 RootWindow(awt_display, screen)); 1953 if (config != NULL) { 1954 Rotation rotation; 1955 short curRate; 1956 SizeID curSizeIndex; 1957 XRRScreenSize *sizes; 1958 int nsizes; 1959 1960 curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation); 1961 sizes = awt_XRRConfigSizes(config, &nsizes); 1962 curRate = awt_XRRConfigCurrentRate(config); 1963 1964 if ((sizes != NULL) && 1965 (curSizeIndex < nsizes)) 1966 { 1967 XRRScreenSize curSize = sizes[curSizeIndex]; 1968 displayMode = X11GD_CreateDisplayMode(env, 1969 curSize.width, 1970 curSize.height, 1971 BIT_DEPTH_MULTI, 1972 curRate); 1973 } 1974 1975 awt_XRRFreeScreenConfigInfo(config); 1976 } 1977 } 1978 1979 AWT_FLUSH_UNLOCK(); 1980 1981 return displayMode; 1982 #endif /* HEADLESS */ 1983 } 1984 1985 /* 1986 * Class: sun_awt_X11GraphicsDevice 1987 * Method: enumDisplayModes 1988 * Signature: (ILjava/util/ArrayList;)V 1989 */ 1990 JNIEXPORT void JNICALL 1991 Java_sun_awt_X11GraphicsDevice_enumDisplayModes 1992 (JNIEnv* env, jclass x11gd, 1993 jint screen, jobject arrayList) 1994 { 1995 #ifndef HEADLESS 1996 1997 AWT_LOCK(); 1998 1999 if (usingXinerama && XScreenCount(awt_display) > 0) { 2000 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display, 2001 RootWindow(awt_display, 0)); 2002 if (res) { 2003 if (res->noutput > screen) { 2004 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display, 2005 res, res->outputs[screen]); 2006 if (output_info) { 2007 int i; 2008 for (i = 0; i < output_info->nmode; i++) { 2009 RRMode m = output_info->modes[i]; 2010 int j; 2011 XRRModeInfo *mode; 2012 for (j = 0; j < res->nmode; j++) { 2013 mode = &res->modes[j]; 2014 if (mode->id == m) { 2015 float rate = 0; 2016 if (mode->hTotal && mode->vTotal) { 2017 rate = ((float)mode->dotClock / 2018 ((float)mode->hTotal * 2019 (float)mode->vTotal)); 2020 } 2021 X11GD_AddDisplayMode(env, arrayList, 2022 mode->width, mode->height, 2023 BIT_DEPTH_MULTI, (int)(rate +.2)); 2024 break; 2025 } 2026 } 2027 } 2028 awt_XRRFreeOutputInfo(output_info); 2029 } 2030 } 2031 awt_XRRFreeScreenResources(res); 2032 } 2033 } else { 2034 XRRScreenConfiguration *config; 2035 2036 config = awt_XRRGetScreenInfo(awt_display, 2037 RootWindow(awt_display, screen)); 2038 if (config != NULL) { 2039 int nsizes, i, j; 2040 XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); 2041 2042 if (sizes != NULL) { 2043 for (i = 0; i < nsizes; i++) { 2044 int nrates; 2045 XRRScreenSize size = sizes[i]; 2046 short *rates = awt_XRRConfigRates(config, i, &nrates); 2047 2048 for (j = 0; j < nrates; j++) { 2049 X11GD_AddDisplayMode(env, arrayList, 2050 size.width, 2051 size.height, 2052 BIT_DEPTH_MULTI, 2053 rates[j]); 2054 if ((*env)->ExceptionCheck(env)) { 2055 break; 2056 } 2057 } 2058 } 2059 } 2060 2061 awt_XRRFreeScreenConfigInfo(config); 2062 } 2063 } 2064 2065 AWT_FLUSH_UNLOCK(); 2066 #endif /* !HEADLESS */ 2067 } 2068 2069 /* 2070 * Class: sun_awt_X11GraphicsDevice 2071 * Method: configDisplayMode 2072 * Signature: (IIII)V 2073 */ 2074 JNIEXPORT void JNICALL 2075 Java_sun_awt_X11GraphicsDevice_configDisplayMode 2076 (JNIEnv* env, jclass x11gd, 2077 jint screen, jint width, jint height, jint refreshRate) 2078 { 2079 #ifndef HEADLESS 2080 jboolean success = JNI_FALSE; 2081 XRRScreenConfiguration *config; 2082 Drawable root; 2083 Rotation currentRotation = RR_Rotate_0; 2084 2085 AWT_LOCK(); 2086 2087 root = RootWindow(awt_display, screen); 2088 config = awt_XRRGetScreenInfo(awt_display, root); 2089 if (config != NULL) { 2090 jboolean foundConfig = JNI_FALSE; 2091 int chosenSizeIndex = -1; 2092 short chosenRate = -1; 2093 int nsizes; 2094 XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); 2095 awt_XRRConfigRotations(config, ¤tRotation); 2096 2097 if (sizes != NULL) { 2098 int i, j; 2099 2100 /* find the size index that matches the requested dimensions */ 2101 for (i = 0; i < nsizes; i++) { 2102 XRRScreenSize size = sizes[i]; 2103 2104 if ((size.width == width) && (size.height == height)) { 2105 /* we've found our size index... */ 2106 int nrates; 2107 short *rates = awt_XRRConfigRates(config, i, &nrates); 2108 2109 /* now find rate that matches requested refresh rate */ 2110 for (j = 0; j < nrates; j++) { 2111 if (rates[j] == refreshRate) { 2112 /* we've found our rate; break out of the loop */ 2113 chosenSizeIndex = i; 2114 chosenRate = rates[j]; 2115 foundConfig = JNI_TRUE; 2116 break; 2117 } 2118 } 2119 2120 break; 2121 } 2122 } 2123 } 2124 2125 if (foundConfig) { 2126 Status status = 2127 awt_XRRSetScreenConfigAndRate(awt_display, config, root, 2128 chosenSizeIndex, 2129 currentRotation, 2130 chosenRate, 2131 CurrentTime); 2132 2133 /* issue XSync to ensure immediate mode change */ 2134 XSync(awt_display, False); 2135 2136 if (status == RRSetConfigSuccess) { 2137 success = JNI_TRUE; 2138 } 2139 } 2140 2141 awt_XRRFreeScreenConfigInfo(config); 2142 } 2143 2144 AWT_FLUSH_UNLOCK(); 2145 2146 if (!success && !(*env)->ExceptionCheck(env)) { 2147 JNU_ThrowInternalError(env, "Could not set display mode"); 2148 } 2149 #endif /* !HEADLESS */ 2150 } 2151 2152 /* 2153 * Class: sun_awt_X11GraphicsDevice 2154 * Method: enterFullScreenExclusive 2155 * Signature: (J)V 2156 */ 2157 JNIEXPORT void JNICALL 2158 Java_sun_awt_X11GraphicsDevice_enterFullScreenExclusive 2159 (JNIEnv* env, jclass x11gd, 2160 jlong window) 2161 { 2162 #ifndef HEADLESS 2163 Window win = (Window)window; 2164 2165 AWT_LOCK(); 2166 XSync(awt_display, False); /* ensures window is visible first */ 2167 X11GD_SetFullscreenMode(win, JNI_TRUE); 2168 AWT_UNLOCK(); 2169 #endif /* !HEADLESS */ 2170 } 2171 2172 /* 2173 * Class: sun_awt_X11GraphicsDevice 2174 * Method: exitFullScreenExclusive 2175 * Signature: (J)V 2176 */ 2177 JNIEXPORT void JNICALL 2178 Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive 2179 (JNIEnv* env, jclass x11gd, 2180 jlong window) 2181 { 2182 #ifndef HEADLESS 2183 Window win = (Window)window; 2184 2185 AWT_LOCK(); 2186 X11GD_SetFullscreenMode(win, JNI_FALSE); 2187 AWT_UNLOCK(); 2188 #endif /* !HEADLESS */ 2189 } 2190 2191 /** 2192 * End DisplayMode/FullScreen support 2193 */ 2194 2195 static char *get_output_screen_name(JNIEnv *env, int screen) { 2196 if (!awt_XRRGetScreenResources || !awt_XRRGetOutputInfo) { 2197 return NULL; 2198 } 2199 char *name = NULL; 2200 AWT_LOCK(); 2201 int scr = 0, out = 0; 2202 if (usingXinerama && XScreenCount(awt_display) > 0) { 2203 out = screen; 2204 } else { 2205 scr = screen; 2206 } 2207 2208 XRRScreenResources *res = awt_XRRGetScreenResources(awt_display, 2209 RootWindow(awt_display, scr)); 2210 if (res) { 2211 if (res->noutput > out) { 2212 XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display, 2213 res, res->outputs[out]); 2214 if (output_info) { 2215 if (output_info->name) { 2216 name = strdup(output_info->name); 2217 } 2218 awt_XRRFreeOutputInfo(output_info); 2219 } 2220 } 2221 awt_XRRFreeScreenResources(res); 2222 } 2223 AWT_UNLOCK(); 2224 return name; 2225 } 2226 2227 /* 2228 * Class: sun_awt_X11GraphicsDevice 2229 * Method: getNativeScaleFactor 2230 * Signature: (I)D 2231 */ 2232 JNIEXPORT jdouble JNICALL 2233 Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor 2234 (JNIEnv *env, jobject this, jint screen) { 2235 // in case of Xinerama individual screen scales are not supported 2236 char *name = get_output_screen_name(env, usingXinerama ? 0 : screen); 2237 double scale = getNativeScaleFactor(name); 2238 if (name) { 2239 free(name); 2240 } 2241 return scale; 2242 } --- EOF ---