2074 lines
51 KiB
C
2074 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 = 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 --- */
|
|
|
|
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 = 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;
|
|
#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 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 */
|