/* vga test n°3 - gestion du curseur de souris - Patrick TRAU mai 02 Les commentaires dans les tests précédents ne sont pas tous recopiés ici ! ici j'affiche le curseur de la souris (une petite croix). ce n'est pas facile : à chaque fois qu'on dessine le curseur, il faut sauver le fond avant de dessiner. puis quand on veut l'effacer, il faut en fait redessiner ce qu'on avait sauvegardé. Evidement, entre les 2 le fond (c.a.d le dessin, sauf le curseur) ne doit pas être modifié sinon on redessine un vieux fond non modifié. Donc deux fonctions : cachecurs et montrecurs. Avant tout dessin on cache, on dessine, puis on remontre (ça marche même si la souris a bougé pendant le dessin). A tout moment (ou du moins pendant les phases où l'on attend un mouvement de souris, les autres le curseur n'est pas obligatoire surtout si elles sont courtes), il faut appeler montrecurs (je l'ai fait vérifier si la souris a bougé, et dans ce cas il cache puis remontre) */ #include <stdio.h> #include <stdlib.h> #include <vga.h> #include <vgamouse.h> int choix_mode(void) { int m; printf("choisissez une définition qui ne plante pas votre carte graphique:\n"); printf(" G320x200x16 1"); printf(" G640x200x16 2"); printf(" G640x350x16 3"); printf(" G640x480x16 4"); printf(" G320x200x256 5"); printf(" G320x240x256 6"); printf(" G320x400x256 7"); printf(" G360x480x256 8"); printf(" G640x480x2 9"); printf(" G640x480x256 10"); printf(" G800x600x256 11"); printf(" G1024x768x256 12 ? "); scanf("%d",&m); return m; } int choix_souris(void) // à faire avant vga_init car printf { int m; printf("choisissez votre souris :\n"); printf(" MOUSE_MICROSOFT 0"); printf(" MOUSE_MOUSESYSTEMS 1"); printf(" MOUSE_MMSERIES 2"); printf(" MOUSE_LOGITECH 3"); printf(" MOUSE_BUSMOUSE 4"); printf(" MOUSE_PS2 5"); printf(" MOUSE_LOGIMAN 6"); printf(" MOUSE_GPM 7"); printf(" MOUSE_SPACEBALL 8"); printf(" MOUSE_NONE 9"); printf(" MOUSE_INTELLIMOUSE 10"); printf(" MOUSE_IMPS2 11 ? "); scanf("%d",&m); return m; } void tracecadre(void) { int x,y,coul,i; x=vga_getxdim(); //récup résolution actuelle y=vga_getydim(); // coul=vga_getcolors(); //récup nb de couleurs dans le mode actu coul=vga_white(); //récup n° de couleur du blanc dans le mode actu vga_drawline(0,0,x-1,0); vga_drawline(x-1,0,x-1,y-1); vga_drawline(x-1,y-1,0,y-1); vga_drawline(0,y-1,0,0); } //partie spécifique souris, pourrait être compilée à part si nécessaire // variables spécifiques à ma gestion du curseur. Elles DOIVENT être statiques // car entre deux appels je dois récupérer le fond sauvé précédemment #define TAILLECURS 5 /* en fait longueur d'une branche, taille totale = ça*2+1 */ #define coulcurs 14 static int cursvisible=0; static int oldcursx=0; static int oldcursy=0; static int curssvg[(TAILLECURS*4)+1]={0}; void cachecurs(void) // remet le fond tel qu'il était, où était le curseur (quelle que soit la pos actu) { int i,j,coulini; vga_drawpixel(oldcursx,oldcursy); //rien que pour récupérer la couleur initiale, je dessine un pt que je teste après coulini=vga_getpixel(oldcursx,oldcursy); j=0;vga_setcolor(curssvg[j++]);vga_drawpixel(oldcursx,oldcursy); //réécriture du vieux fond for(i=TAILLECURS;i;i--) {vga_setcolor(curssvg[j++]);vga_drawpixel(oldcursx+i,oldcursy); vga_setcolor(curssvg[j++]);vga_drawpixel(oldcursx-i,oldcursy); vga_setcolor(curssvg[j++]);vga_drawpixel(oldcursx,oldcursy+i); vga_setcolor(curssvg[j++]);vga_drawpixel(oldcursx,oldcursy-i);} cursvisible=0; vga_setcolor(coulini); } void montrecurs(void) // lit la position de la souris et dessine le curseur ici, après avoir sauvé le fond // si le curseur était déjà visible, à un autre endroit, je le cache et le mets à sa // nouvelle place { int coulini; int i,j; mouse_update(); if(cursvisible) {if(oldcursx!=mouse_getx()||oldcursy!=mouse_gety())cachecurs();} oldcursx=mouse_getx();oldcursy=mouse_gety(); //je sauve (écrase) la pos actu j=0;curssvg[j++]=vga_getpixel(oldcursx,oldcursy); //curssvg du nouveau fond for(i=TAILLECURS;i;i--) {curssvg[j++]=vga_getpixel(oldcursx+i,oldcursy); curssvg[j++]=vga_getpixel(oldcursx-i,oldcursy); curssvg[j++]=vga_getpixel(oldcursx,oldcursy+i); curssvg[j++]=vga_getpixel(oldcursx,oldcursy-i);} vga_drawpixel(oldcursx,oldcursy); //rien que pour récupérer la couleur initiale, je dessine un pt que je teste après coulini=vga_getpixel(oldcursx,oldcursy); vga_setcolor(coulcurs); vga_drawpixel(oldcursx,oldcursy); //tracé curseur for(i=TAILLECURS;i;i--) { if(oldcursx+i<vga_getxdim())vga_drawpixel(oldcursx+i,oldcursy); if(oldcursx-i>=0)vga_drawpixel(oldcursx-i,oldcursy); if(oldcursy+i<vga_getydim())vga_drawpixel(oldcursx,oldcursy+i); if(oldcursy-i>=0)vga_drawpixel(oldcursx,oldcursy-i); } usleep(50); // pour que le cureur ne clignote pas, il faut rester un peu allumé, 50 mini, mais même 5000 ne ralentit pas trop vga_setcolor(coulini); cursvisible=1; } #define deplacecurs(a) montrecurs(a) // avant, deplacecurs() cachait l'ancien curseur (car la souris avait bougé) // et le montrait dans la nouvelle position. montrecurs de faut aussi (si cursvisible) //fin partie spécifique int main(void) { int i,mode,typesouris; int mousetype,c,x,x0=0,y,y0=0; //mode=5; mode=choix_mode(); //4 @home, 4 à 12 à l'ipst //typesouris=5; typesouris=choix_souris(); //0 @home, 5 à l'ipst //debut test graphique de base vga_init(); vga_setmode(mode); tracecadre(); vga_setcolor(14); for(i=0;i<vga_getydim();i++) vga_drawpixel(i,i); //debut test souris mousetype=mouse_init("/dev/mouse",typesouris,400); //MOUSE_PS2 à l'ipst, MOUSE_MICROSOFT @home mouse_setxrange( 0, vga_getxdim()-1); mouse_setyrange( 0, vga_getydim()-1); vga_setmousesupport(mousetype); mouse_setscale(50); montrecurs(); //par défaut le curseur était caché, puisque c'est moi qui le dessine do { mouse_update(); // à faire à tout bout de champ pour que les fonctions suiv soient mises à jour c=7&mouse_getbutton(); //0 pas de bouton, 4 gauche, 1 droite, 5 les 2 (2 boutons) vga_setcolor(c*2); x=mouse_getx();y=mouse_gety(); cachecurs(); if(c>0)vga_drawline(x0,y0,x,y); //tout tracé doit se faire curseur caché ! montrecurs(); x0=x;y0=y; } while(c<5); //sortie si appui sur les 2 boutons fprintf(stderr,"sortie : %d\n",c); //fin testsouris vga_setmode(TEXT); //retourner au mode texte (important) printf("fini\n"); //les printf se font sur la console où on a lancé la commande return EXIT_SUCCESS; }
Patrick Trau, IPST, Université Louis Pasteur Strasbourg, mai 2002