ein Kapitel zurück                                           ein Kapitel weiter

Was liegt näher als gpm in Verbindung mit curses zu verwenden. Nur wie können wir auf die einzelnen oder das einzelne Fenster zugreifen? Zum Einlesen von Ereignissen haben wir doch nur Gpm_Getchar() und Gpm_Getc(). Wenn sie sich noch an curses erinnern (Ist Voraussetzung für dieses und den nächsten Kapiteln) wissen sie doch das wir für jede Funktion Beispiel mvprintw() ein Fensterorientiertes Gegenstück haben das sich nicht auf stdscr bezieht. In diesem Fall wäre das mvwprintw. Und bei der Mausfunktion mit gpm ist dies ebenso der Fall..................

int Gpm_Wgetch(WINDOW *win);  

Wenn sie die Mausabfrage auf den stdscr bezieht können sie sicherlich auch weiterhin Gpm_Getch() verwenden oder aber auch............

Gpm_Wgetch(stdscr);  

Da wir dies nun wissen sollten wir uns das ganze mal in der Praxis ansehen.....

/*Download:gpm5.c*/
#include <stdio.h> #include <unistd.h> #include <gpm.h> #include <linux/keyboard.h> #include <ncurses.h> #define WIDTH 30 #define HEIGHT 10 #define MOVE_DONE 99 int startx = 0; int starty = 0; char *choices[] = { "Wahl 1", "Wahl 2", "Wahl 3", "Wahl 4", "Ende", }; /*Anzahl der Menüs zum Auswählen*/ int n_choices = sizeof(choices) / sizeof(char *); void print_menu(WINDOW *menu_win, int highlight); int my_handler(Gpm_Event *event, void *data) { int choice = -1; /*Eine Art Mouseover-Effekt*/ if(event->type & GPM_MOVE) /*Maus wurde bewegt?*/ { choice = report_choice(event->x, event->y); /*Wenn ja wo?*/ /*Liefert die Funktion report_choice -1 zurück dann wars außerhalb*/ if(choice == -1) return 0; /*Kein Auswahl*/ else return MOVE_DONE + choice; } if(event->type & GPM_DOWN) { choice = report_choice(event->x, event->y); if(choice == -1) return 0; /*Bedeutet für Gpm_Wgetch() weitermachen*/ else return choice; } return 0; } int main() { Gpm_Connect conn; int c, choice = -1; WINDOW *menu_win; /*Standartausgabe auf richtigem Terminal eingestellt?*/ if(!isatty(STDOUT_FILENO)) { printf("Filedeskriptor stdout ist nicht für das Terminal eingestellt"); exit(1); } conn.eventMask = ~0; /*Alle Mausereignisse*/ conn.defaultMask = 0; /*nix davon an gpm*/ conn.minMod = 0; /*Keine Taste muss gedrückt werden*/ conn.maxMod = ~0; /*....aber es dürfen dennoch alle gedrückt werden*/ if(Gpm_Open(&conn, 0) == -1){ printf("Kann keine Verbindung zum Maus-Server herstellen\n"); exit(0); } initscr(); /*curses initialisieren*/ clear(); /*Bildschirm löschen*/ noecho(); /*keine Zeichen ausgeben*/ cbreak(); /*Zeilenpufferung ausschalten*/ startx = (80 - WIDTH) / 2; starty = (24 - HEIGHT) / 2; menu_win = newwin(HEIGHT, WIDTH, starty, startx); /*Zeichne neues Fenster und heben Auswahl 1 "Wahl1" hervor*/ print_menu(menu_win, 1); gpm_handler = my_handler; /*Maushandler einrichten*/ gpm_visiblepointer = 1; /*Mauszeiger immer sichtbar*/ while((c = Gpm_Wgetch(menu_win)) != EOF) /*EOF = -1*/ { if(c != -1 && gpm_hflag) { if(c > MOVE_DONE) /*Wurde ein Menü Ausgewählt?*/ { choice = c - MOVE_DONE; /*Bsp. "Wahl 2" -> 101-99=2*/ /*Menü neu ausgeben mit neuer Hervorhebung*/ print_menu(menu_win, choice); continue; /*Und weiter...........*/ } else { /*Was haben wir Ausgewählt?*/ mvprintw(23, 1, "Ihre Wahl ist : %d. Auswahl \"%10s\"", c, choices[c - 1]); refresh(); if(c == n_choices) /*Haben wir ENDE angeklickt?*/ break; /*Und tschüss........*/ print_menu(menu_win, c); /*Fenster neu zeichnen*/ } } } Gpm_Close(); endwin(); /*Ende curses.......*/ return 0; } /* "Zeichne" Menü*/ void print_menu(WINDOW *menu_win, int highlight) { int x, y, i; x = 2; y = 2; /*Ein Rahmen um das Fenster zeichnen*/ box(menu_win, 0, 0); /*Für die Hervorhebung des Mouseover-Effekt*/ for(i = 0; i < n_choices; ++i) { if(highlight == i + 1) { wattron(menu_win, A_REVERSE|A_BOLD); /*Hervorhebung für Auswahl an*/ mvwprintw(menu_win, y, x, "%s", choices[i]); /*Auswahl mit Hervorhebungausgeben*/ wattroff(menu_win, A_REVERSE|A_BOLD); /*Hervorhebung für Auswahlwieder aus*/ } else/*Auswahl ausgeben ohne Hervorhebung*/ mvwprintw(menu_win, y, x, "%s", choices[i]); ++y; /*Nächste Zeile*/ } wrefresh(menu_win); /*Zum Schluss Fenster neu Zeichnen*/ } /*Gibt Ihre Auswahl zurück, wird in der Funktion my_handler aufgerufen*/ int report_choice(int mouse_x, int mouse_y) { int i,j, choice; i = startx + 2; /*+2 da String "Wahl n" 2Spalten vom Rand entfernt beginnt*/ j = starty + 3; /*+3 da String "Wahl n" 3 Zeilen unter Top beginnt*/ for(choice = 0; choice < n_choices; ++choice) /*Wir testen alle Möglichkeiten durch*/ if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice])) break; if(choice == n_choices) return -1; /*Nix passiert*/ else return (choice + 1); /*...oder neue Position der Auswahl zurückgeben*/ }

Diese Programm stellt normalerweise kein Neuland für sie da wenn sie die Kapitel zuvor gelesen haben. Vorraussetzung ist natürlich auch das sie über curses bescheid wissen. Dies können sie ebenso in diesem Kurs nachlesen. Die einzige "Schwierigkeit" in diesem Programm dieser Art dürfte sein den aktuellen Status und Position der Maus zurückzugeben. Dies geschieht in unserem Fall bei der Funktion report_choice ganz einfach. Passen sie das Programm einfach Ihren Bedürfnissen an. Rufen sie z.B. anstatt der Ausgabe......

mvprintw(23, 1, "Ihre Wahl ist : %d. Auswahl \"%10s\"", c, choices[c - 1]);  

...einfach eine Funktion auf die was tun soll was sie eben benötigen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf