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

📄 walkmenu_render.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lint#ifdef sccsstatic	char sccsid[] = "@(#)walkmenu_render.c 1.1 92/07/30 Copyright 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//*-	WALKING MENU PACKAGE	walkmenu_render.c, Sun Jun 30 15:38:39 1985		Craig Taylor,		Sun Microsystems *//* ------------------------------------------------------------------------- */#include <sys/types.h>#include <sys/time.h>#include <stdio.h>#include <fcntl.h>#include <varargs.h>#include <pixrect/pixrect.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/cms.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_screen.h>#include <sunwindow/win_input.h>#include <sunwindow/win_cursor.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_ioctl.h>#include <suntool/fullscreen.h>#include <suntool/window.h>#include <suntool/walkmenu_impl.h>#define	PIXRECT_NULL	((struct pixrect *)0)#define SCREEN_MARGIN   10		/* Minimum number of pixels away					 * from the edge of the screen a menu's					 * left and top sides should be.					 * (to enable backing out of 					 * pullright menus					 *//* ------------------------------------------------------------------------- *//*  * Public */    /* None *//*  * Package private */Pkg_extern	struct pixrect menu_arrow_pr;	/* in walkmenu_create.c */Pkg_extern	struct fullscreen *menu_fs;	/* in walkmenu_public.c */Pkg_extern	int menu_curitem();Pkg_private	int menu_render();/*  * Private */Private		int compute_item_size();Private		int compute_dimensions();Private		void compute_rects();Private		void render_items();Private		int render_pullright();Private		void paint_shadow();Private		void paint_menu();Private		void feedback();Private		void constrainrect();Private		void destroy_gen_items();/*  * Private defs */#define	MENU_SHADOW	6 /* Width of menu shadow */#define MENU_BORDER	1 /* Width of menu border */#define STANDOFF	3 /* 1/2 the number of active pixels left of the menu */extern	int	sv_journal;extern	void	win_sync();static int      old_mousex, old_mousey;int             menu_count;/* ------------------------------------------------------------------------- *//*  * Menu_render modifies the inputevent parameter iep. * It should contain the last active inputevent read for the fd. */Pkg_private intmenu_render(menu, dynamic, parent, subrect, reenter, fd)	struct menu *menu;	struct menu_info *dynamic;	struct menu_item *parent;	struct rectnode *subrect;	int fd;{       register struct menu *m;    register struct menu_item *mi;    register curitem, item_width, item_height;    register struct inputevent *iep;    register short menu_button, locx;    struct image *std_image;    struct menu *(*gen_proc)();    struct rect menurect, activerect, saverect, itemrect;    struct pixrect *menu_image, *items_image;    Pw_pixel_cache *pixel_cache;    int stand_off, status, gen_items;    int margin, right_margin, ncols, nrows;    /*      *  Initial setup: Pull out dynamic information.     */    menu->dynamic_info = dynamic, menu->parent = parent;    dynamic->depth++;    iep = dynamic->last_iep;    menu_button = iep->ie_code;    stand_off = reenter == FALSE && menu->stand_off;    pixel_cache = PW_PIXEL_CACHE_NULL, gen_items = FALSE, gen_proc = NULL;    /*      *  Dynamically create the menu if requested.     */    if (gen_proc = menu->gen_proc) {	m = (gen_proc)(menu, MENU_DISPLAY);	if (m == NULL) {	    (void) fprintf(stderr,		    "menu_show: menu's gen_proc failed to generate a menu.\n");	    goto error_exit;	}	m->dynamic_info = dynamic, m->parent = parent;    } else {	m = menu;    }    /*      *  No items, return to parent menu     */    if (m->nitems == 0) {	status = 1;	goto exit;    }    /*     * Find the current menu item     */    if (reenter) {	/* Based on default selection */	curitem = menu_curitem(m, m->default_selection, 1);    } else {		/* Based on initial selection */	curitem = menu_curitem(m, m->initial_selection, 1);	if (!curitem) {	    status = 1;	    goto exit;	}		    }    /*      * Compute the size of an item.     */    std_image = &m->default_image;    gen_items = compute_item_size(m, std_image);    item_width = std_image->width;    item_height = std_image->height;    margin =  std_image->margin;    right_margin = std_image->right_margin;    /*      *  Automatically compute the elided dimension.     */    if (!compute_dimensions(m, item_width, item_height,			    &menurect, &ncols, &nrows))        goto error_exit;        /*      *  Compute the rects:     *    menurect -	represents the area of the menu including its borders.     *    activerect -	extends the left edge of the menurect.  Cursor motion     * 			is mapped to its associated menu with this rect.     *    saverect - 	extended menurect with includes the menu shadow.     */    compute_rects(m, iep, stand_off, curitem,		  item_width, item_height, ncols, nrows,		  &menurect, &activerect, &saverect);    /*     * Save the mouse position so that after selecting, it will return     * to the same place     */    if (menu_count++ == 0){      old_mousex = win_get_vuid_value(fd, LOC_X_ABSOLUTE);      old_mousey = win_get_vuid_value(fd, LOC_Y_ABSOLUTE);    }    /*      *  Save image under menu, generate menu and display it.     */    if (((pixel_cache = pw_save_pixels(menu_fs->fs_pixwin, &saverect)) ==            PW_PIXEL_CACHE_NULL) ||        (pw_primary_cached_mpr(menu_fs->fs_pixwin, pixel_cache) ==	    (struct pixrect *)0))		goto error_exit;    /*     *  Create pixrect w/menu image.     *  For now assume that the menu is monochrome.     */    menu_image = mem_create(saverect.r_width, saverect.r_height, 1);    items_image = pr_region(menu_image, MENU_BORDER, MENU_BORDER,			    item_width * ncols, item_height * nrows);    paint_shadow(menu_image, m->shadow_pr,	pw_primary_cached_mpr(menu_fs->fs_pixwin, pixel_cache));    render_items(m, std_image, items_image, ncols, nrows);    /*      * Display the menu and provide item highlighting.     */        (void) pw_lock(menu_fs->fs_pixwin, &saverect);    paint_menu(menu_image, &saverect, (m->shadow_pr)? 1: 0);    if (!stand_off)	feedback(m, &menurect, curitem, ncols, nrows, MENU_PROVIDE_FEEDBACK);    (void) pw_unlock(menu_fs->fs_pixwin);    mem_destroy(items_image);    mem_destroy(menu_image);    if (sv_journal) {	win_sync(WIN_SYNC_MENU, fd);    }    /* From here on any returns from this procedure should go thru exit: */    /*      *  Handle initial selection expansion     */    if (!reenter && !m->display_one_level) {	mi = m->item_list[curitem - 1];	if (mi->pullright && !mi->inactive && !mi->selected &&	    	    (mi->value || mi->gen_pullright))	{ 	    if (!mi->gen_pullright) { /* FIXME: Should handle gen pullright */		struct menu *mn = (struct menu *)LINT_CAST(mi->value);		if (!menu_curitem(mn, mn->initial_selection, 0))		    goto enter_input_loop;	    }	    if (stand_off) {		feedback(m, &menurect,			 curitem, ncols, nrows, MENU_PROVIDE_FEEDBACK);	    }	    locx = menurect.r_left;	    if (m->column_major)		locx += ((curitem - 1) / nrows + 1) * item_width + MENU_BORDER;	    else		locx += ((curitem - 1) % ncols + 1) * item_width + MENU_BORDER;	    itemrect.r_width = locx;	    locx -= margin + right_margin + mi->image->right_pr->pr_width;	    locx -= stand_off ? STANDOFF : -STANDOFF;	    iep->ie_locx = locx;	    iep->ie_locy = menurect.r_top + MENU_BORDER;	    if (m->column_major)		iep->ie_locy += (curitem - 1) % nrows * item_height		    + item_height / 2;	    else		iep->ie_locy += (curitem - 1) / ncols * item_height		    + item_height / 2;	    itemrect.r_left = locx;	    itemrect.r_width -= locx;	    itemrect.r_top = iep->ie_locy - item_height / 2;	    itemrect.r_height = item_height;	    (void) win_setmouseposition(menu_fs->fs_windowfd,				 	iep->ie_locx, iep->ie_locy);	    event_set_id(iep, menu_button);	    status = render_pullright(mi, subrect, &menurect, &itemrect, FALSE,fd);	    if (status == 0 || --status != 0) goto exit;	    stand_off = FALSE;	}    }enter_input_loop:    if (stand_off) curitem = 0;    locx = iep->ie_locx;   /*    * Track the mouse.    */    for (;;) {	register int itemx, itemy, newitem;	int arrow_bdry;	if (rect_includespoint(&activerect, iep->ie_locx, iep->ie_locy)) {	   /*	    * Check if cursor is in the current menu	    */	    itemx = iep->ie_locx - menurect.r_left - MENU_BORDER;	    if (itemx < 0) itemx = m->nitems; /* Outside menu proper */	    else {		itemx = itemx / item_width;		if (itemx >= ncols) itemx = ncols - 1;	    }	    itemy = (iep->ie_locy - menurect.r_top - MENU_BORDER) / item_height;	    if (itemy < 0) itemy = 0;	    else if (itemy >= nrows) itemy = nrows - 1;	    newitem = m->column_major ? 		itemx * nrows + itemy + 1 : itemy * ncols + itemx + 1;	    if (newitem > m->nitems) newitem = 0;	} else {            register struct rectnode *rp;	    if (subrect && !rect_includespoint(&subrect->rn_rect,					       iep->ie_locx, iep->ie_locy)) {		if ((rect_includesrect(&menurect,&subrect->rn_next->rn_rect)) &&			iep->ie_locx < menurect.r_left)  {		    /*		     * cursor is to the left of pullright, and		     * parent is obscured by the child menu, so we		     * pop back to the parent menu.		     */		     status = 1;		     goto exit;		}	       /*		* Check if cursor is in a parent menu		*/		status = 1;		for (rp = subrect->rn_next; rp;		     rp = rp->rn_next ? rp->rn_next->rn_next : NULL, status++) {		    if (rect_includespoint(&rp->rn_rect,					   iep->ie_locx, iep->ie_locy))		        goto exit;		}	    }	    newitem = 0;	}       /*	* Provide feedback for new item.	*/	if (newitem != curitem) { /* revert item to normal state */	    if (curitem)		feedback(m, &menurect,			 curitem, ncols, nrows, MENU_REMOVE_FEEDBACK);	    curitem = newitem;   /* invert new item */	    if (curitem) {		feedback(m, &menurect,			 curitem, ncols, nrows, MENU_PROVIDE_FEEDBACK);		locx = iep->ie_locx;	    }	}	if (locx >= iep->ie_locx) locx = iep->ie_locx;	if (newitem) {	   /*	    * If item is a menu, recurse.	    */	    mi = m->item_list[newitem - 1];	    if (mi->pullright)		arrow_bdry = menurect.r_left + MENU_BORDER + STANDOFF		    + (itemx * item_width) + item_width			- (margin + (mi->image->string?right_margin:0)			   + mi->image->right_pr->pr_width);	    if (mi->pullright && !mi->inactive		&& (iep->ie_locx > arrow_bdry		    || iep->ie_locx >= locx + m->pullright_delta)		&& (mi->value || mi->gen_pullright))	    {   		if (iep->ie_locx > arrow_bdry) iep->ie_locx = arrow_bdry;		iep->ie_locy = (menurect.r_top + MENU_BORDER				+ itemy * item_height				+ (item_height / 2));		event_set_id(iep, menu_button);		/* Recurse */		itemrect.r_left = iep->ie_locx;		itemrect.r_width = menurect.r_left + MENU_BORDER + STANDOFF		    + itemx * item_width + item_width - iep->ie_locx;;		itemrect.r_top = iep->ie_locy - item_height / 2;		itemrect.r_height = item_height;		status =		    render_pullright(mi, subrect, &menurect, &itemrect, TRUE,fd);		if (status == 0 || --status != 0) goto exit;		locx = iep->ie_locx;	    }	}       /*	* Get next input event.	*/	do {	    if (input_readevent(menu_fs->fs_windowfd, iep) == -1) {		(void) fprintf(stderr, "menu_show: failed to track cursor.\n");		perror("menu_show");		status = -1;		goto exit;	    }	   /*	    * If button up is the menu button then	    * an item has been selected,  return it.	    */	    if (menu_button == iep->ie_code && win_inputnegevent(iep)) {		if (curitem == 0 || m->item_list[curitem-1]->inactive)		    m->dynamic_info->depth = 0, curitem = NULL;		status = 0;		goto exit;	    }	    else if (event_action(iep) == ACTION_HELP &&		     win_inputposevent(iep)) {		if (curitem == 0 || !m->item_list[curitem-1]->help_data)		    m->dynamic_info->help = m->help_data;		else		    m->dynamic_info->help = m->item_list[curitem-1]->help_data;		m->dynamic_info->depth = 0, curitem = NULL;		status = 0;		goto exit;	    }	} while (iep->ie_code != LOC_MOVEWHILEBUTDOWN &&		 iep->ie_code != LOC_STILL && iep->ie_code != LOC_MOVE);    }    /* Entry states at the next higher level:     *   status<0 abort menu chain (error or null selection),     *   status=0 valid selection save selected item,     *   status>0 cursor has entered a parent menu.     */exit:    if (status == 0 && curitem)        m->selected_position = curitem;    if (status > 0) --m->dynamic_info->depth;    /*     * set the mouse back to the position where it was first clicked     */    if(--menu_count == 0)      win_setmouseposition(menu_fs->fs_windowfd, old_mousex, old_mousey);    pw_restore_pixels(menu_fs->fs_pixwin, pixel_cache); /* Checks for null */    if (gen_items) destroy_gen_items(m);    m->dynamic_info = NULL;    if (gen_proc) {	(gen_proc)(m, MENU_DISPLAY_DONE);    }

⌨️ 快捷键说明

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