ein Kapitel zurück                                           ein Kapitel weiter

Mit Curses ist es auch möglich die Maus miteinzubeziehen. Gemeint sind nicht die Funktionen der Headerdatei <gpm.h>. Diese möchte in einem späteren Kapitel besprechen. Der Vorteil der Mausroutinen von Curses ist das diese sowohl im Textmodus als auch im XTerm laufen. Folgende Struktur wurde dafür definiert....

typedef struct {
                 short ID;      //Indentität,falls mehrere Mäuse angeschlossen sind
                 int x,y,z;     //Koordinaten,z nicht benötigt
                 mmask_t bstate;//Bitmaske für Mausknöpfe
               }MEVENT;  

Der Datentyp mmask_t wurde folgendermaßen erzeugt:

typedef unsigned long mmask_t;  

Damit Curses überhaupt eine Mauseingabe zur Kenntnis nimmt muss die Funktion....

mmask_t mousemask(mmask_t neuemaske, mmask_t *altemaske);  

....aufgerufen werden. In der Variablen neuemaske definieren wir welche Mausereignisse bearbeitet werden. Folgende Mausereignisse sind in Curses definiert....

#define BUTTON1_RELEASED        000000000001L
#define BUTTON1_PRESSED         000000000002L
#define BUTTON1_CLICKED         000000000004L
#define BUTTON1_DOUBLE_CLICKED  000000000010L
#define BUTTON1_TRIPLE_CLICKED  000000000020L
#define BUTTON1_RESERVED_EVENT  000000000040L
#define BUTTON2_RELEASED        000000000100L
#define BUTTON2_PRESSED         000000000200L
#define BUTTON2_CLICKED         000000000400L
#define BUTTON2_DOUBLE_CLICKED  000000001000L
#define BUTTON2_TRIPLE_CLICKED  000000002000L
#define BUTTON2_RESERVED_EVENT  000000004000L
#define BUTTON3_RELEASED        000000010000L
#define BUTTON3_PRESSED         000000020000L
#define BUTTON3_CLICKED         000000040000L
#define BUTTON3_DOUBLE_CLICKED  000000100000L
#define BUTTON3_TRIPLE_CLICKED  000000200000L
#define BUTTON3_RESERVED_EVENT  000000400000L
#define BUTTON4_RELEASED        000001000000L
#define BUTTON4_PRESSED         000002000000L
#define BUTTON4_CLICKED         000004000000L
#define BUTTON4_DOUBLE_CLICKED  000010000000L
#define BUTTON4_TRIPLE_CLICKED  000020000000L
#define BUTTON4_RESERVED_EVENT  000040000000L
#define BUTTON_CTRL             000100000000L
#define BUTTON_SHIFT            000200000000L
#define BUTTON_ALT              000400000000L
#define ALL_MOUSE_EVENTS
#define REPORT_MOUSE_POSITION  

Ich nehme mal an diese Funktionen sind selbsterklärend. Mit......

int maske=mousemask(BUTTON1_PRESSED,NULL);  

....können wir die Routine BUTTON1_PRESSED, also die linke Maustaste gedrückt, bearbeiten. Nun wollen wir mit wgetch() die Mauseigenschaft abrufen....

chtype button;
button = wgetch(stdscr);  

Wurde eine Mausaktivität registriert so gibt wgetch KEY_MOUSE zurück....

