2123 lines
53 KiB
C
2123 lines
53 KiB
C
/* $Id: menu.c,v 1.38 2003/09/24 18:49:00 ukai 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;
|
||
#if LANG == JA
|
||
static wc_ces MainMenuCharset = WC_CES_EUC_JP; /* charset of source code */
|
||
static int MainMenuEncode = FALSE;
|
||
static MenuItem MainMenuItem[] = {
|
||
/* type label variabel value func popup keys data */
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> (b)", NULL, 0, backBf, NULL, "b", NULL},
|
||
{MENU_POPUP, "<EFBFBD>Хåե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (s)", NULL, 0, NULL, &SelectMenu, "s", NULL},
|
||
{MENU_POPUP, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (t)", NULL, 0, NULL, &SelTabMenu, "tT", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD> (v)", NULL, 0, vwSrc, NULL, "vV", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD> (e)", NULL, 0, editBf, NULL, "eE", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¸ (S)", NULL, 0, svSrc, NULL, "S", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD>ɤ߹<EFBFBD><EFBFBD><EFBFBD> (r)", NULL, 0, reload, NULL, "rR", NULL},
|
||
{MENU_NOP, "----------------", NULL, 0, nulcmd, NULL, "", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD> (a)", NULL, 0, followA, NULL, "a", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>ɽ<EFBFBD><EFBFBD> (n)", NULL, 0, tabA, NULL, "nN", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¸ (A)", NULL, 0, svA, NULL, "A", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD> (i)", NULL, 0, followI, NULL, "i", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¸ (I)", NULL, 0, svI, NULL, "I", NULL},
|
||
{MENU_FUNC, "<EFBFBD>ե졼<EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD> (f)", NULL, 0, rFrame, NULL, "fF", NULL},
|
||
{MENU_NOP, "----------------", NULL, 0, nulcmd, NULL, "", NULL},
|
||
{MENU_FUNC, "<EFBFBD>֥å<EFBFBD><EFBFBD>ޡ<EFBFBD><EFBFBD><EFBFBD> (B)", NULL, 0, ldBmark, NULL, "B", NULL},
|
||
{MENU_FUNC, "<EFBFBD>إ<EFBFBD><EFBFBD><EFBFBD> (h)", NULL, 0, ldhelp, NULL, "hH", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (o)", NULL, 0, ldOpt, NULL, "oO", NULL},
|
||
{MENU_NOP, "----------------", NULL, 0, nulcmd, NULL, "", NULL},
|
||
{MENU_FUNC, "<EFBFBD><EFBFBD>λ (q)", NULL, 0, qquitfm, NULL, "qQ", NULL},
|
||
{MENU_END, "", NULL, 0, nulcmd, NULL, "", NULL},
|
||
};
|
||
#else /* LANG != JA */
|
||
|
||
#ifdef USE_M17N
|
||
/* FIXME: gettextize here */
|
||
static wc_ces MainMenuCharset = WC_CES_US_ASCII;
|
||
#if ENABLE_NLS
|
||
static int MainMenuEncode = FALSE;
|
||
#else
|
||
static int MainMenuEncode = TRUE;
|
||
#endif
|
||
#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},
|
||
};
|
||
#endif /* LANG != JA */
|
||
|
||
/* --- 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;
|
||
#ifdef USE_M17N
|
||
if (SearchConv && !WcOption.pre_conv &&
|
||
Currentbuf->document_charset != DisplayCharset)
|
||
str = wtf_conv_fit(str, Currentbuf->document_charset);
|
||
#endif
|
||
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;
|
||
#ifdef USE_M17N
|
||
if (SearchConv && !WcOption.pre_conv &&
|
||
Currentbuf->document_charset != DisplayCharset)
|
||
str = wtf_conv_fit(str, Currentbuf->document_charset);
|
||
#endif
|
||
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;
|
||
}
|
||
#ifdef USE_M17N
|
||
str = SearchString;
|
||
if (SearchConv && !WcOption.pre_conv &&
|
||
Currentbuf->document_charset != DisplayCharset)
|
||
str = wtf_conv_fit(str, Currentbuf->document_charset);
|
||
#endif
|
||
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__)
|
||
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);
|
||
}
|
||
|
||
void
|
||
mainMn(void)
|
||
{
|
||
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 --- */
|
||
|
||
void
|
||
selMn(void)
|
||
{
|
||
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 = parsedURL2Str(&buf->currentURL)->ptr;
|
||
if (DecodeURL)
|
||
p = url_unquote_conv(p, 0);
|
||
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 --- */
|
||
|
||
void
|
||
tabMn(void)
|
||
{
|
||
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 = parsedURL2Str(&buf->currentURL)->ptr;
|
||
if (DecodeURL)
|
||
p = url_unquote_conv(p, 0);
|
||
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;
|
||
#if ENABLE_NLS
|
||
/* FIXME: charset that gettext(3) returns */
|
||
MainMenuCharset = SystemCharset;
|
||
#endif
|
||
for (item = MainMenuItem; item->type != MENU_END; item++)
|
||
item->label =
|
||
wc_conv(gettext(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 if (DecodeURL)
|
||
p = url_unquote_conv(l->url, buf->document_charset);
|
||
else
|
||
p = l->url;
|
||
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 */
|