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