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

📄 menu.c

📁 最简单的窗口管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *rcsid_Menu_c = "$Header: Menu.c  88/08/09 08:57:49 Xusr Exp $";#endif/* * Copyright 1987 by Digital Equipment Corporation, Maynard, 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 permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES 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. *//* * MODIFICATION HISTORY * * 000 -- M. Gancarz, DEC Ultrix Engineering Group * 001 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab *	  February 16, 1987 *	  Change menu implementation so that it uses EnterWindow, LeaveWindow, *	  and MouseMotion events to track the mouse, instead of polling. * 002 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab *	  April 30, 1987. Convert to X11. * 003 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab *	  June 18, 1987. Change call to system to handle signals move smoothly. */#ifndef lintstatic char *sccsid = "@(#)Menu.c	3.8	1/24/86";#endif#include <signal.h>#include "uwm.h"Bool alternateGC = True;	/* true if only 2 colors are used */#define DisplayLine(w, pane, width, height, str, fg, bg, inv) \         if (alternateGC) { \	     if (inv) \	         XFillRectangle(dpy, w, MenuInvGC, 0, pane, width, height); \	     else \                 XDrawString(dpy, w, MenuGC, HMenuPad, pane + VMenuPad + MFontInfo->ascent, str, strlen(str)); \         } else { \             XSetForeground(dpy, MenuGC, bg); \	     XFillRectangle(dpy, w, MenuGC, 0, pane, width, height); \             XSetForeground(dpy, MenuGC, fg); \             XDrawString(dpy, w, MenuGC, HMenuPad, pane + VMenuPad + MFontInfo->ascent, str, strlen(str)); \         }#ifdef SYSV#ifndef hpux#define vfork() fork()#endif /* hpux */#endif /* SYSV *//* the following procedure is a copy of the implementation of system,  * modified to reset the handling of SIGINT, SIGQUIT, and SIGHUP before * exec-ing */execute(s)char *s;{	int status, pid, w;	register void (*istat)(), (*qstat)();	if ((pid = vfork()) == 0) {		signal(SIGINT, SIG_DFL);		signal(SIGQUIT, SIG_DFL);		signal(SIGHUP, SIG_DFL);		execl("/bin/sh", "sh", "-c", s, 0);		_exit(127);	}	istat = signal(SIGINT, SIG_IGN);	qstat = signal(SIGQUIT, SIG_IGN);	while ((w = wait(&status)) != pid && w != -1)		;	if (w == -1)		status = -1;	signal(SIGINT, istat);	signal(SIGQUIT, qstat);	return(status);}Bool Menu(window, mask, button, x, y, menu)Window window;				/* Event window. */int mask;				/* Button/key mask. */int button;				/* Button event detail. */int x, y;				/* Event mouse position. */MenuInfo *menu;{    XEvent button_event;		/* Button event packet. */    int event_x, event_y;		/* location of button event */    Bool func_stat;			/* Function status return. */    Window sub_window;			/* Current subwindow. */    int cur_item = 0;			/* Current menu item. */    int hi_lite = 0;			/* Current highlighted item. */    int i;				/* Iteration counter. */    int hlfg, hlbg;			/* Hi-liter pixels. */    MenuLine *ml;			/* Menu lines pointer. */    char *hlname;			/* Pointer to hi-liter name. */    char *strbuf;			/* String buffer for IsTextNL. */    Bool checkMotion = TRUE;		/* To Restore Cursor Position */    char *malloc();    /*     * Change the cursor.     */    XChangeActivePointerGrab(dpy, EVENTMASK, MenuCursor, CurrentTime);    /*     * Map the menu.     */    MapMenu(menu, x, y);    if (Autoselect) {        event_x = (menu->width >> 2) * 3;        event_y = (menu->iheight >> 1) * 3;        XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0, event_x, event_y);	goto hilite;    }    else {        XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0,     		(menu->width >> 2) * 3, menu->iheight >> 1);        XFlush(dpy);    }    /*     * Main loop.     */    while (TRUE) {        /*         *  Get next event for menu.         */        if (!GetButton(&button_event)) continue;	switch (button_event.type) {            case LeaveNotify:	        /*	         * If the mouse has moved out of the menu sideways, abort	         * the menu operation. Reset the cursor and unmap the menu.	         */	        event_x = ((XLeaveWindowEvent * )&button_event)->x;	        event_y = ((XLeaveWindowEvent * )&button_event)->y;		if (event_x < 0 || event_x > menu->width) {            	   ResetCursor(button);		   UnmapMenu(menu);            	   return(FALSE);        	}		goto hilite;            case EnterNotify:	        event_x = ((XEnterWindowEvent * )&button_event)->x;	        event_y = ((XEnterWindowEvent * )&button_event)->y;		goto hilite;            case MotionNotify:		{	        event_x = ((XPointerMovedEvent * )&button_event)->x;	        event_y = ((XPointerMovedEvent * )&button_event)->y;		if ((checkMotion == TRUE) &&		    ((event_x != (menu->width >> 2) * 3) ||		     (event_y != (menu->iheight >> 1))))		   checkMotion = FALSE;	 /* Mouse Has Moved From Top Pane */hilite:        	/*         	* If the mouse has moved below or above the menu, but is still         	* within the same vertical plane, then simply adjust the values         	* so the user doesn't fall off the edge.         	*/        	if (event_y >= menu->height) 		  event_y = menu->height - 1;        	else if (event_y < 0) 		  event_y = 0;		          	/*         	* If the mouse has moved to another item in the menu,         	* highlight the new item.         	*/        	cur_item = event_y / menu->iheight;        	if (cur_item != hi_lite) {            	/*             	* Remove highlighting on old item.             	*/            	if (hi_lite) {                	DisplayLine(menu->w, hi_lite * menu->iheight,                            menu->width, menu->iheight, hlname,                            hlfg, hlbg, 1);			XFlush(dpy);            	}           	/*             	* Highlight new item.             	*/            	hi_lite = cur_item;            	if (cur_item) {                	for(i = 1, ml = menu->line; ml; i++, ml = ml->next) {                    		if (i == cur_item) break;               	 	}                	DisplayLine(menu->w, cur_item * menu->iheight,                            menu->width, menu->iheight, ml->name,                            menu->hlfg.pixel, menu->hlbg.pixel, 1);/*                	XSetForeground(dpy, MenuGC, menu->hlfg.pixel );			XDrawRectangle(dpy, menu->w, MenuGC, 1, 				cur_item * menu->iheight + 1, 				menu->width - 3, menu->iheight - 3);*/			XFlush(dpy);             		hlfg = ml->fg.pixel;            		hlbg = ml->bg.pixel;            		hlname = ml->name;            	}		}        	break;            case ButtonRelease:	        /* have we released the invoking button? */	        if (((XButtonReleasedEvent *)&button_event)->button == button) {		    /*		     * If no item was selected, 		     * close the menu, reset the pointer's position and return		     */		    if (!cur_item) {			/* If Needed Reset The Cursor Position */			if (checkMotion == TRUE)			  XWarpPointer (dpy, None, RootWindow(dpy, scr),					0, 0, 0, 0, x, y);		         ResetCursor(button);			 UnmapMenu(menu);		         return(TRUE);		     }		     /*		      * Get a pointer to the menu line selected.		      */		     --cur_item;		     for(i = 0, ml = menu->line; ml; i++, ml = ml->next) {		         if (i == cur_item) break;		     }		     /*		      * Perform the selected menu line action.		      */		     switch (ml->type) {		         case IsShellCommand:		             UnmapMenu(menu);		             execute(ml->text);		             break;		         case IsText:		             UnmapMenu(menu);		             XStoreBytes(dpy, ml->text, strlen(ml->text));		             break;		         case IsTextNL:		             UnmapMenu(menu);		             strbuf = (char *)malloc(strlen(ml->text) + 2);		             strcpy(strbuf, ml->text);		             strcat(strbuf, "\n");		             XStoreBytes(dpy, strbuf, strlen(strbuf));		             free(strbuf);		             break;		         case IsUwmFunction:			     /* change cursor and grab next button event			      * to select the target window */			     if (XGrabPointer( dpy, RootWindow(dpy, scr),					       TRUE, EVENTMASK, GrabModeAsync,					       GrabModeAsync, None,					       TargetCursor, CurrentTime )				   != GrabSuccess )			         Error( "Could not grab pointer" );		             GetContext(			       &sub_window, &event_x, &event_y);		             UnmapMenu(menu);		             if (sub_window != menu->w)			       func_stat =		                 (*ml->func) (				   sub_window, mask, button, event_x, 				   event_y);			     else func_stat = FALSE;			     if (!func_stat) {			       /* eat the next ButtonRelease */			       while (TRUE) {				   if (GetButton(&button_event) &&				       button_event.type == ButtonRelease)				     break;			       }			     }			     XUngrabPointer( dpy, CurrentTime );		             break;		         case IsImmFunction:		             UnmapMenu(menu); 		            (*ml->func) (			      sub_window, mask, button, event_x, 			      event_y);		             break;		 		         case IsMenuFunction:		             while (TRUE) {		                if (!GetButton(&button_event)) continue;		                if (button_event.type != ButtonPress) continue;		                if ((((XButtonPressedEvent *)&button_event)->state != mask) 				 || (((XButtonPressedEvent *)&button_event)->button != button)) 				 {		                     UnmapMenu(menu);		                     return(TRUE);		                 }		                 break;		             }		             UnmapMenu(menu);		             func_stat = 			     	Menu(menu->w, mask, button, x, y, ml->menu);		             return(func_stat);		             break;		         default: 		            Error("Menu -> Internal type error.");		     }		     return(TRUE);		                   } 		 /* else a different button was released. Fall through: */            default:                    /*                     * Some other button event occurred, so abort the menu                     * operation.                     */		    ResetCursor(button);		    /* If Needed Reset The Cursor Position */		    if (checkMotion == TRUE)		      XWarpPointer (dpy, None, RootWindow(dpy, scr),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -