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