/* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2008 Peter Gordon
Copyright 2008 Yves Rizoud
Copyright 2008 Franck Charlet
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.
*/
// Signal handler: I activate it for the two platforms who certainly
// support them. Feel free to check with others.
#if defined(__WIN32__) || defined(__linux__)
#define GRAFX2_CATCHES_SIGNALS
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(__WIN32__)
#include // GetLogicalDrives(), GetDriveType(), DRIVE_*
#endif
#if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__)
#include
#include
#endif
#ifdef GRAFX2_CATCHES_SIGNALS
#include
#endif
#include "const.h"
#include "struct.h"
#include "global.h"
#include "graph.h"
#include "boutons.h"
#include "palette.h"
#include "aide.h"
#include "operatio.h"
#include "divers.h"
#include "erreurs.h"
#include "clavier.h"
#include "io.h"
#include "hotkeys.h"
#include "files.h"
#include "setup.h"
#include "windows.h"
#include "sdlscreen.h"
#include "mountlist.h" // read_file_system_list
#include "loadsave.h" // Image_emergency_backup
// Rechercher la liste et le type des lecteurs de la machine
#if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__)
void bstrtostr( BSTR in, STRPTR out, TEXT max );
#endif
// Fonctions de lecture dans la skin de l'interface graphique
void Chercher_bas(SDL_Surface *gui, int *Debut_X, int *Debut_Y, byte Couleur_neutre,char * Section)
{
byte Couleur;
int Y;
Y=*Debut_Y;
*Debut_X=0;
do
{
Couleur=Sdl_Get_pixel_8(gui,*Debut_X,Y);
if (Couleur!=Couleur_neutre)
{
*Debut_Y=Y;
return;
}
Y++;
} while (Yh);
printf("Error in skin file: Was looking down from %d,%d for a '%s', and reached the end of the image\n",
*Debut_X, *Debut_Y, Section);
Erreur(ERREUR_GUI_CORROMPU);
}
void Chercher_droite(SDL_Surface *gui, int *Debut_X, int Debut_Y, byte Couleur_neutre, char * Section)
{
byte Couleur;
int X;
X=*Debut_X;
do
{
Couleur=Sdl_Get_pixel_8(gui,X,Debut_Y);
if (Couleur!=Couleur_neutre)
{
*Debut_X=X;
return;
}
X++;
} while (Xw);
printf("Error in skin file: Was looking right from %d,%d for a '%s', and reached the edege of the image\n",
*Debut_X, Debut_Y, Section);
Erreur(ERREUR_GUI_CORROMPU);
}
void Lire_bloc(SDL_Surface *gui, int Debut_X, int Debut_Y, void *Dest, int Largeur, int Hauteur, char * Section, int Type)
{
// Type: 0 = normal GUI element, only 4 colors allowed
// Type: 1 = mouse cursor, 4 colors allowed + transparent
// Type: 2 = brush icon or sieve pattern (only CM_Blanc and CM_Trans)
// Type: 3 = raw bitmap (splash screen)
byte * Ptr=Dest;
int X,Y;
byte Couleur;
// Verification taille
if (Debut_Y+Hauteur>=gui->h || Debut_X+Largeur>=gui->w)
{
printf("Error in skin file: Was looking at %d,%d for a %d*%d object (%s) but it doesn't fit the image.\n",
Debut_X, Debut_Y, Hauteur, Largeur, Section);
Erreur(ERREUR_GUI_CORROMPU);
}
for (Y=Debut_Y; Yformat || gui->format->BitsPerPixel != 8)
{
printf("Not a 8-bit image");
Erreur(ERREUR_GUI_CORROMPU);
}
SDLPal=gui->format->palette;
if (!SDLPal || SDLPal->ncolors!=256)
{
printf("Not a 256-color palette");
Erreur(ERREUR_GUI_CORROMPU);
}
// Lecture de la palette par défaut
for (i=0; i<256; i++)
{
Palette_defaut[i].R=SDLPal->colors[i].r;
Palette_defaut[i].V=SDLPal->colors[i].g;
Palette_defaut[i].B=SDLPal->colors[i].b;
}
// Carré "noir"
CM_Noir = Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
do
{
if (++Curseur_X>=gui->w)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
} while(Couleur==CM_Noir);
// Carré "foncé"
CM_Fonce=Couleur;
do
{
if (++Curseur_X>=gui->w)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
} while(Couleur==CM_Fonce);
// Carré "clair"
CM_Clair=Couleur;
do
{
if (++Curseur_X>gui->w)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
} while(Couleur==CM_Clair);
// Carré "blanc"
CM_Blanc=Couleur;
do
{
if (++Curseur_X>=gui->w)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
} while(Couleur==CM_Blanc);
// Carré "transparent"
CM_Trans=Couleur;
do
{
if (++Curseur_X>=gui->w)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y);
} while(Couleur==CM_Trans);
// Reste : couleur neutre
CM_Neutre=Couleur;
Curseur_X=0;
Curseur_Y=1;
while ((Couleur=Sdl_Get_pixel_8(gui,Curseur_X,Curseur_Y))==CM_Noir)
{
Curseur_Y++;
if (Curseur_Y>=gui->h)
{
printf("Error in GUI skin file: should start with 5 consecutive squares for black, dark, light, white, transparent, then a neutral color\n");
Erreur(ERREUR_GUI_CORROMPU);
}
}
// Menu
Chercher_bas(gui, &Curseur_X, &Curseur_Y, CM_Neutre, "menu");
Lire_bloc(gui, Curseur_X, Curseur_Y, BLOCK_MENU, LARGEUR_MENU, HAUTEUR_MENU,"menu",0);
Curseur_Y+=HAUTEUR_MENU;
// Effets
for (i=0; i>1);
Pinceau_predefini_Decalage_Y[Indice]=(Pinceau_predefini_Hauteur[Indice]>>1);
}
Curseur_Decalage_X[FORME_CURSEUR_FLECHE]=0;
Curseur_Decalage_Y[FORME_CURSEUR_FLECHE]=0;
Curseur_Decalage_X[FORME_CURSEUR_CIBLE]=7;
Curseur_Decalage_Y[FORME_CURSEUR_CIBLE]=7;
Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE]=7;
Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE]=7;
Curseur_Decalage_X[FORME_CURSEUR_SABLIER]=7;
Curseur_Decalage_Y[FORME_CURSEUR_SABLIER]=7;
Curseur_Decalage_X[FORME_CURSEUR_MULTIDIRECTIONNEL]=7;
Curseur_Decalage_Y[FORME_CURSEUR_MULTIDIRECTIONNEL]=7;
Curseur_Decalage_X[FORME_CURSEUR_HORIZONTAL]=7;
Curseur_Decalage_Y[FORME_CURSEUR_HORIZONTAL]=3;
Curseur_Decalage_X[FORME_CURSEUR_CIBLE_FINE]=7;
Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_FINE]=7;
Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7;
Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7;
}
// Initialisation des boutons:
// Action factice:
void Rien_du_tout(void)
{}
// Initialiseur d'un bouton:
void Initialiser_bouton(byte Numero,
word Decalage_X , word Decalage_Y,
word Largeur , word Hauteur,
byte Forme,
fonction_action Gauche , fonction_action Droite,
fonction_action Desenclencher,
byte Famille)
{
Bouton[Numero].Decalage_X =Decalage_X;
Bouton[Numero].Decalage_Y =Decalage_Y;
Bouton[Numero].Largeur =Largeur-1;
Bouton[Numero].Hauteur =Hauteur-1;
Bouton[Numero].Enfonce =0;
Bouton[Numero].Forme =Forme;
Bouton[Numero].Gauche =Gauche;
Bouton[Numero].Droite =Droite;
Bouton[Numero].Desenclencher =Desenclencher;
Bouton[Numero].Famille =Famille;
}
// Initiliseur de tous les boutons:
void Initialisation_des_boutons(void)
{
byte Indice_bouton;
for (Indice_bouton=0;Indice_bouton= MAX_MODES_VIDEO-1)
{
DEBUG("Error! Attempt to create too many videomodes. Maximum is:", MAX_MODES_VIDEO);
return;
}
if (!Fullscreen)
Supporte = 128; // Prefere, non modifiable
else if (SDL_VideoModeOK(Largeur, Hauteur, 8, SDL_FULLSCREEN))
Supporte = 1; // Supporte
else
{
// Non supporte : on ne le prend pas
return;
}
Mode_video[Nb_modes_video].Largeur = Largeur;
Mode_video[Nb_modes_video].Hauteur = Hauteur;
Mode_video[Nb_modes_video].Mode = Mode;
Mode_video[Nb_modes_video].Fullscreen = Fullscreen;
Mode_video[Nb_modes_video].Etat = Supporte;
Nb_modes_video ++;
}
// Utilisé pour trier les modes retournés par SDL
int Compare_modes_video(const void *p1, const void *p2)
{
const struct S_Mode_video *Mode1 = (const struct S_Mode_video *)p1;
const struct S_Mode_video *Mode2 = (const struct S_Mode_video *)p2;
// Tris par largeur
if(Mode1->Largeur - Mode2->Largeur)
return Mode1->Largeur - Mode2->Largeur;
// Tri par hauteur
return Mode1->Hauteur - Mode2->Hauteur;
}
// Initiliseur de tous les modes video:
void Definition_des_modes_video(void)
{ // Numero LargHaut Mode FXFY Ratio Ref WinOnly Pointeur
SDL_Rect** Modes;
Nb_modes_video=0;
// Doit être en premier pour avoir le numéro 0:
Definir_mode_video( 640,480,0, 0);
Definir_mode_video( 320,200,0, 1);
Definir_mode_video( 320,224,0, 1);
Definir_mode_video( 320,240,0, 1);
Definir_mode_video( 320,256,0, 1);
Definir_mode_video( 320,270,0, 1);
Definir_mode_video( 320,282,0, 1);
Definir_mode_video( 320,300,0, 1);
Definir_mode_video( 320,360,0, 1);
Definir_mode_video( 320,400,0, 1);
Definir_mode_video( 320,448,0, 1);
Definir_mode_video( 320,480,0, 1);
Definir_mode_video( 320,512,0, 1);
Definir_mode_video( 320,540,0, 1);
Definir_mode_video( 320,564,0, 1);
Definir_mode_video( 320,600,0, 1);
Definir_mode_video( 360,200,0, 1);
Definir_mode_video( 360,224,0, 1);
Definir_mode_video( 360,240,0, 1);
Definir_mode_video( 360,256,0, 1);
Definir_mode_video( 360,270,0, 1);
Definir_mode_video( 360,282,0, 1);
Definir_mode_video( 360,300,0, 1);
Definir_mode_video( 360,360,0, 1);
Definir_mode_video( 360,400,0, 1);
Definir_mode_video( 360,448,0, 1);
Definir_mode_video( 360,480,0, 1);
Definir_mode_video( 360,512,0, 1);
Definir_mode_video( 360,540,0, 1);
Definir_mode_video( 360,564,0, 1);
Definir_mode_video( 360,600,0, 1);
Definir_mode_video( 400,200,0, 1);
Definir_mode_video( 400,224,0, 1);
Definir_mode_video( 400,240,0, 1);
Definir_mode_video( 400,256,0, 1);
Definir_mode_video( 400,270,0, 1);
Definir_mode_video( 400,282,0, 1);
Definir_mode_video( 400,300,0, 1);
Definir_mode_video( 400,360,0, 1);
Definir_mode_video( 400,400,0, 1);
Definir_mode_video( 400,448,0, 1);
Definir_mode_video( 400,480,0, 1);
Definir_mode_video( 400,512,0, 1);
Definir_mode_video( 400,540,0, 1);
Definir_mode_video( 400,564,0, 1);
Definir_mode_video( 400,600,0, 1);
Definir_mode_video( 640,224,0, 1);
Definir_mode_video( 640,240,0, 1);
Definir_mode_video( 640,256,0, 1);
Definir_mode_video( 640,270,0, 1);
Definir_mode_video( 640,300,0, 1);
Definir_mode_video( 640,350,0, 1);
Definir_mode_video( 640,400,0, 1);
Definir_mode_video( 640,448,0, 1);
Definir_mode_video( 640,480,0, 1);
Definir_mode_video( 640,512,0, 1);
Definir_mode_video( 640,540,0, 1);
Definir_mode_video( 640,564,0, 1);
Definir_mode_video( 640,600,0, 1);
Definir_mode_video( 800,600,0, 1);
Definir_mode_video(1024,768,0, 1);
Modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
if ((Modes != (SDL_Rect**)0) && (Modes!=(SDL_Rect**)-1))
{
int Indice;
for (Indice=0; Modes[Indice]; Indice++)
{
int Indice2;
for (Indice2=1; Indice2 < Nb_modes_video; Indice2++)
if (Modes[Indice]->w == Mode_video[Indice2].Largeur &&
Modes[Indice]->h == Mode_video[Indice2].Hauteur)
{
// Mode déja prévu: ok
break;
}
if (Indice2 >= Nb_modes_video && Modes[Indice]->w>=320 && Modes[Indice]->h>=200)
{
// Nouveau mode à ajouter à la liste
Definir_mode_video(Modes[Indice]->w,Modes[Indice]->h,0, 1);
}
}
// Tri des modes : ceux trouvés par SDL ont été listés à la fin.
qsort(&Mode_video[1], Nb_modes_video - 1, sizeof(struct S_Mode_video), Compare_modes_video);
}
}
//---------------------------------------------------------------------------
int Charger_CFG(int Tout_charger)
{
FILE* Handle;
char Nom_du_fichier[TAILLE_CHEMIN_FICHIER];
long Taille_fichier;
int Indice,Indice2;
Config_Header CFG_Header;
Config_Chunk Chunk;
Config_Infos_touche CFG_Infos_touche;
Config_Mode_video CFG_Mode_video;
struct stat Informations_Fichier;
int Conversion_touches = 0;
strcpy(Nom_du_fichier,Repertoire_de_configuration);
strcat(Nom_du_fichier,"gfx2.cfg");
stat(Nom_du_fichier,&Informations_Fichier);
Taille_fichier=Informations_Fichier.st_size;
if ((Handle=fopen(Nom_du_fichier,"rb"))==NULL)
return ERREUR_CFG_ABSENT;
if ( (Taille_fichier<(long)sizeof(CFG_Header))
|| (!read_bytes(Handle, &CFG_Header.Signature, 3))
|| memcmp(CFG_Header.Signature,"CFG",3)
|| (!read_byte(Handle, &CFG_Header.Version1))
|| (!read_byte(Handle, &CFG_Header.Version2))
|| (!read_byte(Handle, &CFG_Header.Beta1))
|| (!read_byte(Handle, &CFG_Header.Beta2)) )
goto Erreur_lecture_config;
// Version DOS de Robinson et X-Man
if ( (CFG_Header.Version1== 2)
&& (CFG_Header.Version2== 0)
&& (CFG_Header.Beta1== 96))
{
// Les touches (scancodes) sont à convertir)
Conversion_touches = 1;
}
// Version SDL jusqu'a 98%
else if ( (CFG_Header.Version1== 2)
&& (CFG_Header.Version2== 0)
&& (CFG_Header.Beta1== 97))
{
// Les touches 00FF (pas de touche) sont a comprendre comme 0x0000
Conversion_touches = 2;
}
// Version SDL
else if ( (CFG_Header.Version1!=VERSION1)
|| (CFG_Header.Version2!=VERSION2)
|| (CFG_Header.Beta1!=BETA1)
|| (CFG_Header.Beta2!=BETA2) )
goto Erreur_config_ancienne;
// - Lecture des infos contenues dans le fichier de config -
while (read_byte(Handle, &Chunk.Numero))
{
read_word_le(Handle, &Chunk.Taille);
switch (Chunk.Numero)
{
case CHUNK_TOUCHES: // Touches
if (Tout_charger)
{
for (Indice=0; Indice<(long)(Chunk.Taille/sizeof(CFG_Infos_touche)); Indice++)
{
if (!read_word_le(Handle, &CFG_Infos_touche.Numero) ||
!read_word_le(Handle, &CFG_Infos_touche.Touche) ||
!read_word_le(Handle, &CFG_Infos_touche.Touche2) )
goto Erreur_lecture_config;
else
{
if (Conversion_touches==1)
{
CFG_Infos_touche.Touche = Touche_pour_scancode(CFG_Infos_touche.Touche);
}
else if (Conversion_touches==2)
{
if (CFG_Infos_touche.Touche == 0x00FF)
CFG_Infos_touche.Touche = 0x0000;
if (CFG_Infos_touche.Touche2 == 0x00FF)
CFG_Infos_touche.Touche2 = 0x0000;
}
for (Indice2=0;
((Indice2>8)
{
case 0 :
Config_Touche[Ordonnancement[Indice2]&0xFF][0]=CFG_Infos_touche.Touche;
Config_Touche[Ordonnancement[Indice2]&0xFF][1]=CFG_Infos_touche.Touche2;
break;
case 1 :
Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_gauche[0] = CFG_Infos_touche.Touche;
Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_gauche[1] = CFG_Infos_touche.Touche2;
break;
case 2 :
Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_droite[0] = CFG_Infos_touche.Touche;
Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_droite[1] = CFG_Infos_touche.Touche2;
break;
}
}
else
goto Erreur_lecture_config;
}
}
}
else
{
if (fseek(Handle,Chunk.Taille,SEEK_CUR)==-1)
goto Erreur_lecture_config;
}
break;
case CHUNK_MODES_VIDEO: // Modes vidéo
for (Indice=0; Indice<(long)(Chunk.Taille/sizeof(CFG_Mode_video)); Indice++)
{
if (!read_byte(Handle, &CFG_Mode_video.Etat) ||
!read_word_le(Handle, &CFG_Mode_video.Largeur) ||
!read_word_le(Handle, &CFG_Mode_video.Hauteur) )
goto Erreur_lecture_config;
for (Indice2=1; Indice2>8)
{
case 0 :
CFG_Infos_touche.Touche =Config_Touche[Ordonnancement[Indice]&0xFF][0];
CFG_Infos_touche.Touche2=Config_Touche[Ordonnancement[Indice]&0xFF][1];
break;
case 1 :
CFG_Infos_touche.Touche =Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche[0];
CFG_Infos_touche.Touche2=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche[1];
break;
case 2 :
CFG_Infos_touche.Touche =Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite[0];
CFG_Infos_touche.Touche2=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite[1];
break;
}
if (!write_word_le(Handle, CFG_Infos_touche.Numero) ||
!write_word_le(Handle, CFG_Infos_touche.Touche) ||
!write_word_le(Handle, CFG_Infos_touche.Touche2) )
goto Erreur_sauvegarde_config;
}
// D'abord compter les modes pour lesquels l'utilisateur a mis une préférence
Modes_a_sauver=0;
for (Indice=1; Indice>8)
{
case 0 :
Config_Touche[Ordonnancement[Indice]&0xFF][0]=ConfigTouche[Indice].Touche;
Config_Touche[Ordonnancement[Indice]&0xFF][1]=ConfigTouche[Indice].Touche2;
break;
case 1 :
Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche[0] = ConfigTouche[Indice].Touche;
Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche[1] = ConfigTouche[Indice].Touche2;
break;
case 2 :
Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite[0] = ConfigTouche[Indice].Touche;
Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite[1] = ConfigTouche[Indice].Touche2;
break;
}
}
// Shade
Shade_Actuel=0;
for (Indice=0; Indice<8; Indice++)
{
Shade_Liste[Indice].Pas=1;
Shade_Liste[Indice].Mode=0;
for (Indice2=0; Indice2<512; Indice2++)
Shade_Liste[Indice].Liste[Indice2]=256;
}
// Shade par défaut pour la palette standard
for (Indice=0; Indice<7; Indice++)
for (Indice2=0; Indice2<16; Indice2++)
Shade_Liste[0].Liste[Indice*17+Indice2]=Indice*16+Indice2+16;
Liste2tables(Shade_Liste[Shade_Actuel].Liste,
Shade_Liste[Shade_Actuel].Pas,
Shade_Liste[Shade_Actuel].Mode,
Shade_Table_gauche,Shade_Table_droite);
// Masque
for (Indice=0; Indice<256; Indice++)
Mask_table[Indice]=0;
// Stencil
for (Indice=0; Indice<256; Indice++)
Stencil[Indice]=1;
// Dégradés
Degrade_Courant=0;
for(Indice=0;Indice<16;Indice++)
{
Degrade_Tableau[Indice].Debut=0;
Degrade_Tableau[Indice].Fin=0;
Degrade_Tableau[Indice].Inverse=0;
Degrade_Tableau[Indice].Melange=0;
Degrade_Tableau[Indice].Technique=0;
}
Degrade_Charger_infos_du_tableau(Degrade_Courant);
// Smooth
Smooth_Matrice[0][0]=1;
Smooth_Matrice[0][1]=2;
Smooth_Matrice[0][2]=1;
Smooth_Matrice[1][0]=2;
Smooth_Matrice[1][1]=4;
Smooth_Matrice[1][2]=2;
Smooth_Matrice[2][0]=1;
Smooth_Matrice[2][1]=2;
Smooth_Matrice[2][2]=1;
// Exclude colors
for (Indice=0; Indice<256; Indice++)
Exclude_color[Indice]=0;
// Quick shade
Quick_shade_Step=1;
Quick_shade_Loop=0;
// Grille
Snap_Largeur=Snap_Hauteur=8;
Snap_Decalage_X=Snap_Decalage_Y=0;
}
#ifdef GRAFX2_CATCHES_SIGNALS
#if defined(__WIN32__)
#define SIGHANDLER_T __p_sig_fn_t
#elif defined(__macosx__)
#define SIGHANDLER_T sig_t
#else
#define SIGHANDLER_T __sighandler_t
#endif
// Memorize the signal handlers of SDL
SIGHANDLER_T Handler_TERM=SIG_DFL;
SIGHANDLER_T Handler_INT=SIG_DFL;
SIGHANDLER_T Handler_ABRT=SIG_DFL;
SIGHANDLER_T Handler_SEGV=SIG_DFL;
SIGHANDLER_T Handler_FPE=SIG_DFL;
void sig_handler(int sig)
{
// Restore default behaviour
signal(SIGTERM, Handler_TERM);
signal(SIGINT, Handler_INT);
signal(SIGABRT, Handler_ABRT);
signal(SIGSEGV, Handler_SEGV);
signal(SIGFPE, Handler_FPE);
switch(sig)
{
case SIGTERM:
case SIGINT:
case SIGABRT:
case SIGSEGV:
Image_emergency_backup();
default:
break;
}
}
#endif
void Initialiser_sighandler(void)
{
#ifdef GRAFX2_CATCHES_SIGNALS
Handler_TERM=signal(SIGTERM,sig_handler);
Handler_INT =signal(SIGINT,sig_handler);
Handler_ABRT=signal(SIGABRT,sig_handler);
Handler_SEGV=signal(SIGSEGV,sig_handler);
Handler_FPE =signal(SIGFPE,sig_handler);
#endif
}