ein Kapitel zurück                                           ein Kapitel weiter

Die meisten dürften mit dem Beispiel im Kapitel zuvor für Ihr Programm zufrieden sein. Für Wissbedürftige gibt es noch ein weiteres Kapitel....... Regions of Interest

Die "Region of Interest" ist ein rechteckiger Bereich des Bildschirmes der von Ihnen festgelegt wird und mit bestimmte Maushandler aufgerufen werden kann. Wozu soll das wieder gut sein? Wenn sie z.B. mit curses mehrere Fenster gleichzeitig offen haben und für jedes Fenster einen eigenen Maushandler einrichten wollen.

Dabei legen sie jede neue Region of Interest auf einem Stack. gpm kümmert sich dann um denn Rest, damit jedes Fenster den passenden Maushandler erhält. Die Funktion die uns das ganze Abnimmt lautet................

Gpm_Roi *Gpm_PushRoi(int xmin, int xmax, int ymax, int ymin,
         int mask, Gpm_Handler *gpm, void *xtradata);  

Zugegeben die vielen Parameter erscheinen einem ja nicht gerade Anwenderfreundlich aber es ist halb so schlimm wie es aussieht. Zuerst müssen wir uns die Struktur Gpm_Roi etwas genauer betrachten..........

typedef struct Gpm_Roi
  {
    short xMin, xMax; /*Obere linke Ecke der Region of Interest*/
    short yMin, yMax; /*Untere rechte Ecke der Region of Interest*/
    unsigned short minMod, maxMod; /*Modifiers und eventMask*/
    unsigned short eventMask; /*das selbe wie schon bei Gpm_Event*/
    unsigned short owned; /*für uns nicht von Interesse*/
    Gpm_Handler *handler; /*Handler für die Region of Interest*/
    void *clientdata; /*Informationen von einer Region of Interest an*/
                                   /*anderen Handler übergeben*/
    struct Gpm_Roi *prev; /*voriges Element auf dem Stack*/
    struct Gpm_Roi *next; /*nextes Element auf dem Stack*/
  }Gpm_Roi;  

Anhand dieser Struktur lässt sich schon erkennen das es sich um einen doppelt Verkettete Liste in Form eines Stacks handelt wie sie Ihn schon im Kurs kennen gelernt haben. Den Region of Interest - Handler dürfen sie nicht wie den normalen Handler mit gpm_handler aktivieren, da dieser Vorrang vor allen Maushandlern der Region of Interest besitzt und wir somit keine Region of Interset haben. Anstatt nun den gpm_handler zu benutzen gibt es für Region of Interest den gpm_roi_handler den sie dafür verwenden können. Ansonsten ist der komplette Ablauf nicht viel anders als schon bei Gpm_Event. Die Konstanten sind ebenso die selben. Wollen wir uns ein einfaches Beispiel dazu ansehen...........

/*Download:gpm6.c*/
#include <stdio.h> #include <gpm.h> int Roi_fuer_Berreich(Gpm_Event *event, char *data) { printf("Ereignis in der \"Region of Interest\" auf Planeten Erde "); printf(" an Position ->%d<- ->%d<- \n", event->x, event->y); if(data != NULL) printf("%s\n",data); return 0; } int Ein_weiterer_Roi_Berreich(Gpm_Event *event, char *data) { printf("Ereignis in der \"Region of Interest\" auf Pluto"); printf(" an Position ->%d<- ->%d<- \n", event->x, event->y); if(data != NULL) printf("%s\n",data); return 0; } int Roi_ausserhalb_Berreich(Gpm_Event *event, void *data) { printf("Diese Ereignis trat NICHT in der \"Region of Interest\" auf "); printf(" an Position ->%d<- ->%d<- \n", event->x, event->y); return 0; } int main() { Gpm_Connect connect; Gpm_Roi *roi, *roi2; char zeichen=0; char erde[] = "Hallo Pluto hier Erde"; char pluto[] = "Hallo Erde take it easy"; connect.eventMask =~0; connect.defaultMask=0; connect.minMod=0; connect.maxMod=~0; if(Gpm_Open(&connect, 0) == -1) /*Verbinden mit Mausserver*/ { fprintf(stderr, "Kann keine Verbindung zum Mausserver herstellen!!\n"); exit(0); } gpm_visiblepointer=1; /*Mauszeiger immer sichtbar*/ /*Handler für 10 Zeilen und 30 Spalten an der linken oberen Ecke anlegen, ~0 = alle Mausereignisse, Handler ist die Funktion Roi_im_Berreich*/ roi=Gpm_PushRoi(1,1,31,10,~0, Roi_fuer_Berreich, (void *)&erde); /*Handler für einen weiteren Bereich ab Spalte 31 Zeile 10 bis Spalte 80 Zeile 25*/ roi2=Gpm_PushRoi(31,10,80,25,~0,Ein_weiterer_Roi_Berreich , (void *)&pluto); /*Jetzt noch einen Region of Interest - Handler einrichten der für den*/ /* restlichen Bereich zuständig ist*/ gpm_roi_handler=Roi_ausserhalb_Berreich; /*Ereignisse lesen..........*/ while(zeichen != 'e') zeichen = Gpm_Getc(stdin); Gpm_PopRoi(roi); /*Region of Interest wieder vom Stack entfernen*/ Gpm_PopRoi(roi2); Gpm_Close(); return 0; }

