Patch to support the siteconf feature, from [w3m-dev 04463] on 2012-06-27, provided by AIDA Shinra.
		
			
				
	
	
		
			2068 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2068 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Id: menu.c,v 1.46 2007/05/23 12:34:20 inu Exp $ */
 | 
						|
/* 
 | 
						|
 * w3m menu.c
 | 
						|
 */
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "fm.h"
 | 
						|
#include "menu.h"
 | 
						|
#include "func.h"
 | 
						|
#include "myctype.h"
 | 
						|
#include "regex.h"
 | 
						|
 | 
						|
#ifdef USE_MOUSE
 | 
						|
#ifdef USE_GPM
 | 
						|
#include <gpm.h>
 | 
						|
static int gpm_process_menu_mouse(Gpm_Event * event, void *data);
 | 
						|
extern int gpm_process_mouse(Gpm_Event *, void *);
 | 
						|
#endif				/* USE_GPM */
 | 
						|
#ifdef USE_SYSMOUSE
 | 
						|
extern int (*sysm_handler) (int x, int y, int nbs, int obs);
 | 
						|
static int sysm_process_menu_mouse(int, int, int, int);
 | 
						|
extern int sysm_process_mouse(int, int, int, int);
 | 
						|
#endif				/* USE_SYSMOUSE */
 | 
						|
#if defined(USE_GPM) || defined(USE_SYSMOUSE)
 | 
						|
#define X_MOUSE_SELECTED (char)0xff
 | 
						|
static int X_Mouse_Selection;
 | 
						|
extern int do_getch();
 | 
						|
#define getch()	do_getch()
 | 
						|
#endif				/* defined(USE_GPM) || defined(USE_SYSMOUSE) */
 | 
						|
#endif				/* USE_MOUSE */
 | 
						|
 | 
						|
#ifdef USE_MENU
 | 
						|
 | 
						|
static char **FRAME;
 | 
						|
static int FRAME_WIDTH;
 | 
						|
static int graph_mode = FALSE;
 | 
						|
#define G_start  {if (graph_mode) graphstart();}
 | 
						|
#define G_end    {if (graph_mode) graphend();}
 | 
						|
 | 
						|
static int mEsc(char c);
 | 
						|
static int mEscB(char c);
 | 
						|
static int mEscD(char c);
 | 
						|
static int mNull(char c);
 | 
						|
static int mSelect(char c);
 | 
						|
static int mDown(char c);
 | 
						|
static int mUp(char c);
 | 
						|
static int mLast(char c);
 | 
						|
static int mTop(char c);
 | 
						|
static int mNext(char c);
 | 
						|
static int mPrev(char c);
 | 
						|
static int mFore(char c);
 | 
						|
static int mBack(char c);
 | 
						|
static int mLineU(char c);
 | 
						|
static int mLineD(char c);
 | 
						|
static int mOk(char c);
 | 
						|
static int mCancel(char c);
 | 
						|
static int mClose(char c);
 | 
						|
static int mSusp(char c);
 | 
						|
static int mMouse(char c);
 | 
						|
static int mSrchF(char c);
 | 
						|
static int mSrchB(char c);
 | 
						|
static int mSrchN(char c);
 | 
						|
static int mSrchP(char c);
 | 
						|
#ifdef __EMX__
 | 
						|
static int mPc(char c);
 | 
						|
#endif
 | 
						|
 | 
						|
/* *INDENT-OFF* */
 | 
						|
static int (*MenuKeymap[128]) (char c) = {
 | 
						|
/*  C-@     C-a     C-b     C-c     C-d     C-e     C-f     C-g      */
 | 
						|
#ifdef __EMX__
 | 
						|
    mPc,    mTop,   mPrev,  mClose, mNull,  mLast,  mNext,  mNull,
 | 
						|
#else
 | 
						|
    mNull,  mTop,   mPrev,  mClose, mNull,  mLast,  mNext,  mNull,
 | 
						|
#endif
 | 
						|
/*  C-h     C-i     C-j     C-k     C-l     C-m     C-n     C-o      */
 | 
						|
    mCancel,mNull,  mOk,    mNull,  mNull,  mOk,    mDown,  mNull,
 | 
						|
/*  C-p     C-q     C-r     C-s     C-t     C-u     C-v     C-w      */
 | 
						|
    mUp,    mNull,  mSrchB, mSrchF, mNull,  mNull,  mNext,  mNull,
 | 
						|
/*  C-x     C-y     C-z     C-[     C-\     C-]     C-^     C-_      */
 | 
						|
    mNull,  mNull,  mSusp,  mEsc,   mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  SPC     !       "       #       $       %       &       '        */
 | 
						|
    mOk,    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  (       )       *       +       ,       -       .       /        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mSrchF,
 | 
						|
/*  0       1       2       3       4       5       6       7        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull , mNull,  mNull,
 | 
						|
/*  8       9       :       ;       <       =       >       ?        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mSrchB,
 | 
						|
/*  @       A       B       C       D       E       F       G        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  H       I       J       K       L       M       N       O        */
 | 
						|
    mNull,  mNull,  mLineU, mLineD, mNull,  mNull,  mSrchP, mNull,
 | 
						|
/*  P       Q       R       S       T       U       V       W        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  X       Y       Z       [       \       ]       ^       _        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  `       a       b       c       d       e       f       g        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  h       i       j       k       l       m       n       o        */
 | 
						|
    mCancel,mNull,  mDown,  mUp,    mOk,    mNull,  mSrchN, mNull,
 | 
						|
/*  p       q       r       s       t       u       v       w        */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  x       y       z       {       |       }       ~       DEL      */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mCancel,
 | 
						|
};
 | 
						|
