?? events.c
字號:
/* $Id: events.c,v 1.1 2004/08/28 19:25:45 dannybackx Exp $ *//*****************************************************************************//** Copyright 1988 by Evans & Sutherland Computer Corporation, **//** Salt Lake City, Utah **//** Portions Copyright 1989 by the Massachusetts Institute of Technology **//** Cambridge, Massachusetts **//** **//** All Rights Reserved **//** **//** Permission to use, copy, modify, and distribute this software and **//** its documentation for any purpose and without fee is hereby **//** granted, provided that the above copyright notice appear in all **//** copies and that both that copyright notice and this permis- **//** sion notice appear in supporting documentation, and that the **//** names of Evans & Sutherland and M.I.T. not be used in advertising **//** in publicity pertaining to distribution of the software without **//** specific, written prior permission. **//** **//** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **//** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **//** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **//** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **//** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **//** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **//** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **//** OR PERFORMANCE OF THIS SOFTWARE. **//*****************************************************************************//**************************************************************************** * This module is based on Twm, but has been siginificantly modified * by Rob Nation ****************************************************************************//*********************************************************************** * The rest of it is all my fault -- MLM * mwm - "LessTif Window Manager" ***********************************************************************/#include <LTconfig.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#include <Xm/XmosP.h>#if XmVERSION >= 2#include <XmI/XmI.h>#endif#include <Xm/Xm.h>#include <Xm/MwmUtil.h>#include <X11/extensions/shape.h>#include "mwm.h"/* * shorthand defines */#define MAX_NAME_LEN 200L /* truncate to this many */#define MAX_ICON_NAME_LEN 200L /* ditto */#define MOD_MASK (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|\ Mod4Mask | Mod5Mask)static int ShapeEventBase, ShapeErrorBase;/* * Waits Mwm.click_time, or until it is evident that the user is not * clicking, but is moving the cursor. */static Booleanis_click(ScreenInfo *scr, int x, int y, XEvent *d){ int xcurrent, ycurrent, total = 0; XEvent trash; xcurrent = x; ycurrent = y;#if 0 XAllowEvents(dpy, ReplayPointer, CurrentTime);#endif while ((total < Mwm.click_time) && (x - xcurrent < Mwm.move_threshold) && (x - xcurrent > -Mwm.move_threshold) && (y - ycurrent < Mwm.move_threshold) && (y - ycurrent > -Mwm.move_threshold)) { _XmMicroSleep(10000); total += 10; if (XCheckMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask, &trash)) { MISC_StashEventTime(&trash); if (trash.xbutton.button == d->xbutton.button) { *d = trash; return True; } } if (XCheckMaskEvent(dpy, ButtonMotionMask | PointerMotionMask, &trash)) { xcurrent = trash.xmotion.x_root; ycurrent = trash.xmotion.y_root; MISC_StashEventTime(&trash); } } return False;}/* * This procedure handles both a client changing its own colormap, and * a client explicitly installing its colormap itself (only the window * manager should do that, so we must set it correctly). */static voidcolor_map_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XColormapEvent *cevent = (XColormapEvent *)event; Boolean reinstall = False; if (!win) return;#ifdef __cplusplus if (cevent->c_new)#else if (cevent->new)#endif { XGetWindowAttributes(dpy, win->w, &(win->attr)); if (win == scr->mwm_colormap && win->number_cmap_windows == 0) scr->last_cmap = win->attr.colormap; reinstall = True; } else if ((cevent->state == ColormapUninstalled) && (scr->last_cmap == cevent->colormap)) { /* Some window installed its colormap, change it back */ reinstall = True; } while (XCheckTypedEvent(dpy, ColormapNotify, event)) { if (XFindContext(dpy, cevent->window, MwmContext, (XPointer *)&win) == XCNOENT) win = NULL;#ifdef __cplusplus if ((win) && (cevent->c_new))#else if ((win) && (cevent->new))#endif { XGetWindowAttributes(dpy, win->w, &(win->attr)); if (win == scr->mwm_colormap && win->number_cmap_windows == 0) scr->last_cmap = win->attr.colormap; reinstall = True; } else if ((win) && (cevent->state == ColormapUninstalled) && (scr->last_cmap == cevent->colormap)) { /* Some window installed its colormap, change it back */ reinstall = True; } else if ((win) && (cevent->state == ColormapInstalled) && (scr->last_cmap == cevent->colormap)) { /* The last color map installed was the correct one. Don't * change anything */ reinstall = False; } } if (reinstall) XInstallColormap(dpy, scr->last_cmap);}/* * handles focus in events */static voidfocus_in(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XEvent d; Window w; w = event->xany.window; while (XCheckTypedEvent(dpy, FocusIn, &d)) w = d.xany.window; if (XFindContext(dpy, w, MwmContext, (XPointer *)&win) == XCNOENT) win = NULL; if (!win) DEC_DrawDecorations(scr, scr->mwm_highlight, False, True, True, None); else if (win != scr->mwm_highlight) DEC_DrawDecorations(scr, win, True, True, True, None); if (win && Mwm.colormap_focus_policy == XmKEYBOARD) COLOR_InstallWindowColorMap(scr, win);}/* * this function deals with bad focus tracks * MLM: 6/??/98. Deal with what seems is a race condition between the * toolkit and the window manager. When we set the input focus in * the unmap_notify() function, it can sometimes implicitly fail without * our knowing it. I believe this is a race condition where the toolkit * calls XSetInputFocus() when dealing with the menu system. The net * result is that we sometimes do not receive the FocusIn event we expect; * therefore the application terminates, and focus reverts to None. * We find out about that here. */static voidfocus_out(ScreenInfo *scr, MwmWindow *win, XEvent *event){ Window focusBug; int rt; XGetInputFocus(dpy, &focusBug, &rt); if (win == NULL && scr->mwm_focus != NULL && focusBug == None) { XSetInputFocus(dpy, scr->mwm_focus->w, RevertToParent, CurrentTime); }}/* * key press event handler */static voidkey_press(ScreenInfo *scr, MwmWindow *win, XEvent *event){ FuncKey *key; unsigned int modifier; Window dummy; if (event->xkey.window == scr->shield_win) { XBell(dpy, 100); return; } scr->event_context = EVENT_GetContext(scr, win, event, &dummy); modifier = (event->xkey.state & MOD_MASK); for (key = scr->keys; key != NULL; key = key->next) { scr->mwm_event = win; /* Here's a real hack - some systems have two keys with the * same keysym and different keycodes. This converts all * the cases to one keycode. */ event->xkey.keycode = XKeysymToKeycode(dpy, XKeycodeToKeysym(dpy, event->xkey.keycode, 0)); if ((key->keycode == event->xkey.keycode) && ((key->mods == (modifier & (~LockMask))) || (key->mods == AnyModifier)) && (key->cont & scr->event_context)) { FUNC_Execute(scr, key->func, key->action, event->xany.window, win, event, scr->event_context, key->val1, key->val2, key->val1_unit, key->val2_unit, key->menu); return; } } /* if we get here, no function key was bound to the key. Send it * to the client if it was in a window we know about. */ if (win) { if (event->xkey.window != win->w) { event->xkey.window = win->w; XSendEvent(dpy, win->w, False, KeyPressMask, event); } } scr->mwm_event = NULL;}/* * property notify event handler */static voidproperty_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ char *prop = NULL; Atom actual = None; int actual_format; unsigned long nitems, bytesafter; if ((!win) || (XGetGeometry(dpy, win->w, &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0)) return; switch (event->xproperty.atom) { case XA_WM_NAME: if (XGetWindowProperty(dpy, win->w, event->xproperty.atom, 0L, MAX_NAME_LEN, False, XA_STRING, &actual, &actual_format, &nitems, &bytesafter, (unsigned char **)&prop) != Success || actual == None) return; if (!prop) prop = NoName; WIN_FreeNames(win, True, False); win->name = prop; /* fix the name in the title bar */ if (!(win->flags & ICONIFIED)) DEC_DrawTitleBar(scr, win, (scr->mwm_highlight == win), True); /* * if the icon name is NoName, set the name of the icon to be * the same as the window */ if (win->icon_active_label == NoName) { win->icon_active_label = win->name; ICON_UpdateWindow(scr, win, False); } break; case XA_WM_ICON_NAME: if (XGetWindowProperty(dpy, win->w, event->xproperty.atom, 0, MAX_ICON_NAME_LEN, False, XA_STRING, &actual, &actual_format, &nitems, &bytesafter, (unsigned char **)&prop) != Success || actual == None) return; if (!prop) prop = NoName; WIN_FreeNames(win, False, True); win->icon_label = prop; ICON_UpdateWindow(scr, win, False); break; case XA_WM_HINTS: if (win->wmhints) XFree((char *)win->wmhints); win->wmhints = XGetWMHints(dpy, event->xany.window); if (win->wmhints == NULL) return; if ((win->wmhints->flags & IconPixmapHint) || (win->wmhints->flags & IconWindowHint)) { if (win->icon_w) XDestroyWindow(dpy, win->icon_w); XDeleteContext(dpy, win->icon_w, MwmContext); if (win->flags & ICON_OURS) { if (win->icon_pixmap_w != None) { XDestroyWindow(dpy, win->icon_pixmap_w); XDeleteContext(dpy, win->icon_pixmap_w, MwmContext); } } else XUnmapWindow(dpy, win->icon_pixmap_w); win->icon_w = None; win->icon_pixmap_w = None; win->icon_pixmap = (Window)NULL; if (win->flags & ICONIFIED) { win->flags &= ~ICONIFIED; win->flags &= ~ICON_UNMAPPED; ICON_CreateWindow(scr, win, win->icon_x_loc, win->icon_y_loc); WIN_Lower(scr, win); ICON_AutoPlace(scr, win); if (win->Desk == scr->current_desk) { if (win->icon_w) XMapWindow(dpy, win->icon_w); if (win->icon_pixmap_w != None) XMapWindow(dpy, win->icon_pixmap_w); } win->flags |= ICONIFIED; ICON_DrawWindow(scr, win); } } break; case XA_WM_NORMAL_HINTS: PROP_GetWindowSizeHints(win); break; default: if (event->xproperty.atom == XA_WM_PROTOCOLS) { PROP_GetWmProtocols(win); } else if (event->xproperty.atom == XA_WM_COLORMAP_WINDOWS) { PROP_GetWmColormapWindows(win); /* frees old data */ COLOR_InstallWindowColorMap(scr, scr->mwm_colormap); } else if (event->xproperty.atom == XA_WM_STATE) { if ((Mwm.keyboard_focus_policy == XmEXPLICIT) && (win == scr->mwm_focus) && (win != NULL)) { scr->mwm_focus = NULL; WIN_SetFocusInTree(win); WIN_SetFocus(scr, win->w, win); MISC_SetFocusSequence(scr); } } else if (event->xproperty.atom == XA_MWM_HINTS) { if (win) { int width, height; PROP_GetMwmHints(win); DEC_ReselectDecorations(scr, win); win->frame_width = win->attr.width + 2 * win->boundary_width + 2 * win->matte_width; win->frame_height = win->attr.height + win->title_height + 2 * win->boundary_width + 2 * win->matte_width; WIN_ConstrainWindow(scr, win, &win->frame_width, &win->frame_height); width = win->frame_width; win->frame_width = 0; height = win->frame_height; win->frame_height = 0; DEC_ConfigureDecorations(scr, win, win->frame_x, win->frame_y, width, height, True); if (scr->mwm_highlight == win) { scr->mwm_highlight = NULL; DEC_DrawDecorations(scr, win, True, True, True, None); } else DEC_DrawDecorations(scr, win, False, False, True, None); } } else if (event->xproperty.atom == XA_MWM_MENU) { if (win) { if (win->mwm_menu) XFree((char *)win->mwm_menu); MENU_DestroyWindowMenu(scr, win); PROP_GetMwmMenu(win); MENU_BuildWindowMenu(scr, win); } } else if (event->xproperty.atom == XA_MWM_MESSAGES) { if (win) { if (win->mwm_messages) XFree((char *)win->mwm_messages); PROP_GetMwmMessages(win); } } }}/* * client message event handler */static voidclient_message(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XEvent button; if ((event->xclient.message_type == XA_WM_CHANGE_STATE) && (win) && (event->xclient.data.l[0] == IconicState) && !(win->flags & ICONIFIED)) { XQueryPointer(dpy, scr->root_win, &JunkRoot, &JunkChild, &(button.xmotion.x_root), &(button.xmotion.y_root), &JunkX, &JunkY, &JunkMask); button.type = 0; FUNC_Execute(scr, F_ICONIFY, NULLSTR, event->xany.window, win, &button, C_FRAME, 0, 0, 0, 0, (MenuRoot *) 0); }}/* * expose event handler */static voidexpose(ScreenInfo *scr, MwmWindow *win, XEvent *event){ if (event->xexpose.count != 0) return; if (win) { if ((win->w == scr->pager_win) || (win->w == scr->pager_child_win)) { PAGER_Redraw(scr); } if ((event->xany.window == win->title)) { DEC_DrawTitleBar(scr, win, (scr->mwm_highlight == win), False); } else { DEC_DrawDecorations(scr, win, (scr->mwm_highlight == win), True, True, event->xany.window); } } else { if (WIN_WindowToStruct(scr, event->xany.window)) PAGER_Redraw(scr); }}/* * DestroyNotify event handler */static voiddestroy_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ WIN_DestroyWindow(scr, win);}/*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -