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