1000 lines
23 KiB
C
1000 lines
23 KiB
C
/* Copyright 1989 GROUPE BULL -- See license conditions in file COPYRIGHT
|
|
* Copyright 1989 Massachusetts Institute of Technology
|
|
*/
|
|
/**************************************************************\
|
|
* *
|
|
* X11 BULL WINDOW MANAGER. *
|
|
* *
|
|
* MODULE FOR OPERATIONS THAT MAY BE CALLED FROM Lisp. *
|
|
* *
|
|
\**************************************************************/
|
|
|
|
/* include */
|
|
|
|
#include "EXTERN.h"
|
|
#include "wool.h"
|
|
#include "wl_atom.h"
|
|
#include "gwm.h"
|
|
#include "wl_number.h"
|
|
#include "wl_string.h"
|
|
#include "wl_client.h"
|
|
#include "wl_menu.h"
|
|
#include "wl_name.h"
|
|
#include "wl_event.h"
|
|
#include "wl_pixmap.h"
|
|
|
|
/* local constants */
|
|
|
|
/* external */
|
|
|
|
extern XError(), NoXError();
|
|
extern WOB_METHOD ClientWindowClass[];
|
|
extern WOOL_OBJECT UserMoveWindow(), UserResizeWindow();
|
|
extern WOOL_OBJECT UserMoveSeveralWindows();
|
|
extern WOOL_OBJECT MwmLikeUserResizeWindow();
|
|
extern ClientWindow ClientWindowLeader();
|
|
|
|
/* routines */
|
|
|
|
char *NoRootError="Window function called on root window%s";
|
|
#define NoRoot(w) ((w)->status != RootStatus ? (w) : \
|
|
(wool_error(NoRootError, ""),w))
|
|
|
|
/*
|
|
* GetTarget returns window having status in ancestors of current wob
|
|
*/
|
|
|
|
Wob
|
|
GetTarget(flag)
|
|
unsigned long flag;
|
|
{
|
|
Wob wob = TargetWob;
|
|
|
|
while ((wob -> parent != NULL) && (wob -> status & flag) == 0)
|
|
wob = wob -> parent;
|
|
return wob;
|
|
}
|
|
|
|
/*
|
|
* SetTarget makes TargetWob, TargetWindow and Context
|
|
*/
|
|
|
|
SetTarget(wob)
|
|
Wob wob;
|
|
{
|
|
extern WOOL_Namespace ContextNamespace;
|
|
|
|
TargetWob = wob;
|
|
while (!(wob -> status & (TargetWindowStatus)))
|
|
wob = wob -> parent;
|
|
TargetWindow = (ClientWindow) wob;
|
|
Context = TargetWindow -> screen;
|
|
ContextNamespace -> current = Context -> screen;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
MapWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cw;
|
|
|
|
if (argc)
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
else
|
|
cw = TargetWindow;
|
|
ClientWindowMap(cw);
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
UnmapWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cw;
|
|
|
|
if (argc)
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
else
|
|
cw = TargetWindow;
|
|
ClientWindowUnmap(cw);
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
IconifyWindow()
|
|
{
|
|
if (TargetWindow) {
|
|
if (TargetWindow -> mapped) {
|
|
XUnmapWindow(dpy, TargetWindow -> hook);
|
|
if (TargetWindow -> client && !TargetWindow -> client_wob)
|
|
XUnmapWindow(dpy, TargetWindow -> client);
|
|
TargetWindow -> mapped = 0;
|
|
}
|
|
if (TargetWindow -> status & IconStatus) { /* de-iconify */
|
|
SetTarget(TargetWindow -> window);
|
|
} else { /* iconify */
|
|
if (!(TargetWindow -> icon)) {
|
|
if (!RealizeIconWindow(TargetWindow)) {
|
|
ClientWindowMap(TargetWindow);
|
|
wool_error("Error in wool code for decorating icon %s",
|
|
((WOOL_String)
|
|
TargetWindow->cached_props->iconname)->string);
|
|
return NIL;
|
|
}
|
|
}
|
|
SetTarget(TargetWindow -> icon);
|
|
}
|
|
ClientWindowMap(TargetWindow);
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/* move window returns () if Ok, else:
|
|
* 0 if X problem with server/window
|
|
* 1 if pointer was not on screen
|
|
* 2 if user cancelled move
|
|
* 3 if button was released before entering function
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
MoveSeveralWindows(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cwl[255];
|
|
int i;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
must_be_number(argv[i], i);
|
|
cwl[i] = (ClientWindow) argv[i]->number;
|
|
}
|
|
return UserMoveSeveralWindows(argc, cwl);
|
|
}
|
|
|
|
|
|
WOOL_OBJECT
|
|
MoveWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
int i;
|
|
ClientWindow cw = TargetWindow;
|
|
|
|
for(i=0; i< argc; i++) /* MOVE HOOK */
|
|
must_be_number(argv[i], i);
|
|
switch (argc) {
|
|
case 1:
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
case 0:
|
|
return UserMoveWindow(cw);
|
|
break;
|
|
case 2:
|
|
XMoveWindow(dpy, TargetWindow -> hook,
|
|
TargetWindow -> box.x = argv[0] -> number,
|
|
TargetWindow -> box.y = argv[1] -> number);
|
|
SendSyntheticMoveEvent(TargetWindow);
|
|
break;
|
|
default:
|
|
XMoveWindow(dpy, ((Wob) (argv[0] -> number)) -> hook,
|
|
((Wob) (argv[0] -> number)) -> box.x = argv[1] -> number,
|
|
((Wob) (argv[0] -> number)) -> box.y = argv[2] -> number);
|
|
SendSyntheticMoveEvent(argv[0] -> number);
|
|
break;
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/* resize window returns () if Ok, else:
|
|
* 0 if X problem with server/window
|
|
* 1 if pointer was not on screen
|
|
* 2 if user cancelled resize
|
|
* 3 if button was released before entering function
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
ResizeWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
int width, height;
|
|
int i;
|
|
ClientWindow cw = TargetWindow;
|
|
|
|
for(i=0; i< argc; i++)
|
|
must_be_number(argv[i], i);
|
|
switch (argc) {
|
|
case 1:
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
case 0:
|
|
if (cw -> client)
|
|
if (GWM_resize_style)
|
|
return MwmLikeUserResizeWindow(cw);
|
|
else
|
|
return UserResizeWindow(cw);
|
|
break;
|
|
case 2:
|
|
if (TargetWindow -> client)
|
|
width = argv[0] -> number;
|
|
height = argv[1] -> number;
|
|
dims_outer_to_inner(TargetWindow, &width, &height);
|
|
conform_to_hints(&(TargetWindow -> cached_props -> normal_hints),
|
|
&width, &height);
|
|
XResizeWindow(dpy, TargetWindow -> client, width, height);
|
|
ReconfigureClientWindow(TargetWindow, TargetWindow -> client);
|
|
break;
|
|
default:
|
|
if (!(cw = ((ClientWindow) argv[0] -> number)) -> client)
|
|
return NIL;
|
|
width = argv[1] -> number;
|
|
height = argv[2] -> number;
|
|
dims_outer_to_inner(cw, &width, &height);
|
|
conform_to_hints(&(cw -> cached_props -> normal_hints),
|
|
&width, &height);
|
|
XResizeWindow(dpy, cw -> client, width, height);
|
|
ReconfigureClientWindow(cw, cw -> client);
|
|
break;
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/*
|
|
* Raise window (optionally % other top-level window)
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
RaiseWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
XWindowChanges values;
|
|
|
|
switch (argc) {
|
|
case 0:
|
|
XRaiseWindow(dpy, TargetWindow -> hook);
|
|
break;
|
|
case 1:
|
|
must_be_number(argv[0], 0);
|
|
values.sibling = ((Wob) (argv[0] -> number)) -> hook;
|
|
values.stack_mode = Above;
|
|
XConfigureWindow(dpy, TargetWindow -> hook,
|
|
CWStackMode | CWSibling, &values);
|
|
break;
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/*
|
|
* Lower window (optionally % other top-level window)
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
LowerWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
XWindowChanges values;
|
|
|
|
switch (argc) {
|
|
case 0:
|
|
XLowerWindow(dpy, TargetWindow -> hook);
|
|
break;
|
|
case 1:
|
|
must_be_number(argv[0], 0);
|
|
values.sibling = ((Wob) (argv[0] -> number)) -> hook;
|
|
values.stack_mode = Below;
|
|
XConfigureWindow(dpy, TargetWindow -> hook,
|
|
CWStackMode | CWSibling, &values);
|
|
break;
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
KillWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cw = TargetWindow;
|
|
Wob wob;
|
|
|
|
if (argc)
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
/* kill always main window, not icon! */
|
|
cw = cw -> window;
|
|
if (wob = (Wob) LookUpWob(cw -> client))
|
|
WOOL_send(WOOL_close, wob, (wob)); /* don't kill gwm! */
|
|
else if (cw -> client)
|
|
XKillClient(dpy, cw -> client);
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
ReDecorateWindow(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cw = TargetWindow;
|
|
int new_target = 0;
|
|
int was_mapped;
|
|
Window window;
|
|
WOOL_List window_group;
|
|
|
|
if (argc)
|
|
cw = (ClientWindow) (argv[0] -> number);
|
|
if (cw && cw -> type == ClientWindowClass) {
|
|
GWM_ProcessingExistingWindows = 1;
|
|
if (cw == TargetWindow)
|
|
new_target = 1;
|
|
cw = cw -> window;
|
|
window = cw -> client;
|
|
if (was_mapped = cw -> mapped)
|
|
ClientWindowUnmap(cw);
|
|
SetTarget(cw);
|
|
if (cw == ClientWindowLeader(cw)) {
|
|
increase_reference(window_group =
|
|
(WOOL_List) wool_window_group_get());
|
|
} else {
|
|
window_group = 0;
|
|
}
|
|
UnDecorateWindow(cw, 1, 1);
|
|
if (cw = (ClientWindow) DecorateWindow(window,
|
|
Context->rootWob, 1, 1)) {
|
|
if (was_mapped) {
|
|
ClientWindowMap(cw);
|
|
wool_process_unmap_events(window);
|
|
} else {
|
|
ClientWindowInitialMap(cw);
|
|
}
|
|
if (window_group && window_group != (WOOL_List) NIL) {
|
|
int i;
|
|
for (i=1; i<window_group->size; i++) {
|
|
AddWindowToGroupLeader(
|
|
((WOOL_Number)window_group->list[i])
|
|
->number, cw);
|
|
}
|
|
}
|
|
GWM_ProcessingExistingWindows = 0;
|
|
if (new_target)
|
|
SetTarget(cw);
|
|
return (WOOL_OBJECT) WLNumber_make(cw);
|
|
} else {
|
|
XMapWindow(dpy, window);
|
|
}
|
|
decrease_reference(window_group);
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/* returns NIL if OK
|
|
* (pop-up [menu [item]])
|
|
* if menu = () takes default
|
|
* item is the nth item in the menu (starting with 0).
|
|
* If pointer is not on screen, do nothing and returns 0
|
|
* if cannot grab, returns 1, Ok= ()
|
|
* returns pointer (modifier + buttons status) mask
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
PopMenu(argc, argv)
|
|
int argc;
|
|
WOOL_Menu argv[];
|
|
{
|
|
WOOL_Menu wl_menu = (WOOL_Menu) TargetWob -> menu;
|
|
int x, y, rx, ry, item = 0, i;
|
|
Window root, child;
|
|
Menu menu;
|
|
int floating = 1;
|
|
unsigned int mask;
|
|
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
if (argv[i] -> type == WLNumber)
|
|
item = ((WOOL_Number) argv[i]) -> number;
|
|
else if (argv[i] -> type == WLMenu)
|
|
wl_menu = argv[i];
|
|
else if (argv[i] == (WOOL_Menu) WA_here)
|
|
floating = 0;
|
|
}
|
|
menu = wl_menu -> wob_menu;
|
|
set_grab(Context -> rootWob);
|
|
XQueryPointer(dpy, Context -> root, &root, &child,
|
|
&x, &y, &rx, &ry, &mask);
|
|
if (root == Context -> root) {
|
|
if (floating) {
|
|
PlaceMenu(item, menu, x, y, TargetWob);
|
|
XMoveWindow(dpy, menu -> hook, menu -> box.x, menu -> box.y);
|
|
}
|
|
XMapRaised(dpy, menu -> hook);
|
|
if (NIL == set_grab(menu)) { /* ok */
|
|
XSync(dpy, 0);
|
|
wool_process_exposes();
|
|
menu -> parent = (TargetWob == (Wob) menu
|
|
? (Wob) Context -> rootWob :TargetWob) ;
|
|
return NIL;
|
|
} else { /* grab failed */
|
|
remove_grab(0);
|
|
XUnmapWindow(dpy, menu -> hook);
|
|
return (WOOL_OBJECT) WLNumber_make(1);
|
|
}
|
|
} else { /* not good screen */
|
|
remove_grab(0);
|
|
return (WOOL_OBJECT) WLNumber_make(0);
|
|
}
|
|
}
|
|
|
|
/* de-pop a menu previously popped by PopMenu
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
UnpopMenu(argc, argv)
|
|
int argc;
|
|
WOOL_Menu argv[];
|
|
{
|
|
Menu menu;
|
|
WOOL_Menu wl_menu;
|
|
|
|
menu = (Menu) GetTarget(MenuStatus);
|
|
if (argc) {
|
|
wl_menu = argv[0];
|
|
if (wl_menu == (WOOL_Menu) NIL)
|
|
return NIL;
|
|
if (wl_menu -> type == WLMenu)
|
|
menu = wl_menu -> wob_menu;
|
|
else
|
|
menu = (Menu) ((WOOL_Number) wl_menu) -> number;
|
|
}
|
|
remove_grab(menu);
|
|
XUnmapWindow(dpy, menu -> hook);
|
|
menu -> parent = (Wob) Context -> rootWob;
|
|
XSync(dpy, 0);
|
|
return (WOOL_OBJECT) WLNumber_make(menu);
|
|
}
|
|
|
|
PlaceMenu(item, menu, x, y, wob)
|
|
int item; /* item to place it */
|
|
Menu menu; /* the menu */
|
|
int x,y; /* mouse coordinates */
|
|
Wob wob; /* triggering wob */
|
|
{
|
|
int oldx, oldy;
|
|
int bw = 2 * menu -> box.borderwidth;
|
|
|
|
if (item >= menu -> nbars) /* if out put to last */
|
|
item = menu -> nbars - 1;
|
|
/* set pointer in item-th item */
|
|
oldx = menu -> box.x = x - menu -> box.width / 2;
|
|
oldy = menu -> box.y = y - (menu -> bars[item] -> box.y +
|
|
menu -> bars[item] -> box.height / 2);
|
|
/* place full pop on screen */
|
|
if (menu -> box.x < 0)
|
|
menu -> box.x = 0;
|
|
if (menu -> box.y < 0)
|
|
menu -> box.y = 0;
|
|
if (menu -> box.x + menu -> box.width + bw > Context -> width)
|
|
menu -> box.x = Context -> width - menu -> box.width - bw;
|
|
if (menu -> box.y + menu -> box.height + bw > Context -> height)
|
|
menu -> box.y = Context -> height - menu -> box.height - bw;
|
|
if (!GWM_never_warp_pointer
|
|
&& (menu -> box.x != oldx || menu -> box.y != oldy))
|
|
XWarpPointer(dpy, None, None, 0, 0, 0, 0,
|
|
menu -> box.x - oldx, menu -> box.y - oldy);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
CirculateWindowsDown()
|
|
{
|
|
XCirculateSubwindowsDown(dpy, Context->root);
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
CirculateWindowsUp()
|
|
{
|
|
XCirculateSubwindowsUp(dpy, Context->root);
|
|
return NIL;
|
|
}
|
|
|
|
/*
|
|
* the "current-window" functions
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window()
|
|
{
|
|
if (TargetWindow)
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow);
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_set_current_window(number)
|
|
WOOL_Number number;
|
|
{
|
|
must_be_number(number, 0);
|
|
if (WobIsValid(number->number)
|
|
&& (
|
|
(((Wob)(number->number))->type == ClientWindowClass)
|
|
|| (((Wob)(number->number))->type == ScreenClass))) {
|
|
SetTarget(number -> number);
|
|
return (WOOL_OBJECT) number;
|
|
} else {
|
|
return wool_error(INTERNAL_ERROR, "Not a Window!");
|
|
}
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_is_mapped()
|
|
{
|
|
if (TargetWindow -> mapped)
|
|
return TRU;
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_name()
|
|
{
|
|
return (WOOL_OBJECT) NoRoot(TargetWindow) -> cached_props -> windowname;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_name_set(name)
|
|
WOOL_String name;
|
|
{
|
|
XStoreName(dpy, NoRoot(TargetWindow) -> client, name -> string);
|
|
return (WOOL_OBJECT) name;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_client_name()
|
|
{
|
|
return (WOOL_OBJECT) NoRoot(TargetWindow) -> cached_props -> clientname;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_client_class()
|
|
{
|
|
return (WOOL_OBJECT) NoRoot(TargetWindow) -> cached_props -> clientclass;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_machine_name()
|
|
{
|
|
return (WOOL_OBJECT) NoRoot(TargetWindow) -> cached_props -> machinename;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_icon_name()
|
|
{
|
|
return (WOOL_OBJECT) NoRoot(TargetWindow) -> cached_props -> iconname;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_icon_name_set(name)
|
|
WOOL_String name;
|
|
{
|
|
XSetIconName(dpy, NoRoot(TargetWindow) -> client, name -> string);
|
|
return (WOOL_OBJECT) name;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_geometry(measure)
|
|
int measure;
|
|
{
|
|
Window root;
|
|
unsigned int measures[6];
|
|
|
|
XGetGeometry(dpy, TargetWindow -> client,
|
|
&root, (int *)&measures[0], (int *)&measures[1], &measures[2],
|
|
&measures[3], &measures[4], &measures[5]);
|
|
return (WOOL_OBJECT) WLNumber_make(measures[measure]);
|
|
}
|
|
|
|
/* sets Context to those of the root of a window */
|
|
|
|
int
|
|
ContextOfXWindow(window)
|
|
Window window;
|
|
{
|
|
Window root;
|
|
unsigned int measures[6];
|
|
int result;
|
|
|
|
XSetErrorHandler(NoXError);
|
|
result = XGetGeometry(dpy, window,
|
|
&root, (int *)&measures[0], (int *)&measures[1], &measures[2],
|
|
&measures[3], &measures[4], &measures[5]);
|
|
XSync(dpy, 0);
|
|
XSetErrorHandler(XError);
|
|
if (!result)
|
|
return result;
|
|
result = ScreenOfRoot(root);
|
|
if (result == -1)
|
|
return result;
|
|
SetTarget(GWMManagedScreens[result] -> rootWob);
|
|
return 0;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_client_x()
|
|
{
|
|
return wool_current_window_geometry(0);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_client_y()
|
|
{
|
|
return wool_current_window_geometry(1);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_client_width()
|
|
{
|
|
return wool_current_window_geometry(2);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_client_height()
|
|
{
|
|
return wool_current_window_geometry(3);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_client_borderwidth()
|
|
{
|
|
return wool_current_window_geometry(4);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_x()
|
|
{
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow -> box.x);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_y()
|
|
{
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow -> box.y);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_width()
|
|
{
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow -> box.width);
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_height()
|
|
{
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow -> box.height);
|
|
}
|
|
|
|
/* returns client-managed icon window, if any, but first check that it exists
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_icon_window()
|
|
{
|
|
Window dummy_win;
|
|
|
|
if (NoRoot(TargetWindow) -> cached_props -> wm_hints.flags
|
|
& IconWindowHint
|
|
&& !TrapXErrors(XGetTransientForHint(dpy,
|
|
TargetWindow -> cached_props -> wm_hints.icon_window,
|
|
&dummy_win))
|
|
) {
|
|
return (WOOL_OBJECT) WLNumber_make(
|
|
TargetWindow -> cached_props -> wm_hints.icon_window);
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/* each time this function is called, construct the icon pixmap from the hints
|
|
* (this to allow for applications changing their icons and user to change
|
|
* color via the foreground and background variables)
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_icon_bitmap()
|
|
{
|
|
if (TargetWindow -> cached_props -> wm_hints.flags & IconPixmapHint) {
|
|
WOOL_Pixmap pixmap = WLPixmap_make(TargetWindow -> cached_props ->
|
|
wm_hints.icon_pixmap);
|
|
if (TargetWindow -> cached_props -> wm_hints.flags & IconMaskHint) {
|
|
Window root;
|
|
int x_hot, y_hot;
|
|
unsigned int width, height, bw, depth;
|
|
GC gc;
|
|
Pixmap mask = TargetWindow -> cached_props -> wm_hints.icon_mask;
|
|
XGetGeometry(dpy, mask, &root, &x_hot, &y_hot,
|
|
&width, &height, &bw, &depth);
|
|
Trace('p', ("wool_current_window_icon_bitmap: create pixmap %d %d %d\n",
|
|
width, height, depth));
|
|
pixmap -> mask = XCreatePixmap(dpy, root, width, height, depth);
|
|
gc = XCreateGC(dpy, pixmap -> mask, 0, 0);
|
|
XCopyArea(dpy, mask, pixmap -> mask, gc, 0, 0,
|
|
width, height, 0, 0);
|
|
}
|
|
return (WOOL_OBJECT) pixmap;
|
|
} else {
|
|
return NIL;
|
|
}
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_icon_bitmap_id()
|
|
{
|
|
if (TargetWindow -> cached_props -> wm_hints.flags & IconPixmapHint) {
|
|
return (WOOL_OBJECT) WLNumber_make(TargetWindow -> cached_props ->
|
|
wm_hints.icon_pixmap);
|
|
} else {
|
|
return NIL;
|
|
}
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_US_position()
|
|
{
|
|
if (NoRoot(TargetWindow) -> status & IconStatus) {
|
|
if (TargetWindow -> cached_props -> wm_hints.flags & IconPositionHint)
|
|
return TRU;
|
|
} else {
|
|
if (TargetWindow && TargetWindow -> cached_props -> normal_hints.flags
|
|
& USPosition)
|
|
return TRU;
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_US_size()
|
|
{
|
|
if (TargetWindow && TargetWindow -> cached_props -> normal_hints.flags
|
|
& USSize)
|
|
return TRU;
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_P_position()
|
|
{
|
|
if (TargetWindow && TargetWindow -> cached_props -> normal_hints.flags
|
|
& PPosition)
|
|
return TRU;
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_P_size()
|
|
{
|
|
if (TargetWindow && TargetWindow -> cached_props -> normal_hints.flags
|
|
& PSize)
|
|
return TRU;
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_current_window_is_transient_for()
|
|
{
|
|
if (NoRoot(TargetWindow)
|
|
&& TargetWindow -> cached_props -> transient_for) {
|
|
return TargetWindow -> cached_props -> transient_for;
|
|
} else {
|
|
return NIL;
|
|
}
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_window_map_as_icon_get()
|
|
{
|
|
if ((TargetWindow && TargetWindow -> cached_props -> wm_hints.flags
|
|
& StateHint)
|
|
&& (TargetWindow -> cached_props -> wm_hints.initial_state == 3))
|
|
return TRU;
|
|
else
|
|
return NIL;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_window_map_as_icon_set(flag)
|
|
WOOL_OBJECT flag;
|
|
{
|
|
if (TargetWindow) {
|
|
TargetWindow -> cached_props -> wm_hints.flags |= StateHint;
|
|
TargetWindow -> cached_props -> wm_hints.initial_state
|
|
= (flag == NIL ? 1 : 3);
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
/*
|
|
* set focus on
|
|
* current client if no arg (do nothing if input hint is false)
|
|
* other window's client if arg
|
|
* if arg = NIL, rootwindow
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_set_focus(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
ClientWindow cw = TargetWindow;
|
|
|
|
if (!cw)
|
|
return NIL;
|
|
if (argc) {
|
|
if (argv[0] == (WOOL_Number) NIL) {
|
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot,
|
|
CurrentTime);
|
|
return TRU;
|
|
} else {
|
|
cw = (ClientWindow) argv[0] -> number;
|
|
}
|
|
}
|
|
if (GWM_No_set_focus)
|
|
return NIL;
|
|
if (GWM_check_input_focus_flag
|
|
|| ((cw -> cached_props -> wm_hints.flags & InputHint)
|
|
&&
|
|
(cw -> cached_props -> wm_hints.input) && cw -> client)) {
|
|
TrapXErrors(XSetInputFocus(dpy, cw -> client, RevertToPointerRoot,
|
|
CurrentTime));
|
|
}
|
|
if (cw -> type == ClientWindowClass) {
|
|
if (cw -> cached_props -> wm_take_focus) {
|
|
send_protocol_message(cw -> client, XA_WM_TAKE_FOCUS,
|
|
GWMTime, 0, 0);
|
|
if ((cw -> cached_props ->wm_hints.flags & InputHint) &&
|
|
(cw -> cached_props -> wm_hints.input)) {
|
|
TrapXErrors(XSetInputFocus(dpy, cw -> client,
|
|
RevertToPointerRoot, CurrentTime));
|
|
}
|
|
}
|
|
} else {
|
|
TrapXErrors(XSetInputFocus(dpy, cw -> hook, RevertToPointerRoot,
|
|
CurrentTime));
|
|
}
|
|
return TRU;
|
|
}
|
|
|
|
/*
|
|
* returns [x y modifiers screen]
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_current_mouse_position()
|
|
{
|
|
unsigned int ptrmask; /* state of ptr when queried */
|
|
Window root, sub_window;
|
|
int root_x, root_y, cur_x, cur_y;
|
|
WOOL_List wl_list = wool_list_make(4);
|
|
|
|
root=0;
|
|
XQueryPointer(dpy,
|
|
Context->root, &root, &sub_window,
|
|
&root_x, &root_y, &cur_x, &cur_y, &ptrmask);
|
|
increase_reference(wl_list -> list[0] = (WOOL_OBJECT)
|
|
WLNumber_make(cur_x));
|
|
increase_reference(wl_list -> list[1] = (WOOL_OBJECT)
|
|
WLNumber_make(cur_y));
|
|
increase_reference(wl_list -> list[2] = (WOOL_OBJECT)
|
|
WLNumber_make(ptrmask));
|
|
increase_reference(wl_list -> list[3] = (WOOL_OBJECT)
|
|
(root ? WLNumber_make(ScreenOfRoot(root))
|
|
: WLNumber_make(0)));
|
|
return (WOOL_OBJECT) wl_list;
|
|
}
|
|
|
|
/* warps pointer to pos
|
|
* (warp-pointer x y [window-relative-to])
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_warp_pointer(argc, argv)
|
|
int argc;
|
|
WOOL_Number argv[];
|
|
{
|
|
Window dest_w = None;
|
|
|
|
if (argc < 2 || argc > 3)
|
|
wool_error(BAD_NUMBER_OF_ARGS, argc);
|
|
must_be_number(argv[0], 0);
|
|
must_be_number(argv[1], 1);
|
|
if (argc == 3) {
|
|
must_be_number(argv[2], 2);
|
|
dest_w = ((Wob) (argv[2] -> number)) -> hook;
|
|
}
|
|
if (!GWM_never_warp_pointer) {
|
|
XWarpPointer(dpy, None, dest_w,
|
|
0, 0, 0, 0, argv[0] -> number, argv[1] -> number);
|
|
}
|
|
return NIL;
|
|
}
|
|
|
|
/*
|
|
* logical size of a window is size divided by resize increments (+ base)
|
|
*/
|
|
|
|
WOOL_OBJECT
|
|
wool_window_logical_size_get()
|
|
{
|
|
WOOL_List wl_list = wool_list_make(2);
|
|
unsigned int w = 0, h = 0;
|
|
|
|
if (TargetWindow -> client) {
|
|
pixel_to_logical_size(&(TargetWindow -> cached_props -> normal_hints),
|
|
TargetWindow -> inner_width, TargetWindow -> inner_height, &w, &h);
|
|
}
|
|
increase_reference(wl_list -> list[0] = (WOOL_OBJECT) WLNumber_make(w));
|
|
increase_reference(wl_list -> list[1] = (WOOL_OBJECT) WLNumber_make(h));
|
|
return (WOOL_OBJECT) wl_list;
|
|
}
|
|
|
|
WOOL_OBJECT
|
|
wool_window_logical_size_set(list)
|
|
WOOL_List list;
|
|
{
|
|
unsigned int w, h;
|
|
|
|
if (list -> type != WLList || list == (WOOL_List) NIL || list -> size != 2
|
|
|| list -> list[0] -> type != WLNumber
|
|
|| list -> list[1] -> type != WLNumber)
|
|
bad_argument(list, 0, "list of two numbers");
|
|
logical_to_pixel_size(&(TargetWindow -> cached_props -> normal_hints),
|
|
((WOOL_Number) list -> list[0]) -> number,
|
|
((WOOL_Number) list -> list[1]) -> number,
|
|
&w, &h);
|
|
XResizeWindow(dpy, TargetWindow -> client, w, h);
|
|
ReconfigureClientWindow(TargetWindow, TargetWindow -> client);
|
|
return NIL;
|
|
}
|
|
|
|
/* moves a window at x,y and gravity
|
|
* WARNING: xpt & yptr are pointers on SHORTS
|
|
*/
|
|
|
|
PlaceWinWithGravity(w, gravity, anchor_x, anchor_y, xptr, yptr, width, height,
|
|
borderwidth)
|
|
Window w;
|
|
int gravity, anchor_x, anchor_y;
|
|
short *xptr, *yptr;
|
|
unsigned int width, height, borderwidth;
|
|
{
|
|
int x = *xptr, y = *yptr;
|
|
|
|
switch((gravity - 1) % 3) {
|
|
case 0:
|
|
x = anchor_x;
|
|
break;
|
|
case 1:
|
|
x = anchor_x - width/2 - borderwidth;
|
|
break;
|
|
case 2:
|
|
x = anchor_x - width - 2*borderwidth;
|
|
break;
|
|
}
|
|
switch((gravity - 1) / 3) {
|
|
case 0:
|
|
y = anchor_y;
|
|
break;
|
|
case 1:
|
|
y = anchor_y - height/2 - borderwidth;
|
|
break;
|
|
case 2:
|
|
y = anchor_y - height - 2*borderwidth;
|
|
break;
|
|
}
|
|
if (*xptr != x || *yptr != y) {
|
|
*xptr = x;
|
|
*yptr = y;
|
|
XMoveWindow(dpy, w, x, y);
|
|
}
|
|
}
|