CVS code -
+- General:
+ - Simplify processing of mouse events. Instead of calling
+ wenclose() to get the window a mouse event took place in and
+ manually adjusting the returned coordinates to be relative to
+ that window the mouse event took place in, call
+ wmouse_trafo(), which does both. Changes to do_browser(),
+ do_mouse(), do_statusbar_mouse(), do_yesno_prompt(), and
+ do_mouseinput(). (DLR)
- winio.c:
get_key_buffer()
- Fix inaccurate comments. (DLR)
+ do_mouseinput()
+ - Add mouse wheel support. Now, if mouse support is enabled,
+ and nano is using a version of ncurses compiled with the
+ --enable-ext-mouse option, rolling the mouse wheel up or down
+ will move the cursor three lines up or down. Note that
+ ncurses built without --enable-ext-mouse needs to handle both
+ clicks and releases of the first mouse button, but ncurses
+ built with --enable-ext-mouse only needs to handle releases,
+ so keep dealing with both events. (DLR, suggested by Helmut
+ Jarausch)
GNU nano 2.0.6 - 2007.04.26
- text.c:
{
int mouse_x, mouse_y;
- if (!get_mouseinput(&mouse_x, &mouse_y, TRUE)) {
- /* We can click in the edit window to select a
- * filename. */
- if (wenclose(edit, mouse_y, mouse_x)) {
- /* Subtract out the size of topwin. */
- mouse_y -= 2 - no_more_space();
-
- /* longest is the width of each column.
- * There are two spaces between each
- * column. */
- selected = (fileline / editwinrows) *
+ /* We can click on the edit window to select a
+ * filename. */
+ if (get_mouseinput(&mouse_x, &mouse_y, TRUE) == 0 &&
+ wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
+ /* longest is the width of each column. There
+ * are two spaces between each column. */
+ selected = (fileline / editwinrows) *
(editwinrows * width) + (mouse_y *
width) + (mouse_x / (longest + 2));
- /* If they clicked beyond the end of a row,
- * select the filename at the end of that
- * row. */
- if (mouse_x > width * (longest + 2))
- selected--;
-
- /* If we're off the screen, select the last
- * filename. */
- if (selected > filelist_len - 1)
- selected = filelist_len - 1;
-
- /* If we selected the same filename as last
- * time, put back the Enter key so that it's
- * read in. */
- if (old_selected == selected)
- unget_kbinput(NANO_ENTER_KEY, FALSE,
- FALSE);
- }
+ /* If they clicked beyond the end of a row,
+ * select the filename at the end of that
+ * row. */
+ if (mouse_x > width * (longest + 2))
+ selected--;
+
+ /* If we're off the screen, select the last
+ * filename. */
+ if (selected > filelist_len - 1)
+ selected = filelist_len - 1;
+
+ /* If we selected the same filename as last
+ * time, put back the Enter key so that it's
+ * read in. */
+ if (old_selected == selected)
+ unget_kbinput(NANO_ENTER_KEY, FALSE, FALSE);
}
}
break;
/* If we got a mouse click and it was on a shortcut, read in the
* shortcut character. */
if (*func_key && input == KEY_MOUSE) {
- if (do_mouse())
+ if (do_mouse() == 1)
input = get_kbinput(edit, meta_key, func_key);
else {
*meta_key = FALSE;
#ifndef DISABLE_MOUSE
/* Handle a mouse click on the edit window or the shortcut list. */
-bool do_mouse(void)
+int do_mouse(void)
{
int mouse_x, mouse_y;
- bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
-
- if (!retval) {
- /* We can click in the edit window to move the cursor. */
- if (wenclose(edit, mouse_y, mouse_x)) {
- bool sameline;
- /* Did they click on the line with the cursor? If they
- * clicked on the cursor, we set the mark. */
- const filestruct *current_save = openfile->current;
- size_t current_x_save = openfile->current_x;
- size_t pww_save = openfile->placewewant;
-
- /* Subtract out the size of topwin. */
- mouse_y -= 2 - no_more_space();
-
- sameline = (mouse_y == openfile->current_y);
-
- /* Move to where the click occurred. */
- for (; openfile->current_y < mouse_y &&
- openfile->current != openfile->filebot;
- openfile->current_y++)
- openfile->current = openfile->current->next;
- for (; openfile->current_y > mouse_y &&
- openfile->current != openfile->fileage;
- openfile->current_y--)
- openfile->current = openfile->current->prev;
-
- openfile->current_x = actual_x(openfile->current->data,
+ int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
+
+ /* We can click on the edit window to move the cursor. */
+ if (retval == 0 && wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
+ bool sameline;
+ /* Did they click on the line with the cursor? If they
+ * clicked on the cursor, we set the mark. */
+ const filestruct *current_save = openfile->current;
+ size_t current_x_save = openfile->current_x;
+ size_t pww_save = openfile->placewewant;
+
+ sameline = (mouse_y == openfile->current_y);
+
+ /* Move to where the click occurred. */
+ for (; openfile->current_y < mouse_y && openfile->current !=
+ openfile->filebot; openfile->current_y++)
+ openfile->current = openfile->current->next;
+ for (; openfile->current_y > mouse_y && openfile->current !=
+ openfile->fileage; openfile->current_y--)
+ openfile->current = openfile->current->prev;
+
+ openfile->current_x = actual_x(openfile->current->data,
get_page_start(xplustabs()) + mouse_x);
- openfile->placewewant = xplustabs();
+ openfile->placewewant = xplustabs();
#ifndef NANO_TINY
- /* Clicking where the cursor is toggles the mark, as does
- * clicking beyond the line length with the cursor at the
- * end of the line. */
- if (sameline && openfile->current_x == current_x_save)
- do_mark();
+ /* Clicking where the cursor is toggles the mark, as does
+ * clicking beyond the line length with the cursor at the end of
+ * the line. */
+ if (sameline && openfile->current_x == current_x_save)
+ do_mark();
#endif
- edit_redraw(current_save, pww_save);
- }
+ edit_redraw(current_save, pww_save);
}
return retval;
/* If we got a mouse click and it was on a shortcut, read in the
* shortcut character. */
if (*func_key && input == KEY_MOUSE) {
- if (do_statusbar_mouse())
+ if (do_statusbar_mouse() == 1)
input = get_kbinput(bottomwin, meta_key, func_key);
else {
*meta_key = FALSE;
#ifndef DISABLE_MOUSE
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
-bool do_statusbar_mouse(void)
+int do_statusbar_mouse(void)
{
int mouse_x, mouse_y;
- bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
+ int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
- if (!retval) {
- /* We can click in the statusbar window text to move the
- * cursor. */
- if (wenclose(bottomwin, mouse_y, mouse_x)) {
- size_t start_col;
+ /* We can click on the statusbar window text to move the cursor. */
+ if (retval == 0 && wmouse_trafo(bottomwin, &mouse_y, &mouse_x,
+ FALSE)) {
+ size_t start_col;
- assert(prompt != NULL);
+ assert(prompt != NULL);
- start_col = strlenpt(prompt) + 1;
+ start_col = strlenpt(prompt) + 1;
- /* Subtract out the sizes of topwin and edit. */
- mouse_y -= (2 - no_more_space()) + editwinrows;
+ /* Move to where the click occurred. */
+ if (mouse_x > start_col && mouse_y == 0) {
+ size_t pww_save = statusbar_pww;
- /* Move to where the click occurred. */
- if (mouse_x > start_col && mouse_y == 0) {
- size_t pww_save = statusbar_pww;
-
- statusbar_x = actual_x(answer,
+ statusbar_x = actual_x(answer,
get_statusbar_page_start(start_col, start_col +
- statusbar_xplustabs()) + mouse_x - start_col -
- 1);
- statusbar_pww = statusbar_xplustabs();
+ statusbar_xplustabs()) + mouse_x -
+ start_col - 1);
+ statusbar_pww = statusbar_xplustabs();
- if (need_statusbar_horizontal_update(pww_save))
- update_statusbar_line(answer, statusbar_x);
- }
+ if (need_statusbar_horizontal_update(pww_save))
+ update_statusbar_line(answer, statusbar_x);
}
}
break;
#ifndef DISABLE_MOUSE
case KEY_MOUSE:
- get_mouseinput(&mouse_x, &mouse_y, FALSE);
-
- if (wenclose(bottomwin, mouse_y, mouse_x) &&
- !ISSET(NO_HELP) && mouse_x < (width * 2) &&
- mouse_y - (2 - no_more_space()) -
- editwinrows - 1 >= 0) {
+ /* We can click on the shortcut list to select an
+ * answer. */
+ if (get_mouseinput(&mouse_x, &mouse_y, FALSE) == 0 &&
+ wmouse_trafo(bottomwin, &mouse_y, &mouse_x,
+ FALSE) && !ISSET(NO_HELP) && mouse_x <
+ (width * 2) && mouse_y > 0) {
int x = mouse_x / width;
/* Calculate the x-coordinate relative to the
* two columns of the Yes/No/All shortcuts in
* bottomwin. */
- int y = mouse_y - (2 - no_more_space()) -
- editwinrows - 1;
+ int y = mouse_y - 1;
/* Calculate the y-coordinate relative to the
* beginning of the Yes/No/All shortcuts in
* bottomwin, i.e. with the sizes of topwin,
int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
*ran_func, bool *finished, bool allow_funcs);
#ifndef DISABLE_MOUSE
-bool do_mouse(void);
+int do_mouse(void);
#endif
void do_output(char *output, size_t output_len, bool allow_cntrls);
bool *ran_func, bool *finished, bool allow_funcs, void
(*refresh_func)(void));
#ifndef DISABLE_MOUSE
-bool do_statusbar_mouse(void);
+int do_statusbar_mouse(void);
#endif
void do_statusbar_output(char *output, size_t output_len, bool
*got_enter, bool allow_cntrls);
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
#ifndef DISABLE_MOUSE
-bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
+int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
#endif
const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
*meta_key, bool *func_key);
}
#ifndef DISABLE_MOUSE
-/* Check for a mouse event, and if one's taken place, save the
- * coordinates where it took place in mouse_x and mouse_y. After that,
- * assuming allow_shortcuts is FALSE, if the shortcut list on the
- * bottom two lines of the screen is visible and the mouse event took
- * place on it, figure out which shortcut was clicked and put back the
- * equivalent keystroke(s). Return FALSE if no keystrokes were
- * put back, or TRUE if at least one was. Assume that KEY_MOUSE has
+/* Handle any mouse events that may have occurred. We currently handle
+ * releases/clicks of the first mouse button. If allow_shortcuts is
+ * TRUE, releasing/clicking on a visible shortcut will put back the
+ * keystroke associated with that shortcut. If NCURSES_MOUSE_VERSION is
+ * at least 2, we also currently handle presses of the fourth mouse
+ * button (upward rolls of the mouse wheel) by putting back the
+ * keystrokes to move up, and presses of the fifth mouse button
+ * (downward rolls of the mouse wheel) by putting back the keystrokes to
+ * move down. Return -1 on error, 0 if the mouse event needs to be
+ * handled, 1 if it's been handled by putting back keystrokes that need
+ * to be handled. or 2 if it's been ignored. Assume that KEY_MOUSE has
* already been read in. */
-bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
+int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
{
MEVENT mevent;
/* First, get the actual mouse event. */
if (getmouse(&mevent) == ERR)
- return FALSE;
-
- /* If it's not a release or click of the first mouse button, get
- * out. */
- if (!(mevent.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)))
- return FALSE;
+ return -1;
/* Save the screen coordinates where the mouse event took place. */
*mouse_x = mevent.x;
*mouse_y = mevent.y;
- /* If we're allowing shortcuts, the current shortcut list is being
- * displayed on the last two lines of the screen, and the mouse
- * event took place inside it, we need to figure out which shortcut
- * was clicked and put back the equivalent keystroke(s) for it. */
- if (allow_shortcuts && !ISSET(NO_HELP) && wenclose(bottomwin,
- *mouse_y, *mouse_x)) {
- int i, j;
- size_t currslen;
- /* The number of shortcuts in the current shortcut list. */
- const shortcut *s = currshortcut;
- /* The actual shortcut we clicked on, starting at the first
- * one in the current shortcut list. */
-
- /* Get the shortcut lists' length. */
- if (currshortcut == main_list)
- currslen = MAIN_VISIBLE;
- else {
- currslen = length_of_list(currshortcut);
-
- /* We don't show any more shortcuts than the main list
- * does. */
- if (currslen > MAIN_VISIBLE)
+ /* Handle clicks/releases of the first mouse button. */
+ if (mevent.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)) {
+ /* If we're allowing shortcuts, the current shortcut list is
+ * being displayed on the last two lines of the screen, and the
+ * first mouse button was released on/clicked inside it, we need
+ * to figure out which shortcut was released on/clicked and put
+ * back the equivalent keystroke(s) for it. */
+ if (allow_shortcuts && !ISSET(NO_HELP) &&
+ wmouse_trafo(bottomwin, mouse_y, mouse_x, FALSE)) {
+ int i;
+ /* The width of all the shortcuts, except for the last
+ * two, in the shortcut list in bottomwin. */
+ int j;
+ /* The y-coordinate relative to the beginning of the
+ * shortcut list in bottomwin. */
+ size_t currslen;
+ /* The number of shortcuts in the current shortcut
+ * list. */
+ const shortcut *s;
+ /* The actual shortcut we released on, starting at the
+ * first one in the current shortcut list. */
+
+ /* Ignore releases/clicks of the first mouse button on the
+ * statusbar. */
+ if (*mouse_y == 0)
+ return 2;
+
+ /* Calculate the y-coordinate relative to the beginning of
+ * the shortcut list in bottomwin. */
+ j = *mouse_y - 1;
+
+ /* Get the shortcut lists' length. */
+ if (currshortcut == main_list)
currslen = MAIN_VISIBLE;
- }
+ else {
+ currslen = length_of_list(currshortcut);
- /* Calculate the width of all of the shortcuts in the list
- * except for the last two, which are longer by (COLS % i)
- * columns so as to not waste space. */
- if (currslen < 2)
- i = COLS / (MAIN_VISIBLE / 2);
- else
- i = COLS / ((currslen / 2) + (currslen % 2));
-
- /* Calculate the y-coordinate relative to the beginning of
- * the shortcut list in bottomwin, i.e. with the sizes of
- * topwin, edit, and the first line of bottomwin subtracted
- * out, and set j to it. */
- j = *mouse_y - (2 - no_more_space()) - editwinrows - 1;
-
- /* If we're on the statusbar, don't do anything. */
- if (j < 0)
- return FALSE;
-
- /* Calculate the x-coordinate relative to the beginning of the
- * shortcut list in bottomwin, and add it to j. j should now be
- * the index in the shortcut list of the shortcut we clicked. */
- j = (*mouse_x / i) * 2 + j;
-
- /* Adjust j if we clicked in the last two shortcuts. */
- if ((j >= currslen) && (*mouse_x % i < COLS % i))
- j -= 2;
-
- /* If we're beyond the last shortcut, don't do anything. */
- if (j >= currslen)
- return FALSE;
-
- /* Go through the shortcut list to determine which shortcut was
- * clicked. */
- for (; j > 0; j--)
- s = s->next;
-
- /* And put back the equivalent key. Assume that each shortcut
- * has, at the very least, an equivalent control key, an
- * equivalent primary meta key sequence, or both. */
- if (s->ctrlval != NANO_NO_KEY) {
- unget_kbinput(s->ctrlval, FALSE, FALSE);
- return TRUE;
- } else if (s->metaval != NANO_NO_KEY) {
- unget_kbinput(s->metaval, TRUE, FALSE);
- return TRUE;
- }
+ /* We don't show any more shortcuts than the main list
+ * does. */
+ if (currslen > MAIN_VISIBLE)
+ currslen = MAIN_VISIBLE;
+ }
+
+ /* Calculate the width of all of the shortcuts in the list
+ * except for the last two, which are longer by (COLS % i)
+ * columns so as to not waste space. */
+ if (currslen < 2)
+ i = COLS / (MAIN_VISIBLE / 2);
+ else
+ i = COLS / ((currslen / 2) + (currslen % 2));
+
+ /* Calculate the x-coordinate relative to the beginning of
+ * the shortcut list in bottomwin, and add it to j. j
+ * should now be the index in the shortcut list of the
+ * shortcut we released/clicked on. */
+ j = (*mouse_x / i) * 2 + j;
+
+ /* Adjust j if we released on the last two shortcuts. */
+ if ((j >= currslen) && (*mouse_x % i < COLS % i))
+ j -= 2;
+
+ /* Ignore releases/clicks of the first mouse button beyond
+ * the last shortcut. */
+ if (j >= currslen)
+ return 2;
+
+ /* Go through the shortcut list to determine which shortcut
+ * we released/clicked on. */
+ s = currshortcut;
+
+ for (; j > 0; j--)
+ s = s->next;
+
+ /* And put back the equivalent key. Assume that each
+ * shortcut has, at the very least, an equivalent control
+ * key, an equivalent primary meta key sequence, or both. */
+ if (s->ctrlval != NANO_NO_KEY) {
+ unget_kbinput(s->ctrlval, FALSE, FALSE);
+ return 1;
+ } else if (s->metaval != NANO_NO_KEY) {
+ unget_kbinput(s->metaval, TRUE, FALSE);
+ return 1;
+ }
+ } else
+ /* Handle releases/clicks of the first mouse button that
+ * aren't on the current shortcut list elsewhere. */
+ return 0;
}
- return FALSE;
+#if NCURSES_MOUSE_VERSION >= 2
+ /* Handle presses of the fourth mouse button (upward rolls of the
+ * mouse wheel) and presses of the fifth mouse button (downward
+ * rolls of the mouse wheel) . */
+ else if (mevent.bstate & (BUTTON4_PRESSED | BUTTON5_PRESSED)) {
+ bool in_edit = wmouse_trafo(edit, mouse_y, mouse_x, FALSE);
+ bool in_bottomwin = wmouse_trafo(bottomwin, mouse_y, mouse_x,
+ FALSE);
+
+ if (in_edit || in_bottomwin) {
+ int i;
+ /* The y-coordinate relative to the beginning of the
+ * shortcut list in bottomwin. */
+
+ /* Ignore presses of the fourth mouse button and presses of
+ * the fifth mouse button below the statusbar. */
+ if (in_bottomwin && *mouse_y > 0)
+ return 2;
+
+ /* Calculate the y-coordinate relative to the beginning of
+ * the shortcut list in bottomwin. */
+ i = *mouse_y - 1;
+
+ /* One upward roll of the mouse wheel is equivalent to
+ * moving up three lines, and one downward roll of the mouse
+ * wheel is equivalent to moving down three lines. */
+ for (i = 0; i < 3; i++)
+ unget_kbinput((mevent.bstate & BUTTON4_PRESSED) ?
+ NANO_PREVLINE_KEY : NANO_NEXTLINE_KEY, FALSE,
+ FALSE);
+
+ return 1;
+ } else
+ /* Ignore presses of the fourth mouse button and presses of
+ * the fifth mouse buttons that aren't on the edit window or
+ * the statusbar. */
+ return 2;
+ }
+#endif
+ else
+ /* Ignore all other mouse events. */
+ return 2;
}
#endif /* !DISABLE_MOUSE */