source: ldm/trunk/fuentes/wwm/client.c @ 855

Last change on this file since 855 was 855, checked in by mabarracus, 5 years ago
  • Updated sources to 2.2.18
  • Ported code from patches to apply in 2.2.18
File size: 4.7 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <X11/Xlib.h>
4#include <X11/Xutil.h>
5#include <X11/Xproto.h>
6#include <X11/Xatom.h>
7#include <X11/extensions/shape.h>
8
9#include "wwm.h"
10
11/*
12 * used all over the place.  return the client that has specified window as
13 * either window or parent
14 */
15
16Client *
17find_client(Window w)
18{
19    Client *c;
20
21    for (c = head_client; c; c = c->next)
22        if (w == c->parent || w == c->window)
23            return (c);
24    return (NULL);
25}
26
27Client *
28next_client_on_vdesk(Client * c)
29{
30    Client *newc = c, *marker = c;
31    int v = vdesk_get();
32
33    if (!c)
34        return NULL;
35
36    do
37        newc = (newc->next ? newc->next : head_client);
38    while (newc != marker && newc->vdesk != v);
39
40    return ((newc == marker) ? NULL : newc);
41}
42
43void
44set_wm_state(Client * c, int state)
45{
46    long data[2];
47
48    data[0] = (long) state;
49    data[1] = None;                              /* icon window */
50
51    XChangeProperty(display, c->window, xa_wm_state, xa_wm_state,
52                    sz_xInternAtomReply, PropModeReplace,
53                    (unsigned char *) data, 2);
54}
55
56void
57send_config(Client * c)
58{
59    XConfigureEvent ce;
60
61    ce.type = ConfigureNotify;
62    ce.event = c->window;
63    ce.window = c->window;
64    ce.x = c->x;
65    ce.y = c->y;
66    ce.width = c->width;
67    ce.height = c->height;
68    ce.border_width = c->border;
69    ce.above = None;
70    ce.override_redirect = False;
71
72    XSendEvent(display, c->window, False, StructureNotifyMask,
73               (XEvent *) & ce);
74    XSync(display, False);
75}
76
77void
78remove_client(Client * c, int from_cleanup)
79{
80    Window root = ROOTWINDOW;
81    Client *p;
82
83    XGrabServer(display);
84    ignore_xerror = True;
85
86    if (!from_cleanup) {
87        set_wm_state(c, WithdrawnState);
88        XRemoveFromSaveSet(display, c->window);
89    }
90
91    change_gravity(c, UNGRAVITATE);
92    XSetWindowBorderWidth(display, c->window, 1);
93    XReparentWindow(display, c->window, root, c->x, c->y);
94
95    if (c->parent)
96        XDestroyWindow(display, c->parent);
97
98    if (head_client == c)
99        head_client = c->next;
100    else
101        for (p = head_client; p && p->next; p = p->next)
102            if (p->next == c)
103                p->next = c->next;
104
105    if (c->size)
106        XFree(c->size);
107    if (current == c)
108        current = NULL;                          /* an enter event should set this up again */
109    free(c);
110
111    XSync(display, False);
112    ignore_xerror = False;
113    XUngrabServer(display);
114}
115
116void
117change_gravity(Client * c, int invert)
118{
119    int dx = 0, dy = 0;
120    int gravity = (c->size->flags & PWinGravity) ?
121        c->size->win_gravity : NorthWestGravity;
122
123    switch (gravity) {
124    case CenterGravity:
125    case StaticGravity:
126    case NorthWestGravity:
127    case NorthGravity:
128    case WestGravity:
129        dx = c->border;
130        dy = c->border;
131        break;
132    case NorthEastGravity:
133    case EastGravity:
134        dx = -(c->border);
135        dy = c->border;
136        break;
137    case SouthEastGravity:
138        dx = -(c->border);
139        dy = -(c->border);
140        break;
141    case SouthGravity:
142    case SouthWestGravity:
143        dx = c->border;
144        dy = -(c->border);
145        break;
146    }
147
148    if (invert) {
149        dx = -dx;
150        dy = -dy;
151    }
152
153    c->x += dx;
154    c->y += dy;
155}
156
157void
158send_wm_delete(Client * c)
159{
160    int i, n, found = 0;
161    Atom *protocols;
162
163    if (!c)
164        return;
165
166    if (XGetWMProtocols(display, c->window, &protocols, &n)) {
167        for (i = 0; i < n; i++)
168            if (protocols[i] == xa_wm_delete)
169                found++;
170        XFree(protocols);
171    }
172
173    if (found)
174        send_xmessage(c->window, xa_wm_protos, xa_wm_delete);
175    else
176        XKillClient(display, c->window);
177}
178
179int
180send_xmessage(Window w, Atom a, long x)
181{
182    XEvent ev;
183
184    ev.type = ClientMessage;
185    ev.xclient.window = w;
186    ev.xclient.message_type = a;
187    ev.xclient.format = 32;
188    ev.xclient.data.l[0] = x;
189    ev.xclient.data.l[1] = CurrentTime;
190
191    return (XSendEvent(display, w, False, NoEventMask, &ev));
192}
193
194void
195set_shape(Client * c)
196{
197    int i, b;
198    unsigned int u;             /* dummies */
199    int bounding_shaped;
200    Status retval;
201
202    if (!have_shape || !c)
203        return;
204
205    if (c->window == None || c->parent == None)
206        return;
207
208    /*
209     * Logic to decide if we have a shaped window cribbed from fvwm-2.5.10.
210     * Previous method (more than one rectangle returned from
211     * XShapeGetRectangles) worked _most_ of the time.
212     */
213
214    retval =
215        XShapeQueryExtents(display, c->window, &bounding_shaped, &i, &i,
216                           &u, &u, &b, &i, &i, &u, &u);
217    if (retval && bounding_shaped)
218        XShapeCombineShape(display, c->parent, ShapeBounding,
219                           c->border, c->border, c->window, ShapeBounding,
220                           ShapeSet);
221}
Note: See TracBrowser for help on using the repository browser.