Logo Search packages:      
Sourcecode: jered version File versions  Download package

ecran.c

/**********************************************************************/
/* ECRAN.C : Tous les affichages et les saisies bas niveau de JERED   */
/**********************************************************************/

/*
    Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    Ce programme fait partie du package JERED et est soumis, comme le
    reste du package JERED, a la Gnu General Public License version 2
    ou superieure dont voici un extrait et dont vous pouvez lire
    la totalite en consultant le fichier COPYING.

    This program 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; either version 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/

#if HAVE_STRTOL == 0
#error  This program needs a library containing the 'strtol()' function
#endif

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
#include <term.h>
#include "jered.h"
#include "formulr.h"
#include "mappable.h"
#include "messages.h"

static int oldcursor = 0;       /* ancienne valeur du curseur */
static int firstcursor = 0;     /* premier curseur au debut de l'appli */
static int rafraichir = 1;      /* par defaut on rafraichit */

int reentrant = 0;
int resizewin = 0;

int readakey_fromkeyboard(void);
void restart_screen(int sig);
/**********************************************************************/
void getscreensize(void)
{
        struct winsize size;
        
        if (isatty(cur_term->Filedes))
        {
        
                errno = 0;
                do
                {
                        if ((ioctl(cur_term->Filedes, TIOCGWINSZ, &size) < 0) && (errno != EINTR))
                                goto failure;
                } 
                while (errno == EINTR);
        
                JEREDLINES = (int)size.ws_row;
                JEREDCOLS  = (int)size.ws_col;
        }
        else
        {
failure:        
                JEREDLINES = LINES;
                JEREDCOLS = COLS;
        }
        
        XMAX = (JEREDCOLS - 1);
        YMAX = (JEREDLINES - 2);
}
/**********************************************************************/
void restart_screen(int sig)
{
        if (inputmode == DIALOGMODE)
                resizewin = 1;
        else
                restart_screen_again();
                
        signal(SIGWINCH, restart_screen);
}
/**********************************************************************/
void restart_screen_again(void)
{
        function_redraw(NULL, NULL, 0);
        resizewin = 0;
}
/**********************************************************************/
void debute_ecran(void)
{
        initscr();              /* initialise curses */
        start_color();          /* initialise la gestion des couleurs */

        noecho();               /* n'affiche pas les caracteres lus par getch */
        nonl();
        keypad(stdscr, TRUE);   /* autorise les touches speciales du terminal a etre renvoyees telles quelles (ex: F1..F10) */
        meta(stdscr, TRUE);     /* autorise le terminal a renvoyer des valeurs de 8 bits au lieu de 7 */
        nodelay(stdscr, FALSE);
        idlok(stdscr, FALSE);   /* interdit les insertions/suppressions de ligne */
        scrollok(stdscr, FALSE); /* interdit le scrolling automatique */
        
        /* patch from Antti K. Barck - proff@iki.fi */
        raw();                  /* forbid special characters like Ctr_Z Ctrl_S etc... */
        
        firstcursor = allume_curseur(0);        /* sauve valeur du curseur et l'eteint */
        oldcursor = firstcursor;

        getscreensize();
        
        signal(SIGWINCH, restart_screen);
}
/**********************************************************************/
void termine_ecran(void)
{
        clr_scr();                      /* efface l'ecran */
        allume_curseur(firstcursor);    /* remet le curseur d'origine */
        endwin();                       /* termine l'utilisation de curses */
}
/**********************************************************************/
int allume_curseur(int type)
{
        /* it seems that curs_set doesn't work like expected */
        oldcursor = curs_set(type);
        if (oldcursor == ERR)
                oldcursor = 1;
        return(oldcursor);
}
/**********************************************************************/
void eteint_curseur(void)
{
        /* it seems that curs_set doesn't work like expected */
        oldcursor = curs_set(0);
        if (oldcursor == ERR)
                oldcursor = 1;
}
/**********************************************************************/
void restaure_curseur(void)
{
        /* it seems that curs_set doesn't work like expected */
        oldcursor = curs_set(oldcursor);
        if (oldcursor == ERR)
                oldcursor = 1;
}
/**********************************************************************/
void clr_scr(void)
{
        clear();        /* efface l'ecran */
        refresh();      /* validation */
}
/**********************************************************************/
int set_refresh(int on_off)
{
        int old;

        old = rafraichir;
        rafraichir = on_off;
        return(old);
}
/**********************************************************************/
int get_refresh(void)
{
        return(rafraichir);
}
/**********************************************************************/
int get_txt(int x, int y, int xmax, int ymax, chtype *dest)
{
        int sauvex;             /* sauve abscisse */
        int sauvey;             /* sauve ordonnee */
        int lg;                 /* longueur */

        xmax = min(xmax, (JEREDCOLS - 1));
        ymax = min(ymax, (JEREDLINES - 1));
        if ((x > xmax) || (x < 0) || (y > ymax) || (y < 0))
                return(-1);
        else
        {
                getyx(stdscr, sauvey, sauvex);  /* sauve la position du curseur */
                lg = xmax - x + 1;
                while (y <= ymax)
                {
#if HAVE_LIBNCURSES                
                        mvwinchnstr(stdscr, y, x, dest, lg);
                        dest += lg;
#else                        
                        for (lg = x; lg <= xmax; lg++)
                        {
                                move(y, lg);
                                *dest++ = inch();
                        }
#endif /* HAVE_LIBNCURSES */                        
                        y++;
                }
                move(sauvey, sauvex);           /* restitue la position du curseur */

                if (rafraichir)
                        refresh();      /* n'est ce pas inutile ? */

                return(0);
        }
}
/**********************************************************************/
int put_txt(int x, int y, int xmax, int ymax, chtype *src)
{
        int sauvex;             /* sauve abscisse */
        int sauvey;             /* sauve ordonnee */
        int lg;                 /* longueur */

        xmax = min(xmax, (JEREDCOLS - 1));
        ymax = min(ymax, (JEREDLINES - 1));
        if ((x > xmax) || (x < 0) || (y > ymax) || (y < 0))
                return(-1);
        else
        {
                getyx(stdscr, sauvey, sauvex);  /* sauve la position du curseur */
                lg = xmax - x + 1;
                while (y <= ymax)
                {
#if HAVE_LIBNCURSES /* il y a NCURSES */
                        mvwaddchnstr(stdscr, y, x, src, lg); /* copie les lg chtype a partir de src */
                        src += lg;
#else
                        for (lg = x; lg <= xmax; lg++)
                        {
                                move(y, lg);
                                addch(*src);
                                src++;
                        }
#endif /* HAVE_LIBNCURSES */
                        y++;
                }
                move(sauvey, sauvex);           /* restitue la position du curseur */

                if (rafraichir)
                        refresh();

                return(0);
        }
}
/**********************************************************************/
void scrollup(int ymin, int ymax)
{
        chtype *sauve;  /* sauve pointeur sur la premiere ligne */
        chtype *ptfin;  /* pointeur sur fin de ligne */

#if HAVE_LIBNCURSES /* il y a NCURSES */
        struct ldat *pl; /* pointeur vers ligne courante; */
        struct ldat *pf; /* pointeur vers derniere ligne */

        pl = &stdscr->_line[ymin];
        pf = &stdscr->_line[ymax];
        sauve = pl->text;
        while (pl != pf)
        {
                pl->text = (pl + 1)->text;
                pl->firstchar = 0;
                pl->lastchar = XMAX;
                pl++;
        }
        pl->text = sauve;
        pl->firstchar = 0;
        pl->lastchar = XMAX;
#else
        int l;

        sauve = stdscr->_y[ymin];
        for (l = ymin; l < ymax; l++)
        {
                stdscr->_y[l] = stdscr->_y[l + 1];
                stdscr->_firstch[l] = (short)0;
                stdscr->_lastch[l] = (short)XMAX;
        }
        stdscr->_y[l] = sauve;
        stdscr->_firstch[l] = (short)0;
        stdscr->_lastch[l] = (short)XMAX;
#endif  /* HAVE_LIBNCURSES */

        ptfin = sauve + XMAX;
        while (sauve <= ptfin)
                *sauve++ = (chtype)' ' | couleur[COULEUR_NORMALE];

        if (rafraichir)
                refresh();
}
/**********************************************************************/
void scrolldown(int ymin, int ymax)
{
        chtype *sauve;  /* sauve pointeur sur la derniere ligne */
        chtype *ptfin;  /* pointeur sur fin de ligne */

#if HAVE_LIBNCURSES /* il y a NCURSES */
        struct ldat *pl; /* pointeur vers ligne courante; */
        struct ldat *pd; /* pointeur vers premiere ligne */

        pl = &stdscr->_line[ymax];
        pd = &stdscr->_line[ymin];
        sauve = pl->text;
        while (pl != pd)
        {
                pl->text = (pl - 1)->text;
                pl->firstchar = 0;
                pl->lastchar = XMAX;
                pl--;
        }
        pl->text = sauve;
        pl->firstchar = 0;
        pl->lastchar = XMAX;
#else
        int l;

        sauve = stdscr->_y[ymax];
        for (l = ymax; l > ymin; l--)
        {
                stdscr->_y[l] = stdscr->_y[l - 1];
                stdscr->_firstch[l] = (short)0;
                stdscr->_lastch[l] = (short)XMAX;
        }
        stdscr->_y[l] = sauve;
        stdscr->_firstch[l] = (short)0;
        stdscr->_lastch[l] = (short)XMAX;
#endif  /* HAVE_LIBNCURSES */

        ptfin = sauve + XMAX;
        while (sauve <= ptfin)
                *sauve++ = (chtype)' ' | couleur[COULEUR_NORMALE];

        if (rafraichir)
                refresh();
}
/**********************************************************************/
void put_statligne(int x, int y, char *texte, chtype attrib)
{
        chtype buffer[256];        /* buffer pour construire ecran */
        chtype *ptw;               /* pointeur sur ce buffer */

        /* cree la ligne et la complete avec des espaces */
        ptw = buffer;
        if (texte != NULL)
        {
                while (*texte)
                        *ptw++ = (chtype)(unsigned char)*texte++ | attrib;
        }
        while (ptw < buffer + JEREDCOLS)
                *ptw++ = (chtype)' ' | attrib;

        put_txt(x, y, (JEREDCOLS - 1), y, buffer);
}
/**********************************************************************/
void put_helpline(int x, int y, char *texte, chtype attrib)
{
        chtype buffer[256];        /* buffer pour construire ecran */
        chtype *ptw;               /* pointeur sur ce buffer */
        chtype a;

        /* cree la ligne et la complete avec des espaces */
        ptw = buffer;
        if (texte != NULL)
        {
                while (*texte)
                {
                        /* a very nice idea from Antti K. Barck <proff@iki.fi> */
                        a = attrib;
                        if (*texte == '&')
                        {
                                texte++;
                                if (*texte != '&')
                                        a = couleur[COULEUR_SURBRILLANCE];
                        }
                        *ptw++ = (chtype)(unsigned char)*texte++ | a;
                }
        }
        while (ptw < buffer + JEREDCOLS)
                *ptw++ = (chtype)' ' | attrib;

        put_txt(x, y, (JEREDCOLS - 1), y, buffer);
}
/**********************************************************************/
void print_ligne(LIGNE *courante, int y, char *texte, int decalage)
{
        chtype buffer[SZBUF + 2];
        chtype *ptw;
        chtype coul;

        if ((courante != NULL) && (courante->debut_marque != NOTMARKED))
                coul = couleur[COULEUR_BLOC];
        else
                coul = couleur[COULEUR_NORMALE];

        ptw = buffer;
        if (texte != NULL)
        {
                while (*texte)
                        *ptw++ = (chtype)(unsigned char)*texte++ | coul;
        }
        while (ptw <= buffer + JEREDCOLS + decalage)
                *ptw++ = (chtype)' ' | coul;

        put_txt(XMIN, y, XMAX, y, buffer + decalage);
}
/**********************************************************************/
int readakey_fromkeyboard(void)
{
        static int wanttoflush = 1;
        int key;

        /* if we want to flush keyboard entries, we do it */
        if (wanttoflush)
                flushinp();

        /* we read a key */
        key = wgetch(stdscr);

        /* if it is ESCAPE, we don't want to flush before reading the next key */
        if (key == KEY_ESCAPE)
                wanttoflush = 0;
        else    /* otherwise we want to flush */
                wanttoflush = 1;

        return(key);
}
/**********************************************************************/
int fread_key(void)
{
        static int pending = 0;
        static char *ptpending;
        static char *ptbegline;
        static char bufmac[SZBUF + 2];
        static int esckey = NOTFOUND;
        int key;                        /* touche appuyee */
        char *ptr;

        /* we don't allow to play a macro when typing a macro name to save one macro */
        if ((! reentrant) && (macro == PLAYING))
        {
                if (! pending)
                {
read_a_new_line:
                        ptbegline = fgets(bufmac, SZBUF, fmacro);
                        if (ptbegline == NULL)
                        {
end_of_file:
                                /* le fichier macro est fini */
                                fclose(fmacro);
                                fmacro = NULL;
                                macro = RECORDED;

                                ptbegline = ptpending = NULL;

                                /* on lit la prochaine touche au clavier */
                                goto lire_clavier; /* pas elegant !!! */
                        }
                        else
                        {
                                ptr = ptpending = ptbegline;
                                while (*ptr)
                                        ptr++;
                                ptr--;
                                if ((ptr >= ptbegline) && (*ptr == '\n'))
                                        *ptr = '\0';    /* we ensure we have no '\n' at the end of the line */
                                pending = 1; /* we must work with the line we have just read */
                        }
                }
                if (pending)
                {
                        if (! strncasecmp(ptbegline, "KEY_", 4))
                        {
                                /* normally only in DIALOGMODE mode */
                                /* but we can allow people to add this directly to existing macros */
                                key = (int)strtol(ptbegline + 4, (char **)NULL, 16);
                                pending = 0;
                        }
                        else if (! strncasecmp(ptbegline, "TEXT_", 5))
                        {
                                if (ptpending == ptbegline)
                                        ptpending = ptbegline + 5;
                                if (*ptpending)
                                        key = (int)(unsigned int)(unsigned char)*ptpending++;
                                else
                                {
                                        pending = 0;
                                        goto read_a_new_line; /* PLEASE, PLEASE, EXCUSE ME !!! */
                                }
                        }
                        else if (! strncasecmp(ptbegline, "FUNCTION_", 9))
                        {
                                /* if esckey is already existing, we just return its value */
                                if (esckey != NOTFOUND)
                                {
                                        key = esckey;
                                        esckey = NOTFOUND;
                                        pending = 0;
                                }
                                else
                                {
                                        /* now the most important job is to find the */
                                        /* key with which this function is mapped, if any */
                                        /* the difficulty is the escape key that we must return first */
                                        key = lookup_keymap(ptbegline, 0); /* normal keys table */
                                        if (key == NOTFOUND)
                                        {
                                                key = lookup_keymap(ptbegline, 1); /* escape keys table */
                                                esckey = key;
                                                if (key != NOTFOUND)
                                                        key = KEY_ESCAPE;
                                                else
                                                        pending = 0;
                                        }
                                        else
                                                pending = 0;
                                        if (key == NOTFOUND)
                                        {
                                                /* the function needed is not mapped to any key */
                                                /* so we can't execute it until we have mapped */
                                                /* it to some non available key !!! */
                                                demap_keymax();
                                                mapkeyindextofuncmactxt(KEY_MAX, ptbegline);
                                                key = KEY_MAX;
                                                pending = 0;
                                        }
                                }
                        }
                        else    /* HOPEFULLY THIS WILL NEVER HAPPEN */
                        {
                                erreur(message[MSG_MACRO_CORRUPTED], NULL);
                                pending = 0; /* small bug correction */
                                goto end_of_file; /* we assume the macro file is ended */
                        }
                }
        }
        else
        {
lire_clavier:
                key = readakey_fromkeyboard();
                if ((inputmode == DIALOGMODE) && (macro == RECORDING) && (fmacro != NULL))
                        fprintf(fmacro, "KEY_0x%04x\n", key);
        }
        return(key);
}
/**********************************************************************/

Generated by  Doxygen 1.6.0   Back to index