/*  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.
*/
//
//  Ce fichier contient la gestion du moteur
//
#include 
#include 
#include 
#include "const.h"
#include "struct.h"
#include "global.h"
#include "graph.h"
#include "divers.h"
#include "special.h"
#include "boutons.h"
#include "operatio.h"
#include "shade.h"
#include "erreurs.h"
#include "sdlscreen.h"
#include "windows.h"
#include "brush.h"
#include "input.h"
#include "moteur.h"
// we need this as global
short Old_MX = -1;
short Old_MY = -1;
//---------- Annuler les effets des modes de dessin (sauf la grille) ---------
// Variables mémorisants les anciens effets
byte Shade_Mode_avant_annulation;
byte Quick_shade_Mode_avant_annulation;
byte Stencil_Mode_avant_annulation;
byte Trame_Mode_avant_annulation;
byte Colorize_Mode_avant_annulation;
byte Smooth_Mode_avant_annulation;
byte Tiling_Mode_avant_annulation;
fonction_effet Fonction_effet_avant_annulation;
byte* Fond_fenetre[8];
void Annuler_les_effets(void)
{
  Shade_Mode_avant_annulation=Shade_Mode;
  Shade_Mode=0;
  Quick_shade_Mode_avant_annulation=Quick_shade_Mode;
  Quick_shade_Mode=0;
  Stencil_Mode_avant_annulation=Stencil_Mode;
  Stencil_Mode=0;
  Trame_Mode_avant_annulation=Trame_Mode;
  Trame_Mode=0;
  Colorize_Mode_avant_annulation=Colorize_Mode;
  Colorize_Mode=0;
  Smooth_Mode_avant_annulation=Smooth_Mode;
  Smooth_Mode=0;
  Tiling_Mode_avant_annulation=Tiling_Mode;
  Tiling_Mode=0;
  Fonction_effet_avant_annulation=Fonction_effet;
  Fonction_effet=Aucun_effet;
}
//----------------- Restaurer les effets des modes de dessin -----------------
void Restaurer_les_effets(void)
{
  Shade_Mode      =Shade_Mode_avant_annulation;
  Quick_shade_Mode=Quick_shade_Mode_avant_annulation;
  Stencil_Mode    =Stencil_Mode_avant_annulation;
  Trame_Mode      =Trame_Mode_avant_annulation;
  Colorize_Mode   =Colorize_Mode_avant_annulation;
  Smooth_Mode     =Smooth_Mode_avant_annulation;
  Tiling_Mode     =Tiling_Mode_avant_annulation;
  Fonction_effet  =Fonction_effet_avant_annulation;
}
char * TITRE_BOUTON[NB_BOUTONS]=
{
  "Paintbrush choice       ",
  "Adjust picture / Effects",
  "Freehand draw. / Toggle ",
  "Splines / Toggle        ",
  "Lines / Toggle          ",
  "Spray / Menu            ",
  "Floodfill / Replace col.",
  "Polylines / Polyforms   ",
  "Polyfill / Filled Pforms",
  "Empty rectangles        ",
  "Filled rectangles       ",
  "Empty circles / ellipses",
  "Filled circles / ellips.",
  "Grad. rectangles        ",
  "Gradation menu          ",
  "Grad. spheres / ellipses",
  "Brush grab. / Restore   ",
  "Lasso / Restore brush   ",
  "Brush effects           ",
  "Drawing modes (effects) ",
  "Text                    ",
  "Magnify mode / Menu     ",
  "Pipette / Invert colors ",
  "Screen size / Safe. res.",
  "Go / Copy to other page ",
  "Save as / Save          ",
  "Load / Re-load          ",
  "Settings                ",
  "Clear / with backcolor  ",
  "Help / Statistics       ",
  "Undo / Redo             ",
  "Kill current page       ",
  "Quit                    ",
  "Palette editor          ",
  "Scroll pal. left / Fast ",
  "Scroll pal. right / Fast",
  "Color #"                 ,
  "Hide tool bar           "
};
// Sauvegarde un bloc (généralement l'arrière-plan d'une fenêtre)
void Sauve_fond(byte **Buffer, int Pos_X, int Pos_Y, int Largeur, int Hauteur)
{
  int Indice;
  if(*Buffer != NULL) DEBUG("WARNING : Buffer already allocated !!!",0);
  *Buffer=(byte *) malloc(Largeur*Menu_Facteur_X*Hauteur*Menu_Facteur_Y*Pixel_width);
  for (Indice=0; Indice<(Hauteur*Menu_Facteur_Y); Indice++)
    Lire_ligne(Pos_X,Pos_Y+Indice,Largeur*Menu_Facteur_X,(*Buffer)+((int)Indice*Largeur*Menu_Facteur_X*Pixel_width));
}
// Restaure de ce que la fenêtre cachait
void Restaure_fond(byte *Buffer, int Pos_X, int Pos_Y, int Largeur, int Hauteur)
{
  int Indice;
  for (Indice=0; Indice=Bouton[Numero].Decalage_X) &&
            (Pos_Y>=Bouton[Numero].Decalage_Y) &&
            (Pos_X<=Bouton[Numero].Decalage_X+Bouton[Numero].Largeur) &&
            (Pos_Y<=Bouton[Numero].Decalage_Y+Bouton[Numero].Hauteur))
          return Numero;
        break;
      case FORME_BOUTON_TRIANGLE_HAUT_GAUCHE:
        if ((Pos_X>=Bouton[Numero].Decalage_X) &&
            (Pos_Y>=Bouton[Numero].Decalage_Y) &&
            (Pos_X+Pos_Y-(short)Bouton[Numero].Decalage_Y-(short)Bouton[Numero].Decalage_X<=Bouton[Numero].Largeur))
          return Numero;
        break;
      case FORME_BOUTON_TRIANGLE_BAS_DROITE:
        if ((Pos_X<=Bouton[Numero].Decalage_X+Bouton[Numero].Largeur) &&
            (Pos_Y<=Bouton[Numero].Decalage_Y+Bouton[Numero].Hauteur) &&
            (Pos_X+Pos_Y-(short)Bouton[Numero].Decalage_Y-(short)Bouton[Numero].Decalage_X>=Bouton[Numero].Largeur))
          return Numero;
        break;
    }
  }
  return -1;
}
void Tracer_cadre_de_bouton_du_menu(byte Numero,byte Enfonce)
{
  byte Couleur_Haut_gauche;
  byte Couleur_Bas_droite;
  byte Couleur_Diagonale;
  word Debut_X;
  word Debut_Y;
  word Fin_X;
  word Fin_Y;
  word Pos_X;
  word Pos_Y;
  Debut_X=Bouton[Numero].Decalage_X;
  Debut_Y=Bouton[Numero].Decalage_Y;
  Fin_X  =Debut_X+Bouton[Numero].Largeur;
  Fin_Y  =Debut_Y+Bouton[Numero].Hauteur;
  if (!Enfonce)
  {
    Couleur_Haut_gauche=CM_Blanc;
    Couleur_Bas_droite=CM_Fonce;
    Couleur_Diagonale=CM_Clair;
  }
  else
  {
    Couleur_Haut_gauche=CM_Fonce;
    Couleur_Bas_droite=CM_Noir;
    Couleur_Diagonale=CM_Fonce;
  }
  switch(Bouton[Numero].Forme)
  {
    case FORME_BOUTON_SANS_CADRE :
      break;
    case FORME_BOUTON_RECTANGLE  :
      // On colorie le point haut droit
      Pixel_dans_menu(Fin_X,Debut_Y,Couleur_Diagonale);
      BLOCK_MENU[Debut_Y][Fin_X]=Couleur_Diagonale;
      // On colorie le point bas gauche
      Pixel_dans_menu(Debut_X,Fin_Y,Couleur_Diagonale);
      BLOCK_MENU[Fin_Y][Debut_X]=Couleur_Diagonale;
      // On colorie la partie haute
      for (Pos_X=Debut_X;Pos_X<=Fin_X-1;Pos_X++)
      {
        Pixel_dans_menu(Pos_X,Debut_Y,Couleur_Haut_gauche);
        BLOCK_MENU[Debut_Y][Pos_X]=Couleur_Haut_gauche;
      }
      for (Pos_Y=Debut_Y+1;Pos_Y<=Fin_Y-1;Pos_Y++)
      {
        // On colorie la partie gauche
        Pixel_dans_menu(Debut_X,Pos_Y,Couleur_Haut_gauche);
        BLOCK_MENU[Pos_Y][Debut_X]=Couleur_Haut_gauche;
        // On colorie la partie droite
        Pixel_dans_menu(Fin_X,Pos_Y,Couleur_Bas_droite);
        BLOCK_MENU[Pos_Y][Fin_X]=Couleur_Bas_droite;
      }
      // On colorie la partie basse
      for (Pos_X=Debut_X+1;Pos_X<=Fin_X;Pos_X++)
      {
        Pixel_dans_menu(Pos_X,Fin_Y,Couleur_Bas_droite);
        BLOCK_MENU[Fin_Y][Pos_X]=Couleur_Bas_droite;
      }
      break;
    case FORME_BOUTON_TRIANGLE_HAUT_GAUCHE:
      // On colorie le point haut droit
      Pixel_dans_menu(Fin_X,Debut_Y,Couleur_Diagonale);
      BLOCK_MENU[Debut_Y][Fin_X]=Couleur_Diagonale;
      // On colorie le point bas gauche
      Pixel_dans_menu(Debut_X,Fin_Y,Couleur_Diagonale);
      BLOCK_MENU[Fin_Y][Debut_X]=Couleur_Diagonale;
      // On colorie le coin haut gauche
      for (Pos_X=0;Pos_XSPECIAL_CLICK_RIGHT)
      switch(Indice_Touche)
      {
        case SPECIAL_SCROLL_UP : // Scroll up
          if (Loupe_Mode)
            Scroller_loupe(0,-(Loupe_Hauteur>>2));
          else
            Scroller_ecran(0,-(Hauteur_ecran>>3));
          Touche=0;
          break;
        case SPECIAL_SCROLL_DOWN : // Scroll down
          if (Loupe_Mode)
            Scroller_loupe(0,(Loupe_Hauteur>>2));
          else
            Scroller_ecran(0,(Hauteur_ecran>>3));
          Touche=0;
          break;
        case SPECIAL_SCROLL_LEFT : // Scroll left
          if (Loupe_Mode)
            Scroller_loupe(-(Loupe_Largeur>>2),0);
          else
            Scroller_ecran(-(Largeur_ecran>>3),0);
          Touche=0;
          break;
        case SPECIAL_SCROLL_RIGHT : // Scroll right
          if (Loupe_Mode)
            Scroller_loupe((Loupe_Largeur>>2),0);
          else
            Scroller_ecran((Largeur_ecran>>3),0);
          Touche=0;
          break;
        case SPECIAL_SCROLL_UP_FAST : // Scroll up faster
          if (Loupe_Mode)
            Scroller_loupe(0,-(Loupe_Hauteur>>1));
          else
            Scroller_ecran(0,-(Hauteur_ecran>>2));
          Touche=0;
          break;
        case SPECIAL_SCROLL_DOWN_FAST : // Scroll down faster
          if (Loupe_Mode)
            Scroller_loupe(0,(Loupe_Hauteur>>1));
          else
            Scroller_ecran(0,(Hauteur_ecran>>2));
          Touche=0;
          break;
        case SPECIAL_SCROLL_LEFT_FAST : // Scroll left faster
          if (Loupe_Mode)
            Scroller_loupe(-(Loupe_Largeur>>1),0);
          else
            Scroller_ecran(-(Largeur_ecran>>2),0);
          Touche=0;
          break;
        case SPECIAL_SCROLL_RIGHT_FAST : // Scroll right faster
          if (Loupe_Mode)
            Scroller_loupe((Loupe_Largeur>>1),0);
          else
            Scroller_ecran((Largeur_ecran>>2),0);
          Touche=0;
          break;
        case SPECIAL_SCROLL_UP_SLOW : // Scroll up slower
          if (Loupe_Mode)
            Scroller_loupe(0,-1);
          else
            Scroller_ecran(0,-1);
          Touche=0;
          break;
        case SPECIAL_SCROLL_DOWN_SLOW : // Scroll down slower
          if (Loupe_Mode)
            Scroller_loupe(0,1);
          else
            Scroller_ecran(0,1);
          Touche=0;
          break;
        case SPECIAL_SCROLL_LEFT_SLOW : // Scroll left slower
          if (Loupe_Mode)
            Scroller_loupe(-1,0);
          else
            Scroller_ecran(-1,0);
          Touche=0;
          break;
        case SPECIAL_SCROLL_RIGHT_SLOW : // Scroll right slower
          if (Loupe_Mode)
            Scroller_loupe(1,0);
          else
            Scroller_ecran(1,0);
          Touche=0;
          break;
        case SPECIAL_NEXT_FORECOLOR : // Next foreground color
          Special_Next_forecolor();
          Touche=0;
          break;
        case SPECIAL_PREVIOUS_FORECOLOR : // Previous foreground color
          Special_Previous_forecolor();
          Touche=0;
          break;
        case SPECIAL_NEXT_BACKCOLOR : // Next background color
          Special_Next_backcolor();
          Touche=0;
          break;
        case SPECIAL_PREVIOUS_BACKCOLOR : // Previous background color
          Special_Previous_backcolor();
          Touche=0;
          break;
        case SPECIAL_RETRECIR_PINCEAU: // Rétrécir le pinceau
          Retrecir_pinceau();
          Touche=0;
          break;
        case SPECIAL_GROSSIR_PINCEAU: // Grossir le pinceau
          Grossir_pinceau();
          Touche=0;
          break;
        case SPECIAL_NEXT_USER_FORECOLOR : // Next user-defined foreground color
          Message_Non_disponible(); // !!! TEMPORAIRE !!!
          //Special_Next_user_forecolor();
          Touche=0;
          break;
        case SPECIAL_PREVIOUS_USER_FORECOLOR : // Previous user-defined foreground color
          Message_Non_disponible(); // !!! TEMPORAIRE !!!
          //Special_Previous_user_forecolor();
          Touche=0;
          break;
        case SPECIAL_NEXT_USER_BACKCOLOR : // Next user-defined background color
          Message_Non_disponible(); // !!! TEMPORAIRE !!!
          //Special_Next_user_backcolor();
          Touche=0;
          break;
        case SPECIAL_PREVIOUS_USER_BACKCOLOR : // Previous user-defined background color
          Message_Non_disponible(); // !!! TEMPORAIRE !!!
          //Special_Previous_user_backcolor();
          Touche=0;
          break;
        case SPECIAL_SHOW_HIDE_CURSOR : // Show / Hide cursor
          Effacer_curseur();
          Cacher_curseur=!Cacher_curseur;
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_PINCEAU_POINT : // Paintbrush = "."
          Effacer_curseur();
          Pinceau_Forme=FORME_PINCEAU_ROND;
          Modifier_pinceau(1,1);
          Changer_la_forme_du_pinceau(FORME_PINCEAU_ROND);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_DESSIN_CONTINU : // Continuous freehand drawing
          Enclencher_bouton(BOUTON_DESSIN,A_GAUCHE);
          // ATTENTION CE TRUC EST MOCHE ET VA MERDER SI ON SE MET A UTILISER DES BOUTONS POPUPS
          while (Operation_en_cours!=OPERATION_DESSIN_CONTINU)
            Enclencher_bouton(BOUTON_DESSIN,A_DROITE);
          Touche=0;
          break;
        case SPECIAL_FLIP_X : // Flip X
          Effacer_curseur();
          Flip_X_LOWLEVEL();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_FLIP_Y : // Flip Y
          Effacer_curseur();
          Flip_Y_LOWLEVEL();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_ROTATE_90 : // 90° brush rotation
          Effacer_curseur();
          Rotate_90_deg();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_ROTATE_180 : // 180° brush rotation
          Effacer_curseur();
          if (Brosse_Hauteur&1)
          {
            // Brosse de hauteur impaire
            Flip_X_LOWLEVEL();
            Flip_Y_LOWLEVEL();
          }
          else
            Rotate_180_deg_LOWLEVEL();
          Brosse_Decalage_X=(Brosse_Largeur>>1);
          Brosse_Decalage_Y=(Brosse_Hauteur>>1);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_STRETCH : // Stretch brush
          Effacer_curseur();
          Demarrer_pile_operation(OPERATION_ETIRER_BROSSE);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_DISTORT : // Distort brush
          Message_Non_disponible(); // !!! TEMPORAIRE !!!
          Touche=0;
          break;
        case SPECIAL_ROTATE_ANY_ANGLE : // Rotate brush by any angle
          Effacer_curseur();
          Demarrer_pile_operation(OPERATION_TOURNER_BROSSE);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_OUTLINE : // Outline brush
          Effacer_curseur();
          Outline_brush();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_NIBBLE : // Nibble brush
          Effacer_curseur();
          Nibble_brush();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_GET_BRUSH_COLORS : // Get colors from brush
          Get_colors_from_brush();
          Touche=0;
          break;
        case SPECIAL_RECOLORIZE_BRUSH : // Recolorize brush
          Effacer_curseur();
          Remap_brosse();
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_LOAD_BRUSH :
          Load_picture(0);
          Touche=0;
          break;
        case SPECIAL_SAVE_BRUSH :
          Save_picture(0);
          Touche=0;
          break;
        case SPECIAL_ZOOM_IN : // Zoom in
          Zoom(+1);
          Touche=0;
          break;
        case SPECIAL_ZOOM_OUT : // Zoom out
          Zoom(-1);
          Touche=0;
          break;
        case SPECIAL_CENTER_ATTACHMENT : // Center brush attachment
          Effacer_curseur();
          Brosse_Decalage_X=(Brosse_Largeur>>1);
          Brosse_Decalage_Y=(Brosse_Hauteur>>1);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_TOP_LEFT_ATTACHMENT : // Top-left brush attachment
          Effacer_curseur();
          Brosse_Decalage_X=0;
          Brosse_Decalage_Y=0;
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_TOP_RIGHT_ATTACHMENT : // Top-right brush attachment
          Effacer_curseur();
          Brosse_Decalage_X=(Brosse_Largeur-1);
          Brosse_Decalage_Y=0;
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_BOTTOM_LEFT_ATTACHMENT : // Bottom-left brush attachment
          Effacer_curseur();
          Brosse_Decalage_X=0;
          Brosse_Decalage_Y=(Brosse_Hauteur-1);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_BOTTOM_RIGHT_ATTACHMENT : // Bottom right brush attachment
          Effacer_curseur();
          Brosse_Decalage_X=(Brosse_Largeur-1);
          Brosse_Decalage_Y=(Brosse_Hauteur-1);
          Afficher_curseur();
          Touche=0;
          break;
        case SPECIAL_EXCLUDE_COLORS_MENU : // Exclude colors menu
          Menu_Tag_couleurs("Tag colors to exclude",Exclude_color,&Temp,1, NULL);
          Touche=0;
          break;
        case SPECIAL_INVERT_SIEVE :
          Inverser_trame();
          Touche=0;
          break;
        case SPECIAL_SHADE_MODE :
          Bouton_Shade_Mode();
          Touche=0;
          break;
        case SPECIAL_SHADE_MENU :
          Bouton_Shade_Menu();
          Touche=0;
          break;
        case SPECIAL_QUICK_SHADE_MODE :
          Bouton_Quick_shade_Mode();
          Touche=0;
          break;
        case SPECIAL_QUICK_SHADE_MENU :
          Bouton_Quick_shade_Menu();
          Touche=0;
          break;
        case SPECIAL_STENCIL_MODE :
          Bouton_Stencil_Mode();
          Touche=0;
          break;
        case SPECIAL_STENCIL_MENU :
          Bouton_Menu_Stencil();
          Touche=0;
          break;
        case SPECIAL_MASK_MODE :
          Bouton_Mask_Mode();
          Touche=0;
          break;
        case SPECIAL_MASK_MENU :
          Bouton_Mask_Menu();
          Touche=0;
          break;
        case SPECIAL_GRID_MODE :
          Bouton_Snap_Mode();
          Touche=0;
          break;
        case SPECIAL_GRID_MENU :
          Bouton_Menu_Grille();
          Touche=0;
          break;
        case SPECIAL_SIEVE_MODE :
          Bouton_Trame_Mode();
          Touche=0;
          break;
        case SPECIAL_SIEVE_MENU :
          Bouton_Trame_Menu();
          Touche=0;
          break;
        case SPECIAL_COLORIZE_MODE :
          Bouton_Colorize_Mode();
          Touche=0;
          break;
        case SPECIAL_COLORIZE_MENU :
          Bouton_Colorize_Menu();
          Touche=0;
          break;
        case SPECIAL_SMOOTH_MODE :
          Bouton_Smooth_Mode();
          Touche=0;
          break;
        case SPECIAL_SMOOTH_MENU :
          Bouton_Smooth_Menu();
          Touche=0;
          break;
        case SPECIAL_SMEAR_MODE :
          Bouton_Smear_Mode();
          Touche=0;
          break;
        case SPECIAL_TILING_MODE :
          Bouton_Tiling_Mode();
          Touche=0;
          break;
        case SPECIAL_TILING_MENU :
          Bouton_Tiling_Menu();
          Touche=0;
          break;
        default   : // Gestion des touches de raccourci de bouton:
          // Pour chaque bouton
          Bouton_Touche=-1;
          for (Indice_bouton=0;Indice_bouton=SPECIAL_SHADE_MODE)
       && (Indice_Touche<=SPECIAL_TILING_MENU))
      {
        Effacer_curseur();
        Tracer_cadre_de_bouton_du_menu(BOUTON_EFFETS,
          (Shade_Mode||Quick_shade_Mode||Colorize_Mode||Smooth_Mode||Tiling_Mode||Smear_Mode||Stencil_Mode||Mask_Mode||Trame_Mode||Snap_Mode));
        Afficher_curseur();
      }
    }
    }
    else Wait_VBL(); // S'il n'y a pas d'évènement, on ne gère pas tout ça et on attend un peu. La partie en dessous doit être exécutée quand
                     // même pour les trucs asynchrones, par exemple le spray.
    // Gestion de la souris
    Curseur_dans_menu=(Mouse_Y>=Menu_Ordonnee) ||
                      ( (Loupe_Mode) && (Mouse_X>=Principal_Split) &&
                        (Mouse_X=Menu_Ordonnee)
        {
          if (Indice_bouton>=0)
          {
            Enclencher_bouton(Indice_bouton,Mouse_K);
            Indice_bouton_precedent=-1;
          }
        }
        else
          if (Loupe_Mode) Deplacer_Split();
      }
    }
    // we need to refresh that one as we may come from a sub window
    Curseur_dans_menu=(Mouse_Y>=Menu_Ordonnee) ||
                      ( (Loupe_Mode) && (Mouse_X>=Principal_Split) &&
                        (Mouse_X>1;
  Fenetre_Pos_Y=(Hauteur_ecran-(Hauteur*Menu_Facteur_Y))>>1;
  // Sauvegarde de ce que la fenêtre remplace
  Sauve_fond(&(Fond_fenetre[Fenetre-1]), Fenetre_Pos_X, Fenetre_Pos_Y, Largeur, Hauteur);
  // Fenêtre grise
  Block(Fenetre_Pos_X+(Menu_Facteur_X<<1),Fenetre_Pos_Y+(Menu_Facteur_Y<<1),(Largeur-4)*Menu_Facteur_X,(Hauteur-4)*Menu_Facteur_Y,CM_Clair);
  // -- Cadre de la fenêtre ----- --- -- -  -
  // Cadre noir puis en relief
  Fenetre_Afficher_cadre_mono(0,0,Largeur,Hauteur,CM_Noir);
  Fenetre_Afficher_cadre_bombe(1,1,Largeur-2,Hauteur-2);
  // Barre sous le titre
  Block(Fenetre_Pos_X+(Menu_Facteur_X<<3),Fenetre_Pos_Y+(11*Menu_Facteur_Y),(Largeur-16)*Menu_Facteur_X,Menu_Facteur_Y,CM_Fonce);
  Block(Fenetre_Pos_X+(Menu_Facteur_X<<3),Fenetre_Pos_Y+(12*Menu_Facteur_Y),(Largeur-16)*Menu_Facteur_X,Menu_Facteur_Y,CM_Blanc);
  Print_dans_fenetre((Largeur-(strlen(Titre)<<3))>>1,3,Titre,CM_Noir,CM_Clair);
  if (Fenetre == 1)
  {
    Menu_visible_avant_fenetre=Menu_visible;
    Menu_visible=0;
    Menu_Ordonnee_avant_fenetre=Menu_Ordonnee;
    Menu_Ordonnee=Hauteur_ecran;
    Forme_curseur_avant_fenetre=Forme_curseur;
    Forme_curseur=FORME_CURSEUR_FLECHE;
    Cacher_pinceau_avant_fenetre=Cacher_pinceau;
    Cacher_pinceau=1;
  }
  // Initialisation des listes de boutons de la fenêtre
  Fenetre_Liste_boutons_normal  =NULL;
  Fenetre_Liste_boutons_palette =NULL;
  Fenetre_Liste_boutons_scroller=NULL;
  Fenetre_Liste_boutons_special =NULL;
  Fenetre_Liste_boutons_dropdown=NULL;
  Nb_boutons_fenetre            =0;
}
//----------------------- Fermer une fenêtre d'options -----------------------
void Fermer_fenetre(void)
// Lors de l'appel à cette procedure, la souris doit être affichée.
// En sortie de cette procedure, la souris est effacée.
{
  T_Bouton_normal   * Temp1;
  T_Bouton_palette  * Temp2;
  T_Bouton_scroller * Temp3;
  T_Bouton_special  * Temp4;
  T_Bouton_dropdown * Temp5;
  Effacer_curseur();
  while (Fenetre_Liste_boutons_normal)
  {
    Temp1=Fenetre_Liste_boutons_normal->Next;
    free(Fenetre_Liste_boutons_normal);
    Fenetre_Liste_boutons_normal=Temp1;
  }
  while (Fenetre_Liste_boutons_palette)
  {
    Temp2=Fenetre_Liste_boutons_palette->Next;
    free(Fenetre_Liste_boutons_palette);
    Fenetre_Liste_boutons_palette=Temp2;
  }
  while (Fenetre_Liste_boutons_scroller)
  {
    Temp3=Fenetre_Liste_boutons_scroller->Next;
    free(Fenetre_Liste_boutons_scroller);
    Fenetre_Liste_boutons_scroller=Temp3;
  }
  while (Fenetre_Liste_boutons_special)
  {
    Temp4=Fenetre_Liste_boutons_special->Next;
    free(Fenetre_Liste_boutons_special);
    Fenetre_Liste_boutons_special=Temp4;
  }
  while (Fenetre_Liste_boutons_dropdown)
  {
    Temp5=Fenetre_Liste_boutons_dropdown->Next;
    Fenetre_Dropdown_vider_choix(Fenetre_Liste_boutons_dropdown);
    free(Fenetre_Liste_boutons_dropdown);
    Fenetre_Liste_boutons_dropdown=Temp5;
  }
  if (Fenetre != 1)
  {
    // Restore de ce que la fenêtre cachait
    Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur);
    Fond_fenetre[Fenetre-1]=NULL;
    UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Fenetre_Largeur*Menu_Facteur_X,Fenetre_Hauteur*Menu_Facteur_Y);
    Fenetre--;
  }
  else
  {
    free(Fond_fenetre[Fenetre-1]);
    Fond_fenetre[Fenetre-1]=NULL;
    Fenetre--;
  
    Cacher_pinceau=Cacher_pinceau_avant_fenetre;
  
    Calculer_coordonnees_pinceau();
  
    Menu_Ordonnee=Menu_Ordonnee_avant_fenetre;
    Menu_visible=Menu_visible_avant_fenetre;
    Forme_curseur=Forme_curseur_avant_fenetre;
    
    Afficher_ecran();
    Afficher_menu();
  }
  Touche=0;
  Mouse_K=0;
  
  Old_MX = -1;
  Old_MY = -1;
}
//---------------- Dessiner un bouton normal dans une fenêtre ----------------
void Fenetre_Dessiner_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur,
                                    char * Titre,byte Lettre_soulignee,byte Clickable)
{
  byte Couleur_titre;
  word Pos_texte_X,Pos_texte_Y;
  if (Clickable)
  {
    Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur);
    Fenetre_Afficher_cadre_general(Pos_X-1,Pos_Y-1,Largeur+2,Hauteur+2,CM_Noir,CM_Noir,CM_Fonce,CM_Fonce,CM_Fonce);
    Couleur_titre=CM_Noir;
  }
  else
  {
    Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur);
    Fenetre_Afficher_cadre_mono(Pos_X-1,Pos_Y-1,Largeur+2,Hauteur+2,CM_Clair);
    Couleur_titre=CM_Fonce;
  }
  Pos_texte_X=Pos_X+( (Largeur-(strlen(Titre)<<3)+1) >>1 );
  Pos_texte_Y=Pos_Y+((Hauteur-7)>>1);
  Print_dans_fenetre(Pos_texte_X,Pos_texte_Y,Titre,Couleur_titre,CM_Clair);
  if (Lettre_soulignee)
    Block(Fenetre_Pos_X+((Pos_texte_X+((Lettre_soulignee-1)<<3))*Menu_Facteur_X),
          Fenetre_Pos_Y+((Pos_texte_Y+8)*Menu_Facteur_Y),
          Menu_Facteur_X<<3,Menu_Facteur_Y,CM_Fonce);
}
// -- Bouton normal enfoncé dans la fenêtre --
void Fenetre_Enfoncer_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
{
  Fenetre_Afficher_cadre_general(Pos_X,Pos_Y,Largeur,Hauteur,CM_Fonce,CM_Noir,CM_Fonce,CM_Fonce,CM_Noir);
  UpdateRect(Fenetre_Pos_X+Pos_X*Menu_Facteur_X, Fenetre_Pos_Y+Pos_Y*Menu_Facteur_Y, Largeur*Menu_Facteur_X, Hauteur*Menu_Facteur_Y);
}
// -- Bouton normal désenfoncé dans la fenêtre --
void Fenetre_Desenfoncer_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
{
  Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur);
  UpdateRect(Fenetre_Pos_X+Pos_X*Menu_Facteur_X, Fenetre_Pos_Y+Pos_Y*Menu_Facteur_Y, Largeur*Menu_Facteur_X, Hauteur*Menu_Facteur_Y);
}
//--------------- Dessiner un bouton palette dans une fenêtre ----------------
void Fenetre_Dessiner_bouton_palette(word Pos_X,word Pos_Y)
{
  word Couleur;
  for (Couleur=0; Couleur<=255; Couleur++)
    Block( Fenetre_Pos_X+((((Couleur >> 4)*10)+Pos_X+6)*Menu_Facteur_X),Fenetre_Pos_Y+((((Couleur & 15)*5)+Pos_Y+3)*Menu_Facteur_Y),Menu_Facteur_X*5,Menu_Facteur_Y*5,Couleur);
  Fenetre_Afficher_cadre(Pos_X,Pos_Y,164,86);
}
// -------------------- Effacer les TAGs sur les palette ---------------------
// Cette fonct° ne sert plus que lorsqu'on efface les tags dans le menu Spray.
void Fenetre_Effacer_tags(void)
{
  word Origine_X;
  word Origine_Y;
  word Pos_X;
  word Pos_fenetre_X;
  //word Pos_fenetre_Y;
  Origine_X=Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3)*Menu_Facteur_X;
  Origine_Y=Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3)*Menu_Facteur_Y;
  for (Pos_X=0,Pos_fenetre_X=Origine_X;Pos_X<16;Pos_X++,Pos_fenetre_X+=(Menu_Facteur_X*10))
    Block(Pos_fenetre_X,Origine_Y,Menu_Facteur_X*3,Menu_Facteur_Y*80,CM_Clair);
  UpdateRect(Origine_X,Origine_Y,ToWinL(160),ToWinH(80));
}
// ---- Tracer les TAGs sur les palettes du menu Palette ou du menu Shade ----
void Tagger_intervalle_palette(byte Debut,byte Fin)
{
  word Origine_X;
  word Origine_Y;
  //word Pos_X;
  word Pos_Y;
  //word Pos_fenetre_X;
  word Pos_fenetre_Y;
  word Indice;
  // On efface les anciens TAGs
  for (Indice=0;Indice<=Debut;Indice++)
    Block(Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3+((Indice>>4)*10))*Menu_Facteur_X,
          Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y,
          Menu_Facteur_X*3,Menu_Facteur_Y*5,CM_Clair);
  for (Indice=Fin;Indice<256;Indice++)
    Block(Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3+((Indice>>4)*10))*Menu_Facteur_X,
          Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y,
          Menu_Facteur_X*3,Menu_Facteur_Y*5,CM_Clair);
  // On affiche le 1er TAG
  Origine_X=(Fenetre_Liste_boutons_palette->Pos_X+3)+(Debut>>4)*10;
  Origine_Y=(Fenetre_Liste_boutons_palette->Pos_Y+3)+(Debut&15)* 5;
  for (Pos_Y=0,Pos_fenetre_Y=Origine_Y  ;Pos_Y<5;Pos_Y++,Pos_fenetre_Y++)
    Pixel_dans_fenetre(Origine_X  ,Pos_fenetre_Y,CM_Noir);
  for (Pos_Y=0,Pos_fenetre_Y=Origine_Y+1;Pos_Y<3;Pos_Y++,Pos_fenetre_Y++)
    Pixel_dans_fenetre(Origine_X+1,Pos_fenetre_Y,CM_Noir);
  Pixel_dans_fenetre(Origine_X+2,Origine_Y+2,CM_Noir);
  if (Debut!=Fin)
  {
    // On complète le 1er TAG
    Pixel_dans_fenetre(Origine_X+1,Origine_Y+4,CM_Noir);
    // On affiche le 2ème TAG
    Origine_X=(Fenetre_Liste_boutons_palette->Pos_X+3)+(Fin>>4)*10;
    Origine_Y=(Fenetre_Liste_boutons_palette->Pos_Y+3)+(Fin&15)* 5;
    for (Pos_Y=0,Pos_fenetre_Y=Origine_Y; Pos_Y<5; Pos_Y++,Pos_fenetre_Y++)
      Pixel_dans_fenetre(Origine_X  ,Pos_fenetre_Y,CM_Noir);
    for (Pos_Y=0,Pos_fenetre_Y=Origine_Y; Pos_Y<4; Pos_Y++,Pos_fenetre_Y++)
      Pixel_dans_fenetre(Origine_X+1,Pos_fenetre_Y,CM_Noir);
    Pixel_dans_fenetre(Origine_X+2,Origine_Y+2,CM_Noir);
    // On TAG toutes les couleurs intermédiaires
    for (Indice=Debut+1;IndicePos_X+3+((Indice>>4)*10))*Menu_Facteur_X,
            Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y,
            Menu_Facteur_X*2,Menu_Facteur_Y*5,CM_Noir);
      // On efface l'éventuelle pointe d'une ancienne extrémité de l'intervalle
      Pixel_dans_fenetre(Fenetre_Liste_boutons_palette->Pos_X+5+((Indice>>4)*10),
                         Fenetre_Liste_boutons_palette->Pos_Y+5+((Indice&15)* 5),
                         CM_Clair);
    }
  }
  UpdateRect(ToWinX(Fenetre_Liste_boutons_palette->Pos_X+3),ToWinY(Fenetre_Liste_boutons_palette->Pos_Y+3),ToWinL(12*16),ToWinH(5*16));
}
//------------------ Dessiner un scroller dans une fenêtre -------------------
void Calculer_hauteur_curseur_jauge(T_Bouton_scroller * Enreg)
{
  if (Enreg->Nb_elements>Enreg->Nb_visibles)
  {
    Enreg->Hauteur_curseur=(Enreg->Nb_visibles*(Enreg->Hauteur-24))/Enreg->Nb_elements;
    if (!(Enreg->Hauteur_curseur))
      Enreg->Hauteur_curseur=1;
  }
  else
  {
    Enreg->Hauteur_curseur=Enreg->Hauteur-24;
  }
}
void Fenetre_Dessiner_jauge(T_Bouton_scroller * Enreg)
{
  word Position_curseur_jauge;
  Position_curseur_jauge=Enreg->Pos_Y+12;
  Block(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X),
        Fenetre_Pos_Y+(Position_curseur_jauge*Menu_Facteur_Y),
        11*Menu_Facteur_X,(Enreg->Hauteur-24)*Menu_Facteur_Y,CM_Noir/*CM_Fonce*/);
  if (Enreg->Nb_elements>Enreg->Nb_visibles)
    Position_curseur_jauge+=Round_div(Enreg->Position*(Enreg->Hauteur-24-Enreg->Hauteur_curseur),Enreg->Nb_elements-Enreg->Nb_visibles);
  Block(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X),
        Fenetre_Pos_Y+(Position_curseur_jauge*Menu_Facteur_Y),
        11*Menu_Facteur_X,Enreg->Hauteur_curseur*Menu_Facteur_Y,CM_Clair/*CM_Blanc*/);
  UpdateRect(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X),
        Fenetre_Pos_Y+Enreg->Pos_Y*Menu_Facteur_Y,
        11*Menu_Facteur_X,(Enreg->Hauteur)*Menu_Facteur_Y);
}
void Fenetre_Dessiner_bouton_scroller(T_Bouton_scroller * Enreg)
{
  Fenetre_Afficher_cadre_general(Enreg->Pos_X-1,Enreg->Pos_Y-1,13,Enreg->Hauteur+2,CM_Noir,CM_Noir,CM_Fonce,CM_Fonce,CM_Fonce);
  Fenetre_Afficher_cadre_mono(Enreg->Pos_X-1,Enreg->Pos_Y+11,13,Enreg->Hauteur-22,CM_Noir);
  Fenetre_Afficher_cadre_bombe(Enreg->Pos_X,Enreg->Pos_Y,11,11);
  Fenetre_Afficher_cadre_bombe(Enreg->Pos_X,Enreg->Pos_Y+Enreg->Hauteur-11,11,11);
  Print_dans_fenetre(Enreg->Pos_X+2,Enreg->Pos_Y+2,"\030",CM_Noir,CM_Clair);
  Print_dans_fenetre(Enreg->Pos_X+2,Enreg->Pos_Y+Enreg->Hauteur-9,"\031",CM_Noir,CM_Clair);
  Fenetre_Dessiner_jauge(Enreg);
}
//--------------- Dessiner une zone de saisie dans une fenêtre ---------------
void Fenetre_Dessiner_bouton_saisie(word Pos_X,word Pos_Y,word Largeur_en_caracteres)
{
  Fenetre_Afficher_cadre_creux(Pos_X,Pos_Y,(Largeur_en_caracteres<<3)+3,11);
}
//------------ Modifier le contenu (caption) d'une zone de saisie ------------
void Fenetre_Contenu_bouton_saisie(T_Bouton_special * Enreg, char * Contenu)
{
  Print_dans_fenetre_limite(Enreg->Pos_X+2,Enreg->Pos_Y+2,Contenu,Enreg->Largeur/8,CM_Noir,CM_Clair);
}
//------------ Effacer le contenu (caption) d'une zone de saisie ------------
void Fenetre_Effacer_bouton_saisie(T_Bouton_special * Enreg)
{
  Block((Enreg->Pos_X+2)*Menu_Facteur_X+Fenetre_Pos_X,(Enreg->Pos_Y+2)*Menu_Facteur_Y+Fenetre_Pos_Y,(Enreg->Largeur/8)*8*Menu_Facteur_X,8*Menu_Facteur_Y,CM_Clair);
  UpdateRect((Enreg->Pos_X+2)*Menu_Facteur_X+Fenetre_Pos_X,(Enreg->Pos_Y+2)*Menu_Facteur_Y+Fenetre_Pos_Y,Enreg->Largeur/8*8*Menu_Facteur_X,8*Menu_Facteur_Y);
}
//------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------
T_Bouton_normal * Fenetre_Definir_bouton_normal(word Pos_X, word Pos_Y,
                                   word Largeur, word Hauteur,
                                   char * Titre, byte Lettre_soulignee,
                                   byte Clickable, word Raccourci)
{
  T_Bouton_normal * Temp=NULL;
  Nb_boutons_fenetre++;
  if (Clickable)
  {
    Temp=(T_Bouton_normal *)malloc(sizeof(T_Bouton_normal));
    Temp->Numero   =Nb_boutons_fenetre;
    Temp->Pos_X    =Pos_X;
    Temp->Pos_Y    =Pos_Y;
    Temp->Largeur  =Largeur;
    Temp->Hauteur  =Hauteur;
    Temp->Raccourci=Raccourci;
    Temp->Repetable=0;
    Temp->Next=Fenetre_Liste_boutons_normal;
    Fenetre_Liste_boutons_normal=Temp;
  }
  Fenetre_Dessiner_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur,Titre,Lettre_soulignee,Clickable);
  return Temp;
}
//------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------
T_Bouton_normal * Fenetre_Definir_bouton_repetable(word Pos_X, word Pos_Y,
                                   word Largeur, word Hauteur,
                                   char * Titre, byte Lettre_soulignee,
                                   byte Clickable, word Raccourci)
{
  T_Bouton_normal * Temp=NULL;
  Nb_boutons_fenetre++;
  if (Clickable)
  {
    Temp=(T_Bouton_normal *)malloc(sizeof(T_Bouton_normal));
    Temp->Numero   =Nb_boutons_fenetre;
    Temp->Pos_X    =Pos_X;
    Temp->Pos_Y    =Pos_Y;
    Temp->Largeur  =Largeur;
    Temp->Hauteur  =Hauteur;
    Temp->Raccourci=Raccourci;
    Temp->Repetable=1;
    Temp->Next=Fenetre_Liste_boutons_normal;
    Fenetre_Liste_boutons_normal=Temp;
  }
  Fenetre_Dessiner_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur,Titre,Lettre_soulignee,Clickable);
  return Temp;
}
T_Bouton_palette * Fenetre_Definir_bouton_palette(word Pos_X, word Pos_Y)
{
  T_Bouton_palette * Temp;
  Temp=(T_Bouton_palette *)malloc(sizeof(T_Bouton_palette));
  Temp->Numero   =++Nb_boutons_fenetre;
  Temp->Pos_X    =Pos_X;
  Temp->Pos_Y    =Pos_Y;
  Temp->Next=Fenetre_Liste_boutons_palette;
  Fenetre_Liste_boutons_palette=Temp;
  Fenetre_Dessiner_bouton_palette(Pos_X,Pos_Y);
  return Temp;
}
T_Bouton_scroller * Fenetre_Definir_bouton_scroller(word Pos_X, word Pos_Y,
                                     word Hauteur,
                                     word Nb_elements,
                                     word Nb_elements_visibles,
                                     word Position_initiale)
{
  T_Bouton_scroller * Temp;
  Temp=(T_Bouton_scroller *)malloc(sizeof(T_Bouton_scroller));
  Temp->Numero        =++Nb_boutons_fenetre;
  Temp->Pos_X         =Pos_X;
  Temp->Pos_Y         =Pos_Y;
  Temp->Hauteur       =Hauteur;
  Temp->Nb_elements   =Nb_elements;
  Temp->Nb_visibles   =Nb_elements_visibles;
  Temp->Position      =Position_initiale;
  Calculer_hauteur_curseur_jauge(Temp);
  Temp->Next=Fenetre_Liste_boutons_scroller;
  Fenetre_Liste_boutons_scroller=Temp;
  Fenetre_Dessiner_bouton_scroller(Temp);
  return Temp;
}
T_Bouton_special * Fenetre_Definir_bouton_special(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
{
  T_Bouton_special * Temp;
  Temp=(T_Bouton_special *)malloc(sizeof(T_Bouton_special));
  Temp->Numero   =++Nb_boutons_fenetre;
  Temp->Pos_X    =Pos_X;
  Temp->Pos_Y    =Pos_Y;
  Temp->Largeur  =Largeur;
  Temp->Hauteur  =Hauteur;
  Temp->Next=Fenetre_Liste_boutons_special;
  Fenetre_Liste_boutons_special=Temp;
  return Temp;
}
T_Bouton_special * Fenetre_Definir_bouton_saisie(word Pos_X,word Pos_Y,word Largeur_en_caracteres)
{
  T_Bouton_special *Temp;
  Temp=Fenetre_Definir_bouton_special(Pos_X,Pos_Y,(Largeur_en_caracteres<<3)+3,11);
  Fenetre_Dessiner_bouton_saisie(Pos_X,Pos_Y,Largeur_en_caracteres);
  return Temp;
}
T_Bouton_dropdown * Fenetre_Definir_bouton_dropdown(word Pos_X,word Pos_Y,word Largeur,word Hauteur,word Largeur_choix,char *Libelle,byte Affiche_choix,byte Affiche_centre,byte Affiche_fleche,byte Bouton_actif)
{
  T_Bouton_dropdown *Temp;
  
  Temp=(T_Bouton_dropdown *)malloc(sizeof(T_Bouton_dropdown));
  Temp->Numero       =++Nb_boutons_fenetre;
  Temp->Pos_X        =Pos_X;
  Temp->Pos_Y        =Pos_Y;
  Temp->Largeur      =Largeur;
  Temp->Hauteur      =Hauteur;
  Temp->Affiche_choix =Affiche_choix;
  Temp->Premier_choix=NULL;
  Temp->Largeur_choix=Largeur_choix?Largeur_choix:Largeur;
  Temp->Affiche_centre=Affiche_centre;
  Temp->Affiche_fleche=Affiche_fleche;
  Temp->Bouton_actif=Bouton_actif;
  Temp->Next=Fenetre_Liste_boutons_dropdown;
  Fenetre_Liste_boutons_dropdown=Temp;
  Fenetre_Dessiner_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur,"",-1,1);
  if (Libelle && Libelle[0])
    Print_dans_fenetre(Temp->Pos_X+2,Temp->Pos_Y+(Temp->Hauteur-7)/2,Libelle,CM_Noir,CM_Clair);
  if (Affiche_fleche)
    Fenetre_Afficher_sprite_drive(Temp->Pos_X+Temp->Largeur-10,Temp->Pos_Y+(Temp->Hauteur-7)/2,6);
  
  return Temp;
}
// Ajoute un choix à une dropdown. Le libellé est seulement référencé,
// il doit pointer sur une zone qui doit être encore valide à la fermeture 
// de la fenêtre (comprise).
void Fenetre_Dropdown_choix(T_Bouton_dropdown * Dropdown, word Numero, const char *Libelle)
{
  T_Dropdown_choix *Temp;
  T_Dropdown_choix *Dernier;
  
  Temp=(T_Dropdown_choix *)malloc(sizeof(T_Dropdown_choix));
  Temp->Numero =Numero;
  Temp->Libelle=Libelle;
  Temp->Next=NULL;
  Dernier=Dropdown->Premier_choix;
  if (Dernier)
  {
    // On cherche le dernier élément
    for (;Dernier->Next;Dernier=Dernier->Next)
      ;
    Dernier->Next=Temp;
  }
  else
  {
    Dropdown->Premier_choix=Temp;
  }
}
// ------------- Suppression de tous les choix d'une dropdown ---------
void Fenetre_Dropdown_vider_choix(T_Bouton_dropdown * Dropdown)
{
  T_Dropdown_choix * Choix_suivant;
    while (Dropdown->Premier_choix)
    {
      Choix_suivant=Dropdown->Premier_choix->Next;
      free(Dropdown->Premier_choix);
      Dropdown->Premier_choix=Choix_suivant;
    }
}
//----------------------- Ouverture d'un pop-up -----------------------
void Ouvrir_popup(word Pos_X, word Pos_Y, word Largeur,word Hauteur)
// Lors de l'appel à cette procédure, la souris doit être affichée.
// En sortie de cette procedure, la souris est effacée.
// Note : les pop-ups sont gérés comme s'ils étaient des sous-fenêtres, ils ont donc leur propre boucle d'évènements et tout, on peut ajouter des widgets dedans, ...
// Les différences sont surtout graphiques :
    // -Possibilité de préciser la position XY
    // -Pas de titre
    // -Pas de cadre en relief mais seulement un plat, et il est blanc au lieu de noir.
{
  Fenetre++;
  Fenetre_Largeur=Largeur;
  Fenetre_Hauteur=Hauteur;
  Fenetre_Pos_X=Pos_X;
  Fenetre_Pos_Y=Pos_Y;
  // Sauvegarde de ce que la fenêtre remplace
  Sauve_fond(&(Fond_fenetre[Fenetre-1]), Fenetre_Pos_X, Fenetre_Pos_Y, Largeur, Hauteur);
/*
  // Fenêtre grise
  Block(Fenetre_Pos_X+1*Menu_Facteur_X,
        Fenetre_Pos_Y+1*Menu_Facteur_Y,
        (Largeur-2)*Menu_Facteur_X,(Hauteur-2)*Menu_Facteur_Y,CM_Clair);
  // Cadre noir puis en relief
  Fenetre_Afficher_cadre_mono(0,0,Largeur,Hauteur,CM_Blanc);
*/
  if (Fenetre == 1)
  {
    Menu_visible_avant_fenetre=Menu_visible;
    Menu_visible=0;
    Menu_Ordonnee_avant_fenetre=Menu_Ordonnee;
    Menu_Ordonnee=Hauteur_ecran;
    Forme_curseur_avant_fenetre=Forme_curseur;
    Forme_curseur=FORME_CURSEUR_FLECHE;
    Cacher_pinceau_avant_fenetre=Cacher_pinceau;
    Cacher_pinceau=1;
  }
  // Initialisation des listes de boutons de la fenêtre
  Fenetre_Liste_boutons_normal  =NULL;
  Fenetre_Liste_boutons_palette =NULL;
  Fenetre_Liste_boutons_scroller=NULL;
  Fenetre_Liste_boutons_special =NULL;
  Fenetre_Liste_boutons_dropdown =NULL;
  Nb_boutons_fenetre            =0;
}
//----------------------- Fermer une fenêtre d'options -----------------------
void Fermer_popup(void)
// Lors de l'appel à cette procedure, la souris doit être affichée.
// En sortie de cette procedure, la souris est effacée.
{
  T_Bouton_normal   * Temp1;
  T_Bouton_palette  * Temp2;
  T_Bouton_scroller * Temp3;
  T_Bouton_special  * Temp4;
  T_Bouton_dropdown  * Temp5;
  Effacer_curseur();
  while (Fenetre_Liste_boutons_normal)
  {
    Temp1=Fenetre_Liste_boutons_normal->Next;
    free(Fenetre_Liste_boutons_normal);
    Fenetre_Liste_boutons_normal=Temp1;
  }
  while (Fenetre_Liste_boutons_palette)
  {
    Temp2=Fenetre_Liste_boutons_palette->Next;
    free(Fenetre_Liste_boutons_palette);
    Fenetre_Liste_boutons_palette=Temp2;
  }
  while (Fenetre_Liste_boutons_scroller)
  {
    Temp3=Fenetre_Liste_boutons_scroller->Next;
    free(Fenetre_Liste_boutons_scroller);
    Fenetre_Liste_boutons_scroller=Temp3;
  }
  while (Fenetre_Liste_boutons_special)
  {
    Temp4=Fenetre_Liste_boutons_special->Next;
    free(Fenetre_Liste_boutons_special);
    Fenetre_Liste_boutons_special=Temp4;
  }
  while (Fenetre_Liste_boutons_dropdown)
  {
    Fenetre_Dropdown_vider_choix(Fenetre_Liste_boutons_dropdown);
    Temp5=Fenetre_Liste_boutons_dropdown->Next;
    free(Fenetre_Liste_boutons_dropdown);
    Fenetre_Liste_boutons_dropdown=Temp5;
  }
  if (Fenetre != 1)
  {
    // Restore de ce que la fenêtre cachait
    Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur);
    Fond_fenetre[Fenetre-1]=NULL;
    UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Fenetre_Largeur*Menu_Facteur_X,Fenetre_Hauteur*Menu_Facteur_Y);
    Fenetre--;
  }
  else
  {
    free(Fond_fenetre[Fenetre-1]);
    Fenetre--;
  
    Cacher_pinceau=Cacher_pinceau_avant_fenetre;
  
    Calculer_coordonnees_pinceau();
  
    Menu_Ordonnee=Menu_Ordonnee_avant_fenetre;
    Menu_visible=Menu_visible_avant_fenetre;
    Forme_curseur=Forme_curseur_avant_fenetre;
    
    Afficher_ecran();
    Afficher_menu();
  }
  Touche=0;
  Mouse_K=0;
  
  Old_MX = -1;
  Old_MY = -1;
}
//////////////////////////////////////////////////////////////////////////////
//                                                                          //
//       Mini-MOTEUR utilisé dans les fenêtres (menus des boutons...)       //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////
// -- Indique si on a cliqué dans une zone définie par deux points extremes --
byte Fenetre_click_dans_zone(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y)
{
  short Pos_X,Pos_Y;
  Pos_X=((short)Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X;
  Pos_Y=((short)Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y;
  return ((Pos_X>=Debut_X) &&
          (Pos_Y>=Debut_Y) &&
          (Pos_X<=Fin_X)   &&
          (Pos_Y<=Fin_Y));
}
// --- Attend que l'on clique dans la palette pour renvoyer la couleur choisie
// ou bien renvoie -1 si on a annulé l'action pas click-droit ou Escape ------
short Attendre_click_dans_palette(T_Bouton_palette * Enreg)
{
  short Debut_X=Enreg->Pos_X+5;
  short Debut_Y=Enreg->Pos_Y+3;
  short Fin_X  =Enreg->Pos_X+160;
  short Fin_Y  =Enreg->Pos_Y+82;
  byte  Couleur_choisie;
  byte  Ancien_Cacher_curseur;
  byte  Ancien_Loupe_Mode;
  Effacer_curseur();
  Ancien_Cacher_curseur=Cacher_curseur;
  Ancien_Loupe_Mode=Loupe_Mode;
  Loupe_Mode=0;
  Cacher_curseur=0;
  Forme_curseur=FORME_CURSEUR_CIBLE;
  Afficher_curseur();
  for (;;)
  {
    while(!Get_input())Wait_VBL();
    if (Mouse_K==A_GAUCHE)
    {
      if (Fenetre_click_dans_zone(Debut_X,Debut_Y,Fin_X,Fin_Y))
      {
        Effacer_curseur();
        Couleur_choisie=(((Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X)-(Enreg->Pos_X+2)) / 10 * 16 +
        (((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-(Enreg->Pos_Y+3)) / 5;
        Forme_curseur=FORME_CURSEUR_FLECHE;
        Cacher_curseur=Ancien_Cacher_curseur;
        Loupe_Mode=Ancien_Loupe_Mode;
        Afficher_curseur();
        return Couleur_choisie;
      }
      if ((Mouse_X=Fenetre_Pos_X+(Fenetre_Largeur*Menu_Facteur_X)) ||
          (Mouse_Y>=Fenetre_Pos_Y+(Fenetre_Hauteur*Menu_Facteur_Y)) )
      {
        Effacer_curseur();
        Couleur_choisie=Lit_pixel(Mouse_X,Mouse_Y);
        Forme_curseur=FORME_CURSEUR_FLECHE;
        Cacher_curseur=Ancien_Cacher_curseur;
        Loupe_Mode=Ancien_Loupe_Mode;
        Afficher_curseur();
        return Couleur_choisie;
      }
    }
    if ((Mouse_K==A_DROITE) || (Touche==TOUCHE_ESC))
    {
      Effacer_curseur();
      Forme_curseur=FORME_CURSEUR_FLECHE;
      Cacher_curseur=Ancien_Cacher_curseur;
      Loupe_Mode=Ancien_Loupe_Mode;
      Afficher_curseur();
      return -1;
    }
  }
}
// -------------- Récupération d'une couleur derrière un menu ----------------
void Recuperer_couleur_derriere_fenetre(byte * Couleur, byte * Click)
{
  short Largeur=Fenetre_Largeur*Menu_Facteur_X;
  short Hauteur=Fenetre_Hauteur*Menu_Facteur_Y;
  short Ancien_X=-1;
  short Ancien_Y=-1;
  short Indice;
  short A,B,C,D; // Variables temporaires et multitâches...
  byte * Buffer;
  char Chaine[25];
  byte Cacher_curseur_avant_recuperation;
  if ((Buffer=(byte *) malloc(Largeur*Hauteur)))
  {
    Effacer_curseur();
    Cacher_curseur_avant_recuperation=Cacher_curseur;
    Cacher_curseur=0;
    for (Indice=0; IndiceLargeur_ecran-Largeur)
    {
      Nouveau_X=Largeur_ecran-Largeur;
      Dx = Mouse_X - Nouveau_X;
    }
    Nouveau_Y=Mouse_Y-Dy;
    if (Nouveau_Y<0)
    {
      Nouveau_Y=0;
      Dy = Mouse_Y;
    }
    if (Nouveau_Y>Hauteur_ecran-Hauteur)
    {
      Nouveau_Y=Hauteur_ecran-Hauteur;
      Dy = Mouse_Y - Nouveau_Y;
    }
    if ((Nouveau_X!=Ancien_X) || (Nouveau_Y!=Ancien_Y))
    {
      Effacer_curseur();
      Ligne_horizontale_XOR(Ancien_X,Ancien_Y,Largeur);
      Ligne_verticale_XOR(Ancien_X,Ancien_Y+1,Hauteur-2);
      Ligne_verticale_XOR(Ancien_X+Largeur-1,Ancien_Y+1,Hauteur-2);
      Ligne_horizontale_XOR(Ancien_X,Ancien_Y+Hauteur-1,Largeur);
      Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y,Largeur);
      Ligne_verticale_XOR(Nouveau_X,Nouveau_Y+1,Hauteur-2);
      Ligne_verticale_XOR(Nouveau_X+Largeur-1,Nouveau_Y+1,Hauteur-2);
      Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y+Hauteur-1,Largeur);
      Afficher_curseur();
      UpdateRect(Ancien_X,Ancien_Y,Largeur,Hauteur);
      UpdateRect(Nouveau_X,Nouveau_Y,Largeur,Hauteur);
    }
  }
  Effacer_curseur();
  Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y,Largeur);
  Ligne_verticale_XOR(Nouveau_X,Nouveau_Y+1,Hauteur-2);
  Ligne_verticale_XOR(Nouveau_X+Largeur-1,Nouveau_Y+1,Hauteur-2);
  Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y+Hauteur-1,Largeur);
  if ((Nouveau_X!=Fenetre_Pos_X)
   || (Nouveau_Y!=Fenetre_Pos_Y))
  {
    A=Menu_Ordonnee;
    Menu_Ordonnee=Menu_Ordonnee_avant_fenetre;
    B=Menu_visible;
    Menu_visible=Menu_visible_avant_fenetre;
    //Afficher_ecran();
    //Afficher_menu();
    Menu_Ordonnee=A;
    Menu_visible=B;
    // Sauvegarde du contenu actuel de la fenêtre
    Sauve_fond(&Buffer, Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur);
    
    // Restore de ce que la fenêtre cachait
    Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur);
    Fond_fenetre[Fenetre-1] = NULL;
    // Sauvegarde de ce que la fenêtre remplace
    Sauve_fond(&(Fond_fenetre[Fenetre-1]), Nouveau_X, Nouveau_Y, Fenetre_Largeur, Fenetre_Hauteur);
    // Raffichage de la fenêtre
    Restaure_fond(Buffer, Nouveau_X, Nouveau_Y, Fenetre_Largeur, Fenetre_Hauteur);
    Buffer = NULL;
    // Mise à jour du rectangle englobant
    UpdateRect(
      (Nouveau_X>Fenetre_Pos_X)?Fenetre_Pos_X:Nouveau_X,
      (Nouveau_Y>Fenetre_Pos_Y)?Fenetre_Pos_Y:Nouveau_Y,
      ((Nouveau_X>Fenetre_Pos_X)?(Nouveau_X-Fenetre_Pos_X):(Fenetre_Pos_X-Nouveau_X)) + Fenetre_Largeur*Menu_Facteur_X,
      ((Nouveau_Y>Fenetre_Pos_Y)?(Nouveau_Y-Fenetre_Pos_Y):(Fenetre_Pos_Y-Nouveau_Y)) + Fenetre_Hauteur*Menu_Facteur_Y);
    Fenetre_Pos_X=Nouveau_X;
    Fenetre_Pos_Y=Nouveau_Y;
  }
  else
  {
    // Update pour effacer le rectangle XOR
    UpdateRect(Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur*Menu_Facteur_X, Fenetre_Hauteur*Menu_Facteur_Y);
  }    
  Forme_curseur=FORME_CURSEUR_FLECHE;
  Afficher_curseur();
}
// Gestion des dropdown
short Fenetre_Dropdown_click(T_Bouton_dropdown *Bouton)
{
  short Nb_choix;
  short Indice_choix;
  short Indice_selectionne;
  short Ancien_Indice_selectionne;
  short Hauteur_boite;
  T_Dropdown_choix *Choix;
  // Taille de l'ombre portée (en plus des dimensions normales)
  #define OMBRE_DROITE 3
  #define OMBRE_BAS 4
  
  // Comptage des items pour calculer la taille
  Nb_choix=0;
  for (Choix=Bouton->Premier_choix; Choix!=NULL; Choix=Choix->Next)
  {
    Nb_choix++;
  }
  Hauteur_boite=3+Nb_choix*8+1;
  
  Effacer_curseur();
  Fenetre_Enfoncer_bouton_normal(Bouton->Pos_X,Bouton->Pos_Y,Bouton->Largeur,Bouton->Hauteur);
  Ouvrir_popup(
    Fenetre_Pos_X+(Bouton->Pos_X)*Menu_Facteur_X,
    Fenetre_Pos_Y+(Bouton->Pos_Y+Bouton->Hauteur)*Menu_Facteur_Y,
    Bouton->Largeur_choix+OMBRE_DROITE,
    Hauteur_boite+OMBRE_BAS);
  // Dessin de la boite
  // Bord gauche
  Block(Fenetre_Pos_X,Fenetre_Pos_Y,Menu_Facteur_X,Hauteur_boite*Menu_Facteur_Y,CM_Noir);
  // Cadre fonce et blanc
  Fenetre_Afficher_cadre_bombe(1,0,Bouton->Largeur_choix-1,Hauteur_boite);
  // Ombre portée
  if (OMBRE_BAS)
  {
    Block(Fenetre_Pos_X+OMBRE_DROITE*Menu_Facteur_X,
        Fenetre_Pos_Y+Hauteur_boite*Menu_Facteur_Y,
        Bouton->Largeur_choix*Menu_Facteur_X,
        OMBRE_BAS*Menu_Facteur_Y,
        CM_Noir);
    Block(Fenetre_Pos_X,
        Fenetre_Pos_Y+Hauteur_boite*Menu_Facteur_Y,
        OMBRE_DROITE*Menu_Facteur_X,
        Menu_Facteur_Y,
        CM_Noir);
  }
  if (OMBRE_DROITE)
  {
    Block(Fenetre_Pos_X+Bouton->Largeur_choix*Menu_Facteur_X,
        Fenetre_Pos_Y+OMBRE_BAS*Menu_Facteur_Y,
        OMBRE_DROITE*Menu_Facteur_X,
        (Hauteur_boite-OMBRE_BAS)*Menu_Facteur_Y,
        CM_Noir);
    Block(Fenetre_Pos_X+Bouton->Largeur_choix*Menu_Facteur_X,
        Fenetre_Pos_Y,
        Menu_Facteur_X,
        OMBRE_BAS*Menu_Facteur_Y,
        CM_Noir);
  }
  Indice_selectionne=-1;
  while (1)
  {
    Ancien_Indice_selectionne = Indice_selectionne;
    // Fenêtre grise
    Block(Fenetre_Pos_X+2*Menu_Facteur_X,
        Fenetre_Pos_Y+1*Menu_Facteur_Y,
        (Bouton->Largeur_choix-3)*Menu_Facteur_X,(Hauteur_boite-2)*Menu_Facteur_Y,CM_Clair);
    // Affichage des items
    for(Choix=Bouton->Premier_choix,Indice_choix=0; Choix!=NULL; Choix=Choix->Next,Indice_choix++)
    {
      byte C1;
      byte C2;
      if (Indice_choix==Indice_selectionne)
      {
        C1=CM_Blanc;
        C2=CM_Fonce;
        Block(Fenetre_Pos_X+3*Menu_Facteur_X,
        Fenetre_Pos_Y+((2+Indice_choix*8)*Menu_Facteur_Y),
        (Bouton->Largeur_choix-5)*Menu_Facteur_X,(8)*Menu_Facteur_Y,CM_Fonce);
      }
      else
      {
        C1=CM_Noir;
        C2=CM_Clair;
      }
      Print_dans_fenetre(3,2+Indice_choix*8,Choix->Libelle,C1,C2);
    }
    UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Fenetre_Largeur*Menu_Facteur_X,Fenetre_Hauteur*Menu_Facteur_Y);
    Afficher_curseur();
    do 
    {
      // Attente
      if(!Get_input())
        Wait_VBL();
      // Mise à jour du survol
      Indice_selectionne=Fenetre_click_dans_zone(2,2,Bouton->Largeur_choix-2,Hauteur_boite-1)?
        (((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y-2)>>3) : -1;
    } while (Mouse_K && Indice_selectionne==Ancien_Indice_selectionne);
    
    if (!Mouse_K)
      break;
    Effacer_curseur();
  }
  Fermer_popup();  
  Fenetre_Desenfoncer_bouton_normal(Bouton->Pos_X,Bouton->Pos_Y,Bouton->Largeur,Bouton->Hauteur);
  Afficher_curseur();
  if (Indice_selectionne>=0 && Indice_selectionnePremier_choix; Indice_selectionne; Choix=Choix->Next,Indice_selectionne--)
      ;
    Fenetre_Attribut2=Choix->Numero;
    if (Bouton->Affiche_choix)
    {
      // Mettre à jour automatiquement le libellé de la dropdown
      Print_dans_fenetre(Bouton->Pos_X+2,Bouton->Pos_Y+(Bouton->Hauteur-7)/2,Choix->Libelle,CM_Noir,CM_Clair);
    }
    return Bouton->Numero;
  }
  Fenetre_Attribut2=-1;
  return 0;
}
// --- Fonction de clic sur un bouton a peu près ordinaire:
// Attend que l'on relache le bouton, et renvoie le numero du bouton si on
// est resté dessus, 0 si on a annulé en sortant du bouton.
short Fenetre_bouton_normal_click(word Pos_X, word Pos_Y, word Largeur, word Hauteur, short Numero)
{
  while(1)
  {
    Effacer_curseur();
    Fenetre_Enfoncer_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur);
    Afficher_curseur();
    while (Fenetre_click_dans_zone(Pos_X,Pos_Y,Pos_X+Largeur-1,Pos_Y+Hauteur-1))
    {
      if(!Get_input())
        Wait_VBL();
      if (!Mouse_K)
      {
        Effacer_curseur();
        Fenetre_Desenfoncer_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur);
        Afficher_curseur();
        return Numero;
      }
    }
    Effacer_curseur();
    Fenetre_Desenfoncer_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur);
    Afficher_curseur();
    while (!(Fenetre_click_dans_zone(Pos_X,Pos_Y,Pos_X+Largeur-1,Pos_Y+Hauteur-1)))
    {
      if(!Get_input())
        Wait_VBL();
      if (!Mouse_K)
        return 0;
    }
  }
}
// --- Renvoie le numéro du bouton clicke (-1:hors de la fenêtre, 0:aucun) ---
short Fenetre_Numero_bouton_clicke(void)
{
  T_Bouton_normal   * Temp1;
  T_Bouton_palette  * Temp2;
  T_Bouton_scroller * Temp3;
  T_Bouton_special  * Temp4;
  T_Bouton_dropdown * Temp5;
  //long Hauteur_Curseur_jauge;
  long Hauteur_maxi_jauge;
  Fenetre_Attribut1=Mouse_K;
  // Test du click sur les boutons normaux
  for (Temp1=Fenetre_Liste_boutons_normal; Temp1; Temp1=Temp1->Next)
  {
    if (Fenetre_click_dans_zone(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Pos_X+Temp1->Largeur-1,Temp1->Pos_Y+Temp1->Hauteur-1))
    {
      if (Temp1->Repetable)
      {
        Effacer_curseur();
        Fenetre_Enfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur);
        Afficher_curseur();
        Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite);
        Effacer_curseur();
        Fenetre_Desenfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur);
        Afficher_curseur();        
        return Temp1->Numero;
      }
      return Fenetre_bouton_normal_click(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur,Temp1->Numero);
    }
  }
  // Test du click sur les zones "palette"
  for (Temp2=Fenetre_Liste_boutons_palette; Temp2; Temp2=Temp2->Next)
  {
    if (Fenetre_click_dans_zone(Temp2->Pos_X+5,Temp2->Pos_Y+3,Temp2->Pos_X+160,Temp2->Pos_Y+82))
    {
      // On stocke dans Attribut2 le numero de couleur cliqué
      Fenetre_Attribut2 = (((Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X)-(Temp2->Pos_X+2)) / 10 * 16 +
        (((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-(Temp2->Pos_Y+3)) / 5;
        return Temp2->Numero;
    }
  }
  // Test du click sur les barres de défilement
  for (Temp3=Fenetre_Liste_boutons_scroller; Temp3; Temp3=Temp3->Next)
  {
    if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-1))
    {
      // Bouton flèche Haut
      if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y,Temp3->Pos_X+10,Temp3->Pos_Y+10))
      {
        Effacer_curseur();
        Fenetre_Enfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y,11,11);
        if (Temp3->Position)
        {
          Temp3->Position--;
          Fenetre_Attribut1=1;
          Fenetre_Attribut2=Temp3->Position;
          Fenetre_Dessiner_jauge(Temp3);
        }
        else
          Fenetre_Attribut1=0;
        
        Afficher_curseur();
        Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite);
        Effacer_curseur();
        Fenetre_Desenfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y,11,11);
        Afficher_curseur();
      }
      else
      // Bouton flèche Bas
      if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-1))
      {
        Effacer_curseur();
        Fenetre_Enfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,11,11);
        if (Temp3->Position+Temp3->Nb_visiblesNb_elements)
        {
          Temp3->Position++;
          Fenetre_Attribut1=2;
          Fenetre_Attribut2=Temp3->Position;
          Fenetre_Dessiner_jauge(Temp3);
        }
        else
          Fenetre_Attribut1=0;
        Afficher_curseur();
        Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite);
        Effacer_curseur();
        Fenetre_Desenfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,11,11);
        Afficher_curseur();
      }
      else
      // Jauge
      if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y+12,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-13))
      {
        if (Temp3->Nb_elements>Temp3->Nb_visibles)
        {
          // S'il y a la place de faire scroller le curseur:
          Hauteur_maxi_jauge=(Temp3->Hauteur-24);
          // Fenetre_Attribut2 reçoit la position dans la jauge correspondant au click
          Fenetre_Attribut2 =(Mouse_Y-Fenetre_Pos_Y) / Menu_Facteur_Y;
          Fenetre_Attribut2-=(Temp3->Pos_Y+12+((Temp3->Hauteur_curseur-1)>>1));
          Fenetre_Attribut2*=(Temp3->Nb_elements-Temp3->Nb_visibles);
          if (Fenetre_Attribut2<0)
            Fenetre_Attribut2=0;
          else
          {
            Fenetre_Attribut2 =Round_div(Fenetre_Attribut2,Hauteur_maxi_jauge-Temp3->Hauteur_curseur);
            if (Fenetre_Attribut2+Temp3->Nb_visibles>Temp3->Nb_elements)
              Fenetre_Attribut2=Temp3->Nb_elements-Temp3->Nb_visibles;
          }
          // Si le curseur de la jauge bouge:
          if (Temp3->Position!=Fenetre_Attribut2)
          {
            Temp3->Position=Fenetre_Attribut2;
            Fenetre_Attribut1=3;
            Effacer_curseur();
            Fenetre_Dessiner_jauge(Temp3);
            Afficher_curseur();
          }
          else
            // Si le curseur de la jauge ne bouge pas:
            Fenetre_Attribut1=0;
        }
        else
          // S'il n'y a pas la place de bouger le curseur de la jauge:
          Fenetre_Attribut1=0;
      }
      else
        // Le click se situe dans la zone de la jauge mais n'est sur aucune
        // des 3 parties importantes de la jauge
        Fenetre_Attribut1=0;
      return (Fenetre_Attribut1)? Temp3->Numero : 0;
    }
  }
  // Test du click sur une zone spéciale
  for (Temp4=Fenetre_Liste_boutons_special; Temp4; Temp4=Temp4->Next)
  {
    if (Fenetre_click_dans_zone(Temp4->Pos_X,Temp4->Pos_Y,Temp4->Pos_X+Temp4->Largeur-1,Temp4->Pos_Y+Temp4->Hauteur-1))
      return Temp4->Numero;
  }
  // Test du click sur une dropdown
  for (Temp5=Fenetre_Liste_boutons_dropdown; Temp5; Temp5=Temp5->Next)
  {
    if (Fenetre_click_dans_zone(Temp5->Pos_X,Temp5->Pos_Y,Temp5->Pos_X+Temp5->Largeur-1,Temp5->Pos_Y+Temp5->Hauteur-1))
    {
      if (Mouse_K & Temp5->Bouton_actif)
        return Fenetre_Dropdown_click(Temp5);
      else
      {
        Fenetre_Attribut2=-1;
        return Fenetre_bouton_normal_click(Temp5->Pos_X,Temp5->Pos_Y,Temp5->Largeur,Temp5->Hauteur,Temp5->Numero);
      }
    }
  }
  return 0;
}
short Fenetre_Numero_bouton_touche(void)
{
  T_Bouton_normal * Temp;
  if (Touche & MOD_SHIFT)
    Fenetre_Attribut1=A_DROITE;
  else
    Fenetre_Attribut1=A_GAUCHE;
  // On fait une première recherche
  Temp=Fenetre_Liste_boutons_normal;
  while (Temp!=NULL)
  {
    if (Temp->Raccourci==Touche)
    {
      Effacer_curseur();
      Fenetre_Enfoncer_bouton_normal(Temp->Pos_X,Temp->Pos_Y,Temp->Largeur,Temp->Hauteur);
      Afficher_curseur();
      
      Tempo_jauge(Config.Valeur_tempo_jauge_droite);
      
      Effacer_curseur();
      Fenetre_Desenfoncer_bouton_normal(Temp->Pos_X,Temp->Pos_Y,Temp->Largeur,Temp->Hauteur);
      Afficher_curseur();
      return Temp->Numero;
    }
    Temp=Temp->Next;
  }
  // Si la recherche n'a pas été fructueuse ET que l'utilisateur appuyait sur
  // , on regarde si un bouton ne pourrait pas réagir comme si 
  // n'était pas appuyé.
  if (Fenetre_Attribut1==A_DROITE)
  {
    Temp=Fenetre_Liste_boutons_normal;
    while (Temp!=NULL)
    {
      if (Temp->Raccourci==(Touche&0x0FFF))
        return Temp->Numero;
      Temp=Temp->Next;
    }
  }
  return 0;
}
short Fenetre_Bouton_clicke(void)
{
  short Bouton;
  if(!Get_input())Wait_VBL();
  // Gestion des clicks
  if (Mouse_K)
  {
    if ((Mouse_X=Fenetre_Pos_X+(Fenetre_Largeur*Menu_Facteur_X))
     || (Mouse_Y>=Fenetre_Pos_Y+(Fenetre_Hauteur*Menu_Facteur_Y)))
      return -1;
    else
    {
      if (Mouse_Y < Fenetre_Pos_Y+(12*Menu_Facteur_Y))
        Deplacer_fenetre(Mouse_X-Fenetre_Pos_X,Mouse_Y-Fenetre_Pos_Y);
      else
        return Fenetre_Numero_bouton_clicke();
    }
  }
  // Gestion des touches
  if (Touche)
  {
    Bouton=Fenetre_Numero_bouton_touche();
    if (Bouton)
    {
      Touche=0;
      return Bouton;
    }
  }
  return 0;
}
//int Moteur_Dernier_bouton_clicke;
//int Moteur_Type_dernier_bouton_clicke;
// Fonction qui sert à remapper les parties sauvegardées derriere les
// fenetres ouvertes. C'est utilisé par exemple par la fenetre de palette
// Qui remappe des couleurs, afin de propager les changements.
void Remappe_fond_fenetres(byte * Table_de_conversion, int Min_Y, int Max_Y)
{
  int Indice_fenetre; 
        byte* EDI;
        int dx,cx;
  for (Indice_fenetre=0; Indice_fenetreMax_Y)
            return;
          if (dx+Pile_Fenetre_Pos_Y[Indice_fenetre]0;cx--)
                {
                        *EDI = Table_de_conversion[*EDI];
                        EDI ++;
                }
        }
  }
}