<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML ><HEAD ><TITLE >Interfacing with the mouse </TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" TITLE=" NCURSES Programming HOWTO " HREF="index.html"><LINK REL="PREVIOUS" TITLE="Interfacing with the key board" HREF="keys.html"><LINK REL="NEXT" TITLE="Screen Manipulation" HREF="screen.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >NCURSES Programming HOWTO</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="keys.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="screen.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="MOUSE" ></A >12. Interfacing with the mouse</H1 ><P >Now that you have seen how to get keys, lets do the same thing from mouse. Usually each UI allows the user to interact with both keyboard and mouse. </P ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="MOUSEBASICS" ></A >12.1. The Basics</H2 ><P >Before you do any thing else, the events you want to receive have to be enabled with <TT CLASS="LITERAL" >mousemask()</TT >.</P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > mousemask( mmask_t newmask, /* The events you want to listen to */ mmask_t *oldmask) /* The old events mask */</PRE ></FONT ></TD ></TR ></TABLE ><P >The first parameter to above function is a bit mask of events you would like to listen. By default, all the events are turned off. The bit mask <TT CLASS="LITERAL" > ALL_MOUSE_EVENTS</TT > can be used to get all the events.</P ><P >The following are all the event masks:</P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > Name Description --------------------------------------------------------------------- BUTTON1_PRESSED mouse button 1 down BUTTON1_RELEASED mouse button 1 up BUTTON1_CLICKED mouse button 1 clicked BUTTON1_DOUBLE_CLICKED mouse button 1 double clicked BUTTON1_TRIPLE_CLICKED mouse button 1 triple clicked BUTTON2_PRESSED mouse button 2 down BUTTON2_RELEASED mouse button 2 up BUTTON2_CLICKED mouse button 2 clicked BUTTON2_DOUBLE_CLICKED mouse button 2 double clicked BUTTON2_TRIPLE_CLICKED mouse button 2 triple clicked BUTTON3_PRESSED mouse button 3 down BUTTON3_RELEASED mouse button 3 up BUTTON3_CLICKED mouse button 3 clicked BUTTON3_DOUBLE_CLICKED mouse button 3 double clicked BUTTON3_TRIPLE_CLICKED mouse button 3 triple clicked BUTTON4_PRESSED mouse button 4 down BUTTON4_RELEASED mouse button 4 up BUTTON4_CLICKED mouse button 4 clicked BUTTON4_DOUBLE_CLICKED mouse button 4 double clicked BUTTON4_TRIPLE_CLICKED mouse button 4 triple clicked BUTTON_SHIFT shift was down during button state change BUTTON_CTRL control was down during button state change BUTTON_ALT alt was down during button state change ALL_MOUSE_EVENTS report all button state changes REPORT_MOUSE_POSITION report mouse movement</PRE ></FONT ></TD ></TR ></TABLE ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="GETTINGEVENTS" ></A >12.2. Getting the events</H2 ><P >Once a class of mouse events have been enabled, getch() class of functions return KEY_MOUSE every time some mouse event happens. Then the mouse event can be retrieved with <TT CLASS="LITERAL" >getmouse()</TT >.</P ><P >The code approximately looks like this:</P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > MEVENT event; ch = getch(); if(ch == KEY_MOUSE) if(getmouse(&event) == OK) . /* Do some thing with the event */ . .</PRE ></FONT ></TD ></TR ></TABLE ><P > getmouse() returns the event into the pointer given to it. It's a structure which contains</P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > typedef struct { short id; /* ID to distinguish multiple devices */ int x, y, z; /* event coordinates */ mmask_t bstate; /* button state bits */ } </PRE ></FONT ></TD ></TR ></TABLE ><P >The <TT CLASS="LITERAL" >bstate</TT > is the main variable we are interested in. It tells the button state of the mouse.</P ><P >Then with a code snippet like the following, we can find out what happened.</P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > if(event.bstate & BUTTON1_PRESSED) printw("Left Button Pressed");</PRE ></FONT ></TD ></TR ></TABLE ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="MOUSETOGETHER" ></A >12.3. Putting it all Together</H2 ><P >That's pretty much interfacing with mouse. Let's create the same menu and enable mouse interaction. To make things simpler, key handling is removed.</P ><DIV CLASS="EXAMPLE" ><A NAME="BMOME" ></A ><P ><B >Example 11. Access the menu with mouse !!! </B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" ><SPAN CLASS="INLINEMEDIAOBJECT" >#include <ncurses.h> #define WIDTH 30 #define HEIGHT 10 int startx = 0; int starty = 0; char *choices[] = { "Choice 1", "Choice 2", "Choice 3", "Choice 4", "Exit", }; int n_choices = sizeof(choices) / sizeof(char *); void print_menu(WINDOW *menu_win, int highlight); void report_choice(int mouse_x, int mouse_y, int *p_choice); int main() { int c, choice = 0; WINDOW *menu_win; MEVENT event; /* Initialize curses */ initscr(); clear(); noecho(); cbreak(); //Line buffering disabled. pass on everything /* Try to put the window in the middle of screen */ startx = (80 - WIDTH) / 2; starty = (24 - HEIGHT) / 2; attron(A_REVERSE); mvprintw(23, 1, "Click on Exit to quit (Works best in a virtual console)"); refresh(); attroff(A_REVERSE); /* Print the menu for the first time */ menu_win = newwin(HEIGHT, WIDTH, starty, startx); print_menu(menu_win, 1); /* Get all the mouse events */ mousemask(ALL_MOUSE_EVENTS, NULL); while(1) { c = wgetch(menu_win); switch(c) { case KEY_MOUSE: if(getmouse(&event) == OK) { /* When the user clicks left mouse button */ if(event.bstate & BUTTON1_PRESSED) { report_choice(event.x + 1, event.y + 1, &choice); if(choice == -1) //Exit chosen goto end; mvprintw(22, 1, "Choice made is : %d String Chosen is \"%10s\"", choice, choices[choice - 1]); refresh(); } } print_menu(menu_win, choice); break; } } end: endwin(); return 0; } void print_menu(WINDOW *menu_win, int highlight) { int x, y, i; x = 2; y = 2; box(menu_win, 0, 0); for(i = 0; i < n_choices; ++i) { if(highlight == i + 1) { wattron(menu_win, A_REVERSE); mvwprintw(menu_win, y, x, "%s", choices[i]); wattroff(menu_win, A_REVERSE); } else mvwprintw(menu_win, y, x, "%s", choices[i]); ++y; } wrefresh(menu_win); } /* Report the choice according to mouse position */ void report_choice(int mouse_x, int mouse_y, int *p_choice) { int i,j, choice; i = startx + 2; j = starty + 3; for(choice = 0; choice < n_choices; ++choice) if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice])) { if(choice == n_choices - 1) *p_choice = -1; else *p_choice = choice + 1; break; } }</SPAN ></PRE ></FONT ></TD ></TR ></TABLE ></DIV ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="MISCMOUSEFUNCS" ></A >12.4. Miscellaneous Functions</H2 ><P >The functions mouse_trafo() and wmouse_trafo() can be used to convert to mouse co-ordinates to screen relative co-ordinates. See curs_mouse(3X) man page for details.</P ><P >The mouseinterval function sets the maximum time (in thousands of a second) that can elapse between press and release events in order for them to be recognized as a click. This function returns the previous interval value. The default is one fifth of a second.</P ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="keys.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="screen.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Interfacing with the key board</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" > </TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Screen Manipulation</TD ></TR ></TABLE ></DIV ></BODY ></HTML >