/* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Grafx2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. Grafx2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grafx2; if not, see or write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "global.h" #include "clavier.h" #include "graph.h" #include "sdlscreen.h" #include "windows.h" #include "erreurs.h" void Handle_Window_Resize(SDL_Event* event); void Handle_Window_Exit(SDL_Event* event); byte Directional_up; byte Directional_up_right; byte Directional_right; byte Directional_down_right; byte Directional_down; byte Directional_down_left; byte Directional_left; byte Directional_up_left; long Directional_delay; long Directional_last_move; long Directional_step; // Called each time there is a cursor move, either triggered by mouse or keyboard shortcuts int Move_cursor_with_constraints() { //Gestion "avancée" du curseur: interdire la descente du curseur dans le //menu lorsqu'on est en train de travailler dans l'image if (Operation_Taille_pile != 0) { byte bl=0;//BL va indiquer si on doit corriger la position du curseur //Si le curseur ne se trouve plus dans l'image if(Menu_Ordonnee<=INPUT_Nouveau_Mouse_Y) { //On bloque le curseur en fin d'image bl++; INPUT_Nouveau_Mouse_Y=Menu_Ordonnee-1; //La ligne !!au-dessus!! du menu } if(Loupe_Mode) { if(Operation_dans_loupe==0) { if(INPUT_Nouveau_Mouse_X>=Principal_Split) { bl++; INPUT_Nouveau_Mouse_X=Principal_Split-1; } } else { if(INPUT_Nouveau_Mouse_Xtype == SDL_VIDEORESIZE ) { Handle_Window_Resize(event); } // Fermeture if (event->type == SDL_QUIT ) { Handle_Window_Exit(event); } } // WM events management void Handle_Window_Resize(SDL_Event* event) { Resize_Largeur = event->resize.w; Resize_Hauteur = event->resize.h; } void Handle_Window_Exit(SDL_Event* event) { Quit_demande = 1; } // Mouse events management int Handle_Mouse_Move(SDL_Event* event) { INPUT_Nouveau_Mouse_X = event->motion.x/Pixel_width; INPUT_Nouveau_Mouse_Y = event->motion.y/Pixel_height; return Move_cursor_with_constraints(); } void Handle_Mouse_Click(SDL_Event* event) { switch(event->button.button) { case SDL_BUTTON_LEFT: INPUT_Nouveau_Mouse_K |= 1; break; case SDL_BUTTON_MIDDLE: INPUT_Nouveau_Mouse_K |= 4; break; case SDL_BUTTON_RIGHT: INPUT_Nouveau_Mouse_K |= 2; break; default: DEBUG("Unknown mouse button!",0); return; } Move_cursor_with_constraints(); } void Handle_Mouse_Release(SDL_Event* event) { switch(event->button.button) { case SDL_BUTTON_LEFT: INPUT_Nouveau_Mouse_K &= ~1; break; case SDL_BUTTON_MIDDLE: INPUT_Nouveau_Mouse_K &= ~4; break; case SDL_BUTTON_RIGHT: INPUT_Nouveau_Mouse_K &= ~2; break; } Move_cursor_with_constraints(); } // Keyboard management int Handle_Key_Press(SDL_Event* event) { //Appui sur une touche du clavier Touche = Conversion_Touche(event->key.keysym); Touche_ANSI = Conversion_ANSI(event->key.keysym); if(Touche == Config_Touche[SPECIAL_MOUSE_UP]) { Directional_up=1; return 0; } else if(Touche == Config_Touche[SPECIAL_MOUSE_DOWN]) { Directional_down=1; return 0; } else if(Touche == Config_Touche[SPECIAL_MOUSE_LEFT]) { Directional_left=1; return 0; } else if(Touche == Config_Touche[SPECIAL_MOUSE_RIGHT]) { Directional_right=1; return 0; } else if(Touche == Config_Touche[SPECIAL_CLICK_LEFT]) { INPUT_Nouveau_Mouse_K=1; Move_cursor_with_constraints(); return 1; } else if(Touche == Config_Touche[SPECIAL_CLICK_RIGHT]) { INPUT_Nouveau_Mouse_K=2; Move_cursor_with_constraints(); return 1; } if (Operation_Taille_pile!=0 && Touche != 0) { //Enfin, on inhibe les touches (sauf si c'est un changement de couleur //ou de taille de pinceau lors d'une des operations suivantes: //OPERATION_DESSIN_CONTINU, OPERATION_DESSIN_DISCONTINU, OPERATION_SPRAY) if(Autoriser_changement_de_couleur_pendant_operation) { //A ce stade là, on sait qu'on est dans une des 3 opérations //supportant le changement de couleur ou de taille de pinceau. if( (Touche != Config_Touche[SPECIAL_NEXT_FORECOLOR]) && (Touche != Config_Touche[SPECIAL_PREVIOUS_FORECOLOR]) && (Touche != Config_Touche[SPECIAL_NEXT_BACKCOLOR]) && (Touche != Config_Touche[SPECIAL_PREVIOUS_BACKCOLOR]) && (Touche != Config_Touche[SPECIAL_RETRECIR_PINCEAU]) && (Touche != Config_Touche[SPECIAL_GROSSIR_PINCEAU]) && (Touche != Config_Touche[SPECIAL_NEXT_USER_FORECOLOR]) && (Touche != Config_Touche[SPECIAL_PREVIOUS_USER_FORECOLOR]) && (Touche != Config_Touche[SPECIAL_NEXT_USER_BACKCOLOR]) && (Touche != Config_Touche[SPECIAL_PREVIOUS_USER_BACKCOLOR]) ) { Touche=0; } } else Touche = 0; } return 0; } void Handle_Key_Release(SDL_Event* event) { int Modifieur; int ToucheR = Conversion_Touche(event->key.keysym) & 0x0FFF; switch(event->key.keysym.sym) { case SDLK_RSHIFT: case SDLK_LSHIFT: Modifieur=MOD_SHIFT; break; case SDLK_RCTRL: case SDLK_LCTRL: Modifieur=MOD_CTRL; break; case SDLK_RALT: case SDLK_LALT: case SDLK_MODE: Modifieur=MOD_ALT; break; default: Modifieur=0; } if(ToucheR == (Config_Touche[SPECIAL_MOUSE_UP]&0x0FFF) || (Config_Touche[SPECIAL_MOUSE_UP]&Modifieur)) { Directional_up=0; } if(ToucheR == (Config_Touche[SPECIAL_MOUSE_DOWN]&0x0FFF) || (Config_Touche[SPECIAL_MOUSE_DOWN]&Modifieur)) { Directional_down=0; } if(ToucheR == (Config_Touche[SPECIAL_MOUSE_LEFT]&0x0FFF) || (Config_Touche[SPECIAL_MOUSE_LEFT]&Modifieur)) { Directional_left=0; } if(ToucheR == (Config_Touche[SPECIAL_MOUSE_RIGHT]&0x0FFF) || (Config_Touche[SPECIAL_MOUSE_RIGHT]&Modifieur)) { Directional_right=0; } if(ToucheR == (Config_Touche[SPECIAL_CLICK_LEFT]&0x0FFF) || (Config_Touche[SPECIAL_CLICK_LEFT]&Modifieur)) { INPUT_Nouveau_Mouse_K &= ~1; Move_cursor_with_constraints(); } if(ToucheR == (Config_Touche[SPECIAL_CLICK_RIGHT]&0x0FFF) || (Config_Touche[SPECIAL_CLICK_RIGHT]&Modifieur)) { INPUT_Nouveau_Mouse_K &= ~2; Move_cursor_with_constraints(); } // Other keys don't need to be released : they are handled as "events" and procesed only once. // These clicks are apart because they need to be continuous (ie move while key pressed) // We are relying on "hardware" keyrepeat to achieve that. } // Joystick management void Handle_Joystick_Press(SDL_Event* event) { if (event->jbutton.which==0) // joystick number 0 { #ifdef __gp2x__ switch(event->jbutton.button) { case 0: Directional_up=1; break; case 7: Directional_up_right=1; break; case 6: Directional_right=1; break; case 5: Directional_down_right=1; break; case 4: Directional_down=1; break; case 3: Directional_down_left=1; break; case 2: Directional_left=1; break; case 1: Directional_up_left=1; break; case 12: // A INPUT_Nouveau_Mouse_K=1; break; case 13: // B INPUT_Nouveau_Mouse_K=2; break; } #else switch(event->jbutton.button) { case 0: // A INPUT_Nouveau_Mouse_K=1; break; case 1: // B INPUT_Nouveau_Mouse_K=2; break; } #endif } } void Handle_Joystick_Release(SDL_Event* event) { if (event->jbutton.which==0) // joystick number 0 { #ifdef __gp2x__ switch(event->jbutton.button) { case 0: Directional_up=0; break; case 7: Directional_up_right=0; break; case 6: Directional_right=0; break; case 5: Directional_down_right=0; break; case 4: Directional_down=0; break; case 3: Directional_down_left=0; break; case 2: Directional_left=0; break; case 1: Directional_up_left=0; break; case 12: // A INPUT_Nouveau_Mouse_K &= ~1; break; case 13: // B INPUT_Nouveau_Mouse_K &= ~2; break; } #else switch(event->jbutton.button) { case 0: // A INPUT_Nouveau_Mouse_K &= ~1; break; case 1: // B INPUT_Nouveau_Mouse_K &= ~2; break; } #endif } } void Handle_Joystick_Movement(SDL_Event* event) { if (event->jaxis.which==0) // joystick number 0 { if (event->jaxis.axis==0) // X { Directional_right=Directional_left=0; if (event->jaxis.value<-1000) { Directional_left=1; } else if (event->jaxis.value>1000) Directional_right=1; } else if (event->jaxis.axis==1) // Y { Directional_up=Directional_down=0; if (event->jaxis.value<-1000) { Directional_up=1; } else if (event->jaxis.value>1000) Directional_down=1; } } } // Main input handling function int Get_input(void) { SDL_Event event; int User_Feedback_Required = 0; // Flag qui indique si on doit arrêter de traiter les évènements ou si on peut enchainer Touche_ANSI = 0; Touche = 0; // Process as much events as possible without redrawing the screen. // This mostly allows us to merge mouse events for people with an high // resolution mouse while( (!User_Feedback_Required) && SDL_PollEvent(&event)) // Try to cumulate for a full VBL except if there is a required feedback { switch(event.type) { case SDL_VIDEORESIZE: Handle_Window_Resize(&event); User_Feedback_Required = 1; break; case SDL_QUIT: Handle_Window_Exit(&event); User_Feedback_Required = 1; break; case SDL_MOUSEMOTION: User_Feedback_Required = Handle_Mouse_Move(&event); break; case SDL_MOUSEBUTTONDOWN: Handle_Mouse_Click(&event); User_Feedback_Required = 1; break; case SDL_MOUSEBUTTONUP: Handle_Mouse_Release(&event); User_Feedback_Required = 1; break; case SDL_KEYDOWN: Handle_Key_Press(&event); User_Feedback_Required = 1; break; case SDL_KEYUP: Handle_Key_Release(&event); break; case SDL_JOYBUTTONUP: Handle_Joystick_Release(&event); User_Feedback_Required = 1; break; case SDL_JOYBUTTONDOWN: Handle_Joystick_Press(&event); User_Feedback_Required = 1; break; case SDL_JOYAXISMOTION: Handle_Joystick_Movement(&event); break; default: DEBUG("Unhandled SDL event number : ",event.type); break; } } // Directional controller if (!(Directional_up||Directional_up_right||Directional_right|| Directional_down_right||Directional_down||Directional_down_left|| Directional_left||Directional_up_left)) { Directional_delay=-1; Directional_last_move=SDL_GetTicks(); } else { long Now; Now=SDL_GetTicks(); if (Now>Directional_last_move+Directional_delay) { if (Directional_delay==-1) { Directional_delay=150; Directional_step=16; } else if (Directional_delay==150) Directional_delay=40; else if (Directional_delay!=0) Directional_delay=Directional_delay*8/10; else if (Directional_step<16*4) Directional_step++; Directional_last_move = Now; // Directional controller UP if ((Directional_up||Directional_up_left||Directional_up_right) && !(Directional_down_right||Directional_down||Directional_down_left)) { //si on est déjà en haut on peut plus bouger if(INPUT_Nouveau_Mouse_Y!=0) { if(Loupe_Mode && INPUT_Nouveau_Mouse_Y < Menu_Ordonnee && INPUT_Nouveau_Mouse_X > Principal_Split) INPUT_Nouveau_Mouse_Y=INPUT_Nouveau_Mouse_Y Principal_Split) { INPUT_Nouveau_Mouse_X+=Loupe_Facteur; if (INPUT_Nouveau_Mouse_X>=Largeur_ecran) INPUT_Nouveau_Mouse_X=Largeur_ecran-1; } else INPUT_Nouveau_Mouse_X+=Directional_step/16; Move_cursor_with_constraints(); } } // Directional controller DOWN if ((Directional_down_right||Directional_down||Directional_down_left) && !(Directional_up_left||Directional_up||Directional_up_right)) { if(INPUT_Nouveau_Mouse_Y Principal_Split) { INPUT_Nouveau_Mouse_Y+=Loupe_Facteur; if (INPUT_Nouveau_Mouse_Y>=Hauteur_ecran) INPUT_Nouveau_Mouse_Y=Hauteur_ecran-1; } else INPUT_Nouveau_Mouse_Y+=Directional_step/16; Move_cursor_with_constraints(); } } // Directional controller LEFT if ((Directional_down_left||Directional_left||Directional_up_left) && !(Directional_up_right||Directional_right||Directional_down_right)) { if(INPUT_Nouveau_Mouse_X!=0) { if(Loupe_Mode && INPUT_Nouveau_Mouse_Y < Menu_Ordonnee && INPUT_Nouveau_Mouse_X > Principal_Split) INPUT_Nouveau_Mouse_X-=Loupe_Facteur; else INPUT_Nouveau_Mouse_X-=Directional_step/16; Move_cursor_with_constraints(); } } } } // Vidage de toute mise à jour de l'affichage à l'écran qui serait encore en attente. // (c'est fait ici car on est sur que cette fonction est apellée partout ou on a besoin d'interragir avec l'utilisateur) Flush_update(); return User_Feedback_Required; }