Wir legen in diesem Beispiel zwei "Regions of Interest" auf dem Stack. Der eine stellt die Erde da der andere den Pluto. Bewegen sie die Maus außerdem nicht in einen der beiden Regionen legen wir noch mit dem gpm_roi_handler eine Region für unbekannten Bereich an. Also: Move the Mouse from Earth to Pluto and return, but take care in Regions out of intrest ;) Neu dürfte in diesem Beispiel die Funktion...........

Gpm_Roi *GpmPopRoi(Gpm_Roi *roi);  

.....womit wir unsere Region of Interest wieder vom Stack entfernen.

Dumm an dem Programm ist nur das wir die Region of Interest nicht sehen können. Und was könnte sich da wieder besser eignen als curses? Dies folgende Programm habe ich in ähnlicher Form im Internet gefunden etwas gekürzt und an den Bedürfnissen des Kurses angepasst.....

/*Download:gpm7.c*/
#include <stdio.h> #include <gpm.h> #include <linux/keyboard.h> #include <ncurses.h> typedef struct _WIN { int nlines; int ncols; int y; int x; WINDOW *p_win; }WIN; void create_windows(WIN my_windows[]); void set_win_params(WIN *win, int nlines, int ncols, int y, int x); /*Handler gilt für alle 4 Fenster, Wir benutzen die Variable data als übergabe um welches Fenster es sich handelt*/ int my_handler(Gpm_Event *p_event, void *data) { WINDOW *current_win; WIN *my_win; my_win = (WIN *)data; current_win = my_win -> p_win; if(p_event->type & GPM_ENTER) mvwprintw(current_win, 1, 1, "Willkommen......"); if(p_event->type & GPM_LEAVE) mvwprintw(current_win, 1, 1, "Und Tschuess......"); if(p_event->type & GPM_DOWN) { mvwprintw(current_win, my_win->nlines - 2, 1, "Mausbutton gedrückt"); if(p_event->buttons & GPM_B_LEFT) mvwprintw(current_win, my_win->nlines/2, 1,"Linke Maustaste gedrückt "); if(p_event->buttons & GPM_B_RIGHT) mvwprintw(current_win, my_win->nlines/2, 1,"Rechte Maustaste gedrückt"); if(p_event->buttons & GPM_B_MIDDLE) mvwprintw(current_win, my_win->nlines/2, 1,"Mittlere Maustaste gedrückt"); } if(p_event->type & GPM_UP) { mvwprintw(current_win, my_win->nlines - 2, 1, "Mausbutton losgelassen "); if(p_event->buttons & GPM_B_LEFT) mvwprintw(current_win, my_win->nlines/2, 1,"Linke Maustaste gedrückt"); if(p_event->buttons & GPM_B_RIGHT) mvwprintw(current_win, my_win->nlines/2, 1,"Rechte Maustaste gedrückt "); if(p_event->buttons & GPM_B_MIDDLE) mvwprintw(current_win, my_win->nlines/2, 1,"Mittlere Maustaste gedrückt"); } wrefresh(current_win); return 1; } int main() { Gpm_Connect conn; WIN my_windows[4]; int i, mask, c; conn.eventMask = ~0; /*Alle Mausereignisse*/ conn.defaultMask = 0; /*nix geht an gpm*/ conn.minMod = 0; /*keine Taste muss gedrückt werden*/ conn.maxMod = ~0; /*Tasten dürfen aber gedrückt werden*/ if(Gpm_Open(&conn, 0) == -1) /*Verbindung zum Mausserver*/ { fprintf(stderr, "Kann keine Verbindung zum Mausserver herstellen.....\n"); exit(0); } initscr(); /*Curses initialisieren*/ clear(); /*Bildschirm löschen*/ refresh(); noecho(); /*Keine Ausgabe auf dem Bildschirm*/ cbreak(); /*Zeilenpufferung ausschalten*/ create_windows(my_windows); /*Unser Interessieren nur die Ereignisse Maus drücken und loslassen und*/ /* Eintritt bzw. Austritt aus dem Region of Interest - Bereich*/ mask = GPM_UP | GPM_DOWN | GPM_ENTER | GPM_LEAVE; for(i = 0;i < 4; ++i) { box(my_windows[i].p_win, 0, 0); /*Rahmen um die Fenster*/ wrefresh(my_windows[i].p_win); /*Zeichenen*/ /*Handler für die einzelnen Regionen einrichten*/ Gpm_PushRoi(my_windows[i].x, my_windows[i].y, /*obere linke Ecke bis......*/ my_windows[i].x + my_windows[i].ncols - 1, my_windows[i].y + my_windows[i].nlines - 1, /*....untere rechte Ecke*/ mask, my_handler, &my_windows[i]); /*Ereignisshandler und die Daten*/ } gpm_visiblepointer = 1; /*Zeiger immer sichtbar*/ gpm_zerobased = 1; /*linke obere ist 1/1*/ gpm_roi_handler = my_handler; /*Handler einrichten für restlichen Bereich*/ gpm_roi_data = stdscr; while((c = Gpm_Wgetch()) != EOF) /*Und Daten lesen*/ { if(c == 4) /*CTRL & D*/ break; } Gpm_Close(); /*Verbindung wieder beenden*/ endwin(); /*curses beenden*/ return 0; } /*Wir erzeugen 4 neue Fenster, alle Daten werden an die Struktur WIN übergeben*/ void create_windows(WIN my_windows[]) { int nlines = (LINES - 3) / 2; int ncols = (COLS - 3) / 2; /*Fenster links oben*/ my_windows[0].p_win = newwin(nlines, ncols, 1, 1); set_win_params(&my_windows[0], nlines, ncols, 1, 1); /*Fenster rechts oben*/ my_windows[1].p_win = newwin(nlines, ncols, 2 + nlines, 1); set_win_params(&my_windows[1], nlines, ncols, 2 + nlines, 1); /*Fenster links unten*/ my_windows[2].p_win = newwin(nlines, ncols, 1, 2 + ncols); set_win_params(&my_windows[2], nlines, ncols, 1, 2 + ncols); /*Fenster rechts unten*/ my_windows[3].p_win = newwin(nlines, ncols, 2 + nlines, 2 + ncols); set_win_params(&my_windows[3], nlines, ncols, 2 + nlines, 2 + ncols); } /*Die Restlichen Parameter an unsere selbstdefinierte Struktur WIN*/ void set_win_params(WIN *win, int nlines, int ncols, int y, int x) { win->nlines = nlines; win->ncols = ncols; win->y = y; win->x = x; }

Diese Simple Beispiel glaube Demonstriert eindeutig was man sich unter Region of Interest vorstellen kann.

Als Ergänzung zu diesem Kapitel sind noch die Funktionen...............

Gpm_Roi *Gpm_RaiseRoi(Gpm_Roi *which, Gpm_Roi *before);
Gpm_Roi *Gpm_LowerRoi(Gpm_Roi *which, Gpm_Roi *after);  

...zu erklären womit wir die einzelnen Regions of Interests auf dem Stapel verschieben können. Mit Gpm_RaiseRoi() können sie eine Roi an den Anfang des Stapels schieben............

Gpm_RaiseRoi(roi, NULL); //Region of Interest roi kommt an den Anfang des Stapels  

...oder...

Gpm_RaiseRoi(roi , roi2) //roi kommt im Stapel vor der Region of Interests roi2  

Mit Gpm_LowerRoi() machen wir genau das Gegenteil..............

Gpm_LowerRoi(roi, NULL); //roi kommt ans Ende des Stapels
Gpm_LowerRoi(roi, roi2); //roi kommt genau hinter roi2  

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf