1 /**
2 *
3 * Compiz group plugin
4 *
5 * queues.c
6 *
7 * Copyright : (C) 2006-2007 by Patrick Niklaus, Roi Cohen, Danny Baumann
8 * Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
9 * Roi Cohen <roico.beryl@gmail.com>
10 * Danny Baumann <maniac@opencompositing.org>
11 *
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 **/
24
25 #include "group-internal.h"
26
27 /*
28 * functions enqueuing pending notifies
29 *
30 */
31
32 /* forward declaration */
33 static Bool groupDequeueTimer (void *closure);
34
35 void
groupEnqueueMoveNotify(CompWindow * w,int dx,int dy,Bool immediate,Bool sync)36 groupEnqueueMoveNotify (CompWindow *w,
37 int dx,
38 int dy,
39 Bool immediate,
40 Bool sync)
41 {
42 GroupPendingMoves *move;
43
44 GROUP_SCREEN (w->screen);
45
46 move = malloc (sizeof (GroupPendingMoves));
47 if (!move)
48 return;
49
50 move->w = w;
51 move->dx = dx;
52 move->dy = dy;
53
54 move->immediate = immediate;
55 move->sync = sync;
56 move->next = NULL;
57
58 if (gs->pendingMoves)
59 {
60 GroupPendingMoves *temp;
61 for (temp = gs->pendingMoves; temp->next; temp = temp->next);
62
63 temp->next = move;
64 }
65 else
66 gs->pendingMoves = move;
67
68 if (!gs->dequeueTimeoutHandle)
69 {
70 gs->dequeueTimeoutHandle =
71 compAddTimeout (0, 0, groupDequeueTimer, (void *) w->screen);
72 }
73 }
74
75 static void
groupDequeueSyncs(GroupPendingSyncs * syncs)76 groupDequeueSyncs (GroupPendingSyncs *syncs)
77 {
78 GroupPendingSyncs *sync;
79
80 while (syncs)
81 {
82 sync = syncs;
83 syncs = sync->next;
84
85 GROUP_WINDOW (sync->w);
86 if (gw->needsPosSync)
87 {
88 syncWindowPosition (sync->w);
89 gw->needsPosSync = FALSE;
90 }
91
92 free (sync);
93 }
94
95 }
96
97 void
groupDequeueMoveNotifies(CompScreen * s)98 groupDequeueMoveNotifies (CompScreen *s)
99 {
100 GroupPendingMoves *move;
101 GroupPendingSyncs *syncs = NULL, *sync;
102
103 GROUP_SCREEN (s);
104
105 gs->queued = TRUE;
106
107 while (gs->pendingMoves)
108 {
109 move = gs->pendingMoves;
110 gs->pendingMoves = move->next;
111
112 moveWindow (move->w, move->dx, move->dy, TRUE, move->immediate);
113 if (move->sync)
114 {
115 sync = malloc (sizeof (GroupPendingSyncs));
116 if (sync)
117 {
118 GROUP_WINDOW (move->w);
119
120 gw->needsPosSync = TRUE;
121 sync->w = move->w;
122 sync->next = syncs;
123 syncs = sync;
124 }
125 }
126 free (move);
127 }
128
129 if (syncs)
130 groupDequeueSyncs (syncs);
131
132 gs->queued = FALSE;
133 }
134
135 void
groupEnqueueGrabNotify(CompWindow * w,int x,int y,unsigned int state,unsigned int mask)136 groupEnqueueGrabNotify (CompWindow *w,
137 int x,
138 int y,
139 unsigned int state,
140 unsigned int mask)
141 {
142 GroupPendingGrabs *grab;
143
144 GROUP_SCREEN (w->screen);
145
146 grab = malloc (sizeof (GroupPendingGrabs));
147 if (!grab)
148 return;
149
150 grab->w = w;
151 grab->x = x;
152 grab->y = y;
153
154 grab->state = state;
155 grab->mask = mask;
156 grab->next = NULL;
157
158 if (gs->pendingGrabs)
159 {
160 GroupPendingGrabs *temp;
161 for (temp = gs->pendingGrabs; temp->next; temp = temp->next);
162
163 temp->next = grab;
164 }
165 else
166 gs->pendingGrabs = grab;
167
168 if (!gs->dequeueTimeoutHandle)
169 {
170 gs->dequeueTimeoutHandle =
171 compAddTimeout (0, 0, groupDequeueTimer, (void *) w->screen);
172 }
173 }
174
175 static void
groupDequeueGrabNotifies(CompScreen * s)176 groupDequeueGrabNotifies (CompScreen *s)
177 {
178 GroupPendingGrabs *grab;
179
180 GROUP_SCREEN (s);
181
182 gs->queued = TRUE;
183
184 while (gs->pendingGrabs)
185 {
186 grab = gs->pendingGrabs;
187 gs->pendingGrabs = gs->pendingGrabs->next;
188
189 (*(grab->w)->screen->windowGrabNotify) (grab->w,
190 grab->x, grab->y,
191 grab->state, grab->mask);
192
193 free (grab);
194 }
195
196 gs->queued = FALSE;
197 }
198
199 void
groupEnqueueUngrabNotify(CompWindow * w)200 groupEnqueueUngrabNotify (CompWindow *w)
201 {
202 GroupPendingUngrabs *ungrab;
203
204 GROUP_SCREEN (w->screen);
205
206 ungrab = malloc (sizeof (GroupPendingUngrabs));
207
208 if (!ungrab)
209 return;
210
211 ungrab->w = w;
212 ungrab->next = NULL;
213
214 if (gs->pendingUngrabs)
215 {
216 GroupPendingUngrabs *temp;
217 for (temp = gs->pendingUngrabs; temp->next; temp = temp->next);
218
219 temp->next = ungrab;
220 }
221 else
222 gs->pendingUngrabs = ungrab;
223
224 if (!gs->dequeueTimeoutHandle)
225 {
226 gs->dequeueTimeoutHandle =
227 compAddTimeout (0, 0, groupDequeueTimer, (void *) w->screen);
228 }
229 }
230
231 static void
groupDequeueUngrabNotifies(CompScreen * s)232 groupDequeueUngrabNotifies (CompScreen *s)
233 {
234 GroupPendingUngrabs *ungrab;
235
236 GROUP_SCREEN (s);
237
238 gs->queued = TRUE;
239
240 while (gs->pendingUngrabs)
241 {
242 ungrab = gs->pendingUngrabs;
243 gs->pendingUngrabs = gs->pendingUngrabs->next;
244
245 (*(ungrab->w)->screen->windowUngrabNotify) (ungrab->w);
246
247 free (ungrab);
248 }
249
250 gs->queued = FALSE;
251 }
252
253 static Bool
groupDequeueTimer(void * closure)254 groupDequeueTimer (void *closure)
255 {
256 CompScreen *s = (CompScreen *) closure;
257
258 GROUP_SCREEN (s);
259
260 groupDequeueMoveNotifies (s);
261 groupDequeueGrabNotifies (s);
262 groupDequeueUngrabNotifies (s);
263
264 gs->dequeueTimeoutHandle = 0;
265
266 return FALSE;
267 }
268