⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 events.c

📁 安装DDD之前
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $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 + -