static int (*MenuEscKeymap[128]) (char c) = {
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  O     */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mEscB,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  [                                     */
 | 
						|
    mNull,  mNull,  mNull,  mEscB,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  v             */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mPrev,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
};
 | 
						|
static int (*MenuEscBKeymap[128]) (char c) = {
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  A       B       C       D       E                     */
 | 
						|
    mNull,  mUp,    mDown,  mOk,    mCancel,mClose, mNull, mNull,
 | 
						|
/*  L       M                     */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mClose, mMouse, mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
};
 | 
						|
static int (*MenuEscDKeymap[128]) (char c) = {
 | 
						|
/*  0       1       INS     3       4       PgUp,   PgDn    7     */
 | 
						|
    mNull,  mNull,  mClose, mNull,  mNull,  mBack,  mFore,  mNull,
 | 
						|
/*  8       9       10      F1      F2      F3      F4      F5       */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  16      F6      F7      F8      F9      F10     22      23       */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
/*  24      25      26      27      HELP    29      30      31       */
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mClose, mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
    mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
};
 | 
						|
 | 
						|
#ifdef __EMX__
 | 
						|
static int (*MenuPcKeymap[256])(char c)={
 | 
						|
//			  Null
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
//							  S-Tab
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-q	  A-w	  A-E	  A-r	  A-t	  A-y	  A-u	  A-i
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-o	  A-p	  A-[	  A-]			  A-a	  A-s
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-d	  A-f	  A-g	  A-h	  A-j	  A-k	  A-l	  A-;
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-'    A-'		  A-\		  A-x	  A-c	  A-v
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mPrev,
 | 
						|
// A-b	  A-n	  A-m	  A-,	  A-.	  A-/		  A-+
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
//			  F1	  F2	  F3	  F4	  F5
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// F6	  F7	  F8	  F9	  F10			  Home
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mTop,
 | 
						|
// Up	  PgUp	  A-/	  Left	  5	  Right	  C-*	  End
 | 
						|
  mUp,	  mUp,	  mNull,  mCancel,mNull,  mOk,	  mNull,  mLast,
 | 
						|
// Down	  PgDn	  Ins	  Del	  S-F1	  S-F2	  S-F3	  S-F4
 | 
						|
  mDown,  mDown,  mClose, mCancel,mNull,  mNull,  mNull,  mNull,
 | 
						|
// S-F5	  S-F6	  S-F7	  S-F8	  S-F9	  S-F10	  C-F1	  C-F2
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// C-F3	  C-F4	  C-F5	  C-F6	  C-F7	  C-F8	  C-F9	  C-F10
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-F1	  A-F2	  A-F3	  A-F4	  A-F5	  A-F6	  A-F7	  A-F8
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-F9	  A-F10	  PrtSc	  C-Left  C-Right C-End	  C-PgDn  C-Home
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-1	  A-2	  A-3	  A-4	  A-5	  A-6	  A-7/8	  A-9
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// A-0	  A -	  A-=		  C-PgUp  F11	  F12	  S-F11
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// S-F12  C-F11	  C-F12	  A-F11	  A-F12	  C-Up	  C-/	  C-5
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
// S-*	  C-Down  C-Ins	  C-Del	  C-Tab	  C -	  C-+
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,
 | 
						|
//				  A -	  A-Tab	  A-Enter
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 160
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 168
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 176
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 184
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 192
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 200
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 208
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 216
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 224
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 232
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,   // 240
 | 
						|
  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull,  mNull	   // 248
 | 
						|
};
 | 
						|
#endif
 | 
						|
/* *INDENT-ON* */
 | 
						|
/* --- SelectMenu --- */
 | 
						|
 | 
						|
static Menu SelectMenu;
 | 
						|
static int SelectV = 0;
 | 
						|
static void initSelectMenu(void);
 | 
						|
static void smChBuf(void);
 | 
						|
static int smDelBuf(char c);
 | 
						|
 | 
						|
/* --- SelectMenu (END) --- */
 | 
						|
 | 
						|
/* --- SelTabMenu --- */
 | 
						|
 | 
						|
static Menu SelTabMenu;
 | 
						|
static int SelTabV = 0;
 | 
						|
static void initSelTabMenu(void);
 | 
						|
static void smChTab(void);
 | 
						|
static int smDelTab(char c);
 | 
						|
 | 
						|
/* --- SelTabMenu (END) --- */
 | 
						|
 | 
						|
/* --- MainMenu --- */
 | 
						|
 | 
						|
static Menu MainMenu;
 | 
						|
#ifdef USE_M17N
 | 
						|
/* FIXME: gettextize here */
 | 
						|
static wc_ces MainMenuCharset = WC_CES_US_ASCII;	/* FIXME: charset of source code */
 | 
						|
static int MainMenuEncode = FALSE;
 | 
						|
#endif
 | 
						|
 | 
						|
static MenuItem MainMenuItem[] = {
 | 
						|
    /* type        label           variable value func     popup keys data  */
 | 
						|
    {MENU_FUNC, N_(" Back         (b) "), NULL, 0, backBf, NULL, "b", NULL},
 | 
						|
    {MENU_POPUP, N_(" Select Buffer(s) "), NULL, 0, NULL, &SelectMenu, "s",
 | 
						|
     NULL},
 | 
						|
    {MENU_POPUP, N_(" Select Tab   (t) "), NULL, 0, NULL, &SelTabMenu, "tT",
 | 
						|
     NULL},
 | 
						|
    {MENU_FUNC, N_(" View Source  (v) "), NULL, 0, vwSrc, NULL, "vV", NULL},
 | 
						|
    {MENU_FUNC, N_(" Edit Source  (e) "), NULL, 0, editBf, NULL, "eE", NULL},
 | 
						|
    {MENU_FUNC, N_(" Save Source  (S) "), NULL, 0, svSrc, NULL, "S", NULL},
 | 
						|
    {MENU_FUNC, N_(" Reload       (r) "), NULL, 0, reload, NULL, "rR", NULL},
 | 
						|
    {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL},
 | 
						|
    {MENU_FUNC, N_(" Go Link      (a) "), NULL, 0, followA, NULL, "a", NULL},
 | 
						|
    {MENU_FUNC, N_("   on New Tab (n) "), NULL, 0, tabA, NULL, "nN", NULL},
 | 
						|
    {MENU_FUNC, N_(" Save Link    (A) "), NULL, 0, svA, NULL, "A", NULL},
 | 
						|
    {MENU_FUNC, N_(" View Image   (i) "), NULL, 0, followI, NULL, "i", NULL},
 | 
						|
    {MENU_FUNC, N_(" Save Image   (I) "), NULL, 0, svI, NULL, "I", NULL},
 | 
						|
    {MENU_FUNC, N_(" View Frame   (f) "), NULL, 0, rFrame, NULL, "fF", NULL},
 | 
						|
    {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL},
 | 
						|
    {MENU_FUNC, N_(" Bookmark     (B) "), NULL, 0, ldBmark, NULL, "B", NULL},
 | 
						|
    {MENU_FUNC, N_(" Help         (h) "), NULL, 0, ldhelp, NULL, "hH", NULL},
 | 
						|
    {MENU_FUNC, N_(" Option       (o) "), NULL, 0, ldOpt, NULL, "oO", NULL},
 | 
						|
    {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL},
 | 
						|
    {MENU_FUNC, N_(" Quit         (q) "), NULL, 0, qquitfm, NULL, "qQ", NULL},
 | 
						|
    {MENU_END, "", NULL, 0, nulcmd, NULL, "", NULL},
 | 
						|
};
 | 
						|
 | 
						|
/* --- MainMenu (END) --- */
 | 
						|
 | 
						|
static MenuList *w3mMenuList;
 | 
						|
 | 
						|
static Menu *CurrentMenu = NULL;
 | 
						|
 | 
						|
#define mvaddch(y, x, c)        (move(y, x), addch(c))
 | 
						|
#define mvaddstr(y, x, str)     (move(y, x), addstr(str))
 | 
						|
#define mvaddnstr(y, x, str, n) (move(y, x), addnstr_sup(str, n))
 | 
						|
 | 
						|
void
 | 
						|
new_menu(Menu *menu, MenuItem *item)
 | 
						|
{
 | 
						|
    int i, l;
 | 
						|
    char *p;
 | 
						|
 | 
						|
    menu->cursorX = 0;
 | 
						|
    menu->cursorY = 0;
 | 
						|
    menu->x = 0;
 | 
						|
    menu->y = 0;
 | 
						|
    menu->nitem = 0;
 | 
						|
    menu->item = item;
 | 
						|
    menu->initial = 0;
 | 
						|
    menu->select = 0;
 | 
						|
    menu->offset = 0;
 | 
						|
    menu->active = 0;
 | 
						|
 | 
						|
    if (item == NULL)
 | 
						|
	return;
 | 
						|
 | 
						|
    for (i = 0; item[i].type != MENU_END; i++) ;
 | 
						|
    menu->nitem = i;
 | 
						|
    menu->height = menu->nitem;
 | 
						|
    for (i = 0; i < 128; i++)
 | 
						|
	menu->keymap[i] = MenuKeymap[i];
 | 
						|
    menu->width = 0;
 | 
						|
    for (i = 0; i < menu->nitem; i++) {
 | 
						|
	if ((p = item[i].keys) != NULL) {
 | 
						|
	    while (*p) {
 | 
						|
		if (IS_ASCII(*p)) {
 | 
						|
		    menu->keymap[(int)*p] = mSelect;
 | 
						|
		    menu->keyselect[(int)*p] = i;
 | 
						|
		}
 | 
						|
		p++;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	l = get_strwidth(item[i].label);
 | 
						|
	if (l > menu->width)
 | 
						|
	    menu->width = l;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
geom_menu(Menu *menu, int x, int y, int mselect)
 | 
						|
{
 | 
						|
    int win_x, win_y, win_w, win_h;
 | 
						|
 | 
						|
    menu->select = mselect;
 | 
						|
 | 
						|
    if (menu->width % FRAME_WIDTH)
 | 
						|
	menu->width = (menu->width / FRAME_WIDTH + 1) * FRAME_WIDTH;
 | 
						|
    win_x = menu->x - FRAME_WIDTH;
 | 
						|
    win_w = menu->width + 2 * FRAME_WIDTH;
 | 
						|
    if (win_x + win_w > COLS)
 | 
						|
	win_x = COLS - win_w;
 | 
						|
    if (win_x < 0) {
 | 
						|
	win_x = 0;
 | 
						|
	if (win_w > COLS) {
 | 
						|
	    menu->width = COLS - 2 * FRAME_WIDTH;
 | 
						|
	    menu->width -= menu->width % FRAME_WIDTH;
 | 
						|
	    win_w = menu->width + 2 * FRAME_WIDTH;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    menu->x = win_x + FRAME_WIDTH;
 | 
						|
 | 
						|
    win_y = menu->y - mselect - 1;
 | 
						|
    win_h = menu->height + 2;
 | 
						|
    if (win_y + win_h > LASTLINE)
 | 
						|
	win_y = LASTLINE - win_h;
 | 
						|
    if (win_y < 0) {
 | 
						|
	win_y = 0;
 | 
						|
	if (win_y + win_h > LASTLINE) {
 | 
						|
	    win_h = LASTLINE - win_y;
 | 
						|
	    menu->height = win_h - 2;
 | 
						|
	    if (menu->height <= mselect)
 | 
						|
		menu->offset = mselect - menu->height + 1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    menu->y = win_y + 1;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
draw_all_menu(Menu *menu)
 | 
						|
{
 | 
						|
    if (menu->parent != NULL)
 | 
						|
	draw_all_menu(menu->parent);
 | 
						|
    draw_menu(menu);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
draw_menu(Menu *menu)
 | 
						|
{
 | 
						|
    int x, y, w;
 | 
						|
    int i, j;
 | 
						|
 | 
						|
    x = menu->x - FRAME_WIDTH;
 | 
						|
    w = menu->width + 2 * FRAME_WIDTH;
 | 
						|
    y = menu->y - 1;
 | 
						|
 | 
						|
    if (menu->offset == 0) {
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x, FRAME[3]);
 | 
						|
	for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i += FRAME_WIDTH)
 | 
						|
	    mvaddstr(y, x + i, FRAME[10]);
 | 
						|
	mvaddstr(y, x + i, FRAME[6]);
 | 
						|
	G_end;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
	for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++)
 | 
						|
	    mvaddstr(y, x + i, " ");
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x + i, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
	i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH;
 | 
						|
	mvaddstr(y, x + i, ":");
 | 
						|
    }
 | 
						|
 | 
						|
    for (j = 0; j < menu->height; j++) {
 | 
						|
	y++;
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
	draw_menu_item(menu, menu->offset + j);
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x + w - FRAME_WIDTH, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
    }
 | 
						|
    y++;
 | 
						|
    if (menu->offset + menu->height == menu->nitem) {
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x, FRAME[9]);
 | 
						|
	for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i += FRAME_WIDTH)
 | 
						|
	    mvaddstr(y, x + i, FRAME[10]);
 | 
						|
	mvaddstr(y, x + i, FRAME[12]);
 | 
						|
	G_end;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
	for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++)
 | 
						|
	    mvaddstr(y, x + i, " ");
 | 
						|
	G_start;
 | 
						|
	mvaddstr(y, x + i, FRAME[5]);
 | 
						|
	G_end;
 | 
						|
	i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH;
 | 
						|
	mvaddstr(y, x + i, ":");
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
draw_menu_item(Menu *menu, int mselect)
 | 
						|
{
 | 
						|
    mvaddnstr(menu->y + mselect - menu->offset, menu->x,
 | 
						|
	      menu->item[mselect].label, menu->width);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
select_menu(Menu *menu, int mselect)
 | 
						|
{
 | 
						|
    if (mselect < 0 || mselect >= menu->nitem)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    if (mselect < menu->offset)
 | 
						|
	up_menu(menu, menu->offset - mselect);
 | 
						|
    else if (mselect >= menu->offset + menu->height)
 | 
						|
	down_menu(menu, mselect - menu->offset - menu->height + 1);
 | 
						|
 | 
						|
    if (menu->select >= menu->offset &&
 | 
						|
	menu->select < menu->offset + menu->height)
 | 
						|
	draw_menu_item(menu, menu->select);
 | 
						|
    menu->select = mselect;
 | 
						|
    standout();
 | 
						|
    draw_menu_item(menu, menu->select);
 | 
						|
    standend();
 | 
						|
    /* 
 | 
						|
     * move(menu->cursorY, menu->cursorX); */
 | 
						|
    move(menu->y + mselect - menu->offset, menu->x);
 | 
						|
    toggle_stand();
 | 
						|
    refresh();
 | 
						|
 | 
						|
    return (menu->select);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
goto_menu(Menu *menu, int mselect, int down)
 | 
						|
{
 | 
						|
    int select_in;
 | 
						|
    if (mselect >= menu->nitem)
 | 
						|
	mselect = menu->nitem - 1;
 | 
						|
    else if (mselect < 0)
 | 
						|
	mselect = 0;
 | 
						|
    select_in = mselect;
 | 
						|
    while (menu->item[mselect].type == MENU_NOP) {
 | 
						|
	if (down > 0) {
 | 
						|
	    if (++mselect >= menu->nitem) {
 | 
						|
		down_menu(menu, select_in - menu->select);
 | 
						|
		mselect = menu->select;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else if (down < 0) {
 | 
						|
	    if (--mselect < 0) {
 | 
						|
		up_menu(menu, menu->select - select_in);
 | 
						|
		mselect = menu->select;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    select_menu(menu, mselect);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
up_menu(Menu *menu, int n)
 | 
						|
{
 | 
						|
    if (n < 0 || menu->offset == 0)
 | 
						|
	return;
 | 
						|
    menu->offset -= n;
 | 
						|
    if (menu->offset < 0)
 | 
						|
	menu->offset = 0;
 | 
						|
 | 
						|
    draw_menu(menu);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
down_menu(Menu *menu, int n)
 | 
						|
{
 | 
						|
    if (n < 0 || menu->offset + menu->height == menu->nitem)
 | 
						|
	return;
 | 
						|
    menu->offset += n;
 | 
						|
    if (menu->offset + menu->height > menu->nitem)
 | 
						|
	menu->offset = menu->nitem - menu->height;
 | 
						|
 | 
						|
    draw_menu(menu);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
action_menu(Menu *menu)
 | 
						|
{
 | 
						|
    char c;
 | 
						|
    int mselect;
 | 
						|
    MenuItem item;
 | 
						|
 | 
						|
    if (menu->active == 0) {
 | 
						|
	if (menu->parent != NULL)
 | 
						|
	    menu->parent->active = 0;
 | 
						|
	return (0);
 | 
						|
    }
 | 
						|
    draw_all_menu(menu);
 | 
						|
    select_menu(menu, menu->select);
 | 
						|
 | 
						|
    while (1) {
 | 
						|
#ifdef USE_MOUSE
 | 
						|
	if (use_mouse)
 | 
						|
	    mouse_active();
 | 
						|
#endif				/* USE_MOUSE */
 | 
						|
	c = getch();
 | 
						|
#ifdef USE_MOUSE
 | 
						|
	if (use_mouse)
 | 
						|
	    mouse_inactive();
 | 
						|
#if defined(USE_GPM) || defined(USE_SYSMOUSE)
 | 
						|
	if (c == X_MOUSE_SELECTED) {
 | 
						|
	    mselect = X_Mouse_Selection;
 | 
						|
	    if (mselect != MENU_NOTHING)
 | 
						|
		break;
 | 
						|
	}
 | 
						|
#endif				/* defined(USE_GPM) || defined(USE_SYSMOUSE) */
 | 
						|
#endif				/* USE_MOUSE */
 | 
						|
	if (IS_ASCII(c)) {	/* Ascii */
 | 
						|
	    mselect = (*menu->keymap[(int)c]) (c);
 | 
						|
	    if (mselect != MENU_NOTHING)
 | 
						|
		break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (mselect >= 0 && mselect < menu->nitem) {
 | 
						|
	item = menu->item[mselect];
 | 
						|
	if (item.type & MENU_POPUP) {
 | 
						|
	    popup_menu(menu, item.popup);
 | 
						|
	    return (1);
 | 
						|
	}
 | 
						|
	if (menu->parent != NULL)
 | 
						|
	    menu->parent->active = 0;
 | 
						|
	if (item.type & MENU_VALUE)
 | 
						|
	    *item.variable = item.value;
 | 
						|
	if (item.type & MENU_FUNC) {
 | 
						|
	    CurrentKey = -1;
 | 
						|
	    CurrentKeyData = NULL;
 | 
						|
	    CurrentCmdData = item.data;
 | 
						|
	    (*item.func) ();
 | 
						|
	    CurrentCmdData = NULL;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (mselect == MENU_CLOSE) {
 | 
						|
	if (menu->parent != NULL)
 | 
						|
	    menu->parent->active = 0;
 | 
						|
    }
 | 
						|
    return (0);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
popup_menu(Menu *parent, Menu *menu)
 | 
						|
{
 | 
						|
    int active = 1;
 | 
						|
 | 
						|
    if (menu->item == NULL || menu->nitem == 0)
 | 
						|
	return;
 | 
						|
    if (menu->active)
 | 
						|
	return;
 | 
						|
 | 
						|
#ifdef USE_MOUSE
 | 
						|
#ifdef USE_GPM
 | 
						|
    gpm_handler = gpm_process_menu_mouse;
 | 
						|
#endif				/* USE_GPM */
 | 
						|
#ifdef USE_SYSMOUSE
 | 
						|
    sysm_handler = sysm_process_menu_mouse;
 | 
						|
#endif				/* USE_SYSMOUSE */
 | 
						|
#endif				/* USE_MOUSE */
 | 
						|
    menu->parent = parent;
 | 
						|
    menu->select = menu->initial;
 | 
						|
    menu->offset = 0;
 | 
						|
    menu->active = 1;
 | 
						|
    if (parent != NULL) {
 | 
						|
	menu->cursorX = parent->cursorX;
 | 
						|
	menu->cursorY = parent->cursorY;
 | 
						|
	guess_menu_xy(parent, menu->width, &menu->x, &menu->y);
 | 
						|
    }
 | 
						|
    geom_menu(menu, menu->x, menu->y, menu->select);
 | 
						|
 | 
						|
    CurrentMenu = menu;
 | 
						|
    while (active) {
 | 
						|
	active = action_menu(CurrentMenu);
 | 
						|
	displayBuffer(Currentbuf, B_FORCE_REDRAW);
 | 
						|
    }
 | 
						|
    menu->active = 0;
 | 
						|
    CurrentMenu = parent;
 | 
						|
#ifdef USE_MOUSE
 | 
						|
#ifdef USE_GPM
 | 
						|
    if (CurrentMenu == NULL)
 | 
						|
	gpm_handler = gpm_process_mouse;
 | 
						|
#endif				/* USE_GPM */
 | 
						|
#ifdef USE_SYSMOUSE
 | 
						|
    if (CurrentMenu == NULL)
 | 
						|
	sysm_handler = sysm_process_mouse;
 | 
						|
#endif				/* USE_SYSMOUSE */
 | 
						|
#endif				/* USE_MOUSE */
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
guess_menu_xy(Menu *parent, int width, int *x, int *y)
 | 
						|
{
 | 
						|
    *x = parent->x + parent->width + FRAME_WIDTH - 1;
 | 
						|
    if (*x + width + FRAME_WIDTH > COLS) {
 | 
						|
	*x = COLS - width - FRAME_WIDTH;
 | 
						|
	if ((parent->x + parent->width / 2 > *x) &&
 | 
						|
	    (parent->x + parent->width / 2 > COLS / 2))
 | 
						|
	    *x = parent->x - width - FRAME_WIDTH + 1;
 | 
						|
    }
 | 
						|
    *y = parent->y + parent->select - parent->offset;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
new_option_menu(Menu *menu, char **label, int *variable, void (*func) ())
 | 
						|
{
 | 
						|
    int i, nitem;
 | 
						|
    char **p;
 | 
						|
    MenuItem *item;
 | 
						|
 | 
						|
    if (label == NULL || *label == NULL)
 | 
						|
	return;
 | 
						|
 | 
						|
    for (i = 0, p = label; *p != NULL; i++, p++) ;
 | 
						|
    nitem = i;
 | 
						|
 | 
						|
    item = New_N(MenuItem, nitem + 1);
 | 
						|
 | 
						|
    for (i = 0, p = label; i < nitem; i++, p++) {
 | 
						|
	if (func != NULL)
 | 
						|
	    item[i].type = MENU_VALUE | MENU_FUNC;
 | 
						|
	else
 | 
						|
	    item[i].type = MENU_VALUE;
 | 
						|
	item[i].label = *p;
 | 
						|
	item[i].variable = variable;
 | 
						|
	item[i].value = i;
 | 
						|
	item[i].func = func;
 | 
						|
	item[i].popup = NULL;
 | 
						|
	item[i].keys = "";
 | 
						|
    }
 | 
						|
    item[nitem].type = MENU_END;
 | 
						|
 | 
						|
    new_menu(menu, item);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
set_menu_frame(void)
 | 
						|
{
 | 
						|
    if (graph_ok()) {
 | 
						|
	graph_mode = TRUE;
 | 
						|
	FRAME_WIDTH = 1;
 | 
						|
	FRAME = graph_symbol;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	graph_mode = FALSE;
 | 
						|
#ifdef USE_M17N
 | 
						|
	FRAME_WIDTH = 0;
 | 
						|
	FRAME = get_symbol(DisplayCharset, &FRAME_WIDTH);
 | 
						|
	if (!WcOption.use_wide)
 | 
						|
	    FRAME_WIDTH = 1;
 | 
						|
#else
 | 
						|
	FRAME_WIDTH = 1;
 | 
						|
	FRAME = get_symbol();
 | 
						|
#endif
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* --- MenuFunctions --- */
 | 
						|
 | 
						|
#ifdef __EMX__
 | 
						|
static int
 | 
						|
mPc(char c)
 | 
						|
{
 | 
						|
    c = getch();
 | 
						|
    return (MenuPcKeymap[(int)c] (c));
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static int
 | 
						|
mEsc(char c)
 | 
						|
{
 | 
						|
    c = getch();
 | 
						|
    return (MenuEscKeymap[(int)c] (c));
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mEscB(char c)
 | 
						|
{
 | 
						|
    c = getch();
 | 
						|
    if (IS_DIGIT(c))
 | 
						|
	return (mEscD(c));
 | 
						|
    else
 | 
						|
	return (MenuEscBKeymap[(int)c] (c));
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mEscD(char c)
 | 
						|
{
 | 
						|
    int d;
 | 
						|
 | 
						|
    d = (int)c - (int)'0';
 | 
						|
    c = getch();
 | 
						|
    if (IS_DIGIT(c)) {
 | 
						|
	d = d * 10 + (int)c - (int)'0';
 | 
						|
	c = getch();
 | 
						|
    }
 | 
						|
    if (c == '~')
 | 
						|
	return (MenuEscDKeymap[d] (c));
 | 
						|
    else
 | 
						|
	return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mNull(char c)
 | 
						|
{
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSelect(char c)
 | 
						|
{
 | 
						|
    if (IS_ASCII(c))
 | 
						|
	return (select_menu(CurrentMenu, CurrentMenu->keyselect[(int)c]));
 | 
						|
    else
 | 
						|
	return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mDown(char c)
 | 
						|
{
 | 
						|
    if (CurrentMenu->select >= CurrentMenu->nitem - 1)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    goto_menu(CurrentMenu, CurrentMenu->select + 1, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mUp(char c)
 | 
						|
{
 | 
						|
    if (CurrentMenu->select <= 0)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    goto_menu(CurrentMenu, CurrentMenu->select - 1, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mLast(char c)
 | 
						|
{
 | 
						|
    goto_menu(CurrentMenu, CurrentMenu->nitem - 1, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mTop(char c)
 | 
						|
{
 | 
						|
    goto_menu(CurrentMenu, 0, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mNext(char c)
 | 
						|
{
 | 
						|
    int mselect = CurrentMenu->select + CurrentMenu->height;
 | 
						|
 | 
						|
    if (mselect >= CurrentMenu->nitem)
 | 
						|
	return mLast(c);
 | 
						|
    down_menu(CurrentMenu, CurrentMenu->height);
 | 
						|
    goto_menu(CurrentMenu, mselect, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mPrev(char c)
 | 
						|
{
 | 
						|
    int mselect = CurrentMenu->select - CurrentMenu->height;
 | 
						|
 | 
						|
    if (mselect < 0)
 | 
						|
	return mTop(c);
 | 
						|
    up_menu(CurrentMenu, CurrentMenu->height);
 | 
						|
    goto_menu(CurrentMenu, mselect, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mFore(char c)
 | 
						|
{
 | 
						|
    if (CurrentMenu->select >= CurrentMenu->nitem - 1)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    goto_menu(CurrentMenu, (CurrentMenu->select + CurrentMenu->height - 1),
 | 
						|
	      (CurrentMenu->height + 1));
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mBack(char c)
 | 
						|
{
 | 
						|
    if (CurrentMenu->select <= 0)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    goto_menu(CurrentMenu, (CurrentMenu->select - CurrentMenu->height + 1),
 | 
						|
	      (-1 - CurrentMenu->height));
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mLineU(char c)
 | 
						|
{
 | 
						|
    int mselect = CurrentMenu->select;
 | 
						|
 | 
						|
    if (mselect >= CurrentMenu->nitem)
 | 
						|
	return mLast(c);
 | 
						|
    if (CurrentMenu->offset + CurrentMenu->height >= CurrentMenu->nitem)
 | 
						|
	mselect++;
 | 
						|
    else {
 | 
						|
	down_menu(CurrentMenu, 1);
 | 
						|
	if (mselect < CurrentMenu->offset)
 | 
						|
	    mselect++;
 | 
						|
    }
 | 
						|
    goto_menu(CurrentMenu, mselect, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mLineD(char c)
 | 
						|
{
 | 
						|
    int mselect = CurrentMenu->select;
 | 
						|
 | 
						|
    if (mselect <= 0)
 | 
						|
	return mTop(c);
 | 
						|
    if (CurrentMenu->offset <= 0)
 | 
						|
	mselect--;
 | 
						|
    else {
 | 
						|
	up_menu(CurrentMenu, 1);
 | 
						|
	if (mselect >= CurrentMenu->offset + CurrentMenu->height)
 | 
						|
	    mselect--;
 | 
						|
    }
 | 
						|
    goto_menu(CurrentMenu, mselect, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mOk(char c)
 | 
						|
{
 | 
						|
    int mselect = CurrentMenu->select;
 | 
						|
 | 
						|
    if (CurrentMenu->item[mselect].type == MENU_NOP)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    return (mselect);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mCancel(char c)
 | 
						|
{
 | 
						|
    return (MENU_CANCEL);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mClose(char c)
 | 
						|
{
 | 
						|
    return (MENU_CLOSE);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSusp(char c)
 | 
						|
{
 | 
						|
    susp();
 | 
						|
    draw_all_menu(CurrentMenu);
 | 
						|
    select_menu(CurrentMenu, CurrentMenu->select);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static char *SearchString = NULL;
 | 
						|
 | 
						|
int (*menuSearchRoutine) (Menu *, char *, int);
 | 
						|
 | 
						|
static int
 | 
						|
menuForwardSearch(Menu *menu, char *str, int from)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    char *p;
 | 
						|
    if ((p = regexCompile(str, IgnoreCase)) != NULL) {
 | 
						|
	message(p, 0, 0);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
    if (from < 0)
 | 
						|
	from = 0;
 | 
						|
    for (i = from; i < menu->nitem; i++)
 | 
						|
	if (menu->item[i].type != MENU_NOP &&
 | 
						|
	    regexMatch(menu->item[i].label, -1, 1) == 1)
 | 
						|
	    return i;
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
menu_search_forward(Menu *menu, int from)
 | 
						|
{
 | 
						|
    char *str;
 | 
						|
    int found;
 | 
						|
    str = inputStrHist("Forward: ", NULL, TextHist);
 | 
						|
    if (str != NULL && *str == '\0')
 | 
						|
	str = SearchString;
 | 
						|
    if (str == NULL || *str == '\0')
 | 
						|
	return -1;
 | 
						|
    SearchString = str;
 | 
						|
    str = conv_search_string(str, DisplayCharset);
 | 
						|
    menuSearchRoutine = menuForwardSearch;
 | 
						|
    found = menuForwardSearch(menu, str, from + 1);
 | 
						|
    if (WrapSearch && found == -1)
 | 
						|
	found = menuForwardSearch(menu, str, 0);
 | 
						|
    if (found >= 0)
 | 
						|
	return found;
 | 
						|
    disp_message("Not found", TRUE);
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSrchF(char c)
 | 
						|
{
 | 
						|
    int mselect;
 | 
						|
    mselect = menu_search_forward(CurrentMenu, CurrentMenu->select);
 | 
						|
    if (mselect >= 0)
 | 
						|
	goto_menu(CurrentMenu, mselect, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
menuBackwardSearch(Menu *menu, char *str, int from)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    char *p;
 | 
						|
    if ((p = regexCompile(str, IgnoreCase)) != NULL) {
 | 
						|
	message(p, 0, 0);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
    if (from >= menu->nitem)
 | 
						|
	from = menu->nitem - 1;
 | 
						|
    for (i = from; i >= 0; i--)
 | 
						|
	if (menu->item[i].type != MENU_NOP &&
 | 
						|
	    regexMatch(menu->item[i].label, -1, 1) == 1)
 | 
						|
	    return i;
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
menu_search_backward(Menu *menu, int from)
 | 
						|
{
 | 
						|
    char *str;
 | 
						|
    int found;
 | 
						|
    str = inputStrHist("Backward: ", NULL, TextHist);
 | 
						|
    if (str != NULL && *str == '\0')
 | 
						|
	str = SearchString;
 | 
						|
    if (str == NULL || *str == '\0')
 | 
						|
	return -1;
 | 
						|
    SearchString = str;
 | 
						|
    str = conv_search_string(str, DisplayCharset);
 | 
						|
    menuSearchRoutine = menuBackwardSearch;
 | 
						|
    found = menuBackwardSearch(menu, str, from - 1);
 | 
						|
    if (WrapSearch && found == -1)
 | 
						|
	found = menuBackwardSearch(menu, str, menu->nitem);
 | 
						|
    if (found >= 0)
 | 
						|
	return found;
 | 
						|
    disp_message("Not found", TRUE);
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSrchB(char c)
 | 
						|
{
 | 
						|
    int mselect;
 | 
						|
    mselect = menu_search_backward(CurrentMenu, CurrentMenu->select);
 | 
						|
    if (mselect >= 0)
 | 
						|
	goto_menu(CurrentMenu, mselect, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
menu_search_next_previous(Menu *menu, int from, int reverse)
 | 
						|
{
 | 
						|
    int found;
 | 
						|
    static int (*routine[2]) (Menu *, char *, int) = {
 | 
						|
    menuForwardSearch, menuBackwardSearch};
 | 
						|
    char *str;
 | 
						|
 | 
						|
    if (menuSearchRoutine == NULL) {
 | 
						|
	disp_message("No previous regular expression", TRUE);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
    str = conv_search_string(SearchString, DisplayCharset);
 | 
						|
    if (reverse != 0)
 | 
						|
	reverse = 1;
 | 
						|
    if (menuSearchRoutine == menuBackwardSearch)
 | 
						|
	reverse ^= 1;
 | 
						|
    from += reverse ? -1 : 1;
 | 
						|
    found = (*routine[reverse]) (menu, str, from);
 | 
						|
    if (WrapSearch && found == -1)
 | 
						|
	found = (*routine[reverse]) (menu, str, reverse * menu->nitem);
 | 
						|
    if (found >= 0)
 | 
						|
	return found;
 | 
						|
    disp_message("Not found", TRUE);
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSrchN(char c)
 | 
						|
{
 | 
						|
    int mselect;
 | 
						|
    mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 0);
 | 
						|
    if (mselect >= 0)
 | 
						|
	goto_menu(CurrentMenu, mselect, 1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mSrchP(char c)
 | 
						|
{
 | 
						|
    int mselect;
 | 
						|
    mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 1);
 | 
						|
    if (mselect >= 0)
 | 
						|
	goto_menu(CurrentMenu, mselect, -1);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef USE_MOUSE
 | 
						|
#define MOUSE_BTN1_DOWN 0
 | 
						|
#define MOUSE_BTN2_DOWN 1
 | 
						|
#define MOUSE_BTN3_DOWN 2
 | 
						|
#define MOUSE_BTN4_DOWN_RXVT 3
 | 
						|
#define MOUSE_BTN5_DOWN_RXVT 4
 | 
						|
#define MOUSE_BTN4_DOWN_XTERM 64
 | 
						|
#define MOUSE_BTN5_DOWN_XTERM 65
 | 
						|
#define MOUSE_BTN_UP 3
 | 
						|
#define MOUSE_BTN_RESET -1
 | 
						|
 | 
						|
static int
 | 
						|
mMouse_scroll_line(void)
 | 
						|
{
 | 
						|
    int i = 0;
 | 
						|
    if (relative_wheel_scroll)
 | 
						|
	i = (relative_wheel_scroll_ratio * CurrentMenu->height + 99) / 100;
 | 
						|
    else
 | 
						|
	i = fixed_wheel_scroll_count;
 | 
						|
    return i ? i : 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
process_mMouse(int btn, int x, int y)
 | 
						|
{
 | 
						|
    Menu *menu;
 | 
						|
    int mselect, i;
 | 
						|
    static int press_btn = MOUSE_BTN_RESET, press_x, press_y;
 | 
						|
    char c = ' ';
 | 
						|
 | 
						|
    menu = CurrentMenu;
 | 
						|
 | 
						|
    if (x < 0 || x >= COLS || y < 0 || y > LASTLINE)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
 | 
						|
    if (btn == MOUSE_BTN_UP) {
 | 
						|
	switch (press_btn) {
 | 
						|
	case MOUSE_BTN1_DOWN:
 | 
						|
	case MOUSE_BTN3_DOWN:
 | 
						|
	    if (x < menu->x - FRAME_WIDTH ||
 | 
						|
		x >= menu->x + menu->width + FRAME_WIDTH ||
 | 
						|
		y < menu->y - 1 || y >= menu->y + menu->height + 1) {
 | 
						|
		return (MENU_CANCEL);
 | 
						|
	    }
 | 
						|
	    else if ((x >= menu->x - FRAME_WIDTH &&
 | 
						|
		      x < menu->x) ||
 | 
						|
		     (x >= menu->x + menu->width &&
 | 
						|
		      x < menu->x + menu->width + FRAME_WIDTH)) {
 | 
						|
		return (MENU_NOTHING);
 | 
						|
	    }
 | 
						|
	    else if (press_y > y) {
 | 
						|
		for (i = 0; i < press_y - y; i++)
 | 
						|
		    mLineU(c);
 | 
						|
		return (MENU_NOTHING);
 | 
						|
	    }
 | 
						|
	    else if (press_y < y) {
 | 
						|
		for (i = 0; i < y - press_y; i++)
 | 
						|
		    mLineD(c);
 | 
						|
		return (MENU_NOTHING);
 | 
						|
	    }
 | 
						|
	    else if (y == menu->y - 1) {
 | 
						|
		mPrev(c);
 | 
						|
		return (MENU_NOTHING);
 | 
						|
	    }
 | 
						|
	    else if (y == menu->y + menu->height) {
 | 
						|
		mNext(c);
 | 
						|
		return (MENU_NOTHING);
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		mselect = y - menu->y + menu->offset;
 | 
						|
		if (menu->item[mselect].type == MENU_NOP)
 | 
						|
		    return (MENU_NOTHING);
 | 
						|
		return (select_menu(menu, mselect));
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	case MOUSE_BTN4_DOWN_RXVT:
 | 
						|
	    for (i = 0; i < mMouse_scroll_line(); i++)
 | 
						|
		mLineD(c);
 | 
						|
	    break;
 | 
						|
	case MOUSE_BTN5_DOWN_RXVT:
 | 
						|
	    for (i = 0; i < mMouse_scroll_line(); i++)
 | 
						|
		mLineU(c);
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (btn == MOUSE_BTN4_DOWN_XTERM) {
 | 
						|
	for (i = 0; i < mMouse_scroll_line(); i++)
 | 
						|
	    mLineD(c);
 | 
						|
    }
 | 
						|
    else if (btn == MOUSE_BTN5_DOWN_XTERM) {
 | 
						|
	for (i = 0; i < mMouse_scroll_line(); i++)
 | 
						|
	    mLineU(c);
 | 
						|
    }
 | 
						|
 | 
						|
    if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) {
 | 
						|
	press_btn = btn;
 | 
						|
	press_x = x;
 | 
						|
	press_y = y;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	press_btn = MOUSE_BTN_RESET;
 | 
						|
    }
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
mMouse(char c)
 | 
						|
{
 | 
						|
    int btn, x, y;
 | 
						|
 | 
						|
    btn = (unsigned char)getch() - 32;
 | 
						|
#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005
 | 
						|
    if (cygwin_mouse_btn_swapped) {
 | 
						|
	if (btn == MOUSE_BTN2_DOWN)
 | 
						|
	    btn = MOUSE_BTN3_DOWN;
 | 
						|
	else if (btn == MOUSE_BTN3_DOWN)
 | 
						|
	    btn = MOUSE_BTN2_DOWN;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    x = (unsigned char)getch() - 33;
 | 
						|
    if (x < 0)
 | 
						|
	x += 0x100;
 | 
						|
    y = (unsigned char)getch() - 33;
 | 
						|
    if (y < 0)
 | 
						|
	y += 0x100;
 | 
						|
 | 
						|
    /* 
 | 
						|
     * if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) return; */
 | 
						|
    return process_mMouse(btn, x, y);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef USE_GPM
 | 
						|
static int
 | 
						|
gpm_process_menu_mouse(Gpm_Event * event, void *data)
 | 
						|
{
 | 
						|
    int btn = MOUSE_BTN_RESET, x, y;
 | 
						|
    if (event->type & GPM_UP)
 | 
						|
	btn = MOUSE_BTN_UP;
 | 
						|
    else if (event->type & GPM_DOWN) {
 | 
						|
	switch (event->buttons) {
 | 
						|
	case GPM_B_LEFT:
 | 
						|
	    btn = MOUSE_BTN1_DOWN;
 | 
						|
	    break;
 | 
						|
	case GPM_B_MIDDLE:
 | 
						|
	    btn = MOUSE_BTN2_DOWN;
 | 
						|
	    break;
 | 
						|
	case GPM_B_RIGHT:
 | 
						|
	    btn = MOUSE_BTN3_DOWN;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	GPM_DRAWPOINTER(event);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
    x = event->x;
 | 
						|
    y = event->y;
 | 
						|
    X_Mouse_Selection = process_mMouse(btn, x - 1, y - 1);
 | 
						|
    return X_MOUSE_SELECTED;
 | 
						|
}
 | 
						|
#endif				/* USE_GPM */
 | 
						|
 | 
						|
#ifdef USE_SYSMOUSE
 | 
						|
static int
 | 
						|
sysm_process_menu_mouse(int x, int y, int nbs, int obs)
 | 
						|
{
 | 
						|
    int btn;
 | 
						|
    int bits;
 | 
						|
 | 
						|
    if (obs & ~nbs)
 | 
						|
	btn = MOUSE_BTN_UP;
 | 
						|
    else if (nbs & ~obs) {
 | 
						|
	bits = nbs & ~obs;
 | 
						|
	btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
 | 
						|
	    (bits & 0x2 ? MOUSE_BTN2_DOWN :
 | 
						|
	     (bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
 | 
						|
    }
 | 
						|
    else			/* nbs == obs */
 | 
						|
	return 0;
 | 
						|
    X_Mouse_Selection = process_mMouse(btn, x, y);
 | 
						|
    return X_MOUSE_SELECTED;
 | 
						|
}
 | 
						|
#endif				/* USE_SYSMOUSE */
 | 
						|
#else				/* not USE_MOUSE */
 | 
						|
static int
 | 
						|
mMouse(char c)
 | 
						|
{
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
#endif				/* not USE_MOUSE */
 | 
						|
 | 
						|
/* --- MenuFunctions (END) --- */
 | 
						|
 | 
						|
/* --- MainMenu --- */
 | 
						|
 | 
						|
void
 | 
						|
popupMenu(int x, int y, Menu *menu)
 | 
						|
{
 | 
						|
    set_menu_frame();
 | 
						|
 | 
						|
    initSelectMenu();
 | 
						|
    initSelTabMenu();
 | 
						|
 | 
						|
    menu->cursorX = Currentbuf->cursorX + Currentbuf->rootX;
 | 
						|
    menu->cursorY = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
    menu->x = x + FRAME_WIDTH + 1;
 | 
						|
    menu->y = y + 2;
 | 
						|
 | 
						|
    popup_menu(NULL, menu);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
mainMenu(int x, int y)
 | 
						|
{
 | 
						|
    popupMenu(x, y, &MainMenu);
 | 
						|
}
 | 
						|
 | 
						|
DEFUN(mainMn, MAIN_MENU MENU, "Popup menu")
 | 
						|
{
 | 
						|
    Menu *menu = &MainMenu;
 | 
						|
    char *data;
 | 
						|
    int n;
 | 
						|
    int x = Currentbuf->cursorX + Currentbuf->rootX,
 | 
						|
	y = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
 | 
						|
    data = searchKeyData();
 | 
						|
    if (data != NULL) {
 | 
						|
	n = getMenuN(w3mMenuList, data);
 | 
						|
	if (n < 0)
 | 
						|
	    return;
 | 
						|
	menu = w3mMenuList[n].menu;
 | 
						|
    }
 | 
						|
#ifdef USE_MOUSE
 | 
						|
    if (mouse_action.in_action) {
 | 
						|
	x = mouse_action.cursorX;
 | 
						|
	y = mouse_action.cursorY;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    popupMenu(x, y, menu);
 | 
						|
}
 | 
						|
 | 
						|
/* --- MainMenu (END) --- */
 | 
						|
 | 
						|
/* --- SelectMenu --- */
 | 
						|
 | 
						|
DEFUN(selMn, SELECT_MENU, "Popup buffer selection menu")
 | 
						|
{
 | 
						|
    int x = Currentbuf->cursorX + Currentbuf->rootX,
 | 
						|
	y = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
 | 
						|
#ifdef USE_MOUSE
 | 
						|
    if (mouse_action.in_action) {
 | 
						|
	x = mouse_action.cursorX;
 | 
						|
	y = mouse_action.cursorY;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    popupMenu(x, y, &SelectMenu);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
initSelectMenu(void)
 | 
						|
{
 | 
						|
    int i, nitem, len = 0, l;
 | 
						|
    Buffer *buf;
 | 
						|
    Str str;
 | 
						|
    char **label;
 | 
						|
    char *p;
 | 
						|
    static char *comment = " SPC for select / D for delete buffer ";
 | 
						|
 | 
						|
    SelectV = -1;
 | 
						|
    for (i = 0, buf = Firstbuf; buf != NULL; i++, buf = buf->nextBuffer) {
 | 
						|
	if (buf == Currentbuf)
 | 
						|
	    SelectV = i;
 | 
						|
    }
 | 
						|
    nitem = i;
 | 
						|
 | 
						|
    label = New_N(char *, nitem + 2);
 | 
						|
    for (i = 0, buf = Firstbuf; i < nitem; i++, buf = buf->nextBuffer) {
 | 
						|
	str = Sprintf("<%s>", buf->buffername);
 | 
						|
	if (buf->filename != NULL) {
 | 
						|
	    switch (buf->currentURL.scheme) {
 | 
						|
	    case SCM_LOCAL:
 | 
						|
		if (strcmp(buf->currentURL.file, "-")) {
 | 
						|
		    Strcat_char(str, ' ');
 | 
						|
		    Strcat_charp(str,
 | 
						|
				 conv_from_system(buf->currentURL.real_file));
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		/* case SCM_UNKNOWN: */
 | 
						|
	    case SCM_MISSING:
 | 
						|
		break;
 | 
						|
	    default:
 | 
						|
		Strcat_char(str, ' ');
 | 
						|
		p = url_decode2(parsedURL2Str(&buf->currentURL)->ptr, NULL);
 | 
						|
		Strcat_charp(str, p);
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	label[i] = str->ptr;
 | 
						|
	if (len < str->length)
 | 
						|
	    len = str->length;
 | 
						|
    }
 | 
						|
    l = get_strwidth(comment);
 | 
						|
    if (len < l + 4)
 | 
						|
	len = l + 4;
 | 
						|
    if (len > COLS - 2 * FRAME_WIDTH)
 | 
						|
	len = COLS - 2 * FRAME_WIDTH;
 | 
						|
    len = (len > 1) ? ((len - l + 1) / 2) : 0;
 | 
						|
    str = Strnew();
 | 
						|
    for (i = 0; i < len; i++)
 | 
						|
	Strcat_char(str, '-');
 | 
						|
    Strcat_charp(str, comment);
 | 
						|
    for (i = 0; i < len; i++)
 | 
						|
	Strcat_char(str, '-');
 | 
						|
    label[nitem] = str->ptr;
 | 
						|
    label[nitem + 1] = NULL;
 | 
						|
 | 
						|
    new_option_menu(&SelectMenu, label, &SelectV, smChBuf);
 | 
						|
    SelectMenu.initial = SelectV;
 | 
						|
    SelectMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX;
 | 
						|
    SelectMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
    SelectMenu.keymap['D'] = smDelBuf;
 | 
						|
    SelectMenu.item[nitem].type = MENU_NOP;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smChBuf(void)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    Buffer *buf;
 | 
						|
 | 
						|
    if (SelectV < 0 || SelectV >= SelectMenu.nitem)
 | 
						|
	return;
 | 
						|
    for (i = 0, buf = Firstbuf; i < SelectV; i++, buf = buf->nextBuffer) ;
 | 
						|
    Currentbuf = buf;
 | 
						|
    for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
 | 
						|
	if (buf == Currentbuf)
 | 
						|
	    continue;
 | 
						|
#ifdef USE_IMAGE
 | 
						|
	deleteImage(buf);
 | 
						|
#endif
 | 
						|
	if (clear_buffer)
 | 
						|
	    tmpClearBuffer(buf);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
smDelBuf(char c)
 | 
						|
{
 | 
						|
    int i, x, y, mselect;
 | 
						|
    Buffer *buf;
 | 
						|
 | 
						|
    if (CurrentMenu->select < 0 || CurrentMenu->select >= SelectMenu.nitem)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    for (i = 0, buf = Firstbuf; i < CurrentMenu->select;
 | 
						|
	 i++, buf = buf->nextBuffer) ;
 | 
						|
    if (Currentbuf == buf)
 | 
						|
	Currentbuf = buf->nextBuffer;
 | 
						|
    Firstbuf = deleteBuffer(Firstbuf, buf);
 | 
						|
    if (!Currentbuf)
 | 
						|
	Currentbuf = nthBuffer(Firstbuf, i - 1);;
 | 
						|
    if (Firstbuf == NULL) {
 | 
						|
	Firstbuf = nullBuffer();
 | 
						|
	Currentbuf = Firstbuf;
 | 
						|
    }
 | 
						|
 | 
						|
    x = CurrentMenu->x;
 | 
						|
    y = CurrentMenu->y;
 | 
						|
    mselect = CurrentMenu->select;
 | 
						|
 | 
						|
    initSelectMenu();
 | 
						|
 | 
						|
    CurrentMenu->x = x;
 | 
						|
    CurrentMenu->y = y;
 | 
						|
 | 
						|
    geom_menu(CurrentMenu, x, y, 0);
 | 
						|
 | 
						|
    CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect
 | 
						|
	: (CurrentMenu->nitem - 2);
 | 
						|
 | 
						|
    displayBuffer(Currentbuf, B_FORCE_REDRAW);
 | 
						|
    draw_all_menu(CurrentMenu);
 | 
						|
    select_menu(CurrentMenu, CurrentMenu->select);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
/* --- SelectMenu (END) --- */
 | 
						|
 | 
						|
/* --- SelTabMenu --- */
 | 
						|
 | 
						|
DEFUN(tabMn, TAB_MENU, "Popup tab selection menu")
 | 
						|
{
 | 
						|
    int x = Currentbuf->cursorX + Currentbuf->rootX,
 | 
						|
	y = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
 | 
						|
#ifdef USE_MOUSE
 | 
						|
    if (mouse_action.in_action) {
 | 
						|
	x = mouse_action.cursorX;
 | 
						|
	y = mouse_action.cursorY;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    popupMenu(x, y, &SelTabMenu);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
initSelTabMenu(void)
 | 
						|
{
 | 
						|
    int i, nitem, len = 0, l;
 | 
						|
    TabBuffer *tab;
 | 
						|
    Buffer *buf;
 | 
						|
    Str str;
 | 
						|
    char **label;
 | 
						|
    char *p;
 | 
						|
    static char *comment = " SPC for select / D for delete tab ";
 | 
						|
 | 
						|
    SelTabV = -1;
 | 
						|
    for (i = 0, tab = LastTab; tab != NULL; i++, tab = tab->prevTab) {
 | 
						|
	if (tab == CurrentTab)
 | 
						|
	    SelTabV = i;
 | 
						|
    }
 | 
						|
    nitem = i;
 | 
						|
 | 
						|
    label = New_N(char *, nitem + 2);
 | 
						|
    for (i = 0, tab = LastTab; i < nitem; i++, tab = tab->prevTab) {
 | 
						|
	buf = tab->currentBuffer;
 | 
						|
	str = Sprintf("<%s>", buf->buffername);
 | 
						|
	if (buf->filename != NULL) {
 | 
						|
	    switch (buf->currentURL.scheme) {
 | 
						|
	    case SCM_LOCAL:
 | 
						|
		if (strcmp(buf->currentURL.file, "-")) {
 | 
						|
		    Strcat_char(str, ' ');
 | 
						|
		    Strcat_charp(str,
 | 
						|
				 conv_from_system(buf->currentURL.real_file));
 | 
						|
		}
 | 
						|
		break;
 | 
						|
		/* case SCM_UNKNOWN: */
 | 
						|
	    case SCM_MISSING:
 | 
						|
		break;
 | 
						|
	    default:
 | 
						|
		p = url_decode2(parsedURL2Str(&buf->currentURL)->ptr, NULL);
 | 
						|
		Strcat_charp(str, p);
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	label[i] = str->ptr;
 | 
						|
	if (len < str->length)
 | 
						|
	    len = str->length;
 | 
						|
    }
 | 
						|
    l = strlen(comment);
 | 
						|
    if (len < l + 4)
 | 
						|
	len = l + 4;
 | 
						|
    if (len > COLS - 2 * FRAME_WIDTH)
 | 
						|
	len = COLS - 2 * FRAME_WIDTH;
 | 
						|
    len = (len > 1) ? ((len - l + 1) / 2) : 0;
 | 
						|
    str = Strnew();
 | 
						|
    for (i = 0; i < len; i++)
 | 
						|
	Strcat_char(str, '-');
 | 
						|
    Strcat_charp(str, comment);
 | 
						|
    for (i = 0; i < len; i++)
 | 
						|
	Strcat_char(str, '-');
 | 
						|
    label[nitem] = str->ptr;
 | 
						|
    label[nitem + 1] = NULL;
 | 
						|
 | 
						|
    new_option_menu(&SelTabMenu, label, &SelTabV, smChTab);
 | 
						|
    SelTabMenu.initial = SelTabV;
 | 
						|
    SelTabMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX;
 | 
						|
    SelTabMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY;
 | 
						|
    SelTabMenu.keymap['D'] = smDelTab;
 | 
						|
    SelTabMenu.item[nitem].type = MENU_NOP;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
smChTab(void)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    TabBuffer *tab;
 | 
						|
    Buffer *buf;
 | 
						|
 | 
						|
    if (SelTabV < 0 || SelTabV >= SelTabMenu.nitem)
 | 
						|
	return;
 | 
						|
    for (i = 0, tab = LastTab; i < SelTabV && tab != NULL;
 | 
						|
	 i++, tab = tab->prevTab) ;
 | 
						|
    CurrentTab = tab;
 | 
						|
    for (tab = LastTab; tab != NULL; tab = tab->prevTab) {
 | 
						|
	if (tab == CurrentTab)
 | 
						|
	    continue;
 | 
						|
	buf = tab->currentBuffer;
 | 
						|
#ifdef USE_IMAGE
 | 
						|
	deleteImage(buf);
 | 
						|
#endif
 | 
						|
	if (clear_buffer)
 | 
						|
	    tmpClearBuffer(buf);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
smDelTab(char c)
 | 
						|
{
 | 
						|
    int i, x, y, mselect;
 | 
						|
    TabBuffer *tab;
 | 
						|
 | 
						|
    if (CurrentMenu->select < 0 || CurrentMenu->select >= SelTabMenu.nitem)
 | 
						|
	return (MENU_NOTHING);
 | 
						|
    for (i = 0, tab = LastTab; i < CurrentMenu->select && tab != NULL;
 | 
						|
	 i++, tab = tab->prevTab) ;
 | 
						|
    deleteTab(tab);
 | 
						|
 | 
						|
    x = CurrentMenu->x;
 | 
						|
    y = CurrentMenu->y;
 | 
						|
    mselect = CurrentMenu->select;
 | 
						|
 | 
						|
    initSelTabMenu();
 | 
						|
 | 
						|
    CurrentMenu->x = x;
 | 
						|
    CurrentMenu->y = y;
 | 
						|
 | 
						|
    geom_menu(CurrentMenu, x, y, 0);
 | 
						|
 | 
						|
    CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect
 | 
						|
	: (CurrentMenu->nitem - 2);
 | 
						|
 | 
						|
    displayBuffer(Currentbuf, B_FORCE_REDRAW);
 | 
						|
    draw_all_menu(CurrentMenu);
 | 
						|
    select_menu(CurrentMenu, CurrentMenu->select);
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
/* --- SelectMenu (END) --- */
 | 
						|
 | 
						|
/* --- OptionMenu --- */
 | 
						|
 | 
						|
void
 | 
						|
optionMenu(int x, int y, char **label, int *variable, int initial,
 | 
						|
	   void (*func) ())
 | 
						|
{
 | 
						|
    Menu menu;
 | 
						|
 | 
						|
    set_menu_frame();
 | 
						|
 | 
						|
    new_option_menu(&menu, label, variable, func);
 | 
						|
    menu.cursorX = COLS - 1;
 | 
						|
    menu.cursorY = LASTLINE;
 | 
						|
    menu.x = x;
 | 
						|
    menu.y = y;
 | 
						|
    menu.initial = initial;
 | 
						|
 | 
						|
    popup_menu(NULL, &menu);
 | 
						|
}
 | 
						|
 | 
						|
/* --- OptionMenu (END) --- */
 | 
						|
 | 
						|
/* --- InitMenu --- */
 | 
						|
 | 
						|
static void
 | 
						|
interpret_menu(FILE * mf)
 | 
						|
{
 | 
						|
    Str line;
 | 
						|
    char *p, *s;
 | 
						|
    int in_menu = 0, nmenu = 0, nitem = 0, type;
 | 
						|
    MenuItem *item = NULL;
 | 
						|
#ifdef USE_M17N
 | 
						|
    wc_ces charset = SystemCharset;
 | 
						|
#endif
 | 
						|
 | 
						|
    while (!feof(mf)) {
 | 
						|
	line = Strfgets(mf);
 | 
						|
	Strchop(line);
 | 
						|
	Strremovefirstspaces(line);
 | 
						|
	if (line->length == 0)
 | 
						|
	    continue;
 | 
						|
#ifdef USE_M17N
 | 
						|
	line = wc_Str_conv(line, charset, InnerCharset);
 | 
						|
#endif
 | 
						|
	p = line->ptr;
 | 
						|
	s = getWord(&p);
 | 
						|
	if (*s == '#')		/* comment */
 | 
						|
	    continue;
 | 
						|
	if (in_menu) {
 | 
						|
	    type = setMenuItem(&item[nitem], s, p);
 | 
						|
	    if (type == -1)
 | 
						|
		continue;	/* error */
 | 
						|
	    if (type == MENU_END)
 | 
						|
		in_menu = 0;
 | 
						|
	    else {
 | 
						|
		nitem++;
 | 
						|
		item = New_Reuse(MenuItem, item, (nitem + 1));
 | 
						|
		w3mMenuList[nmenu].item = item;
 | 
						|
		item[nitem].type = MENU_END;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else if (!strcmp(s, "menu")) {
 | 
						|
	    s = getQWord(&p);
 | 
						|
	    if (*s == '\0')	/* error */
 | 
						|
		continue;
 | 
						|
	    in_menu = 1;
 | 
						|
	    if ((nmenu = getMenuN(w3mMenuList, s)) != -1)
 | 
						|
		w3mMenuList[nmenu].item = New(MenuItem);
 | 
						|
	    else
 | 
						|
		nmenu = addMenuList(&w3mMenuList, s);
 | 
						|
	    item = w3mMenuList[nmenu].item;
 | 
						|
	    nitem = 0;
 | 
						|
	    item[nitem].type = MENU_END;
 | 
						|
	}
 | 
						|
#ifdef USE_M17N
 | 
						|
	else if (!strcmp(s, "charset") || !strcmp(s, "encoding")) {
 | 
						|
	    s = getQWord(&p);
 | 
						|
	    if (*s == '\0')	/* error */
 | 
						|
		continue;
 | 
						|
	    charset = wc_guess_charset(s, charset);
 | 
						|
	}
 | 
						|
#endif
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
initMenu(void)
 | 
						|
{
 | 
						|
    FILE *mf;
 | 
						|
    MenuList *list;
 | 
						|
 | 
						|
    w3mMenuList = New_N(MenuList, 3);
 | 
						|
    w3mMenuList[0].id = "Main";
 | 
						|
    w3mMenuList[0].menu = &MainMenu;
 | 
						|
    w3mMenuList[0].item = MainMenuItem;
 | 
						|
    w3mMenuList[1].id = "Select";
 | 
						|
    w3mMenuList[1].menu = &SelectMenu;
 | 
						|
    w3mMenuList[1].item = NULL;
 | 
						|
    w3mMenuList[2].id = "SelectTab";
 | 
						|
    w3mMenuList[2].menu = &SelTabMenu;
 | 
						|
    w3mMenuList[2].item = NULL;
 | 
						|
    w3mMenuList[3].id = NULL;
 | 
						|
 | 
						|
#ifdef USE_M17N
 | 
						|
    if (!MainMenuEncode) {
 | 
						|
	MenuItem *item;
 | 
						|
#ifdef ENABLE_NLS
 | 
						|
	/* FIXME: charset that gettext(3) returns */
 | 
						|
	MainMenuCharset = SystemCharset;
 | 
						|
#endif
 | 
						|
	for (item = MainMenuItem; item->type != MENU_END; item++)
 | 
						|
	    item->label =
 | 
						|
		wc_conv(_(item->label), MainMenuCharset,
 | 
						|
			InnerCharset)->ptr;
 | 
						|
	MainMenuEncode = TRUE;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    if ((mf = fopen(confFile(MENU_FILE), "rt")) != NULL) {
 | 
						|
	interpret_menu(mf);
 | 
						|
	fclose(mf);
 | 
						|
    }
 | 
						|
    if ((mf = fopen(rcFile(MENU_FILE), "rt")) != NULL) {
 | 
						|
	interpret_menu(mf);
 | 
						|
	fclose(mf);
 | 
						|
    }
 | 
						|
 | 
						|
    for (list = w3mMenuList; list->id != NULL; list++) {
 | 
						|
	if (list->item == NULL)
 | 
						|
	    continue;
 | 
						|
	new_menu(list->menu, list->item);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
setMenuItem(MenuItem *item, char *type, char *line)
 | 
						|
{
 | 
						|
    char *label, *func, *popup, *keys, *data;
 | 
						|
    int f;
 | 
						|
    int n;
 | 
						|
 | 
						|
    if (type == NULL || *type == '\0')	/* error */
 | 
						|
	return -1;
 | 
						|
    if (strcmp(type, "end") == 0) {
 | 
						|
	item->type = MENU_END;
 | 
						|
	return MENU_END;
 | 
						|
    }
 | 
						|
    else if (strcmp(type, "nop") == 0) {
 | 
						|
	item->type = MENU_NOP;
 | 
						|
	item->label = getQWord(&line);
 | 
						|
	return MENU_NOP;
 | 
						|
    }
 | 
						|
    else if (strcmp(type, "func") == 0) {
 | 
						|
	label = getQWord(&line);
 | 
						|
	func = getWord(&line);
 | 
						|
	keys = getQWord(&line);
 | 
						|
	data = getQWord(&line);
 | 
						|
	if (*func == '\0')	/* error */
 | 
						|
	    return -1;
 | 
						|
	item->type = MENU_FUNC;
 | 
						|
	item->label = label;
 | 
						|
	f = getFuncList(func);
 | 
						|
	item->func = w3mFuncList[(f >= 0) ? f : FUNCNAME_nulcmd].func;
 | 
						|
	item->keys = keys;
 | 
						|
	item->data = data;
 | 
						|
	return MENU_FUNC;
 | 
						|
    }
 | 
						|
    else if (strcmp(type, "popup") == 0) {
 | 
						|
	label = getQWord(&line);
 | 
						|
	popup = getQWord(&line);
 | 
						|
	keys = getQWord(&line);
 | 
						|
	if (*popup == '\0')	/* error */
 | 
						|
	    return -1;
 | 
						|
	item->type = MENU_POPUP;
 | 
						|
	item->label = label;
 | 
						|
	if ((n = getMenuN(w3mMenuList, popup)) == -1)
 | 
						|
	    n = addMenuList(&w3mMenuList, popup);
 | 
						|
	item->popup = w3mMenuList[n].menu;
 | 
						|
	item->keys = keys;
 | 
						|
	return MENU_POPUP;
 | 
						|
    }
 | 
						|
    return -1;			/* error */
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
addMenuList(MenuList **mlist, char *id)
 | 
						|
{
 | 
						|
    int n;
 | 
						|
    MenuList *list = *mlist;
 | 
						|
 | 
						|
    for (n = 0; list->id != NULL; list++, n++) ;
 | 
						|
    *mlist = New_Reuse(MenuList, *mlist, (n + 2));
 | 
						|
    list = *mlist + n;
 | 
						|
    list->id = id;
 | 
						|
    list->menu = New(Menu);
 | 
						|
    list->item = New(MenuItem);
 | 
						|
    (list + 1)->id = NULL;
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
getMenuN(MenuList *list, char *id)
 | 
						|
{
 | 
						|
    int n;
 | 
						|
 | 
						|
    for (n = 0; list->id != NULL; list++, n++) {
 | 
						|
	if (strcmp(id, list->id) == 0)
 | 
						|
	    return n;
 | 
						|
    }
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
/* --- InitMenu (END) --- */
 | 
						|
 | 
						|
LinkList *
 | 
						|
link_menu(Buffer *buf)
 | 
						|
{
 | 
						|
    Menu menu;
 | 
						|
    LinkList *l;
 | 
						|
    int i, nitem, len = 0, linkV = -1;
 | 
						|
    char **label;
 | 
						|
    Str str;
 | 
						|
    char *p;
 | 
						|
 | 
						|
    if (!buf->linklist)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
    for (i = 0, l = buf->linklist; l; i++, l = l->next) ;
 | 
						|
    nitem = i;
 | 
						|
 | 
						|
    label = New_N(char *, nitem + 1);
 | 
						|
    for (i = 0, l = buf->linklist; l; i++, l = l->next) {
 | 
						|
	str = Strnew_charp(l->title ? l->title : "(empty)");
 | 
						|
	if (l->type == LINK_TYPE_REL)
 | 
						|
	    Strcat_charp(str, " [Rel] ");
 | 
						|
	else if (l->type == LINK_TYPE_REV)
 | 
						|
	    Strcat_charp(str, " [Rev] ");
 | 
						|
	else
 | 
						|
	    Strcat_charp(str, " ");
 | 
						|
	if (!l->url)
 | 
						|
	    p = "";
 | 
						|
	else
 | 
						|
	    p = url_decode2(l->url, buf);
 | 
						|
	Strcat_charp(str, p);
 | 
						|
	label[i] = str->ptr;
 | 
						|
	if (len < str->length)
 | 
						|
	    len = str->length;
 | 
						|
    }
 | 
						|
    label[nitem] = NULL;
 | 
						|
 | 
						|
    set_menu_frame();
 | 
						|
    new_option_menu(&menu, label, &linkV, NULL);
 | 
						|
 | 
						|
    menu.initial = 0;
 | 
						|
    menu.cursorX = buf->cursorX + buf->rootX;
 | 
						|
    menu.cursorY = buf->cursorY + buf->rootY;
 | 
						|
    menu.x = menu.cursorX + FRAME_WIDTH + 1;
 | 
						|
    menu.y = menu.cursorY + 2;
 | 
						|
 | 
						|
    popup_menu(NULL, &menu);
 | 
						|
 | 
						|
    if (linkV < 0)
 | 
						|
	return NULL;
 | 
						|
    for (i = 0, l = buf->linklist; l; i++, l = l->next) {
 | 
						|
	if (i == linkV)
 | 
						|
	    return l;
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* --- LinkMenu (END) --- */
 | 
						|
 | 
						|
Anchor *
 | 
						|
accesskey_menu(Buffer *buf)
 | 
						|
{
 | 
						|
    Menu menu;
 | 
						|
    AnchorList *al = buf->href;
 | 
						|
    Anchor *a;
 | 
						|
    Anchor **ap;
 | 
						|
    int i, n, nitem = 0, key = -1;
 | 
						|
    char **label;
 | 
						|
    char *t;
 | 
						|
    unsigned char c;
 | 
						|
 | 
						|
    if (!al)
 | 
						|
	return NULL;
 | 
						|
    for (i = 0; i < al->nanchor; i++) {
 | 
						|
	a = &al->anchors[i];
 | 
						|
	if (!a->slave && a->accesskey && IS_ASCII(a->accesskey))
 | 
						|
	    nitem++;
 | 
						|
    }
 | 
						|
    if (!nitem)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
    label = New_N(char *, nitem + 1);
 | 
						|
    ap = New_N(Anchor *, nitem);
 | 
						|
    for (i = 0, n = 0; i < al->nanchor; i++) {
 | 
						|
	a = &al->anchors[i];
 | 
						|
	if (!a->slave && a->accesskey && IS_ASCII(a->accesskey)) {
 | 
						|
	    t = getAnchorText(buf, al, a);
 | 
						|
	    label[n] = Sprintf("%c: %s", a->accesskey, t ? t : "")->ptr;
 | 
						|
	    ap[n] = a;
 | 
						|
	    n++;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    label[nitem] = NULL;
 | 
						|
 | 
						|
    new_option_menu(&menu, label, &key, NULL);
 | 
						|
 | 
						|
    menu.initial = 0;
 | 
						|
    menu.cursorX = buf->cursorX + buf->rootX;
 | 
						|
    menu.cursorY = buf->cursorY + buf->rootY;
 | 
						|
    menu.x = menu.cursorX + FRAME_WIDTH + 1;
 | 
						|
    menu.y = menu.cursorY + 2;
 | 
						|
    for (i = 0; i < 128; i++)
 | 
						|
	menu.keyselect[i] = -1;
 | 
						|
    for (i = 0; i < nitem; i++) {
 | 
						|
	c = ap[i]->accesskey;
 | 
						|
	menu.keymap[(int)c] = mSelect;
 | 
						|
	menu.keyselect[(int)c] = i;
 | 
						|
    }
 | 
						|
    for (i = 0; i < nitem; i++) {
 | 
						|
	c = ap[i]->accesskey;
 | 
						|
	if (!IS_ALPHA(c) || menu.keyselect[n] >= 0)
 | 
						|
	    continue;
 | 
						|
	c = TOLOWER(c);
 | 
						|
	menu.keymap[(int)c] = mSelect;
 | 
						|
	menu.keyselect[(int)c] = i;
 | 
						|
	c = TOUPPER(c);
 | 
						|
	menu.keymap[(int)c] = mSelect;
 | 
						|
	menu.keyselect[(int)c] = i;
 | 
						|
    }
 | 
						|
 | 
						|
    a = retrieveCurrentAnchor(buf);
 | 
						|
    if (a && a->accesskey && IS_ASCII(a->accesskey)) {
 | 
						|
	for (i = 0; i < nitem; i++) {
 | 
						|
	    if (a->hseq == ap[i]->hseq) {
 | 
						|
		menu.initial = i;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    popup_menu(NULL, &menu);
 | 
						|
 | 
						|
    return (key >= 0) ? ap[key] : NULL;
 | 
						|
}
 | 
						|
 | 
						|
static char lmKeys[] = "abcdefgimopqrstuvwxyz";
 | 
						|
static char lmKeys2[] = "1234567890ABCDEFGHILMOPQRSTUVWXYZ";
 | 
						|
#define nlmKeys (sizeof(lmKeys) - 1)
 | 
						|
#define nlmKeys2 (sizeof(lmKeys2) - 1)
 | 
						|
 | 
						|
static int
 | 
						|
lmGoto(char c)
 | 
						|
{
 | 
						|
    if (IS_ASCII(c) && CurrentMenu->keyselect[(int)c] >= 0) {
 | 
						|
	goto_menu(CurrentMenu, CurrentMenu->nitem - 1, -1);
 | 
						|
	goto_menu(CurrentMenu, CurrentMenu->keyselect[(int)c] * nlmKeys, 1);
 | 
						|
    }
 | 
						|
    return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
lmSelect(char c)
 | 
						|
{
 | 
						|
    if (IS_ASCII(c))
 | 
						|
	return select_menu(CurrentMenu, (CurrentMenu->select / nlmKeys) *
 | 
						|
			   nlmKeys + CurrentMenu->keyselect[(int)c]);
 | 
						|
    else
 | 
						|
	return (MENU_NOTHING);
 | 
						|
}
 | 
						|
 | 
						|
Anchor *
 | 
						|
list_menu(Buffer *buf)
 | 
						|
{
 | 
						|
    Menu menu;
 | 
						|
    AnchorList *al = buf->href;
 | 
						|
    Anchor *a;
 | 
						|
    Anchor **ap;
 | 
						|
    int i, n, nitem = 0, key = -1, two = FALSE;
 | 
						|
    char **label;
 | 
						|
    char *t;
 | 
						|
    unsigned char c;
 | 
						|
 | 
						|
    if (!al)
 | 
						|
	return NULL;
 | 
						|
    for (i = 0; i < al->nanchor; i++) {
 | 
						|
	a = &al->anchors[i];
 | 
						|
	if (!a->slave)
 | 
						|
	    nitem++;
 | 
						|
    }
 | 
						|
    if (!nitem)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
    if (nitem >= nlmKeys)
 | 
						|
	two = TRUE;
 | 
						|
    label = New_N(char *, nitem + 1);
 | 
						|
    ap = New_N(Anchor *, nitem);
 | 
						|
    for (i = 0, n = 0; i < al->nanchor; i++) {
 | 
						|
	a = &al->anchors[i];
 | 
						|
	if (!a->slave) {
 | 
						|
	    t = getAnchorText(buf, al, a);
 | 
						|
	    if (!t)
 | 
						|
		t = "";
 | 
						|
	    if (two && n >= nlmKeys2 * nlmKeys)
 | 
						|
		label[n] = Sprintf("  : %s", t)->ptr;
 | 
						|
	    else if (two)
 | 
						|
		label[n] = Sprintf("%c%c: %s", lmKeys2[n / nlmKeys],
 | 
						|
				   lmKeys[n % nlmKeys], t)->ptr;
 | 
						|
	    else
 | 
						|
		label[n] = Sprintf("%c: %s", lmKeys[n], t)->ptr;
 | 
						|
	    ap[n] = a;
 | 
						|
	    n++;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    label[nitem] = NULL;
 | 
						|
 | 
						|
    set_menu_frame();
 | 
						|
    set_menu_frame();
 | 
						|
    new_option_menu(&menu, label, &key, NULL);
 | 
						|
 | 
						|
    menu.initial = 0;
 | 
						|
    menu.cursorX = buf->cursorX + buf->rootX;
 | 
						|
    menu.cursorY = buf->cursorY + buf->rootY;
 | 
						|
    menu.x = menu.cursorX + FRAME_WIDTH + 1;
 | 
						|
    menu.y = menu.cursorY + 2;
 | 
						|
    for (i = 0; i < 128; i++)
 | 
						|
	menu.keyselect[i] = -1;
 | 
						|
    if (two) {
 | 
						|
	for (i = 0; i < nlmKeys2; i++) {
 | 
						|
	    c = lmKeys2[i];
 | 
						|
	    menu.keymap[(int)c] = lmGoto;
 | 
						|
	    menu.keyselect[(int)c] = i;
 | 
						|
	}
 | 
						|
	for (i = 0; i < nlmKeys; i++) {
 | 
						|
	    c = lmKeys[i];
 | 
						|
	    menu.keymap[(int)c] = lmSelect;
 | 
						|
	    menu.keyselect[(int)c] = i;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	for (i = 0; i < nitem; i++) {
 | 
						|
	    c = lmKeys[i];
 | 
						|
	    menu.keymap[(int)c] = mSelect;
 | 
						|
	    menu.keyselect[(int)c] = i;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    a = retrieveCurrentAnchor(buf);
 | 
						|
    if (a) {
 | 
						|
	for (i = 0; i < nitem; i++) {
 | 
						|
	    if (a->hseq == ap[i]->hseq) {
 | 
						|
		menu.initial = i;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    popup_menu(NULL, &menu);
 | 
						|
 | 
						|
    return (key >= 0) ? ap[key] : NULL;
 | 
						|
}
 | 
						|
 | 
						|
#endif				/* USE_MENU */
 |