if(button==KEY_MOUSE)
{
   {/*Mausaktivitäten*/
   ..................  

Jetzt wollen wir die Mausaktivität auslesen. Dies geschieht mittels der Funktion...

int getmouse(MEVENT *event);  

....in der Praxis.......

if(getmouse(&event) == OK)
{
   /*Konnte Mausereignis lesen*/
   ......................  

Der Rückgabewert von getmouse lautet OK bei erfolgreichen lesen. Ansonsten ERR. Auf einzelne Ereignisse greifen sie folgendermaßen zu.....

y-Koordinate = event.y;
x-Koordinate = event.x;
bitmaske = event.bstate;
ID = event.id;  

z.B. Wir testen auf Doppelklick...

If(event.bstate == BUTTON1_DOUBLE_CLICK)
{
   /*die linke Taste wurde Doppeltgeklickt*/
   ..............................  

Um zu überprüfen wo und ob im zulässigen Fenster die Mauskoordinate (y,x) liegt, benötigen wir die Funktion...........

bool wenclose(WINDOW *win, int y, int x);  

Der Rückgabewert dieser Funktion lautet falls das Ereignis im Fenster passierte TRUE ansonsten FALSE. Ein kleines Programmbeispiel soll dies Demonstrieren. Wir klicken in einem Bereich des Fensters stdscr und geben die Werte zurück an welcher Position genau wir im Fenster den linken Mausbutton betätigt haben....

/*Download:cur13.c*/
#include <curses.h> #include <stdlib.h> int main() { MEVENT pos; int l_maus; chtype button; initscr(); noecho(); keypad(stdscr,TRUE); l_maus=mousemask(BUTTON1_PRESSED,NULL); while(1) { button=wgetch(stdscr); if(button==KEY_MOUSE) { if(getmouse(&pos)==OK) { wenclose(stdscr,pos.y,pos.x); mvwprintw(stdscr,1,0,"y = %2d x = %2d",pos.y,pos.x); } } wrefresh(stdscr); } endwin(); return 0; }

Dieses Beispiel wollen wir jetzt verändern und Überprüfen an welcher Stelle im Fenster stdscr die Maustaste gedrückt wurde (y,x) und an welcher Stelle die Maustaste im Fenster wieder losgelassen wurde......

/*Download:cur14.c*/
#include <curses.h> #include <stdlib.h> int main() { MEVENT pos; int l_maus; chtype button; initscr(); noecho(); keypad(stdscr,TRUE); l_maus=mousemask(BUTTON1_RELEASED|BUTTON1_PRESSED|BUTTON1_CLICKED,NULL); while(1) { button=wgetch(stdscr); clear(); if(button==KEY_MOUSE) { if(getmouse(&pos)==OK) {/*linke Maustaste gedrückt bei..*/ if(pos.bstate==BUTTON1_PRESSED) { wenclose(stdscr,pos.y,pos.x); mvwprintw(stdscr,1,0, "linke Maustaste gedrückt bei y = %2d x = %2d",pos.y,pos.x); }/*linke Maustaste losgelassen bei....*/ if(pos.bstate==BUTTON1_RELEASED) {/*Reaktionszeit beim loslassen auf 1 Tausendstel Sekunde*/ mouseinterval(1); wenclose(stdscr,pos.y,pos.x); mvwprintw(stdscr,2,0, "linke Maustaste losgelassen y = %2d x = %2d",pos.y,pos.x); } } } wrefresh(stdscr); } endwin(); return 0; }

Wenn die Maustaste zu schnell oder zu langsam reagiert können sie (wie im Beispiel eben geschehen) die Funktion.........

int mouseinterval(int Tausendstelsekunde);  

...benutzen. Jetzt wollen wir die Mausroutinen etwas praktischer Einsetzten. Wir erzeugen ein Fenster (WINDOW *fenster) und geben diese auf dem Bildschirm aus. Sie könne jetzt auf jedem beliebigen Bereich im stdscr mit der linken Maus drücken und das Fenster wird an diesem Punkt falls möglich versetzt. Als Ausganspunkt nehmen wir die linke obere Ecke. Weiterhin habe ich an der linken oberen Ecke den Buchstaben 'S' und an der rechten oberen Ecke den Buchstaben 'M' an die Fensterecken gesetzt. Mit 'S' für Schließen schließen wir das Fenster. Mit 'M' Maximieren wir das Fenster *fenster. Erneutes Klicken auf 'M' bewirkt wieder das Minimieren zur normalen Größe des Fensters............

/*Download:cur15.c*/
#include <curses.h> #include <stdlib.h> #define MAXSIZE 1 #define MINSIZE 0 int y_click,x_click; int y_click2,x_click2; int size=MINSIZE; void where_clicked(WINDOW *win,WINDOW *win2,MEVENT pos) { getbegyx(win2,y_click2,x_click2); /*linke obere Ecke von win2*/ mouseinterval(1); wenclose(win,pos.y,pos.x); /*wo in win wurde geklickt*/ y_click = pos.y; x_click = pos.x; /*wurde auf die linke obere Ecke von win2*/ if(y_click==y_click2 && x_click==x_click2) { endwin(); exit(0); } else if(y_click==y_click2 && x_click==x_click2+39 || x_click==x_click2+78) { //oder wurde auf der rechten oberen Ecke geklickt touchwin(stdscr); refresh(); if(size==MINSIZE) { delwin(win2); size=MAXSIZE; } else if(size==MAXSIZE) { delwin(win2); size=MINSIZE; } } } /*Verschieben des Fensters an Position der globalen Variablen*/ /* x_click und y_click die zuvor mit where_clicked() ermittelt wurden*/ void move_win_to(WINDOW *win) { touchwin(stdscr); wrefresh(stdscr); mvwin(win,y_click+1,x_click+1); touchwin(win); wrefresh(win); } WINDOW *create_new_window(WINDOW *neues_fenster, int zeilen, int spalten, int hinterg, int vordergr, int begin_y, int begin_x) { neues_fenster=newwin(zeilen,spalten,begin_y,begin_x); init_pair(1,hinterg,vorderg); wattrset(neues_fenster,COLOR_PAIR(1)); box(neues_fenster,ACS_VLINE,ACS_HLINE); return neues_fenster; } int main() { MEVENT pos; int l_maus; chtype button; WINDOW *fenster,mfenster; int y_alt,x_alt; initscr(); if(has_colors()==TRUE) start_color(); noecho(); keypad(stdscr,TRUE); fenster=create_new_window(fenster,10,40,COLOR_RED,COLOR_BLUE,5,15); init_pair(2,COLOR_BLACK,COLOR_YELLOW); wattrset(fenster,COLOR_PAIR(2)); mvwaddch(fenster,0,0,'S'); mvwaddch(fenster,0,39,'M'); wattrset(fenster,COLOR_PAIR(0)); mvwprintw(fenster,2,10,"S=Fenster schliessen"); mvwprintw(fenster,6,10,"M=Fenster maximieren"); wrefresh(fenster); l_maus=mousemask(BUTTON1_RELEASED|BUTTON1_PRESSED,NULL); while(1) { button=wgetch(stdscr); if(button==KEY_MOUSE) { if(getmouse(&pos)==OK) { where_clicked(stdscr,fenster,pos); //move_win_to(fenster); if(size==MAXSIZE) { fenster=create_new_window(fenster,24,79,COLOR_RED,COLOR_BLUE,0,0); wattrset(fenster,COLOR_PAIR(2)); mvwaddch(fenster,0,0,'S'); mvwaddch(fenster,0,78,'M'); wattrset(fenster,COLOR_PAIR(0)); mvwprintw(fenster,10,30,"S=Fenster schliessen"); mvwprintw(fenster,14,30,"M=Fenster minimieren"); wrefresh(fenster); } else if(size==MINSIZE) { fenster=create_new_window(fenster,10,40,COLOR_RED,COLOR_BLUE,5,15); init_pair(2,COLOR_BLACK,COLOR_YELLOW); wattrset(fenster,COLOR_PAIR(2)); mvwaddch(fenster,0,0,'S'); mvwaddch(fenster,0,39,'M'); wattrset(fenster,COLOR_PAIR(0)); mvwprintw(fenster,2,10,"S=Fenster schliessen"); mvwprintw(fenster,6,10,"M=Fenster maximieren"); wrefresh(fenster); move_win_to(fenster); } } } } endwin(); return 0; }




So siehts aus:



Auf diesem Grundwissen können sie eine Benutzeroberfläche bauen. Z.B.: Eine Daten- bank für die Textkonsole........
Zwei weitere Funktionen die es noch gibt, ich aber nicht durchnehmen will wären die Funktion....

int ungetmouse(MEVENT *event);  

...und...

bool wmouse_trafo(WINDOW *win, int *Py, int *Px);  

Für Informationen dazu lesen sie bitte die man-Page (man mouse).

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf