Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c
66646 views
1
/*
2
* Copyright (c) 1997, 2022, 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
if (nTrue != 0)
583
XFree (pVITrue);
584
AWT_UNLOCK ();
585
}
586
587
/*
588
* Checks if Xinerama is running and perform Xinerama-related initialization.
589
*/
590
static void xineramaInit(void) {
591
char* XinExtName = "XINERAMA";
592
int32_t major_opcode, first_event, first_error;
593
Bool gotXinExt = False;
594
void* libHandle = NULL;
595
char* XineramaQueryScreensName = "XineramaQueryScreens";
596
597
gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
598
&first_event, &first_error);
599
600
if (!gotXinExt) {
601
DTRACE_PRINTLN("Xinerama extension is not available");
602
return;
603
}
604
605
DTRACE_PRINTLN("Xinerama extension is available");
606
607
/* load library */
608
libHandle = dlopen(VERSIONED_JNI_LIB_NAME("Xinerama", "1"),
609
RTLD_LAZY | RTLD_GLOBAL);
610
if (libHandle == NULL) {
611
#if defined(_AIX)
612
libHandle = dlopen("libXext.a(shr_64.o)", RTLD_MEMBER | RTLD_LAZY | RTLD_GLOBAL);
613
#else
614
libHandle = dlopen(JNI_LIB_NAME("Xinerama"), RTLD_LAZY | RTLD_GLOBAL);
615
#endif
616
}
617
if (libHandle != NULL) {
618
XineramaQueryScreens = (XineramaQueryScreensFunc*)
619
dlsym(libHandle, XineramaQueryScreensName);
620
621
if (XineramaQueryScreens == NULL) {
622
DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");
623
dlclose(libHandle);
624
}
625
} else {
626
DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
627
}
628
}
629
630
static void resetNativeData(int screen) {
631
/*
632
* Reset references to the various configs; the actual native config data
633
* will be free'd later by the Disposer mechanism when the Java-level
634
* X11GraphicsConfig objects go away. By setting these values to NULL,
635
* we ensure that they will be reinitialized as necessary (for example,
636
* see the getNumConfigs() method).
637
*/
638
if (x11Screens[screen].configs) {
639
free(x11Screens[screen].configs);
640
x11Screens[screen].configs = NULL;
641
}
642
x11Screens[screen].defaultConfig = NULL;
643
x11Screens[screen].numConfigs = 0;
644
}
645
646
/*
647
* Class: sun_awt_X11GraphicsEnvironment
648
* Method: initDevices
649
* Signature: (Z)V
650
*/
651
JNIEXPORT void JNICALL
652
Java_sun_awt_X11GraphicsEnvironment_initNativeData(JNIEnv *env, jobject this) {
653
usingXinerama = False;
654
if (x11Screens) {
655
for (int i = 0; i < awt_numScreens; ++i) {
656
resetNativeData(i);
657
}
658
free((void *)x11Screens);
659
x11Screens = NULL;
660
awt_numScreens = 0;
661
}
662
663
// will try xinerama first
664
if (XineramaQueryScreens) {
665
int32_t locNumScr = 0;
666
XineramaScreenInfo *xinInfo;
667
DTRACE_PRINTLN("calling XineramaQueryScreens func");
668
xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
669
if (xinInfo != NULL) {
670
if (locNumScr > XScreenCount(awt_display)) {
671
DTRACE_PRINTLN("Enabling Xinerama support");
672
usingXinerama = True;
673
/* set global number of screens */
674
DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
675
awt_numScreens = locNumScr;
676
} else {
677
DTRACE_PRINTLN("XineramaQueryScreens <= XScreenCount");
678
}
679
XFree(xinInfo);
680
} else {
681
DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
682
}
683
}
684
// if xinerama is not enabled or does not work will use X11
685
if (!usingXinerama) {
686
awt_numScreens = XScreenCount(awt_display);
687
}
688
DTRACE_PRINTLN1("allocating %i screens\n", awt_numScreens);
689
/* Allocate screen data structure array */
690
x11Screens = calloc(awt_numScreens, sizeof(AwtScreenData));
691
if (x11Screens == NULL) {
692
JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),
693
NULL);
694
return;
695
}
696
697
for (int i = 0; i < awt_numScreens; i++) {
698
if (usingXinerama) {
699
/* All Xinerama screens use the same X11 root for now */
700
x11Screens[i].root = RootWindow(awt_display, 0);
701
}
702
else {
703
x11Screens[i].root = RootWindow(awt_display, i);
704
}
705
x11Screens[i].defaultConfig = makeDefaultConfig(env, i);
706
JNU_CHECK_EXCEPTION(env);
707
}
708
}
709
710
Display *
711
awt_init_Display(JNIEnv *env, jobject this)
712
{
713
jclass klass;
714
Display *dpy;
715
char errmsg[128];
716
int i;
717
718
if (awt_display) {
719
return awt_display;
720
}
721
722
/* Load AWT lock-related methods in SunToolkit */
723
klass = (*env)->FindClass(env, "sun/awt/SunToolkit");
724
if (klass == NULL) return NULL;
725
GET_STATIC_METHOD(klass, awtLockMID, "awtLock", "()V");
726
GET_STATIC_METHOD(klass, awtUnlockMID, "awtUnlock", "()V");
727
GET_STATIC_METHOD(klass, awtWaitMID, "awtLockWait", "(J)V");
728
GET_STATIC_METHOD(klass, awtNotifyMID, "awtLockNotify", "()V");
729
GET_STATIC_METHOD(klass, awtNotifyAllMID, "awtLockNotifyAll", "()V");
730
tkClass = (*env)->NewGlobalRef(env, klass);
731
awtLockInited = JNI_TRUE;
732
733
if (getenv("_AWT_IGNORE_XKB") != NULL &&
734
strlen(getenv("_AWT_IGNORE_XKB")) > 0) {
735
if (XkbIgnoreExtension(True)) {
736
printf("Ignoring XKB.\n");
737
}
738
}
739
740
dpy = awt_display = XOpenDisplay(NULL);
741
if (!dpy) {
742
jio_snprintf(errmsg,
743
sizeof(errmsg),
744
"Can't connect to X11 window server using '%s' as the value of the DISPLAY variable.",
745
(getenv("DISPLAY") == NULL) ? ":0.0" : getenv("DISPLAY"));
746
JNU_ThrowByName(env, "java/awt/AWTError", errmsg);
747
return NULL;
748
}
749
750
XSetIOErrorHandler(xioerror_handler);
751
JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil", "init", "(J)V",
752
ptr_to_jlong(awt_display));
753
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
754
755
/* set awt_numScreens, and whether or not we're using Xinerama */
756
xineramaInit();
757
return dpy;
758
}
759
760
/*
761
* Class: sun_awt_X11GraphicsEnvironment
762
* Method: getDefaultScreenNum
763
* Signature: ()I
764
*/
765
JNIEXPORT jint JNICALL
766
Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum(
767
JNIEnv *env, jobject this)
768
{
769
return DefaultScreen(awt_display);
770
}
771
772
static void ensureConfigsInited(JNIEnv* env, int screen) {
773
if (x11Screens[screen].numConfigs == 0) {
774
if (env == NULL) {
775
env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
776
}
777
getAllConfigs (env, screen, &(x11Screens[screen]));
778
}
779
}
780
781
AwtGraphicsConfigDataPtr
782
getDefaultConfig(int screen) {
783
ensureConfigsInited(NULL, screen);
784
return x11Screens[screen].defaultConfig;
785
}
786
787
/*
788
* Class: sun_awt_X11GraphicsEnvironment
789
* Method: initDisplay
790
* Signature: (Z)V
791
*/
792
JNIEXPORT void JNICALL
793
Java_sun_awt_X11GraphicsEnvironment_initDisplay(JNIEnv *env, jobject this,
794
jboolean glxReq)
795
{
796
glxRequested = glxReq;
797
(void) awt_init_Display(env, this);
798
}
799
800
/*
801
* Class: sun_awt_X11GraphicsEnvironment
802
* Method: initGLX
803
* Signature: ()Z
804
*/
805
JNIEXPORT jboolean JNICALL
806
Java_sun_awt_X11GraphicsEnvironment_initGLX(JNIEnv *env, jclass x11ge)
807
{
808
jboolean glxAvailable;
809
810
AWT_LOCK();
811
glxAvailable = GLXGC_IsGLXAvailable();
812
AWT_UNLOCK();
813
814
return glxAvailable;
815
}
816
817
/*
818
* Class: sun_awt_X11GraphicsEnvironment
819
* Method: getNumScreens
820
* Signature: ()I
821
*/
822
JNIEXPORT jint JNICALL
823
Java_sun_awt_X11GraphicsEnvironment_getNumScreens(JNIEnv *env, jobject this)
824
{
825
return awt_numScreens;
826
}
827
828
/*
829
* Class: sun_awt_X11GraphicsDevice
830
* Method: getDisplay
831
* Signature: ()J
832
*/
833
JNIEXPORT jlong JNICALL
834
Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)
835
{
836
return ptr_to_jlong(awt_display);
837
}
838
839
#ifdef MITSHM
840
841
static jint canUseShmExt = UNSET_MITSHM;
842
static jint canUseShmExtPixmaps = UNSET_MITSHM;
843
static jboolean xshmAttachFailed = JNI_FALSE;
844
845
int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr) {
846
if (xerr->minor_code == X_ShmAttach) {
847
xshmAttachFailed = JNI_TRUE;
848
}
849
return 0;
850
}
851
jboolean isXShmAttachFailed() {
852
return xshmAttachFailed;
853
}
854
void resetXShmAttachFailed() {
855
xshmAttachFailed = JNI_FALSE;
856
}
857
858
extern int mitShmPermissionMask;
859
860
void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) {
861
XShmSegmentInfo shminfo;
862
int XShmMajor, XShmMinor;
863
int a, b, c;
864
865
AWT_LOCK();
866
if (canUseShmExt != UNSET_MITSHM) {
867
*shmExt = canUseShmExt;
868
*shmPixmaps = canUseShmExtPixmaps;
869
AWT_UNLOCK();
870
return;
871
}
872
873
*shmExt = canUseShmExt = CANT_USE_MITSHM;
874
*shmPixmaps = canUseShmExtPixmaps = CANT_USE_MITSHM;
875
876
if (awt_display == (Display *)NULL) {
877
AWT_NOFLUSH_UNLOCK();
878
return;
879
}
880
881
/**
882
* XShmQueryExtension returns False in remote server case.
883
* Unfortunately it also returns True in ssh case, so
884
* we need to test that we can actually do XShmAttach.
885
*/
886
if (XShmQueryExtension(awt_display)) {
887
shminfo.shmid = shmget(IPC_PRIVATE, 0x10000,
888
IPC_CREAT|mitShmPermissionMask);
889
if (shminfo.shmid < 0) {
890
AWT_UNLOCK();
891
J2dRlsTraceLn1(J2D_TRACE_ERROR,
892
"TryInitMITShm: shmget has failed: %s",
893
strerror(errno));
894
return;
895
}
896
shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0);
897
if (shminfo.shmaddr == ((char *) -1)) {
898
shmctl(shminfo.shmid, IPC_RMID, 0);
899
AWT_UNLOCK();
900
J2dRlsTraceLn1(J2D_TRACE_ERROR,
901
"TryInitMITShm: shmat has failed: %s",
902
strerror(errno));
903
return;
904
}
905
shminfo.readOnly = True;
906
907
resetXShmAttachFailed();
908
/**
909
* The J2DXErrHandler handler will set xshmAttachFailed
910
* to JNI_TRUE if any Shm error has occured.
911
*/
912
EXEC_WITH_XERROR_HANDLER(XShmAttachXErrHandler,
913
XShmAttach(awt_display, &shminfo));
914
915
/**
916
* Get rid of the id now to reduce chances of leaking
917
* system resources.
918
*/
919
shmctl(shminfo.shmid, IPC_RMID, 0);
920
921
if (isXShmAttachFailed() == JNI_FALSE) {
922
canUseShmExt = CAN_USE_MITSHM;
923
/* check if we can use shared pixmaps */
924
XShmQueryVersion(awt_display, &XShmMajor, &XShmMinor,
925
(Bool*)&canUseShmExtPixmaps);
926
canUseShmExtPixmaps = canUseShmExtPixmaps &&
927
(XShmPixmapFormat(awt_display) == ZPixmap);
928
XShmDetach(awt_display, &shminfo);
929
}
930
shmdt(shminfo.shmaddr);
931
*shmExt = canUseShmExt;
932
*shmPixmaps = canUseShmExtPixmaps;
933
}
934
AWT_UNLOCK();
935
}
936
#endif /* MITSHM */
937
938
/*
939
* Class: sun_awt_X11GraphicsEnvironment
940
* Method: checkShmExt
941
* Signature: ()I
942
*/
943
JNIEXPORT jint JNICALL
944
Java_sun_awt_X11GraphicsEnvironment_checkShmExt(JNIEnv *env, jobject this)
945
{
946
947
int shmExt = NOEXT_MITSHM, shmPixmaps;
948
#ifdef MITSHM
949
TryInitMITShm(env, &shmExt, &shmPixmaps);
950
#endif
951
return shmExt;
952
}
953
954
/*
955
* Class: sun_awt_X11GraphicsEnvironment
956
* Method: getDisplayString
957
* Signature: ()Ljava/lang/String
958
*/
959
JNIEXPORT jstring JNICALL
960
Java_sun_awt_X11GraphicsEnvironment_getDisplayString
961
(JNIEnv *env, jobject this)
962
{
963
return (*env)->NewStringUTF(env, DisplayString(awt_display));
964
}
965
966
967
/*
968
* Class: sun_awt_X11GraphicsDevice
969
* Method: getNumConfigs
970
* Signature: ()I
971
*/
972
JNIEXPORT jint JNICALL
973
Java_sun_awt_X11GraphicsDevice_getNumConfigs(
974
JNIEnv *env, jobject this, jint screen)
975
{
976
AWT_LOCK();
977
ensureConfigsInited(env, screen);
978
int configs = x11Screens[screen].numConfigs;
979
AWT_UNLOCK();
980
return configs;
981
}
982
983
/*
984
* Class: sun_awt_X11GraphicsDevice
985
* Method: getConfigVisualId
986
* Signature: (I)I
987
*/
988
JNIEXPORT jint JNICALL
989
Java_sun_awt_X11GraphicsDevice_getConfigVisualId(
990
JNIEnv *env, jobject this, jint index, jint screen)
991
{
992
int visNum;
993
AWT_LOCK();
994
ensureConfigsInited(env, screen);
995
jint id = (jint) (index == 0 ? x11Screens[screen].defaultConfig
996
: x11Screens[screen].configs[index])->awt_visInfo.visualid;
997
AWT_UNLOCK();
998
return id;
999
}
1000
1001
/*
1002
* Class: sun_awt_X11GraphicsDevice
1003
* Method: getConfigDepth
1004
* Signature: (I)I
1005
*/
1006
JNIEXPORT jint JNICALL
1007
Java_sun_awt_X11GraphicsDevice_getConfigDepth(
1008
JNIEnv *env, jobject this, jint index, jint screen)
1009
{
1010
int visNum;
1011
AWT_LOCK();
1012
ensureConfigsInited(env, screen);
1013
jint depth = (jint) (index == 0 ? x11Screens[screen].defaultConfig
1014
: x11Screens[screen].configs[index])->awt_visInfo.depth;
1015
AWT_UNLOCK();
1016
return depth;
1017
}
1018
1019
/*
1020
* Class: sun_awt_X11GraphicsDevice
1021
* Method: getConfigColormap
1022
* Signature: (I)I
1023
*/
1024
JNIEXPORT jint JNICALL
1025
Java_sun_awt_X11GraphicsDevice_getConfigColormap(
1026
JNIEnv *env, jobject this, jint index, jint screen)
1027
{
1028
int visNum;
1029
AWT_LOCK();
1030
ensureConfigsInited(env, screen);
1031
jint colormap = (jint) (index == 0 ? x11Screens[screen].defaultConfig
1032
: x11Screens[screen].configs[index])->awt_cmap;
1033
AWT_UNLOCK();
1034
return colormap;
1035
}
1036
1037
1038
/*
1039
* Class: sun_awt_X11GraphicsConfig
1040
* Method: dispose
1041
* Signature: (J)V
1042
*/
1043
JNIEXPORT void JNICALL
1044
Java_sun_awt_X11GraphicsConfig_dispose
1045
(JNIEnv *env, jclass x11gc, jlong configData)
1046
{
1047
AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)
1048
jlong_to_ptr(configData);
1049
1050
if (aData == NULL) {
1051
return;
1052
}
1053
1054
AWT_LOCK();
1055
if (aData->awt_cmap) {
1056
XFreeColormap(awt_display, aData->awt_cmap);
1057
}
1058
if (aData->awtImage) {
1059
free(aData->awtImage);
1060
}
1061
if (aData->monoImage) {
1062
XFree(aData->monoImage);
1063
}
1064
if (aData->monoPixmap) {
1065
XFreePixmap(awt_display, aData->monoPixmap);
1066
}
1067
if (aData->monoPixmapGC) {
1068
XFreeGC(awt_display, aData->monoPixmapGC);
1069
}
1070
if (aData->color_data) {
1071
free(aData->color_data);
1072
}
1073
AWT_UNLOCK();
1074
1075
if (aData->glxInfo) {
1076
/*
1077
* The native GLXGraphicsConfig data needs to be disposed separately
1078
* on the OGL queue flushing thread (should not be called while
1079
* the AWT lock is held).
1080
*/
1081
JNU_CallStaticMethodByName(env, NULL,
1082
"sun/java2d/opengl/OGLRenderQueue",
1083
"disposeGraphicsConfig", "(J)V",
1084
ptr_to_jlong(aData->glxInfo));
1085
}
1086
1087
free(aData);
1088
}
1089
1090
/*
1091
* Class: sun_awt_X11GraphicsConfig
1092
* Method: getXResolution
1093
* Signature: ()I
1094
*/
1095
JNIEXPORT jdouble JNICALL
1096
Java_sun_awt_X11GraphicsConfig_getXResolution(
1097
JNIEnv *env, jobject this, jint screen)
1098
{
1099
return ((DisplayWidth(awt_display, screen) * 25.4) /
1100
DisplayWidthMM(awt_display, screen));
1101
}
1102
1103
/*
1104
* Class: sun_awt_X11GraphicsConfig
1105
* Method: getYResolution
1106
* Signature: ()I
1107
*/
1108
JNIEXPORT jdouble JNICALL
1109
Java_sun_awt_X11GraphicsConfig_getYResolution(
1110
JNIEnv *env, jobject this, jint screen)
1111
{
1112
return ((DisplayHeight(awt_display, screen) * 25.4) /
1113
DisplayHeightMM(awt_display, screen));
1114
}
1115
1116
1117
/*
1118
* Class: sun_awt_X11GraphicsConfig
1119
* Method: getNumColors
1120
* Signature: ()I
1121
*/
1122
JNIEXPORT jint JNICALL
1123
Java_sun_awt_X11GraphicsConfig_getNumColors(
1124
JNIEnv *env, jobject this)
1125
{
1126
AwtGraphicsConfigData *adata;
1127
1128
adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1129
x11GraphicsConfigIDs.aData);
1130
1131
return adata->awt_num_colors;
1132
}
1133
1134
/*
1135
* Class: sun_awt_X11GraphicsConfig
1136
* Method: init
1137
* Signature: (I)V
1138
*/
1139
JNIEXPORT void JNICALL
1140
Java_sun_awt_X11GraphicsConfig_init(
1141
JNIEnv *env, jobject this, jint visualNum, jint screen)
1142
{
1143
AwtGraphicsConfigData *adata = NULL;
1144
AWT_LOCK();
1145
AwtScreenData asd = x11Screens[screen];
1146
int i, n;
1147
int depth;
1148
XImage * tempImage;
1149
1150
/* If haven't gotten all of the configs yet, do it now. */
1151
if (asd.numConfigs == 0) {
1152
getAllConfigs (env, screen, &asd);
1153
}
1154
1155
/* Check the graphicsConfig for this visual */
1156
for (i = 0; i < asd.numConfigs; i++) {
1157
AwtGraphicsConfigDataPtr agcPtr = asd.configs[i];
1158
if ((jint)agcPtr->awt_visInfo.visualid == visualNum) {
1159
adata = agcPtr;
1160
break;
1161
}
1162
}
1163
1164
/* If didn't find the visual, throw an exception... */
1165
if (adata == (AwtGraphicsConfigData *) NULL) {
1166
AWT_UNLOCK();
1167
JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified");
1168
return;
1169
}
1170
1171
/* adata->awt_cmap initialization has been deferred to
1172
* makeColorModel call
1173
*/
1174
1175
JNU_SetLongFieldFromPtr(env, this, x11GraphicsConfigIDs.aData, adata);
1176
1177
depth = adata->awt_visInfo.depth;
1178
tempImage = XCreateImage(awt_display,
1179
adata->awt_visInfo.visual,
1180
depth, ZPixmap, 0, NULL, 1, 1, 32, 0);
1181
adata->pixelStride = (tempImage->bits_per_pixel + 7) / 8;
1182
(*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel,
1183
(jint)tempImage->bits_per_pixel);
1184
XDestroyImage(tempImage);
1185
AWT_UNLOCK();
1186
}
1187
1188
/*
1189
* Class: sun_awt_X11GraphicsConfig
1190
* Method: makeColorModel
1191
* Signature: ()Ljava/awt/image/ColorModel
1192
*/
1193
JNIEXPORT jobject JNICALL
1194
Java_sun_awt_X11GraphicsConfig_makeColorModel(
1195
JNIEnv *env, jobject this)
1196
{
1197
AwtGraphicsConfigData *adata;
1198
jobject colorModel;
1199
1200
/*
1201
* If awt is not locked yet, return null since the toolkit is not
1202
* initialized yet.
1203
*/
1204
if (!awtLockInited) {
1205
return NULL;
1206
}
1207
1208
AWT_LOCK ();
1209
1210
adata = (AwtGraphicsConfigData *) JNU_GetLongFieldAsPtr(env, this,
1211
x11GraphicsConfigIDs.aData);
1212
1213
/* If colormap entry of adata is NULL, need to create it now */
1214
if (adata->awt_cmap == (Colormap) NULL) {
1215
awtJNI_CreateColorData (env, adata, 1);
1216
}
1217
1218
/* Make Color Model object for this GraphicsConfiguration */
1219
colorModel = (*env)->ExceptionCheck(env)
1220
? NULL : awtJNI_GetColorModel (env, adata);
1221
1222
AWT_UNLOCK ();
1223
1224
return colorModel;
1225
}
1226
1227
1228
/*
1229
* Class: sun_awt_X11GraphicsDevice
1230
* Method: getBounds
1231
* Signature: ()Ljava/awt/Rectangle
1232
*/
1233
JNIEXPORT jobject JNICALL
1234
Java_sun_awt_X11GraphicsDevice_pGetBounds(JNIEnv *env, jobject this, jint screen)
1235
{
1236
jclass clazz;
1237
jmethodID mid;
1238
jobject bounds = NULL;
1239
int32_t locNumScr = 0;
1240
XineramaScreenInfo *xinInfo;
1241
1242
clazz = (*env)->FindClass(env, "java/awt/Rectangle");
1243
CHECK_NULL_RETURN(clazz, NULL);
1244
mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V");
1245
if (mid != NULL) {
1246
if (usingXinerama) {
1247
if (0 <= screen && screen < awt_numScreens) {
1248
AWT_LOCK();
1249
xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
1250
AWT_UNLOCK();
1251
if (xinInfo != NULL && locNumScr > 0) {
1252
if (screen >= locNumScr) {
1253
screen = 0; // fallback to the main screen
1254
}
1255
DASSERT(xinInfo[screen].screen_number == screen);
1256
bounds = (*env)->NewObject(env, clazz, mid,
1257
xinInfo[screen].x_org,
1258
xinInfo[screen].y_org,
1259
xinInfo[screen].width,
1260
xinInfo[screen].height);
1261
XFree(xinInfo);
1262
}
1263
} else {
1264
jclass exceptionClass = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
1265
if (exceptionClass != NULL) {
1266
(*env)->ThrowNew(env, exceptionClass, "Illegal screen index");
1267
}
1268
}
1269
}
1270
if (!bounds) {
1271
// Xinerama cannot provide correct bounds, will try X11
1272
XWindowAttributes xwa;
1273
memset(&xwa, 0, sizeof(xwa));
1274
1275
AWT_LOCK ();
1276
XGetWindowAttributes(awt_display, RootWindow(awt_display, screen),
1277
&xwa);
1278
AWT_UNLOCK ();
1279
1280
bounds = (*env)->NewObject(env, clazz, mid, 0, 0,
1281
xwa.width, xwa.height);
1282
}
1283
1284
if ((*env)->ExceptionOccurred(env)) {
1285
return NULL;
1286
}
1287
}
1288
return bounds;
1289
}
1290
1291
/*
1292
* Class: sun_awt_X11GraphicsConfig
1293
* Method: createBackBuffer
1294
* Signature: (JI)J
1295
*/
1296
JNIEXPORT jlong JNICALL
1297
Java_sun_awt_X11GraphicsConfig_createBackBuffer
1298
(JNIEnv *env, jobject this, jlong window, jint swapAction)
1299
{
1300
int32_t v1, v2;
1301
XdbeBackBuffer ret = (unsigned long) 0;
1302
Window w = (Window)window;
1303
AWT_LOCK();
1304
if (!XdbeQueryExtension(awt_display, &v1, &v2)) {
1305
JNU_ThrowByName(env, "java/lang/Exception",
1306
"Could not query double-buffer extension");
1307
AWT_UNLOCK();
1308
return (jlong)0;
1309
}
1310
ret = XdbeAllocateBackBufferName(awt_display, w,
1311
(XdbeSwapAction)swapAction);
1312
AWT_FLUSH_UNLOCK();
1313
return (jlong)ret;
1314
}
1315
1316
/*
1317
* Class: sun_awt_X11GraphicsConfig
1318
* Method: destroyBackBuffer
1319
* Signature: (J)V
1320
*/
1321
JNIEXPORT void JNICALL
1322
Java_sun_awt_X11GraphicsConfig_destroyBackBuffer
1323
(JNIEnv *env, jobject this, jlong backBuffer)
1324
{
1325
AWT_LOCK();
1326
XdbeDeallocateBackBufferName(awt_display, (XdbeBackBuffer)backBuffer);
1327
AWT_FLUSH_UNLOCK();
1328
}
1329
1330
/*
1331
* Class: sun_awt_X11GraphicsConfig
1332
* Method: swapBuffers
1333
* Signature: (JI)V
1334
*/
1335
JNIEXPORT void JNICALL
1336
Java_sun_awt_X11GraphicsConfig_swapBuffers
1337
(JNIEnv *env, jobject this,
1338
jlong window, jint swapAction)
1339
{
1340
XdbeSwapInfo swapInfo;
1341
1342
AWT_LOCK();
1343
1344
XdbeBeginIdiom(awt_display);
1345
swapInfo.swap_window = (Window)window;
1346
swapInfo.swap_action = (XdbeSwapAction)swapAction;
1347
if (!XdbeSwapBuffers(awt_display, &swapInfo, 1)) {
1348
JNU_ThrowInternalError(env, "Could not swap buffers");
1349
}
1350
XdbeEndIdiom(awt_display);
1351
1352
AWT_FLUSH_UNLOCK();
1353
}
1354
1355
/*
1356
* Class: sun_awt_X11GraphicsConfig
1357
* Method: isTranslucencyCapable
1358
* Signature: (J)V
1359
*/
1360
JNIEXPORT jboolean JNICALL
1361
Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable
1362
(JNIEnv *env, jobject this, jlong configData)
1363
{
1364
AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);
1365
if (aData == NULL) {
1366
return JNI_FALSE;
1367
}
1368
return aData->isTranslucencySupported ? JNI_TRUE : JNI_FALSE;
1369
}
1370
1371
/*
1372
* Class: sun_awt_X11GraphicsDevice
1373
* Method: isDBESupported
1374
* Signature: ()Z
1375
*/
1376
JNIEXPORT jboolean JNICALL
1377
Java_sun_awt_X11GraphicsDevice_isDBESupported(JNIEnv *env, jobject this)
1378
{
1379
int opcode = 0, firstEvent = 0, firstError = 0;
1380
jboolean ret;
1381
1382
AWT_LOCK();
1383
ret = (jboolean)XQueryExtension(awt_display, "DOUBLE-BUFFER",
1384
&opcode, &firstEvent, &firstError);
1385
AWT_FLUSH_UNLOCK();
1386
return ret;
1387
}
1388
1389
/*
1390
* Class: sun_awt_X11GraphicsDevice
1391
* Method: getDoubleBufferVisuals
1392
* Signature: (I)V
1393
*/
1394
JNIEXPORT void JNICALL
1395
Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env,
1396
jobject this, jint screen)
1397
{
1398
jclass clazz;
1399
jmethodID midAddVisual;
1400
Window rootWindow;
1401
int i, n = 1;
1402
XdbeScreenVisualInfo* visScreenInfo;
1403
int xinawareScreen;
1404
1405
if (usingXinerama) {
1406
xinawareScreen = 0;
1407
}
1408
else {
1409
xinawareScreen = screen;
1410
}
1411
1412
clazz = (*env)->GetObjectClass(env, this);
1413
midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual",
1414
"(I)V");
1415
CHECK_NULL(midAddVisual);
1416
AWT_LOCK();
1417
rootWindow = RootWindow(awt_display, xinawareScreen);
1418
visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n);
1419
if (visScreenInfo == NULL) {
1420
JNU_ThrowInternalError(env, "Could not get visual info");
1421
AWT_UNLOCK();
1422
return;
1423
}
1424
AWT_FLUSH_UNLOCK();
1425
for (i = 0; i < visScreenInfo->count; i++) {
1426
XdbeVisualInfo* visInfo = visScreenInfo->visinfo;
1427
(*env)->CallVoidMethod(env, this, midAddVisual, (visInfo[i]).visual);
1428
if ((*env)->ExceptionCheck(env)) {
1429
break;
1430
}
1431
}
1432
AWT_LOCK();
1433
XdbeFreeVisualInfo(visScreenInfo);
1434
AWT_UNLOCK();
1435
}
1436
1437
/*
1438
* Class: sun_awt_X11GraphicsEnvironment
1439
* Method: pRunningXinerama
1440
* Signature: ()Z
1441
*/
1442
JNIEXPORT jboolean JNICALL
1443
Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama(JNIEnv *env,
1444
jobject this)
1445
{
1446
return usingXinerama ? JNI_TRUE : JNI_FALSE;
1447
}
1448
1449
/**
1450
* Begin DisplayMode/FullScreen support
1451
*/
1452
1453
#ifndef NO_XRANDR
1454
1455
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
1456
#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
1457
1458
typedef Status
1459
(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
1460
typedef XRRScreenConfiguration*
1461
(*XRRGetScreenInfoType)(Display *dpy, Drawable root);
1462
typedef void
1463
(*XRRFreeScreenConfigInfoType)(XRRScreenConfiguration *config);
1464
typedef short*
1465
(*XRRConfigRatesType)(XRRScreenConfiguration *config,
1466
int sizeID, int *nrates);
1467
typedef short
1468
(*XRRConfigCurrentRateType)(XRRScreenConfiguration *config);
1469
typedef XRRScreenSize*
1470
(*XRRConfigSizesType)(XRRScreenConfiguration *config,
1471
int *nsizes);
1472
typedef SizeID
1473
(*XRRConfigCurrentConfigurationType)(XRRScreenConfiguration *config,
1474
Rotation *rotation);
1475
typedef Status
1476
(*XRRSetScreenConfigAndRateType)(Display *dpy,
1477
XRRScreenConfiguration *config,
1478
Drawable draw,
1479
int size_index,
1480
Rotation rotation,
1481
short rate,
1482
Time timestamp);
1483
typedef Rotation
1484
(*XRRConfigRotationsType)(XRRScreenConfiguration *config,
1485
Rotation *current_rotation);
1486
1487
typedef XRRScreenResources* (*XRRGetScreenResourcesType)(Display *dpy,
1488
Window window);
1489
1490
typedef void (*XRRFreeScreenResourcesType)(XRRScreenResources *resources);
1491
1492
typedef XRROutputInfo * (*XRRGetOutputInfoType)(Display *dpy,
1493
XRRScreenResources *resources, RROutput output);
1494
1495
typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo);
1496
1497
typedef XRRCrtcInfo* (*XRRGetCrtcInfoType)(Display *dpy,
1498
XRRScreenResources *resources, RRCrtc crtc);
1499
1500
typedef void (*XRRFreeCrtcInfoType)(XRRCrtcInfo *crtcInfo);
1501
1502
static XRRQueryVersionType awt_XRRQueryVersion;
1503
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
1504
static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
1505
static XRRConfigRatesType awt_XRRConfigRates;
1506
static XRRConfigCurrentRateType awt_XRRConfigCurrentRate;
1507
static XRRConfigSizesType awt_XRRConfigSizes;
1508
static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;
1509
static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;
1510
static XRRConfigRotationsType awt_XRRConfigRotations;
1511
static XRRGetScreenResourcesType awt_XRRGetScreenResources;
1512
static XRRFreeScreenResourcesType awt_XRRFreeScreenResources;
1513
static XRRGetOutputInfoType awt_XRRGetOutputInfo;
1514
static XRRFreeOutputInfoType awt_XRRFreeOutputInfo;
1515
static XRRGetCrtcInfoType awt_XRRGetCrtcInfo;
1516
static XRRFreeCrtcInfoType awt_XRRFreeCrtcInfo;
1517
1518
#define LOAD_XRANDR_FUNC(f) \
1519
do { \
1520
awt_##f = (f##Type)dlsym(pLibRandR, #f); \
1521
if (awt_##f == NULL) { \
1522
J2dRlsTraceLn1(J2D_TRACE_ERROR, \
1523
"X11GD_InitXrandrFuncs: Could not load %s", #f); \
1524
dlclose(pLibRandR); \
1525
return JNI_FALSE; \
1526
} \
1527
} while (0)
1528
1529
static jboolean
1530
X11GD_InitXrandrFuncs(JNIEnv *env)
1531
{
1532
int rr_maj_ver = 0, rr_min_ver = 0;
1533
1534
void *pLibRandR = dlopen(VERSIONED_JNI_LIB_NAME("Xrandr", "2"),
1535
RTLD_LAZY | RTLD_LOCAL);
1536
if (pLibRandR == NULL) {
1537
pLibRandR = dlopen(JNI_LIB_NAME("Xrandr"), RTLD_LAZY | RTLD_LOCAL);
1538
}
1539
if (pLibRandR == NULL) {
1540
J2dRlsTraceLn(J2D_TRACE_ERROR,
1541
"X11GD_InitXrandrFuncs: Could not open libXrandr.so.2");
1542
return JNI_FALSE;
1543
}
1544
1545
LOAD_XRANDR_FUNC(XRRQueryVersion);
1546
1547
if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) {
1548
J2dRlsTraceLn(J2D_TRACE_ERROR,
1549
"X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status");
1550
dlclose(pLibRandR);
1551
return JNI_FALSE;
1552
}
1553
1554
if (usingXinerama) {
1555
/*
1556
* We can proceed as long as this is RANDR 1.2 or above.
1557
* As of Xorg server 1.3 onwards the Xinerama backend may actually be
1558
* a fake one provided by RANDR itself. See Java bug 6636469 for info.
1559
*/
1560
if (!(rr_maj_ver > 1 || (rr_maj_ver == 1 && rr_min_ver >= 2))) {
1561
J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
1562
"Xinerama is active and Xrandr version is %d.%d",
1563
rr_maj_ver, rr_min_ver);
1564
dlclose(pLibRandR);
1565
return JNI_FALSE;
1566
}
1567
1568
/*
1569
* REMIND: Fullscreen mode doesn't work quite right with multi-monitor
1570
* setups and RANDR 1.2.
1571
*/
1572
if ((rr_maj_ver == 1 && rr_min_ver <= 2) && awt_numScreens > 1) {
1573
J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
1574
"Multiple screens in use");
1575
dlclose(pLibRandR);
1576
return JNI_FALSE;
1577
}
1578
}
1579
1580
LOAD_XRANDR_FUNC(XRRGetScreenInfo);
1581
LOAD_XRANDR_FUNC(XRRFreeScreenConfigInfo);
1582
LOAD_XRANDR_FUNC(XRRConfigRates);
1583
LOAD_XRANDR_FUNC(XRRConfigCurrentRate);
1584
LOAD_XRANDR_FUNC(XRRConfigSizes);
1585
LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);
1586
LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
1587
LOAD_XRANDR_FUNC(XRRConfigRotations);
1588
LOAD_XRANDR_FUNC(XRRGetScreenResources);
1589
LOAD_XRANDR_FUNC(XRRFreeScreenResources);
1590
LOAD_XRANDR_FUNC(XRRGetOutputInfo);
1591
LOAD_XRANDR_FUNC(XRRFreeOutputInfo);
1592
LOAD_XRANDR_FUNC(XRRGetCrtcInfo);
1593
LOAD_XRANDR_FUNC(XRRFreeCrtcInfo);
1594
1595
return JNI_TRUE;
1596
}
1597
1598
static jobject
1599
X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,
1600
jint bitDepth, jint refreshRate)
1601
{
1602
jclass displayModeClass;
1603
jmethodID cid;
1604
jint validRefreshRate = refreshRate;
1605
1606
displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");
1607
CHECK_NULL_RETURN(displayModeClass, NULL);
1608
if (JNU_IsNull(env, displayModeClass)) {
1609
JNU_ThrowInternalError(env,
1610
"Could not get display mode class");
1611
return NULL;
1612
}
1613
1614
cid = (*env)->GetMethodID(env, displayModeClass, "<init>", "(IIII)V");
1615
CHECK_NULL_RETURN(cid, NULL);
1616
if (cid == NULL) {
1617
JNU_ThrowInternalError(env,
1618
"Could not get display mode constructor");
1619
return NULL;
1620
}
1621
1622
// early versions of xrandr may report "empty" rates (6880694)
1623
if (validRefreshRate <= 0) {
1624
validRefreshRate = REFRESH_RATE_UNKNOWN;
1625
}
1626
1627
return (*env)->NewObject(env, displayModeClass, cid,
1628
width, height, bitDepth, validRefreshRate);
1629
}
1630
1631
static void
1632
X11GD_AddDisplayMode(JNIEnv *env, jobject arrayList,
1633
jint width, jint height,
1634
jint bitDepth, jint refreshRate)
1635
{
1636
jobject displayMode = X11GD_CreateDisplayMode(env, width, height,
1637
bitDepth, refreshRate);
1638
if (!JNU_IsNull(env, displayMode)) {
1639
jclass arrayListClass;
1640
jmethodID mid;
1641
arrayListClass = (*env)->GetObjectClass(env, arrayList);
1642
if (JNU_IsNull(env, arrayListClass)) {
1643
JNU_ThrowInternalError(env,
1644
"Could not get class java.util.ArrayList");
1645
return;
1646
}
1647
mid = (*env)->GetMethodID(env, arrayListClass, "add",
1648
"(Ljava/lang/Object;)Z");
1649
CHECK_NULL(mid);
1650
if (mid == NULL) {
1651
JNU_ThrowInternalError(env,
1652
"Could not get method java.util.ArrayList.add()");
1653
return;
1654
}
1655
(*env)->CallObjectMethod(env, arrayList, mid, displayMode);
1656
(*env)->DeleteLocalRef(env, displayMode);
1657
}
1658
}
1659
1660
#endif /* !NO_XRANDR */
1661
1662
static void
1663
X11GD_SetFullscreenMode(Window win, jboolean enabled)
1664
{
1665
Atom wmState = XInternAtom(awt_display, "_NET_WM_STATE", False);
1666
Atom wmStateFs = XInternAtom(awt_display,
1667
"_NET_WM_STATE_FULLSCREEN", False);
1668
XWindowAttributes attr;
1669
XEvent event;
1670
1671
if (wmState == None || wmStateFs == None
1672
|| !XGetWindowAttributes(awt_display, win, &attr)) {
1673
return;
1674
}
1675
1676
memset(&event, 0, sizeof(event));
1677
event.xclient.type = ClientMessage;
1678
event.xclient.message_type = wmState;
1679
event.xclient.display = awt_display;
1680
event.xclient.window = win;
1681
event.xclient.format = 32;
1682
event.xclient.data.l[0] = enabled ? 1 : 0; // 1==add, 0==remove
1683
event.xclient.data.l[1] = wmStateFs;
1684
1685
XSendEvent(awt_display, attr.root, False,
1686
SubstructureRedirectMask | SubstructureNotifyMask,
1687
&event);
1688
XSync(awt_display, False);
1689
}
1690
1691
/*
1692
* Class: sun_awt_X11GraphicsDevice
1693
* Method: initXrandrExtension
1694
* Signature: ()Z
1695
*/
1696
JNIEXPORT jboolean JNICALL
1697
Java_sun_awt_X11GraphicsDevice_initXrandrExtension
1698
(JNIEnv *env, jclass x11gd)
1699
{
1700
#if defined(NO_XRANDR)
1701
return JNI_FALSE;
1702
#else
1703
int opcode = 0, firstEvent = 0, firstError = 0;
1704
jboolean ret;
1705
1706
AWT_LOCK();
1707
ret = (jboolean)XQueryExtension(awt_display, "RANDR",
1708
&opcode, &firstEvent, &firstError);
1709
if (ret) {
1710
ret = X11GD_InitXrandrFuncs(env);
1711
}
1712
AWT_FLUSH_UNLOCK();
1713
1714
return ret;
1715
#endif /* NO_XRANDR */
1716
}
1717
1718
/*
1719
* Class: sun_awt_X11GraphicsDevice
1720
* Method: getCurrentDisplayMode
1721
* Signature: (I)Ljava/awt/DisplayMode;
1722
*/
1723
JNIEXPORT jobject JNICALL
1724
Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
1725
(JNIEnv* env, jclass x11gd, jint screen)
1726
{
1727
#if defined(NO_XRANDR)
1728
return NULL;
1729
#else
1730
XRRScreenConfiguration *config;
1731
jobject displayMode = NULL;
1732
1733
AWT_LOCK();
1734
1735
if (screen < ScreenCount(awt_display)) {
1736
1737
config = awt_XRRGetScreenInfo(awt_display,
1738
RootWindow(awt_display, screen));
1739
if (config != NULL) {
1740
Rotation rotation;
1741
short curRate;
1742
SizeID curSizeIndex;
1743
XRRScreenSize *sizes;
1744
int nsizes;
1745
1746
curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);
1747
sizes = awt_XRRConfigSizes(config, &nsizes);
1748
curRate = awt_XRRConfigCurrentRate(config);
1749
1750
if ((sizes != NULL) &&
1751
(curSizeIndex < nsizes))
1752
{
1753
XRRScreenSize curSize = sizes[curSizeIndex];
1754
displayMode = X11GD_CreateDisplayMode(env,
1755
curSize.width,
1756
curSize.height,
1757
BIT_DEPTH_MULTI,
1758
curRate);
1759
}
1760
1761
awt_XRRFreeScreenConfigInfo(config);
1762
}
1763
}
1764
1765
AWT_FLUSH_UNLOCK();
1766
1767
return displayMode;
1768
#endif /* NO_XRANDR */
1769
}
1770
1771
/*
1772
* Class: sun_awt_X11GraphicsDevice
1773
* Method: enumDisplayModes
1774
* Signature: (ILjava/util/ArrayList;)V
1775
*/
1776
JNIEXPORT void JNICALL
1777
Java_sun_awt_X11GraphicsDevice_enumDisplayModes
1778
(JNIEnv* env, jclass x11gd,
1779
jint screen, jobject arrayList)
1780
{
1781
#if !defined(NO_XRANDR)
1782
1783
AWT_LOCK();
1784
1785
if (XScreenCount(awt_display) > 0) {
1786
1787
XRRScreenConfiguration *config;
1788
1789
config = awt_XRRGetScreenInfo(awt_display,
1790
RootWindow(awt_display, screen));
1791
if (config != NULL) {
1792
int nsizes, i, j;
1793
XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
1794
1795
if (sizes != NULL) {
1796
for (i = 0; i < nsizes; i++) {
1797
int nrates;
1798
XRRScreenSize size = sizes[i];
1799
short *rates = awt_XRRConfigRates(config, i, &nrates);
1800
1801
for (j = 0; j < nrates; j++) {
1802
X11GD_AddDisplayMode(env, arrayList,
1803
size.width,
1804
size.height,
1805
BIT_DEPTH_MULTI,
1806
rates[j]);
1807
if ((*env)->ExceptionCheck(env)) {
1808
goto ret1;
1809
}
1810
}
1811
}
1812
}
1813
ret1:
1814
awt_XRRFreeScreenConfigInfo(config);
1815
}
1816
}
1817
1818
AWT_FLUSH_UNLOCK();
1819
#endif /* !NO_XRANDR */
1820
}
1821
1822
/*
1823
* Class: sun_awt_X11GraphicsDevice
1824
* Method: configDisplayMode
1825
* Signature: (IIII)V
1826
*/
1827
JNIEXPORT void JNICALL
1828
Java_sun_awt_X11GraphicsDevice_configDisplayMode
1829
(JNIEnv* env, jclass x11gd,
1830
jint screen, jint width, jint height, jint refreshRate)
1831
{
1832
#if !defined(NO_XRANDR)
1833
jboolean success = JNI_FALSE;
1834
XRRScreenConfiguration *config;
1835
Drawable root;
1836
Rotation currentRotation = RR_Rotate_0;
1837
1838
AWT_LOCK();
1839
1840
root = RootWindow(awt_display, screen);
1841
config = awt_XRRGetScreenInfo(awt_display, root);
1842
if (config != NULL) {
1843
jboolean foundConfig = JNI_FALSE;
1844
int chosenSizeIndex = -1;
1845
short chosenRate = -1;
1846
int nsizes;
1847
XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
1848
awt_XRRConfigRotations(config, &currentRotation);
1849
1850
if (sizes != NULL) {
1851
int i, j;
1852
1853
/* find the size index that matches the requested dimensions */
1854
for (i = 0; i < nsizes; i++) {
1855
XRRScreenSize size = sizes[i];
1856
1857
if ((size.width == width) && (size.height == height)) {
1858
/* we've found our size index... */
1859
int nrates;
1860
short *rates = awt_XRRConfigRates(config, i, &nrates);
1861
1862
/* now find rate that matches requested refresh rate */
1863
for (j = 0; j < nrates; j++) {
1864
if (rates[j] == refreshRate) {
1865
/* we've found our rate; break out of the loop */
1866
chosenSizeIndex = i;
1867
chosenRate = rates[j];
1868
foundConfig = JNI_TRUE;
1869
break;
1870
}
1871
}
1872
1873
break;
1874
}
1875
}
1876
}
1877
1878
if (foundConfig) {
1879
Status status =
1880
awt_XRRSetScreenConfigAndRate(awt_display, config, root,
1881
chosenSizeIndex,
1882
currentRotation,
1883
chosenRate,
1884
CurrentTime);
1885
1886
/* issue XSync to ensure immediate mode change */
1887
XSync(awt_display, False);
1888
1889
if (status == RRSetConfigSuccess) {
1890
success = JNI_TRUE;
1891
}
1892
}
1893
1894
awt_XRRFreeScreenConfigInfo(config);
1895
}
1896
1897
AWT_FLUSH_UNLOCK();
1898
1899
if (!success && !(*env)->ExceptionCheck(env)) {
1900
JNU_ThrowInternalError(env, "Could not set display mode");
1901
}
1902
#endif /* !NO_XRANDR */
1903
}
1904
1905
/*
1906
* Class: sun_awt_X11GraphicsDevice
1907
* Method: enterFullScreenExclusive
1908
* Signature: (J)V
1909
*/
1910
JNIEXPORT void JNICALL
1911
Java_sun_awt_X11GraphicsDevice_enterFullScreenExclusive
1912
(JNIEnv* env, jclass x11gd,
1913
jlong window)
1914
{
1915
Window win = (Window)window;
1916
1917
AWT_LOCK();
1918
XSync(awt_display, False); /* ensures window is visible first */
1919
X11GD_SetFullscreenMode(win, JNI_TRUE);
1920
AWT_UNLOCK();
1921
}
1922
1923
/*
1924
* Class: sun_awt_X11GraphicsDevice
1925
* Method: exitFullScreenExclusive
1926
* Signature: (J)V
1927
*/
1928
JNIEXPORT void JNICALL
1929
Java_sun_awt_X11GraphicsDevice_exitFullScreenExclusive
1930
(JNIEnv* env, jclass x11gd,
1931
jlong window)
1932
{
1933
Window win = (Window)window;
1934
1935
AWT_LOCK();
1936
X11GD_SetFullscreenMode(win, JNI_FALSE);
1937
AWT_UNLOCK();
1938
}
1939
1940
/**
1941
* End DisplayMode/FullScreen support
1942
*/
1943
1944
/*
1945
* Class: sun_awt_X11GraphicsDevice
1946
* Method: getNativeScaleFactor
1947
* Signature: (I)D
1948
*/
1949
JNIEXPORT jdouble JNICALL
1950
Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
1951
(JNIEnv *env, jobject this, jint screen) {
1952
1953
return getNativeScaleFactor();
1954
}
1955
1956