1 /*
2 * Copyright (C) 1993 Rob Nation
3 * Copyright (C) 1995 Bo Yang
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21 /**************************************************************************
22 *
23 * Assorted odds and ends
24 *
25 **************************************************************************/
26 #define LOCAL_DEBUG
27
28 #include "../../configure.h"
29
30 #include "asinternals.h"
31
32 /****************************************************************************/
33 /* window management specifics - button ungrabbing convinience functions: */
34 /****************************************************************************/
ungrab_window_buttons(Window w)35 inline void ungrab_window_buttons (Window w)
36 {
37 LOCAL_DEBUG_OUT ("w = %lX", w);
38 XUngrabButton (dpy, AnyButton, AnyModifier, w);
39 }
40
ungrab_window_keys(Window w)41 inline void ungrab_window_keys (Window w)
42 {
43 XUngrabKey (dpy, AnyKey, AnyModifier, w);
44 }
45
46 /******************************************************************************
47 * Versions of grab primitives that circumvent modifier problems
48 *****************************************************************************/
49 void
MyXGrabButton(unsigned button,unsigned modifiers,Window grab_window,Bool owner_events,unsigned event_mask,int pointer_mode,int keyboard_mode,Window confine_to,Cursor cursor)50 MyXGrabButton (unsigned button, unsigned modifiers,
51 Window grab_window, Bool owner_events, unsigned event_mask,
52 int pointer_mode, int keyboard_mode, Window confine_to,
53 Cursor cursor)
54 {
55 LOCAL_DEBUG_CALLER_OUT ("button = %d, w = %lX modifiers = %X", button,
56 grab_window, modifiers);
57 if (modifiers == AnyModifier)
58 XGrabButton (dpy, button, AnyModifier, grab_window,
59 owner_events, event_mask, pointer_mode, keyboard_mode,
60 confine_to, cursor);
61 else {
62 register int i = 0;
63 do {
64 /* LOCAL_DEBUG_OUT( "grabbing button %d with mod %lX on window %lX", button, modifiers | lock_mods[i], grab_window ); */
65 XGrabButton (dpy, button, modifiers | lock_mods[i], grab_window,
66 owner_events, event_mask, pointer_mode, keyboard_mode,
67 confine_to, cursor);
68 if (lock_mods[i] == 0)
69 break;
70 } while (++i < MAX_LOCK_MODS);
71 }
72 }
73
74 void
MyXUngrabButton(unsigned button,unsigned modifiers,Window grab_window)75 MyXUngrabButton (unsigned button, unsigned modifiers, Window grab_window)
76 {
77 LOCAL_DEBUG_CALLER_OUT ("w = %lX", grab_window);
78 if (modifiers == AnyModifier)
79 XUngrabButton (dpy, button, AnyModifier, grab_window);
80 else {
81 register int i = 0;
82 do {
83 XUngrabButton (dpy, button, modifiers | lock_mods[i], grab_window);
84 if (lock_mods[i] == 0)
85 break;
86 } while (++i < MAX_LOCK_MODS);
87 }
88 }
89
grab_window_buttons(Window w,ASFlagType context_mask)90 void grab_window_buttons (Window w, ASFlagType context_mask)
91 {
92 register MouseButton *MouseEntry;
93 LOCAL_DEBUG_OUT ("w = %lX, context = 0x%lX", w, context_mask);
94 for (MouseEntry = Scr.Feel.MouseButtonRoot; MouseEntry;
95 MouseEntry = MouseEntry->NextButton) {
96 if (MouseEntry->fdata && get_flags (MouseEntry->Context, context_mask)) {
97 LOCAL_DEBUG_OUT
98 ("mouse fdata %p button %d + modifier %X has context %lx",
99 MouseEntry->fdata, MouseEntry->Button, MouseEntry->Modifier,
100 get_flags (MouseEntry->Context, context_mask));
101 if (MouseEntry->Button > 0)
102 MyXGrabButton (MouseEntry->Button, MouseEntry->Modifier, w,
103 True, ButtonPressMask | ButtonReleaseMask,
104 GrabModeAsync, GrabModeAsync, None,
105 Scr.Feel.cursors[ASCUR_Default]);
106 else {
107 register int i = MAX_MOUSE_BUTTONS + 1;
108 while (--i > 0)
109 MyXGrabButton (i, MouseEntry->Modifier, w,
110 True, ButtonPressMask | ButtonReleaseMask,
111 GrabModeAsync, GrabModeAsync, None,
112 Scr.Feel.cursors[ASCUR_Default]);
113 }
114 }
115 }
116 }
117
118
grab_focus_click(Window w)119 void grab_focus_click (Window w)
120 {
121 int i;
122 LOCAL_DEBUG_CALLER_OUT ("w = %lX", w);
123 if (w) { /* need to grab all buttons for window that we are about to unfocus */
124 for (i = 0; i < MAX_MOUSE_BUTTONS; i++)
125 if (Scr.Feel.buttons2grab & (0x01 << i)) {
126 MyXGrabButton (i + 1, 0, w, True, ButtonPressMask, GrabModeSync,
127 GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Sys]);
128 }
129 }
130 }
131
ungrab_focus_click(Window w)132 void ungrab_focus_click (Window w)
133 {
134 LOCAL_DEBUG_CALLER_OUT ("w = %lX", w);
135 if (w) { /* if we do click to focus, remove the grab on mouse events that
136 * was made to detect the focus change */
137 register int i = 0;
138 #if 0
139 register ASFlagType grab_btn_mask = Scr.Feel.buttons2grab << 1;
140 while (++i <= MAX_MOUSE_BUTTONS)
141 if (grab_btn_mask & (1 << i)) {
142 MyXUngrabButton (i, 0, w);
143 }
144 #else
145 for (i = 0; i < MAX_MOUSE_BUTTONS; i++)
146 if (Scr.Feel.buttons2grab & (0x01 << i)) {
147 MyXUngrabButton (i + 1, 0, w);
148 }
149 #endif
150 }
151 }
152
153
154 /***********************************************************************
155 * Key grabbing :
156 ***********************************************************************/
grab_window_keys(Window w,ASFlagType context_mask)157 void grab_window_keys (Window w, ASFlagType context_mask)
158 {
159 FuncKey *tmp;
160 for (tmp = Scr.Feel.FuncKeyRoot; tmp != NULL; tmp = tmp->next)
161 if (get_flags (tmp->cont, context_mask)) {
162 if (tmp->mods == AnyModifier)
163 XGrabKey (dpy, tmp->keycode, AnyModifier, w, True, GrabModeAsync,
164 GrabModeAsync);
165 else {
166 register int i = 0;
167 do { /* combining modifiers with <Lock> keys,
168 * so to enable things like ScrollLock+Alt+A to work the same as Alt+A */
169 XGrabKey (dpy, tmp->keycode, tmp->mods | lock_mods[i], w, True,
170 GrabModeAsync, GrabModeAsync);
171 if (lock_mods[i] == 0)
172 break;
173 } while (++i < MAX_LOCK_MODS);
174 }
175 }
176 }
177
178
179
180 /******************************************************************************
181 *
182 * Grab ClickToRaise button press events for a window
183 *
184 *****************************************************************************/
GrabRaiseClick(ASWindow * t)185 void GrabRaiseClick (ASWindow * t)
186 {
187 int b;
188
189 for (b = 1; b <= MAX_MOUSE_BUTTONS; b++) {
190 if (Scr.Feel.RaiseButtons & (1 << b))
191 MyXGrabButton (b, 0, t->w, True, ButtonPressMask, GrabModeSync,
192 GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Title]);
193 }
194 }
195
196 /******************************************************************************
197 *
198 * Ungrab ClickToRaise button press events to allow their use in applications
199 *
200 *****************************************************************************/
UngrabRaiseClick(ASWindow * t)201 void UngrabRaiseClick (ASWindow * t)
202 {
203 int b;
204
205 for (b = 1; b <= MAX_MOUSE_BUTTONS; b++) {
206 if (Scr.Feel.RaiseButtons & (1 << b))
207 MyXUngrabButton (b, 0, t->w);
208 }
209 }
210
211 /******************************************************************************
212 *
213 * Recalculate the visibility flags
214 *
215 *****************************************************************************/
216
UpdateVisibility(void)217 void UpdateVisibility (void)
218 {
219 #if 0
220 ASWindow *t, *s, *tbase;
221
222 tbase = Scr.ASRoot.next;
223 for (t = Scr.ASRoot.next; t != NULL; t = t->next) {
224 int visible = 0;
225 int tx1, ty1, tx2, ty2;
226
227 if (t->flags & MAPPED) {
228 tx1 = t->frame_x;
229 ty1 = t->frame_y;
230 if (t->flags & SHADED) {
231 tx2 = t->frame_x + t->title_width;
232 ty2 = t->frame_y + t->title_height;
233 } else {
234 tx2 = t->frame_x + t->frame_width;
235 ty2 = t->frame_y + t->frame_height;
236 }
237 } else if (t->flags & ICONIFIED) {
238 tx1 = t->icon_p_x;
239 ty1 = t->icon_p_y;
240 tx2 = t->icon_p_x + t->icon_p_width;
241 ty2 = t->icon_p_y + t->icon_p_height;
242 } else
243 continue;
244
245 if ((tx2 > 0) && (tx1 < Scr.MyDisplayWidth) && (ty2 > 0)
246 && (ty1 < Scr.MyDisplayHeight)) {
247 visible = VISIBLE;
248 for (s = Scr.ASRoot.next; s != t; s = s->next) {
249 if (get_flags (s->hints->flags, AS_Transient)
250 && (s->hints->transient_for == t->w))
251 continue;
252 else if (s->status->layer != t->status->layer)
253 continue;
254
255 if (s->flags & MAPPED) {
256 if ((tx2 > s->frame_x) && (tx1 < s->frame_x + s->frame_width) &&
257 (ty2 > s->frame_y) && (ty1 < s->frame_y + s->frame_height)) {
258 visible = 0;
259 break;
260 }
261 } else if (s->flags & ICONIFIED) {
262 if ((tx2 > s->icon_p_x) && (tx1 < s->icon_p_x + s->icon_p_width)
263 && (ty2 > s->icon_p_y)
264 && (ty1 < s->icon_p_y + s->icon_p_height)) {
265 visible = 0;
266 break;
267 }
268 } else if (s->flags & SHADED) {
269 if ((tx2 > s->frame_x) && (tx1 < s->frame_x + s->title_width) &&
270 (ty2 > s->frame_y) && (ty1 < s->frame_y + s->title_height)) {
271 visible = 0;
272 break;
273 }
274 }
275 }
276 }
277 if ((t->flags & VISIBLE) != visible) {
278 t->flags ^= VISIBLE;
279 if ((Scr.flags & ClickToRaise) && !(Scr.flags & ClickToFocus)
280 && (t->flags & MAPPED)) {
281 if (visible)
282 UngrabRaiseClick (t);
283 else
284 GrabRaiseClick (t);
285 }
286 }
287 }
288 #endif
289 }
290