/* * Copyright (C) 1993 Rob Nation * Copyright (C) 1995 Bo Yang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /************************************************************************** * * Assorted odds and ends * **************************************************************************/ #define LOCAL_DEBUG #include "../../configure.h" #include "asinternals.h" /****************************************************************************/ /* window management specifics - button ungrabbing convinience functions: */ /****************************************************************************/ inline void ungrab_window_buttons (Window w) { LOCAL_DEBUG_OUT ("w = %lX", w); XUngrabButton (dpy, AnyButton, AnyModifier, w); } inline void ungrab_window_keys (Window w) { XUngrabKey (dpy, AnyKey, AnyModifier, w); } /****************************************************************************** * Versions of grab primitives that circumvent modifier problems *****************************************************************************/ 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) { LOCAL_DEBUG_CALLER_OUT ("button = %d, w = %lX modifiers = %X", button, grab_window, modifiers); if (modifiers == AnyModifier) XGrabButton (dpy, button, AnyModifier, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor); else { register int i = 0; do { /* LOCAL_DEBUG_OUT( "grabbing button %d with mod %lX on window %lX", button, modifiers | lock_mods[i], grab_window ); */ XGrabButton (dpy, button, modifiers | lock_mods[i], grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor); if (lock_mods[i] == 0) break; } while (++i < MAX_LOCK_MODS); } } void MyXUngrabButton (unsigned button, unsigned modifiers, Window grab_window) { LOCAL_DEBUG_CALLER_OUT ("w = %lX", grab_window); if (modifiers == AnyModifier) XUngrabButton (dpy, button, AnyModifier, grab_window); else { register int i = 0; do { XUngrabButton (dpy, button, modifiers | lock_mods[i], grab_window); if (lock_mods[i] == 0) break; } while (++i < MAX_LOCK_MODS); } } void grab_window_buttons (Window w, ASFlagType context_mask) { register MouseButton *MouseEntry; LOCAL_DEBUG_OUT ("w = %lX, context = 0x%lX", w, context_mask); for (MouseEntry = Scr.Feel.MouseButtonRoot; MouseEntry; MouseEntry = MouseEntry->NextButton) { if (MouseEntry->fdata && get_flags (MouseEntry->Context, context_mask)) { LOCAL_DEBUG_OUT ("mouse fdata %p button %d + modifier %X has context %lx", MouseEntry->fdata, MouseEntry->Button, MouseEntry->Modifier, get_flags (MouseEntry->Context, context_mask)); if (MouseEntry->Button > 0) MyXGrabButton (MouseEntry->Button, MouseEntry->Modifier, w, True, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Default]); else { register int i = MAX_MOUSE_BUTTONS + 1; while (--i > 0) MyXGrabButton (i, MouseEntry->Modifier, w, True, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Default]); } } } } void grab_focus_click (Window w) { int i; LOCAL_DEBUG_CALLER_OUT ("w = %lX", w); if (w) { /* need to grab all buttons for window that we are about to unfocus */ for (i = 0; i < MAX_MOUSE_BUTTONS; i++) if (Scr.Feel.buttons2grab & (0x01 << i)) { MyXGrabButton (i + 1, 0, w, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Sys]); } } } void ungrab_focus_click (Window w) { LOCAL_DEBUG_CALLER_OUT ("w = %lX", w); if (w) { /* if we do click to focus, remove the grab on mouse events that * was made to detect the focus change */ register int i = 0; #if 0 register ASFlagType grab_btn_mask = Scr.Feel.buttons2grab << 1; while (++i <= MAX_MOUSE_BUTTONS) if (grab_btn_mask & (1 << i)) { MyXUngrabButton (i, 0, w); } #else for (i = 0; i < MAX_MOUSE_BUTTONS; i++) if (Scr.Feel.buttons2grab & (0x01 << i)) { MyXUngrabButton (i + 1, 0, w); } #endif } } /*********************************************************************** * Key grabbing : ***********************************************************************/ void grab_window_keys (Window w, ASFlagType context_mask) { FuncKey *tmp; for (tmp = Scr.Feel.FuncKeyRoot; tmp != NULL; tmp = tmp->next) if (get_flags (tmp->cont, context_mask)) { if (tmp->mods == AnyModifier) XGrabKey (dpy, tmp->keycode, AnyModifier, w, True, GrabModeAsync, GrabModeAsync); else { register int i = 0; do { /* combining modifiers with keys, * so to enable things like ScrollLock+Alt+A to work the same as Alt+A */ XGrabKey (dpy, tmp->keycode, tmp->mods | lock_mods[i], w, True, GrabModeAsync, GrabModeAsync); if (lock_mods[i] == 0) break; } while (++i < MAX_LOCK_MODS); } } } /****************************************************************************** * * Grab ClickToRaise button press events for a window * *****************************************************************************/ void GrabRaiseClick (ASWindow * t) { int b; for (b = 1; b <= MAX_MOUSE_BUTTONS; b++) { if (Scr.Feel.RaiseButtons & (1 << b)) MyXGrabButton (b, 0, t->w, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, Scr.Feel.cursors[ASCUR_Title]); } } /****************************************************************************** * * Ungrab ClickToRaise button press events to allow their use in applications * *****************************************************************************/ void UngrabRaiseClick (ASWindow * t) { int b; for (b = 1; b <= MAX_MOUSE_BUTTONS; b++) { if (Scr.Feel.RaiseButtons & (1 << b)) MyXUngrabButton (b, 0, t->w); } } /****************************************************************************** * * Recalculate the visibility flags * *****************************************************************************/ void UpdateVisibility (void) { #if 0 ASWindow *t, *s, *tbase; tbase = Scr.ASRoot.next; for (t = Scr.ASRoot.next; t != NULL; t = t->next) { int visible = 0; int tx1, ty1, tx2, ty2; if (t->flags & MAPPED) { tx1 = t->frame_x; ty1 = t->frame_y; if (t->flags & SHADED) { tx2 = t->frame_x + t->title_width; ty2 = t->frame_y + t->title_height; } else { tx2 = t->frame_x + t->frame_width; ty2 = t->frame_y + t->frame_height; } } else if (t->flags & ICONIFIED) { tx1 = t->icon_p_x; ty1 = t->icon_p_y; tx2 = t->icon_p_x + t->icon_p_width; ty2 = t->icon_p_y + t->icon_p_height; } else continue; if ((tx2 > 0) && (tx1 < Scr.MyDisplayWidth) && (ty2 > 0) && (ty1 < Scr.MyDisplayHeight)) { visible = VISIBLE; for (s = Scr.ASRoot.next; s != t; s = s->next) { if (get_flags (s->hints->flags, AS_Transient) && (s->hints->transient_for == t->w)) continue; else if (s->status->layer != t->status->layer) continue; if (s->flags & MAPPED) { if ((tx2 > s->frame_x) && (tx1 < s->frame_x + s->frame_width) && (ty2 > s->frame_y) && (ty1 < s->frame_y + s->frame_height)) { visible = 0; break; } } else if (s->flags & ICONIFIED) { if ((tx2 > s->icon_p_x) && (tx1 < s->icon_p_x + s->icon_p_width) && (ty2 > s->icon_p_y) && (ty1 < s->icon_p_y + s->icon_p_height)) { visible = 0; break; } } else if (s->flags & SHADED) { if ((tx2 > s->frame_x) && (tx1 < s->frame_x + s->title_width) && (ty2 > s->frame_y) && (ty1 < s->frame_y + s->title_height)) { visible = 0; break; } } } } if ((t->flags & VISIBLE) != visible) { t->flags ^= VISIBLE; if ((Scr.flags & ClickToRaise) && !(Scr.flags & ClickToFocus) && (t->flags & MAPPED)) { if (visible) UngrabRaiseClick (t); else GrabRaiseClick (t); } } } #endif }