-
Notifications
You must be signed in to change notification settings - Fork 0
/
WMAddOns.c
358 lines (305 loc) · 9.95 KB
/
WMAddOns.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xmd.h>
#include <WINGs/WINGsP.h>
#include "WMAddOns.h"
#define W_GetViewEventHandlers(x) (WMArray*)(((W_View*)x)->eventHandlers)
typedef struct W_MaskedEvents {
WMView *view;
WMArray *procs;
WMArray *data;
} W_MaskedEvents;
/*
* The following structure is taken from wlist.c of the version 0.92.0
* Window Maker sources. I don't think so but it _may_ fall under the LGPL:
* WINGs is copyright (c) Alfredo K. Kojima and is licensed through the GNU
* Library General Public License (LGPL).
*/
typedef struct W_List {
W_Class widgetClass;
W_View *view;
WMArray *items;
WMArray *selectedItems;
short itemHeight;
int topItem;
short fullFitLines;
void *clientData;
WMAction *action;
void *doubleClientData;
WMAction *doubleAction;
WMListDrawProc *draw;
WMHandlerID *idleID;
WMHandlerID *selectID;
WMScroller *vScroller;
Pixmap doubleBuffer;
struct {
unsigned int allowMultipleSelection:1;
unsigned int allowEmptySelection:1;
unsigned int userDrawn:1;
unsigned int userItemHeight:1;
unsigned int dontFitAll:1;
unsigned int redrawPending:1;
unsigned int buttonPressed:1;
unsigned int buttonWasPressed:1;
} flags;
} W_List;
typedef struct W_Window {
W_Class widgetClass;
W_View *view;
struct W_Window *nextPtr; /* next in the window list */
struct W_Window *owner;
char *title;
WMPixmap *miniImage; /* miniwindow */
char *miniTitle;
char *wname;
WMSize resizeIncrement;
WMSize baseSize;
WMSize minSize;
WMSize maxSize;
WMPoint minAspect;
WMPoint maxAspect;
WMPoint upos;
WMPoint ppos;
WMAction *closeAction;
void *closeData;
int level;
struct {
unsigned style:4;
unsigned configured:1;
unsigned documentEdited:1;
unsigned setUPos:1;
unsigned setPPos:1;
unsigned setAspect:1;
} flags;
} W_Window;
typedef struct {
CARD32 flags;
CARD32 window_style;
CARD32 window_level;
CARD32 reserved;
Pixmap miniaturize_pixmap; /* pixmap for miniaturize button */
Pixmap close_pixmap; /* pixmap for close button */
Pixmap miniaturize_mask; /* miniaturize pixmap mask */
Pixmap close_mask; /* close pixmap mask */
CARD32 extra_flags;
} GNUstepWMAttributes;
#define GSWindowStyleAttr (1<<0)
#define GSWindowLevelAttr (1<<1)
#define GSMiniaturizePixmapAttr (1<<3)
#define GSClosePixmapAttr (1<<4)
#define GSMiniaturizeMaskAttr (1<<5)
#define GSCloseMaskAttr (1<<6)
#define GSExtraFlagsAttr (1<<7)
void W_MaskedEventHandler(XEvent *event, void *data) {
W_MaskedEvents *events = (W_MaskedEvents*)data;
WMEventProc *proc = NULL;
unsigned int i;
for (i = 0; i < WMGetArrayItemCount(events->procs); i++) {
if (WMIsDraggingFromView(events->view) == False) {
proc = WMGetFromArray(events->procs, i);
(*proc)(event, WMGetFromArray(events->data, i));
} else {
/* *cough* evil *cough* hack... */
if (W_CLASS(events->view->self) == WC_List) {
((W_List*)(events->view->self))->flags.buttonWasPressed = 0;
((W_List*)(events->view->self))->flags.buttonPressed = 0;
}
}
}
}
WMMaskedEvents* WMMaskEvents(WMView* view) {
W_MaskedEvents *mask;
unsigned int i;
Bool changed = False;
mask = wmalloc(sizeof(W_MaskedEvents));
mask->view = view;
mask->procs = WMCreateArray(0);
mask->data = WMCreateArray(0);
for (i = 0; i < WMGetArrayItemCount(W_GetViewEventHandlers(view)); i++) {
W_EventHandler *h = (W_EventHandler*) WMGetFromArray(W_GetViewEventHandlers(view), i);
if (h->eventMask == (ButtonPressMask|ButtonReleaseMask|
EnterWindowMask|LeaveWindowMask|ButtonMotionMask)) {
WMAddToArray(mask->procs, h->proc);
WMAddToArray(mask->data, h->clientData);
/* we change only the first handler to our one, because they seem
to be processed upside-down and we want the dnd-handler to be processed
first. */
if (changed == False) {
h->proc = W_MaskedEventHandler;
h->clientData = (void*) mask;
changed = True;
} else {
WMDeleteEventHandler(view, h->eventMask, h->proc, h->clientData);
}
}
}
return mask;
}
void WMFreeMaskedEvents(WMMaskedEvents* maskev) {
W_MaskedEvents* mask = (W_MaskedEvents*)maskev;
WMFreeArray(mask->procs);
WMFreeArray(mask->data);
wfree(mask);
return;
}
Window WMGetLeader(W_Screen *scr) {
return scr->groupLeader;
}
void WMWindowChangeStyle(W_Window *win, int style) {
if (win->flags.style == style) return;
XFlush(win->view->screen->display);
win->flags.style = style;
if (win->view->flags.realized) {
WMSetWindowLevel(win, WMNormalWindowLevel);
/* GNUstepWMAttributes data;
data.flags = GSWindowStyleAttr; // GSWindowStyleAttr
data.window_style = style;
XChangeProperty(win->view->screen->display, WMWidgetXID(win), win->view->screen->attribsAtom,
win->view->screen->attribsAtom, 32, PropModeReplace, (unsigned char*)&data, 9);
}
if (win->view->flags.mapped) {
// FIXME: this does not work :(
XPropertyEvent xev;
memset(&xev, 0, sizeof(XPropertyEvent));
xev.type = PropertyNotify;
xev.state = PropertyNewValue;
xev.atom = win->view->screen->attribsAtom;
XSendEvent(win->view->screen->display, win->view->screen->rootWin, False, PropertyChangeMask, (XEvent*)&xev);
//WMPoint pos = win->view->ppos;
//WMUnmapWidget(win);
//WMSetWindowInitialPosition(win, pos.x, pos.y);
//WMMapWidget(win);*/
}
}
void WMScreenAbortDrag(W_Screen *screen) {
if (!screen || !screen->dragInfo.sourceInfo) return;
W_DragSourceInfo *source = screen->dragInfo.sourceInfo;
W_DragSourceStopTimer();
// inform the other client
if (source->destinationWindow)
W_SendDnDClientMessage(screen->display, source->destinationWindow,
screen->xdndLeaveAtom, WMViewXID(source->sourceView), 0, 0, 0, 0);
WMDeleteSelectionHandler(source->sourceView, screen->xdndSelectionAtom, CurrentTime);
wfree(source->selectionProcs);
if (source->sourceView->dragSourceProcs->endedDrag)
source->sourceView->dragSourceProcs->endedDrag(source->sourceView, &source->imageLocation, False);
if (source->icon)
XDestroyWindow(screen->display, source->icon);
if (source->dragCursor != None) {
XDefineCursor(screen->display, screen->rootWin, screen->defaultCursor);
XFreeCursor(screen->display, source->dragCursor);
}
wfree(source);
screen->dragInfo.sourceInfo = NULL;
}
Atom WMGetXdndPositionAtom(W_Screen *screen) {
return screen->xdndPositionAtom;
}
Atom WMGetXdndLeaveAtom(W_Screen *screen) {
return screen->xdndLeaveAtom;
}
Window WMGetRootWin(W_Screen *screen) {
return screen->rootWin;
}
Bool WMSetGrayColor(W_Screen *scr, WMColor *col) {
if (!scr || !col) return False;
WMReleaseColor(scr->gray);
scr->gray = col;
return True;
}
Bool WMSetDarkGrayColor(W_Screen *scr, WMColor *col) {
if (!scr || !col) return False;
WMReleaseColor(scr->darkGray);
scr->darkGray = col;
return True;
}
Bool WMSetWhiteColor(W_Screen *scr, WMColor *col) {
if (!scr || !col) return False;
WMReleaseColor(scr->white);
scr->white = col;
return True;
}
Bool WMSetBlackColor(W_Screen *scr, WMColor *col) {
if (!scr || !col) return False;
WMReleaseColor(scr->black);
scr->black = col;
return True;
}
void WMSetUDColorForKey(WMUserDefaults *s, WMColor *col, char *key) {
static char colstr[8];
snprintf(colstr, sizeof(colstr), "#%02x%02x%02x",
WMRedComponentOfColor(col) >> 8,
WMBlueComponentOfColor(col) >> 8,
WMGreenComponentOfColor(col) >> 8);
WMSetUDStringForKey(s, colstr, key);
}
WMColor* WMGetUDColorForKey(WMUserDefaults *s, char *key, WMScreen *scr) {
char *str = WMGetUDStringForKey(s, key);
if (!str || strlen(str) != 7) return NULL;
char *nptr;
long color = strtol(str+1, &nptr, 16);
if (*nptr != '\0') return NULL;
return WMCreateRGBColor(scr, (color >> 16) << 8, color & 0xff00, (color & 0xff) << 8, False);
}
typedef struct {
int statusPipe[2];
WMCallback *callback;
void *clientData;
WMHandlerID hid;
struct sigaction act;
} WMSigInfo;
static WMSigInfo wmsiginfo[NSIG];
static sigset_t wmsigset;
void pipedsignalhandler(int sig) {
#ifdef DEBUG
fprintf(stderr, "SIGNAL %i received.\n", sig);
fflush(stderr);
#endif
char buf;
if (sig <= 0 || sig >= NSIG) return;
//while (read(wmsiginfo[sig].statusPipe[0], &buf, 1)) ;
if (wmsiginfo[sig].callback) {
write(wmsiginfo[sig].statusPipe[1], &buf, 1);
}
}
void pipeinputhandler(int fd, int mask, void *data) {
#ifdef DEBUG
fprintf(stderr, "pipe input %i received.\n", data);
fflush(stderr);
#endif
char buf;
int sig = (int) data;
while (read(wmsiginfo[sig].statusPipe[0], &buf, 1) > 0) {
if (wmsiginfo[sig].callback) {
(*wmsiginfo[sig].callback)(wmsiginfo[sig].clientData);
}
}
}
WMHandlerID WMAddPipedSignalHandler(int sig, WMCallback *cb, void *data) {
if (pipe(wmsiginfo[sig].statusPipe) == -1) {
perror("could not set up signal handling pipe.\n");
return NULL;
}
wmsiginfo[sig].callback = cb;
wmsiginfo[sig].clientData = data;
wmsiginfo[sig].hid = WMAddInputHandler(wmsiginfo[sig].statusPipe[0], 1,
pipeinputhandler, (void*) sig);
struct sigaction act;
act.sa_handler = pipedsignalhandler;
sigfillset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sigaction(sig, &act, &wmsiginfo[sig].act);
return (WMHandlerID)sig;
}
void WMDeletePipedSignalHandler(WMHandlerID hid) {
int sig = (int) hid;
char buf;
sigaction(sig, &wmsiginfo[sig].act, NULL);
WMDeleteInputHandler(wmsiginfo[sig].hid);
close(wmsiginfo[sig].statusPipe[1]);
close(wmsiginfo[sig].statusPipe[0]);
wmsiginfo[sig].hid = NULL;
wmsiginfo[sig].callback = NULL;
wmsiginfo[sig].clientData = NULL;
return;
}