From ff27c5dcf93dd922ad1c7788351ec4b6e1f3e0f0 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Fri, 28 Nov 2008 23:50:28 +0000 Subject: [PATCH] BIG change in directory handling: - Unix users can "make install" and "make uninstall" (as root). - Installation creates shortcuts "grafx2" and "gfx2cfg" in /usr/local/bin - Installation puts data files (icon GIFs, gfx2.dat,..) and the actual binaries in /usr/local/share/grafx2 - At runtime, the programs search and create configuration files (gfx2.cfg and gfx2.ini) in ~/.grafx2 (But if there are some present in program's own directory, they override) - Uninstall removes programs and data, but leaves all users' configurations. Win32: User's config directory is %APPDATA%\GrafX2 Win98: %APPDATA% is not set by default, so the program falls back to executable's directory. Tested on Debian Linux Partially tested on Win XP (early version) Tested on Win98 git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@365 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- Makefile | 58 +++++++++++++++-- Makefile.dep | 12 ++-- SFont.h | 2 +- boutons.c | 2 +- files.c | 44 ------------- files.h | 7 +-- gfxcfg.c | 41 ++++++++---- global.h | 5 +- hotkeys.h | 2 +- init.c | 50 +++------------ init.h | 1 - io.c | 51 +++++++++++++++ io.h | 7 +++ main.c | 17 +++-- readini.c | 4 +- saveini.c | 14 ++--- setup.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++ setup.h | 27 ++++++++ texte.c | 13 ++-- 19 files changed, 386 insertions(+), 143 deletions(-) create mode 100644 setup.c create mode 100644 setup.h diff --git a/Makefile b/Makefile index a2034aef..3416c9fc 100644 --- a/Makefile +++ b/Makefile @@ -20,10 +20,19 @@ # write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Overridable defaults + prefix = /usr/local + exec_prefix = $(prefix) + bindir = $(exec_prefix)/bin + datarootdir = $(prefix)/share + datadir = $(datarootdir) + # Windows specific ifdef COMSPEC - DELCOMMAND = del - MKDIR = mkdir /s + DELCOMMAND = rm -f + MKDIR = mkdir + RMDIR = rmdir + CP = cp BIN = grafx2.exe CFGBIN = gfxcfg.exe COPT = -W -Wall -Wdeclaration-after-statement -O -g -ggdb `sdl-config --cflags` $(TTFCOPT) @@ -42,6 +51,8 @@ else ifeq ($(PLATFORM),AmigaOS) DELCOMMAND = rm -rf MKDIR = mkdir -p + RMDIR = rmdir + CP = cp BIN = grafx2 CFGBIN = gfxcfg COPT = -Wall -c -gstabs -mcrt=newlib `sdl-config --cflags` $(TTFCOPT) @@ -55,6 +66,8 @@ else ifeq ($(PLATFORM),BeOS) DELCOMMAND = rm -rf MKDIR = mkdir -p + RMDIR = rmdir + CP = cp BIN = grafx2 CFGBIN = gfxcfg COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include @@ -67,6 +80,8 @@ else ifeq ($(PLATFORM),Haiku) DELCOMMAND = rm -rf MKDIR = mkdir -p + RMDIR = rmdir + CP = cp BIN = grafx2 CFGBIN = gfxcfg COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include @@ -78,6 +93,8 @@ else # Linux specific DELCOMMAND = rm -rf MKDIR = mkdir -p + RMDIR = rmdir + CP = cp ifdef WIN32CROSS #cross compile a Win32 executable CC = i586-mingw32msvc-gcc @@ -114,10 +131,10 @@ else endif -.PHONY : all debug release clean depend zip version force +.PHONY : all debug release clean depend zip version force install uninstall -OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/divers.o $(OBJDIR)/special.o $(OBJDIR)/boutons.o $(OBJDIR)/palette.o $(OBJDIR)/aide.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/moteur.o $(OBJDIR)/files.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/texte.o $(OBJDIR)/SFont.o -CFGOBJ = $(OBJDIR)/gfxcfg.o $(OBJDIR)/SFont.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o +OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/divers.o $(OBJDIR)/special.o $(OBJDIR)/boutons.o $(OBJDIR)/palette.o $(OBJDIR)/aide.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/moteur.o $(OBJDIR)/files.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/texte.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o +CFGOBJ = $(OBJDIR)/gfxcfg.o $(OBJDIR)/SFont.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/setup.o all : $(BIN) $(CFGBIN) @@ -165,6 +182,35 @@ clean : $(DELCOMMAND) $(OBJ) $(CFGOBJ) $(OBJDIR)/version.o $(OBJRES) $(CFGOBJRES) $(DELCOMMAND) $(BIN) $(CFGBIN) -test : +install : $(BIN) $(CFGBIN) + echo "#!/bin/sh" > $(bindir)/grafx2 + echo $(datadir)/grafx2/$(BIN) '$$*' >> $(bindir)/grafx2 + chmod 755 $(bindir)/grafx2 + echo "#!/bin/sh" > $(bindir)/gfxcfg + echo $(datadir)/grafx2/$(CFGBIN) '$$*' >> $(bindir)/gfxcfg + chmod 755 $(bindir)/gfxcfg + $(if $(wildcard $(datadir)/grafx2),,$(MKDIR) $(datadir)/grafx2) + $(CP) $(BIN) $(datadir)/grafx2/ + $(CP) $(CFGBIN) $(datadir)/grafx2/ + $(CP) gfx2.dat $(datadir)/grafx2/ + $(CP) gfx2.gif $(datadir)/grafx2/ + $(CP) gfx2cfg.gif $(datadir)/grafx2/ + $(if $(wildcard $(datadir)/grafx2/fonts),,$(MKDIR) $(datadir)/grafx2/fonts) + cd fonts && $(CP) * $(datadir)/grafx2/fonts/ + @echo Install complete + +uninstall : + $(DELCOMMAND) $(bindir)/grafx2 + $(DELCOMMAND) $(bindir)/gfxcfg + $(DELCOMMAND) $(datadir)/grafx2/$(BIN) + $(DELCOMMAND) $(datadir)/grafx2/$(CFGBIN) + $(DELCOMMAND) $(datadir)/grafx2/gfx2.dat + $(DELCOMMAND) $(datadir)/grafx2/gfx2.gif + $(DELCOMMAND) $(datadir)/grafx2/gfx2cfg.gif + $(DELCOMMAND) $(datadir)/grafx2/fonts/* + $(if $(wildcard $(datadir)/grafx2/fonts),,$(RMDIR) $(datadir)/grafx2/fonts) + $(if $(wildcard $(datadir)/grafx2),,$(RMDIR) $(datadir)/grafx2) + @echo Uninstall complete -include Makefile.dep + diff --git a/Makefile.dep b/Makefile.dep index 6ea5823b..bffac602 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -1,6 +1,6 @@ $(OBJDIR)/SFont.o: SFont.c SFont.h $(OBJDIR)/aide.o: aide.c const.h struct.h global.h loadsave.h divers.h graph.h \ - moteur.h tables_aide.h aide.h sdlscreen.h texte.h + moteur.h tables_aide.h aide.h sdlscreen.h texte.h clavier.h $(OBJDIR)/boutons.o: boutons.c const.h struct.h global.h loadsave.h divers.h \ graph.h moteur.h readline.h files.h init.h boutons.h operatio.h pages.h \ erreurs.h readini.h saveini.h shade.h io.h aide.h texte.h sdlscreen.h @@ -9,17 +9,19 @@ $(OBJDIR)/divers.o: divers.c struct.h const.h sdlscreen.h global.h loadsave.h \ graph.h erreurs.h boutons.h moteur.h divers.h clavier.h $(OBJDIR)/files.o: files.c const.h struct.h global.h loadsave.h graph.h divers.h \ erreurs.h io.h -$(OBJDIR)/gfxcfg.o: gfxcfg.c SFont.h struct.h const.h clavier.h io.h hotkeys.h +$(OBJDIR)/gfxcfg.o: gfxcfg.c SFont.h struct.h const.h clavier.h io.h hotkeys.h \ + setup.h $(OBJDIR)/graph.o: graph.c global.h struct.h const.h loadsave.h moteur.h boutons.h \ pages.h erreurs.h sdlscreen.h graph.h divers.h $(OBJDIR)/init.o: init.c const.h struct.h global.h loadsave.h graph.h boutons.h \ - palette.h aide.h operatio.h divers.h erreurs.h clavier.h io.h hotkeys.h + palette.h aide.h operatio.h divers.h erreurs.h clavier.h io.h hotkeys.h \ + files.h setup.h $(OBJDIR)/io.o: io.c struct.h const.h io.h $(OBJDIR)/loadsave.o: loadsave.c const.h struct.h global.h loadsave.h graph.h \ divers.h pages.h op_c.h boutons.h erreurs.h io.h sdlscreen.h $(OBJDIR)/main.o: main.c const.h struct.h global.h loadsave.h graph.h divers.h \ init.h boutons.h moteur.h pages.h files.h sdlscreen.h erreurs.h \ - readini.h saveini.h io.h texte.h + readini.h saveini.h io.h texte.h setup.h $(OBJDIR)/moteur.o: moteur.c const.h struct.h global.h loadsave.h graph.h divers.h \ special.h boutons.h operatio.h shade.h erreurs.h sdlscreen.h $(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h erreurs.h graph.h @@ -37,11 +39,11 @@ $(OBJDIR)/saveini.o: saveini.c const.h global.h struct.h loadsave.h readini.h \ files.h erreurs.h graph.h $(OBJDIR)/sdlscreen.o: sdlscreen.c global.h struct.h const.h loadsave.h sdlscreen.h \ divers.h erreurs.h graph.h +$(OBJDIR)/setup.o: setup.c struct.h const.h io.h files.h $(OBJDIR)/shade.o: shade.c global.h struct.h const.h loadsave.h graph.h moteur.h \ divers.h readline.h aide.h sdlscreen.h $(OBJDIR)/special.o: special.c const.h struct.h global.h loadsave.h graph.h \ moteur.h -$(OBJDIR)/testfonts.o: testfonts.c $(OBJDIR)/texte.o: texte.c SFont.h struct.h const.h global.h loadsave.h sdlscreen.h \ io.h files.h $(OBJDIR)/version.o: version.c diff --git a/SFont.h b/SFont.h index 2bcda190..6f3d8da8 100644 --- a/SFont.h +++ b/SFont.h @@ -36,7 +36,7 @@ #ifndef SFONT_H #define SFONT_H -#include +#include #ifdef __cplusplus extern "C" { diff --git a/boutons.c b/boutons.c index a49256e6..578292db 100644 --- a/boutons.c +++ b/boutons.c @@ -3107,7 +3107,7 @@ int Meilleur_mode_video(void) void Swapper_infos_selecteurs_image_et_brosse(void) { - char Chaine_temporaire[256]; + char Chaine_temporaire[TAILLE_CHEMIN_FICHIER]; byte Octet_temporaire; short Entier_temporaire; diff --git a/files.c b/files.c index df4116ea..cda38ca2 100644 --- a/files.c +++ b/files.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -72,49 +71,6 @@ int Determiner_repertoire_courant(void) return (getcwd(Principal_Repertoire_courant,256)==NULL); } - -int Repertoire_existe(char * Repertoire) -// Détermine si un répertoire passé en paramètre existe ou non dans le -// répertoire courant. -{ - DIR* Enreg; // Structure de lecture des éléments - - if (strcmp(Repertoire,"..")==0) - return 1; - else - { - // On va chercher si le répertoire existe à l'aide d'un Opendir. S'il - // renvoie NULL c'est que le répertoire n'est pas accessible... - - Enreg=opendir(Repertoire); - if (Enreg==NULL) - return 0; - else - { - closedir(Enreg); - return 1; - } - } -} - - -int Fichier_existe(char * Fichier) -// Détermine si un fichier passé en paramètre existe ou non dans le -// répertoire courant. -{ - struct stat buf; - int Resultat; - - Resultat=stat(Fichier,&buf); - if (Resultat!=0) - return(errno!=ENOENT); - else - return 1; - -} - - - // Conventions: // // * Le fileselect modifie le répertoire courant. Ceci permet de n'avoir diff --git a/files.h b/files.h index 15cf70c0..fc7b2779 100644 --- a/files.h +++ b/files.h @@ -21,12 +21,6 @@ // Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur // (avec le nom du disque) int Determiner_repertoire_courant(void); -// Détermine si un répertoire passé en paramètre existe ou non dans le -// répertoire courant. -int Repertoire_existe(char * Repertoire); -// Détermine si un fichier passé en paramètre existe ou non dans le -// répertoire courant. -int Fichier_existe(char * Fichier); // -- Destruction de la liste chaînée --------------------------------------- void Detruire_liste_du_fileselect(void); @@ -56,3 +50,4 @@ char * Nom_formate(char * Nom, int Type); // Scans a directory, calls Callback for each file in it, void for_each_file(const char * Nom_repertoire, void Callback(const char *)); + diff --git a/gfxcfg.c b/gfxcfg.c index 21d79725..b2606746 100644 --- a/gfxcfg.c +++ b/gfxcfg.c @@ -29,9 +29,9 @@ #include //SDL -#include +#include #include -#include +#include //#include //mine @@ -47,7 +47,7 @@ #include "const.h" #include "io.h" #include "hotkeys.h" - +#include "setup.h" /*** Constants ***/ #define NB_MAX_TOUCHES 134 @@ -65,7 +65,8 @@ /*** Global variables ***/ SFont_Font* MyFont; SDL_Surface* Ecran; - +char Repertoire_config[TAILLE_CHEMIN_FICHIER]; +char Repertoire_donnees[TAILLE_CHEMIN_FICHIER]; bool Erreur[NB_MAX_TOUCHES]; uint8_t Choix_enreg; @@ -178,7 +179,7 @@ void Tout_ecrire() /* returns an error message, or NULL if everything OK */ char * Interpretation_du_fichier_config() { - + char Nom_Fichier[TAILLE_CHEMIN_FICHIER]; FILE* Fichier; long int Taille_fichier; byte Numero_chunk; @@ -186,7 +187,9 @@ char * Interpretation_du_fichier_config() byte * Ptr; int i; - Fichier = fopen("gfx2.cfg","rb"); + strcpy(Nom_Fichier, Repertoire_config); + strcat(Nom_Fichier, "gfx2.cfg"); + Fichier = fopen(Nom_Fichier,"rb"); if (!Fichier) { return "gfx2.cfg is missing! Please run the\nmain program to generate it."; @@ -593,7 +596,7 @@ bool Verifier_ecriture_possible() return 1; #else // Doesn't work on OS4. - return access("./",W_OK) == 0; + return access(Repertoire_config,W_OK) == 0; #endif } @@ -606,7 +609,10 @@ void Enregistrer_config() if(Choix_enreg==true) // Save keys if wanted { - Fichier = fopen("gfx2.cfg","wb"); + char Nom_Fichier[TAILLE_CHEMIN_FICHIER]; + strcpy(Nom_Fichier, Repertoire_config); + strcat(Nom_Fichier, "gfx2.cfg"); + Fichier = fopen(Nom_Fichier,"wb"); // En-tete sprintf(Header.Signature,"CFG"); @@ -649,17 +655,24 @@ void Enregistrer_config() int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) { + char Repertoire_programme[TAILLE_CHEMIN_FICHIER]; + char Nom_fichier[TAILLE_CHEMIN_FICHIER]; + + Set_Program_Directory(argv[0],Repertoire_programme); + Set_Config_Directory(Repertoire_programme,Repertoire_config); + Set_Data_Directory(Repertoire_programme,Repertoire_donnees); if (Verifier_ecriture_possible()) { /* On initialise SDL */ SDL_Init(SDL_INIT_VIDEO); - Ecran = SDL_SetVideoMode(640,480,8,0); - SDL_WM_SetCaption ("Grafx2 configuration tool","Gfx2Cfg"); { // Routine pour définir l'icone. - SDL_Surface * Icone = IMG_Load("gfx2cfg.gif"); + SDL_Surface * Icone; byte *Masque_icone; + strcpy(Nom_fichier, Repertoire_donnees); + strcat(Nom_fichier, "gfx2cfg.gif"); + Icone = IMG_Load(Nom_fichier); if (Icone) { int x,y; @@ -672,11 +685,15 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) SDL_WM_SetIcon(Icone,Masque_icone); } } + Ecran = SDL_SetVideoMode(640,480,8,0); + SDL_WM_SetCaption ("Grafx2 configuration tool","Gfx2Cfg"); SDL_EnableKeyRepeat(250, 32); SDL_EnableUNICODE(SDL_ENABLE); /* On initialise SFont */ - MyFont = SFont_InitFont(IMG_Load("fonts/8pxfont.png")); + strcpy(Nom_fichier, Repertoire_donnees); + strcat(Nom_fichier, "fonts/8pxfont.png"); + MyFont = SFont_InitFont(IMG_Load(Nom_fichier)); if(MyFont==NULL) { diff --git a/global.h b/global.h index 17adc8cb..5f00e734 100644 --- a/global.h +++ b/global.h @@ -522,8 +522,9 @@ GLOBAL byte Spray_Multi_flow[256]; // Idem pour chaque couleur // Données diverses sur le programme: GLOBAL byte Sortir_du_programme; -GLOBAL char Repertoire_du_programme[256]; // Répertoire dans lequel se trouve le programme -GLOBAL char Repertoire_initial[256]; // Répertoire à partir duquel à été lancé le programme +GLOBAL char Repertoire_initial[256]; // Répertoire à partir duquel à été lancé le programme +GLOBAL char Repertoire_des_donnees[256]; // Répertoire contenant les fichiers lus (interface graphique, etc) +GLOBAL char Repertoire_de_configuration[256]; // Répertoire contenant les fichiers .ini et .cfg GLOBAL byte Fore_color; GLOBAL byte Back_color; GLOBAL byte Mode_de_dessin_en_cours; diff --git a/hotkeys.h b/hotkeys.h index 13c465b2..cf49bef1 100644 --- a/hotkeys.h +++ b/hotkeys.h @@ -20,7 +20,7 @@ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include +#include /*** Types definitions and structs ***/ diff --git a/init.c b/init.c index 52f41fbc..b5b094b7 100644 --- a/init.c +++ b/init.c @@ -30,7 +30,11 @@ #include #include #include +#include #include +#if defined(__WIN32__) + #include // GetLogicalDrives(), GetDriveType(), DRIVE_* +#endif #include "const.h" #include "struct.h" @@ -45,45 +49,9 @@ #include "clavier.h" #include "io.h" #include "hotkeys.h" +#include "files.h" +#include "setup.h" -#include "errno.h" - -#if defined(__WIN32__) - #include -#elif defined(__macosx__) - #import - #import -#endif - -// Chercher le répertoire contenant GFX2.EXE -// en: Determine which directory contains the executable, data, and configuration. -// The argument is argv[0], but some platforms don't need it. -#if defined(__macosx__) || defined(__amigaos4__) - #define ARG_UNUSED __attribute__((unused)) -#else - #define ARG_UNUSED -#endif -void Chercher_repertoire_du_programme(ARG_UNUSED char * Chaine) -{ - #undef ARG_UNUSED - - // MacOSX - #if defined(__macosx__) - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLGetFileSystemRepresentation(url,true,(UInt8*)Repertoire_du_programme,MAXPATHLEN); - CFRelease(url); - strcat(Repertoire_du_programme,"/Contents/Resources/"); - - // AmigaOS4: hard-coded volume name. - #elif defined(__amigaos4__) - strcpy(Repertoire_du_programme,"PROGDIR:"); - - // Windows, linux: The part of argv[0] before the executable name. - // Keep the last / or \. - #else - Extraire_chemin(Repertoire_du_programme, Chaine); - #endif -} // Ajouter un lecteur à la liste de lecteurs void Ajouter_lecteur(char Lettre, byte Type, char *Chemin) @@ -181,7 +149,7 @@ void Charger_DAT(void) struct stat Informations_Fichier; - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_des_donnees); strcat(Nom_du_fichier,"gfx2.dat"); if(stat(Nom_du_fichier,&Informations_Fichier)) @@ -1592,7 +1560,7 @@ int Charger_CFG(int Tout_charger) struct stat Informations_Fichier; int Conversion_touches = 0; - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_de_configuration); strcat(Nom_du_fichier,"gfx2.cfg"); stat(Nom_du_fichier,&Informations_Fichier); @@ -1863,7 +1831,7 @@ int Sauver_CFG(void) struct Config_Infos_touche CFG_Infos_touche; struct Config_Mode_video CFG_Mode_video; - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_de_configuration); strcat(Nom_du_fichier,"gfx2.cfg"); if ((Handle=fopen(Nom_du_fichier,"wb"))==NULL) diff --git a/init.h b/init.h index 8e86a40c..c010f39b 100644 --- a/init.h +++ b/init.h @@ -18,7 +18,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -void Chercher_repertoire_du_programme(char * Chaine); void Rechercher_drives(void); void Charger_DAT(void); void Initialisation_des_boutons(void); diff --git a/io.c b/io.c index 3f892c1f..00840fbe 100644 --- a/io.c +++ b/io.c @@ -25,6 +25,20 @@ #include #include +#include +#include +#if defined(__amigaos4__) + #include + #include +#elif defined(__WATCOMC__) + #include +#elif defined(__WIN32__) + #include + #include +#else + #include +#endif + #include "struct.h" #include "io.h" @@ -192,3 +206,40 @@ void Extraire_chemin(char *Destination, const char *Source) strcat(Destination, SEPARATEUR_CHEMIN); } +int Fichier_existe(char * Fichier) +// Détermine si un fichier passé en paramètre existe ou non dans le +// répertoire courant. +{ + struct stat buf; + int Resultat; + + Resultat=stat(Fichier,&buf); + if (Resultat!=0) + return(errno!=ENOENT); + else + return 1; + +} +int Repertoire_existe(char * Repertoire) +// Détermine si un répertoire passé en paramètre existe ou non dans le +// répertoire courant. +{ + DIR* Enreg; // Structure de lecture des éléments + + if (strcmp(Repertoire,"..")==0) + return 1; + else + { + // On va chercher si le répertoire existe à l'aide d'un Opendir. S'il + // renvoie NULL c'est que le répertoire n'est pas accessible... + + Enreg=opendir(Repertoire); + if (Enreg==NULL) + return 0; + else + { + closedir(Enreg); + return 1; + } + } +} diff --git a/io.h b/io.h index 18a4a6ec..2742e57e 100644 --- a/io.h +++ b/io.h @@ -48,3 +48,10 @@ char * Position_dernier_slash(const char * Chaine); #else #define SEPARATEUR_CHEMIN "/" #endif + +// Détermine si un fichier passé en paramètre existe ou non dans le +// répertoire courant. +int Fichier_existe(char * Fichier); +// Détermine si un répertoire passé en paramètre existe ou non dans le +// répertoire courant. +int Repertoire_existe(char * Repertoire); diff --git a/main.c b/main.c index 32de18fa..20e6c0fe 100644 --- a/main.c +++ b/main.c @@ -32,7 +32,6 @@ #include "moteur.h" #include #include - #include #include #include @@ -48,6 +47,7 @@ #include "saveini.h" #include "io.h" #include "texte.h" +#include "setup.h" #if defined(__WIN32__) #include @@ -246,6 +246,7 @@ void Initialisation_du_programme(int argc,char * argv[]) { int Temp; int Mode_dans_lequel_on_demarre; + char Repertoire_du_programme[TAILLE_CHEMIN_FICHIER]; // On crée dès maintenant les descripteurs des listes de pages pour la page // principale et la page de brouillon afin que leurs champs ne soient pas @@ -256,9 +257,13 @@ void Initialisation_du_programme(int argc,char * argv[]) Initialiser_S_Liste_de_pages(Principal_Backups); Initialiser_S_Liste_de_pages(Brouillon_Backups); - // On détermine dès le départ où se trouve le fichier: - Chercher_repertoire_du_programme(argv[0]); - + // Determine the executable directory + Set_Program_Directory(argv[0],Repertoire_du_programme); + // Choose directory for data (read only) + Set_Data_Directory(Repertoire_du_programme,Repertoire_des_donnees); + // Choose directory for settings (read/write) + Set_Config_Directory(Repertoire_du_programme,Repertoire_de_configuration); + // On détecte les lecteurs qui sont accessibles: Rechercher_drives(); // On détermine le répertoire courant: @@ -333,9 +338,9 @@ void Initialisation_du_programme(int argc,char * argv[]) SDL_WM_SetCaption("GrafX2 beta "POURCENTAGE_VERSION" - USE AT YOUR OWN RISK","GrafX2"); { // Routine pour définir l'icone. - char Chemin_icone[256]; + char Chemin_icone[TAILLE_CHEMIN_FICHIER]; SDL_Surface * Icone; - sprintf(Chemin_icone, "%s%s", Repertoire_du_programme, "gfx2.gif"); + sprintf(Chemin_icone, "%s%s", Repertoire_des_donnees, "gfx2.gif"); Icone = IMG_Load(Chemin_icone); if (Icone) { diff --git a/readini.c b/readini.c index 93928912..cfe70de7 100644 --- a/readini.c +++ b/readini.c @@ -403,14 +403,14 @@ int Charger_INI(struct S_Config * Conf) Nom_du_fichier=(char *)malloc(256); // On calcule le nom du fichier qu'on manipule: - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_de_configuration); strcat(Nom_du_fichier,"gfx2.ini"); Fichier=fopen(Nom_du_fichier,"rb"); if (Fichier==0) { // Si le fichier ini est absent on le relit depuis gfx2.dat - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_des_donnees); strcat(Nom_du_fichier,"gfx2.dat"); Fichier=fopen(Nom_du_fichier,"rb"); if (Fichier == 0) diff --git a/saveini.c b/saveini.c index f76da073..e1b6dc68 100644 --- a/saveini.c +++ b/saveini.c @@ -26,7 +26,7 @@ #include "const.h" #include "global.h" #include "readini.h" -#include "files.h" +#include "io.h" #include "erreurs.h" #include "graph.h" @@ -389,23 +389,23 @@ int Sauver_INI(struct S_Config * Conf) FILE * Nouveau_fichier; char * Buffer; int Valeurs[3]; - char Nom_du_fichier[256]; - char Nom_du_fichier_temporaire[256]; + char Nom_du_fichier[TAILLE_CHEMIN_FICHIER]; + char Nom_du_fichier_temporaire[TAILLE_CHEMIN_FICHIER]; int Retour; - char Nom_du_fichier_DAT[256]; + char Nom_du_fichier_DAT[TAILLE_CHEMIN_FICHIER]; int Ini_existe; // On alloue les zones de mémoire: Buffer=(char *)malloc(1024); // On calcule les noms des fichiers qu'on manipule: - strcpy(Nom_du_fichier,Repertoire_du_programme); + strcpy(Nom_du_fichier,Repertoire_de_configuration); strcat(Nom_du_fichier,"gfx2.ini"); // On vérifie si le fichier INI existe if ((Ini_existe = Fichier_existe(Nom_du_fichier))) { - strcpy(Nom_du_fichier_temporaire,Repertoire_du_programme); + strcpy(Nom_du_fichier_temporaire,Repertoire_de_configuration); strcat(Nom_du_fichier_temporaire,"gfx2.$$$"); // On renome l'ancienne version du fichier INI vers un fichier temporaire: @@ -415,7 +415,7 @@ int Sauver_INI(struct S_Config * Conf) } } // On récupère un fichier INI "propre" dans GFX2.DAT - strcpy(Nom_du_fichier_DAT,Repertoire_du_programme); + strcpy(Nom_du_fichier_DAT,Repertoire_des_donnees); strcat(Nom_du_fichier_DAT,"gfx2.dat"); Ancien_fichier=fopen(Nom_du_fichier_DAT,"rb"); if (Ancien_fichier==0) diff --git a/setup.c b/setup.c new file mode 100644 index 00000000..61059e5f --- /dev/null +++ b/setup.c @@ -0,0 +1,172 @@ +/* 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. +*/ + +#include +#include +#include +#include +#include +#if defined(__WIN32__) + #include + #include // Mingw's _mkdir() +#elif defined(__macosx__) + #import + #import +#endif + +#include "struct.h" +#include "io.h" +#include "files.h" + +int Create_ConfigDirectory(char * Config_Dir) +{ + #ifdef __WIN32__ + // Mingw's mkdir has a weird name and only one argument + return _mkdir(Config_Dir); + #else + return mkdir(Config_Dir,S_IRUSR|S_IWUSR|S_IXUSR); + #endif +} + +#if defined(__macosx__) || defined(__amigaos4__) + #define ARG_UNUSED __attribute__((unused)) +#else + #define ARG_UNUSED +#endif +// Determine which directory contains the executable. +// IN: Main's argv[0], some platforms need it, some don't. +// OUT: Write into Program_Dir. Trailing / or \ is kept. +void Set_Program_Directory(ARG_UNUSED const char * argv0,char * Program_Dir) +{ + #undef ARG_UNUSED + + // MacOSX + #if defined(__macosx__) + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLGetFileSystemRepresentation(url,true,(UInt8*)Program_Dir,MAXPATHLEN); + CFRelease(url); + // Append trailing slash + strcat(Program_Dir ,"/"); + + // AmigaOS4: hard-coded volume name. + #elif defined(__amigaos4__) + strcpy(Program_Dir,"PROGDIR:"); + + // Others: The part of argv[0] before the executable name. + // Keep the last \ or /. + // Note that on Unix, once installed, the executable is called from a shell script + // sitting in /usr/local/bin/, this allows argv[0] to contain the full path. + // On Windows, Mingw32 already provides the full path in all cases. + #else + Extraire_chemin(Program_Dir, argv0); + #endif +} +// Determine which directory contains the read-only data. +// IN: The directory containing the executable +// OUT: Write into Data_Dir. Trailing / or \ is kept. +void Set_Data_Directory(const char * Program_Dir, char * Data_Dir) +{ + // On all platforms, data is in the executable's directory + strcpy(Data_Dir,Program_Dir); + // Except MacOSX: + #if defined(__macosx__) + strcat(Data_Dir,"Contents/Resources/"); + #endif +} + +// Determine which directory should store the user's configuration. +// +// For most Unix and Windows platforms: +// If a config file already exists in Program_Dir, it will return it in priority +// (Useful for development, and possibly for upgrading from DOS version) +// If the standard directory doesn't exist yet, this function will attempt +// to create it ($(HOME)/.grafx2, or %APPDATA%\GrafX2) +// If it cannot be created, this function will return the executable's +// own directory. +// IN: The directory containing the executable +// OUT: Write into Config_Dir. Trailing / or \ is kept. +void Set_Config_Directory(const char * Program_Dir, char * Config_Dir) +{ + // MacOSX + #if defined(__macosx__) + strcpy(Config_Dir,Program_Dir); + strcat(Config_Dir,"Contents/Resources/"); + // AmigaOS4 + #elif defined(__amigaos4__) + strcpy(Config_Dir,"PROGDIR:"); + #else + char FileName[TAILLE_CHEMIN_FICHIER]; + + // In priority: check own directory + strcpy(Config_Dir, Program_Dir); + strcpy(FileName, Config_Dir); + strcat(FileName, "gfx2.cfg"); + if (!Fichier_existe(FileName)) + { + char *Config_ParentDir; + #if defined(__WIN32__) + // "%APPDATA%\GrafX2" + const char* Config_SubDir = "GrafX2"; + Config_ParentDir = getenv("APPDATA"); + #elif defined(__BEOS__) || defined(__HAIKU__) + // "~/.grafx2" + const char* Config_SubDir = ".grafx2"; + Config_ParentDir = getenv("$HOME"); + #else + // "~/.grafx2" + const char* Config_SubDir = ".grafx2"; + Config_ParentDir = getenv("HOME"); + #endif + if (Config_ParentDir && Config_ParentDir[0]!='\0') + { + int Taille = strlen(Config_ParentDir); + strcpy(Config_Dir, Config_ParentDir); + if (Config_ParentDir[Taille-1] != '\\' && Config_ParentDir[Taille-1] != '/') + { + strcat(Config_Dir,SEPARATEUR_CHEMIN); + } + strcat(Config_Dir,Config_SubDir); + if (Repertoire_existe(Config_Dir)) + { + // Répertoire trouvé, ok + strcat(Config_Dir,SEPARATEUR_CHEMIN); + } + else + { + // Tentative de création + if (!Create_ConfigDirectory(Config_Dir)) + { + // Réussi + strcat(Config_Dir,SEPARATEUR_CHEMIN); + } + else + { + // Echec: on se rabat sur le repertoire de l'executable. + strcpy(Config_Dir,Program_Dir); + } + } + } + } + #endif +} diff --git a/setup.h b/setup.h new file mode 100644 index 00000000..b2d4fc79 --- /dev/null +++ b/setup.h @@ -0,0 +1,27 @@ +/* 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. +*/ +void Set_Program_Directory(const char * argv0,char * Program_Dir); +void Set_Data_Directory(const char * Program_Dir, char * Data_Dir); +void Set_Config_Directory(const char * Program_Dir, char * Config_Dir); + diff --git a/texte.c b/texte.c index c400c174..3350d704 100644 --- a/texte.c +++ b/texte.c @@ -265,11 +265,6 @@ int TrueType_fonte(int Indice) // Initialisation à faire une fois au début du programme void Initialisation_Texte(void) { -/* - // Pour scan de répertoire - DIR* Repertoire_Courant; //Répertoire courant - struct dirent* Enreg; // Structure de lecture des éléments -*/ char Nom_repertoire[TAILLE_CHEMIN_FICHIER]; #ifndef NOTTF // Initialisation de TTF @@ -280,7 +275,7 @@ void Initialisation_Texte(void) Liste_fontes_debut = NULL; Fonte_nombre=0; // Parcours du répertoire "fonts" - strcpy(Nom_repertoire, Repertoire_du_programme); + strcpy(Nom_repertoire, Repertoire_des_donnees); strcat(Nom_repertoire, "fonts"); for_each_file(Nom_repertoire, Ajout_fonte); @@ -323,7 +318,8 @@ void Initialisation_Texte(void) #else #define USE_XLIB - #ifdef USE_XLIB + #ifdef USE_XLIB + { int i,number; Display* dpy = XOpenDisplay(NULL); char** font_path_list = XGetFontPath(dpy,&number); @@ -331,7 +327,8 @@ void Initialisation_Texte(void) for(i=0;i