270 |
#define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); } |
#define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); } |
271 |
|
|
272 |
static seamless_window * |
static seamless_window * |
273 |
seamless_get_window_by_id(unsigned long id) |
sw_get_window_by_id(unsigned long id) |
274 |
{ |
{ |
275 |
seamless_window *sw; |
seamless_window *sw; |
276 |
for (sw = g_seamless_windows; sw; sw = sw->next) |
for (sw = g_seamless_windows; sw; sw = sw->next) |
283 |
|
|
284 |
|
|
285 |
static seamless_window * |
static seamless_window * |
286 |
seamless_get_window_by_wnd(Window wnd) |
sw_get_window_by_wnd(Window wnd) |
287 |
{ |
{ |
288 |
seamless_window *sw; |
seamless_window *sw; |
289 |
for (sw = g_seamless_windows; sw; sw = sw->next) |
for (sw = g_seamless_windows; sw; sw = sw->next) |
296 |
|
|
297 |
|
|
298 |
static void |
static void |
299 |
seamless_remove_window(seamless_window * win) |
sw_remove_window(seamless_window * win) |
300 |
{ |
{ |
301 |
seamless_window *sw, **prevnext = &g_seamless_windows; |
seamless_window *sw, **prevnext = &g_seamless_windows; |
302 |
for (sw = g_seamless_windows; sw; sw = sw->next) |
for (sw = g_seamless_windows; sw; sw = sw->next) |
315 |
|
|
316 |
/* Move all windows except wnd to new desktop */ |
/* Move all windows except wnd to new desktop */ |
317 |
static void |
static void |
318 |
seamless_all_to_desktop(Window wnd, unsigned int desktop) |
sw_all_to_desktop(Window wnd, unsigned int desktop) |
319 |
{ |
{ |
320 |
seamless_window *sw; |
seamless_window *sw; |
321 |
for (sw = g_seamless_windows; sw; sw = sw->next) |
for (sw = g_seamless_windows; sw; sw = sw->next) |
333 |
|
|
334 |
/* Send our position */ |
/* Send our position */ |
335 |
static void |
static void |
336 |
seamless_update_position(seamless_window * sw) |
sw_update_position(seamless_window * sw) |
337 |
{ |
{ |
338 |
XWindowAttributes wa; |
XWindowAttributes wa; |
339 |
int x, y; |
int x, y; |
358 |
|
|
359 |
/* Check if it's time to send our position */ |
/* Check if it's time to send our position */ |
360 |
static void |
static void |
361 |
seamless_check_timers() |
sw_check_timers() |
362 |
{ |
{ |
363 |
seamless_window *sw; |
seamless_window *sw; |
364 |
struct timeval now; |
struct timeval now; |
369 |
if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <)) |
if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <)) |
370 |
{ |
{ |
371 |
timerclear(sw->position_timer); |
timerclear(sw->position_timer); |
372 |
seamless_update_position(sw); |
sw_update_position(sw); |
373 |
} |
} |
374 |
} |
} |
375 |
} |
} |
376 |
|
|
377 |
|
|
378 |
static void |
static void |
379 |
seamless_restack_window(seamless_window * sw, unsigned long behind) |
sw_restack_window(seamless_window * sw, unsigned long behind) |
380 |
{ |
{ |
381 |
seamless_window *sw_above; |
seamless_window *sw_above; |
382 |
|
|
406 |
|
|
407 |
|
|
408 |
static void |
static void |
409 |
|
sw_handle_restack(seamless_window * sw) |
410 |
|
{ |
411 |
|
Status status; |
412 |
|
Window root, parent, *children; |
413 |
|
unsigned int nchildren, i; |
414 |
|
seamless_window *sw_below; |
415 |
|
|
416 |
|
status = XQueryTree(g_display, RootWindowOfScreen(g_screen), |
417 |
|
&root, &parent, &children, &nchildren); |
418 |
|
if (!status || !nchildren) |
419 |
|
return; |
420 |
|
|
421 |
|
sw_below = NULL; |
422 |
|
|
423 |
|
i = 0; |
424 |
|
while (children[i] != sw->wnd) |
425 |
|
{ |
426 |
|
i++; |
427 |
|
if (i >= nchildren) |
428 |
|
return; |
429 |
|
} |
430 |
|
|
431 |
|
for (i++; i < nchildren; i++) |
432 |
|
{ |
433 |
|
sw_below = sw_get_window_by_wnd(children[i]); |
434 |
|
if (sw_below) |
435 |
|
break; |
436 |
|
} |
437 |
|
|
438 |
|
if (!sw_below && !sw->behind) |
439 |
|
return; |
440 |
|
if (sw_below && (sw_below->id == sw->behind)) |
441 |
|
return; |
442 |
|
|
443 |
|
if (sw_below) |
444 |
|
{ |
445 |
|
seamless_send_zchange(sw->id, sw_below->id, 0); |
446 |
|
sw_restack_window(sw, sw_below->id); |
447 |
|
} |
448 |
|
else |
449 |
|
{ |
450 |
|
seamless_send_zchange(sw->id, 0, 0); |
451 |
|
sw_restack_window(sw, 0); |
452 |
|
} |
453 |
|
} |
454 |
|
|
455 |
|
|
456 |
|
static void |
457 |
mwm_hide_decorations(Window wnd) |
mwm_hide_decorations(Window wnd) |
458 |
{ |
{ |
459 |
PropMotifWmHints motif_hints; |
PropMotifWmHints motif_hints; |
1874 |
} |
} |
1875 |
} |
} |
1876 |
|
|
|
static void |
|
|
ui_seamless_handle_restack(seamless_window * sw) |
|
|
{ |
|
|
Status status; |
|
|
Window root, parent, *children; |
|
|
unsigned int nchildren, i; |
|
|
seamless_window *sw_below; |
|
|
|
|
|
status = XQueryTree(g_display, RootWindowOfScreen(g_screen), |
|
|
&root, &parent, &children, &nchildren); |
|
|
if (!status || !nchildren) |
|
|
return; |
|
|
|
|
|
sw_below = NULL; |
|
|
|
|
|
i = 0; |
|
|
while (children[i] != sw->wnd) |
|
|
{ |
|
|
i++; |
|
|
if (i >= nchildren) |
|
|
return; |
|
|
} |
|
|
|
|
|
for (i++; i < nchildren; i++) |
|
|
{ |
|
|
sw_below = seamless_get_window_by_wnd(children[i]); |
|
|
if (sw_below) |
|
|
break; |
|
|
} |
|
|
|
|
|
if (!sw_below && !sw->behind) |
|
|
return; |
|
|
if (sw_below && (sw_below->id == sw->behind)) |
|
|
return; |
|
|
|
|
|
if (sw_below) |
|
|
{ |
|
|
seamless_send_zchange(sw->id, sw_below->id, 0); |
|
|
seamless_restack_window(sw, sw_below->id); |
|
|
} |
|
|
else |
|
|
{ |
|
|
seamless_send_zchange(sw->id, 0, 0); |
|
|
seamless_restack_window(sw, 0); |
|
|
} |
|
|
} |
|
1877 |
|
|
1878 |
/* Process events in Xlib queue |
/* Process events in Xlib queue |
1879 |
Returns 0 after user quit, 1 otherwise */ |
Returns 0 after user quit, 1 otherwise */ |
2008 |
XGrabKeyboard(g_display, g_wnd, True, |
XGrabKeyboard(g_display, g_wnd, True, |
2009 |
GrabModeAsync, GrabModeAsync, CurrentTime); |
GrabModeAsync, GrabModeAsync, CurrentTime); |
2010 |
|
|
2011 |
sw = seamless_get_window_by_wnd(xevent.xfocus.window); |
sw = sw_get_window_by_wnd(xevent.xfocus.window); |
2012 |
if (!sw) |
if (!sw) |
2013 |
break; |
break; |
2014 |
|
|
2059 |
} |
} |
2060 |
else |
else |
2061 |
{ |
{ |
2062 |
sw = seamless_get_window_by_wnd(xevent.xexpose.window); |
sw = sw_get_window_by_wnd(xevent.xexpose.window); |
2063 |
if (sw) |
if (sw) |
2064 |
XCopyArea(g_display, g_backstore, |
XCopyArea(g_display, g_backstore, |
2065 |
xevent.xexpose.window, g_gc, |
xevent.xexpose.window, g_gc, |
2109 |
break; |
break; |
2110 |
|
|
2111 |
/* seamless */ |
/* seamless */ |
2112 |
sw = seamless_get_window_by_wnd(xevent.xproperty.window); |
sw = sw_get_window_by_wnd(xevent.xproperty.window); |
2113 |
if (!sw) |
if (!sw) |
2114 |
break; |
break; |
2115 |
|
|
2124 |
&& (xevent.xproperty.state == PropertyNewValue)) |
&& (xevent.xproperty.state == PropertyNewValue)) |
2125 |
{ |
{ |
2126 |
sw->desktop = ewmh_get_window_desktop(sw->wnd); |
sw->desktop = ewmh_get_window_desktop(sw->wnd); |
2127 |
seamless_all_to_desktop(sw->wnd, sw->desktop); |
sw_all_to_desktop(sw->wnd, sw->desktop); |
2128 |
} |
} |
2129 |
|
|
2130 |
break; |
break; |
2140 |
if (!g_seamless_active) |
if (!g_seamless_active) |
2141 |
break; |
break; |
2142 |
|
|
2143 |
sw = seamless_get_window_by_wnd(xevent.xconfigure.window); |
sw = sw_get_window_by_wnd(xevent.xconfigure.window); |
2144 |
if (!sw) |
if (!sw) |
2145 |
{ |
{ |
2146 |
error("ConfigureNotify for unknown window 0x%lx\n", |
error("ConfigureNotify for unknown window 0x%lx\n", |
2160 |
sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER; |
sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER; |
2161 |
} |
} |
2162 |
|
|
2163 |
ui_seamless_handle_restack(sw); |
sw_handle_restack(sw); |
2164 |
break; |
break; |
2165 |
} |
} |
2166 |
} |
} |
2186 |
return 0; |
return 0; |
2187 |
|
|
2188 |
if (g_seamless_active) |
if (g_seamless_active) |
2189 |
seamless_check_timers(); |
sw_check_timers(); |
2190 |
|
|
2191 |
FD_ZERO(&rfds); |
FD_ZERO(&rfds); |
2192 |
FD_ZERO(&wfds); |
FD_ZERO(&wfds); |
3176 |
{ |
{ |
3177 |
} |
} |
3178 |
|
|
3179 |
|
|
3180 |
void |
void |
3181 |
ui_seamless_begin() |
ui_seamless_begin() |
3182 |
{ |
{ |
3187 |
return; |
return; |
3188 |
|
|
3189 |
g_seamless_started = True; |
g_seamless_started = True; |
|
|
|
3190 |
ui_seamless_toggle(); |
ui_seamless_toggle(); |
3191 |
} |
} |
3192 |
|
|
3193 |
|
|
3194 |
void |
void |
3195 |
ui_seamless_toggle() |
ui_seamless_toggle() |
3196 |
{ |
{ |
3206 |
while (g_seamless_windows) |
while (g_seamless_windows) |
3207 |
{ |
{ |
3208 |
XDestroyWindow(g_display, g_seamless_windows->wnd); |
XDestroyWindow(g_display, g_seamless_windows->wnd); |
3209 |
seamless_remove_window(g_seamless_windows); |
sw_remove_window(g_seamless_windows); |
3210 |
} |
} |
3211 |
XMapWindow(g_display, g_wnd); |
XMapWindow(g_display, g_wnd); |
3212 |
} |
} |
3220 |
g_seamless_active = !g_seamless_active; |
g_seamless_active = !g_seamless_active; |
3221 |
} |
} |
3222 |
|
|
3223 |
|
|
3224 |
void |
void |
3225 |
ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags) |
ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags) |
3226 |
{ |
{ |
3235 |
return; |
return; |
3236 |
|
|
3237 |
/* Ignore CREATEs for existing windows */ |
/* Ignore CREATEs for existing windows */ |
3238 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3239 |
if (sw) |
if (sw) |
3240 |
return; |
return; |
3241 |
|
|
3276 |
/* Set WM_TRANSIENT_FOR, if necessary */ |
/* Set WM_TRANSIENT_FOR, if necessary */ |
3277 |
else if (parent != 0x00000000) |
else if (parent != 0x00000000) |
3278 |
{ |
{ |
3279 |
sw_parent = seamless_get_window_by_id(parent); |
sw_parent = sw_get_window_by_id(parent); |
3280 |
if (sw_parent) |
if (sw_parent) |
3281 |
XSetTransientForHint(g_display, wnd, sw_parent->wnd); |
XSetTransientForHint(g_display, wnd, sw_parent->wnd); |
3282 |
else |
else |
3322 |
if (!g_seamless_active) |
if (!g_seamless_active) |
3323 |
return; |
return; |
3324 |
|
|
3325 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3326 |
if (!sw) |
if (!sw) |
3327 |
{ |
{ |
3328 |
warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id); |
warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id); |
3330 |
} |
} |
3331 |
|
|
3332 |
XDestroyWindow(g_display, sw->wnd); |
XDestroyWindow(g_display, sw->wnd); |
3333 |
seamless_remove_window(sw); |
sw_remove_window(sw); |
3334 |
} |
} |
3335 |
|
|
3336 |
|
|
3342 |
if (!g_seamless_active) |
if (!g_seamless_active) |
3343 |
return; |
return; |
3344 |
|
|
3345 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3346 |
if (!sw) |
if (!sw) |
3347 |
{ |
{ |
3348 |
warning("ui_seamless_move_window: No information for window 0x%lx\n", id); |
warning("ui_seamless_move_window: No information for window 0x%lx\n", id); |
3375 |
XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height); |
XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height); |
3376 |
} |
} |
3377 |
|
|
3378 |
|
|
3379 |
void |
void |
3380 |
ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags) |
ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags) |
3381 |
{ |
{ |
3384 |
if (!g_seamless_active) |
if (!g_seamless_active) |
3385 |
return; |
return; |
3386 |
|
|
3387 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3388 |
if (!sw) |
if (!sw) |
3389 |
{ |
{ |
3390 |
warning("ui_seamless_restack_window: No information for window 0x%lx\n", id); |
warning("ui_seamless_restack_window: No information for window 0x%lx\n", id); |
3396 |
seamless_window *sw_behind; |
seamless_window *sw_behind; |
3397 |
Window wnds[2]; |
Window wnds[2]; |
3398 |
|
|
3399 |
sw_behind = seamless_get_window_by_id(behind); |
sw_behind = sw_get_window_by_id(behind); |
3400 |
if (!sw_behind) |
if (!sw_behind) |
3401 |
{ |
{ |
3402 |
warning("ui_seamless_restack_window: No information for window 0x%lx\n", |
warning("ui_seamless_restack_window: No information for window 0x%lx\n", |
3414 |
XRaiseWindow(g_display, sw->wnd); |
XRaiseWindow(g_display, sw->wnd); |
3415 |
} |
} |
3416 |
|
|
3417 |
seamless_restack_window(sw, behind); |
sw_restack_window(sw, behind); |
3418 |
} |
} |
3419 |
|
|
3420 |
|
|
3421 |
void |
void |
3422 |
ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags) |
ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags) |
3423 |
{ |
{ |
3426 |
if (!g_seamless_active) |
if (!g_seamless_active) |
3427 |
return; |
return; |
3428 |
|
|
3429 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3430 |
if (!sw) |
if (!sw) |
3431 |
{ |
{ |
3432 |
warning("ui_seamless_settitle: No information for window 0x%lx\n", id); |
warning("ui_seamless_settitle: No information for window 0x%lx\n", id); |
3447 |
if (!g_seamless_active) |
if (!g_seamless_active) |
3448 |
return; |
return; |
3449 |
|
|
3450 |
sw = seamless_get_window_by_id(id); |
sw = sw_get_window_by_id(id); |
3451 |
if (!sw) |
if (!sw) |
3452 |
{ |
{ |
3453 |
warning("ui_seamless_setstate: No information for window 0x%lx\n", id); |
warning("ui_seamless_setstate: No information for window 0x%lx\n", id); |
3499 |
while (g_seamless_windows) |
while (g_seamless_windows) |
3500 |
{ |
{ |
3501 |
XDestroyWindow(g_display, g_seamless_windows->wnd); |
XDestroyWindow(g_display, g_seamless_windows->wnd); |
3502 |
seamless_remove_window(g_seamless_windows); |
sw_remove_window(g_seamless_windows); |
3503 |
} |
} |
3504 |
} |
} |
3505 |
|
|
3506 |
|
|
3507 |
void |
void |
3508 |
ui_seamless_ack(unsigned int serial) |
ui_seamless_ack(unsigned int serial) |
3509 |
{ |
{ |
3516 |
sw->yoffset = sw->outpos_yoffset; |
sw->yoffset = sw->outpos_yoffset; |
3517 |
sw->width = sw->outpos_width; |
sw->width = sw->outpos_width; |
3518 |
sw->height = sw->outpos_height; |
sw->height = sw->outpos_height; |
|
|
|
3519 |
sw->outstanding_position = False; |
sw->outstanding_position = False; |
|
|
|
3520 |
break; |
break; |
3521 |
} |
} |
3522 |
} |
} |