5
#include "connections.h"
10
time_t last_subwin_trap = 0;
11
int subwin_trap_count = 0;
12
XErrorHandler old_getimage_handler;
14
int xrandr_present = 0;
15
int xrandr_width = -1;
16
int xrandr_height = -1;
17
int xrandr_rotation = -1;
18
Time xrandr_timestamp = 0;
19
Time xrandr_cfg_time = 0;
21
void initialize_xrandr(void);
22
int check_xrandr_event(char *msg);
23
int known_xrandr_mode(char *s);
25
static int handle_subwin_resize(char *msg);
26
static void handle_xrandr_change(int new_x, int new_y);
29
void initialize_xrandr(void) {
30
if (xrandr_present && dpy) {
31
#if LIBVNCSERVER_HAVE_LIBXRANDR
35
xrandr_width = XDisplayWidth(dpy, scr);
36
xrandr_height = XDisplayHeight(dpy, scr);
37
XRRRotations(dpy, scr, &rot);
38
xrandr_rotation = (int) rot;
39
if (xrandr || xrandr_maybe) {
40
XRRSelectInput(dpy, rootwin, RRScreenChangeNotifyMask);
42
XRRSelectInput(dpy, rootwin, 0);
47
rfbLog("-xrandr mode specified, but no RANDR support on\n");
48
rfbLog(" display or in client library. Disabling -xrandr "
54
static int handle_subwin_resize(char *msg) {
56
int i, check = 10, ms = 250; /* 2.5 secs total... */
58
if (msg) {} /* unused vars warning: */
60
return 0; /* hmmm... */
62
if (! valid_window(subwin, NULL, 0)) {
64
rfbLog("subwin 0x%lx went away!\n", subwin);
68
if (! get_window_size(subwin, &new_x, &new_y)) {
70
rfbLog("could not get size of subwin 0x%lx\n", subwin);
74
if (wdpy_x == new_x && wdpy_y == new_y) {
79
/* window may still be changing (e.g. drag resize) */
80
for (i=0; i < check; i++) {
84
if (! get_window_size(subwin, &newer_x, &newer_y)) {
86
rfbLog("could not get size of subwin 0x%lx\n", subwin);
89
if (new_x == newer_x && new_y == newer_y) {
93
rfbLog("subwin 0x%lx still changing size...\n", subwin);
99
rfbLog("subwin 0x%lx new size: x: %d -> %d, y: %d -> %d\n",
100
subwin, wdpy_x, new_x, wdpy_y, new_y);
101
rfbLog("calling handle_xrandr_change() for resizing\n");
104
handle_xrandr_change(new_x, new_y);
108
static void handle_xrandr_change(int new_x, int new_y) {
109
rfbClientIteratorPtr iter;
114
/* sanity check xrandr_mode */
116
xrandr_mode = strdup("default");
117
} else if (! known_xrandr_mode(xrandr_mode)) {
119
xrandr_mode = strdup("default");
121
rfbLog("xrandr_mode: %s\n", xrandr_mode);
122
if (!strcmp(xrandr_mode, "exit")) {
124
rfbLog(" shutting down due to XRANDR event.\n");
127
if (!strcmp(xrandr_mode, "newfbsize") && screen) {
128
iter = rfbGetClientIterator(screen);
129
while( (cl = rfbClientIteratorNext(iter)) ) {
130
if (cl->useNewFBSize) {
133
rfbLog(" closing client %s (no useNewFBSize"
134
" support).\n", cl->host);
136
rfbClientConnectionGone(cl);
138
rfbReleaseClientIterator(iter);
141
/* default, resize, and newfbsize create a new fb: */
142
rfbLog("check_xrandr_event: trying to create new framebuffer...\n");
143
if (new_x < wdpy_x || new_y < wdpy_y) {
147
rfbLog("check_xrandr_event: fb WxH: %dx%d\n", wdpy_x, wdpy_y);
150
int check_xrandr_event(char *msg) {
156
return handle_subwin_resize(msg);
158
#if LIBVNCSERVER_HAVE_LIBXRANDR
159
if (! xrandr_present) {
162
if (! xrandr && ! xrandr_maybe) {
165
if (xrandr_base_event_type && XCheckTypedEvent(dpy,
166
xrandr_base_event_type + RRScreenChangeNotify, &xev)) {
167
int do_change, qout = 0;
168
static int first = 1;
169
XRRScreenChangeNotifyEvent *rev;
171
rev = (XRRScreenChangeNotifyEvent *) &xev;
173
if (first && ! xrandr) {
174
fprintf(stderr, "\n");
179
rfbLog("check_xrandr_event():\n");
180
rfbLog("Detected XRANDR event at location '%s':\n", msg);
185
rfbLog(" serial: %d\n", (int) rev->serial);
186
rfbLog(" timestamp: %d\n", (int) rev->timestamp);
187
rfbLog(" cfg_timestamp: %d\n", (int) rev->config_timestamp);
188
rfbLog(" size_id: %d\n", (int) rev->size_index);
189
rfbLog(" sub_pixel: %d\n", (int) rev->subpixel_order);
190
rfbLog(" rotation: %d\n", (int) rev->rotation);
191
rfbLog(" width: %d\n", (int) rev->width);
192
rfbLog(" height: %d\n", (int) rev->height);
193
rfbLog(" mwidth: %d mm\n", (int) rev->mwidth);
194
rfbLog(" mheight: %d mm\n", (int) rev->mheight);
196
rfbLog("check_xrandr_event: previous WxH: %dx%d\n",
200
if (wdpy_x == rev->width && wdpy_y == rev->height &&
201
xrandr_rotation == (int) rev->rotation) {
202
rfbLog("check_xrandr_event: no change detected.\n");
207
rfbLog("check_xrandr_event: Resize; "
208
"enabling full XRANDR trapping.\n");
213
xrandr_width = rev->width;
214
xrandr_height = rev->height;
215
xrandr_timestamp = rev->timestamp;
216
xrandr_cfg_time = rev->config_timestamp;
217
xrandr_rotation = (int) rev->rotation;
219
if (! qout) rfbLog("check_xrandr_event: updating config...\n");
220
XRRUpdateConfiguration(&xev);
224
handle_xrandr_change(rev->width, rev->height);
229
rfbLog("check_xrandr_event: current WxH: %dx%d\n",
230
XDisplayWidth(dpy, scr), XDisplayHeight(dpy, scr));
231
rfbLog("check_xrandr_event(): returning control to"
241
int known_xrandr_mode(char *s) {
244
* resize: the default
245
* exit: shutdown clients and exit.
246
* newfbsize: shutdown clients that do not support NewFBSize encoding.
248
if (strcmp(s, "default") && strcmp(s, "resize") &&
249
strcmp(s, "exit") && strcmp(s, "newfbsize")) {