Page d'accueil Description du projet
/******************************************
 *
 *   Cedric Pradalier   2001
 *   mail : http://cedric.pradalier.free.fr/mail.html
 *
 *****************************************/

/* Creation d'une librairie pour faciliter les acces aux fenetres graphiques
   Compilation avec :
   graphic_contextc -lX11 -lsocket <nom_fichier>
   -lsocket : particularite du Sun apparement

 */


#include "X11/Xlib.h"
#include "X11/Xutil.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include "libX+.h"
#include <unistd.h>


// #define DEBUG

XWin::XWin ()
{
    Current_FGColor = Current_FGColor = 0;
    Current_LineStyle = LSolid;
    Current_LineWidth = 1;
    Graph_Opened = false;
    OpenGraphBW (100, 100, 100, 100, "Graphic Window");
}

XWin::XWin (int width, int height, char *title)
{
    Current_FGColor = Current_FGColor = 0;
    Current_LineStyle = LSolid;
    Current_LineWidth = 1;
    Graph_Opened = false;
    OpenGraphBW (0, 0, width, height, title);
}

XWin::XWin (int x, int y, int width, int height, char *title)
{
    Current_FGColor = Current_FGColor = 0;
    Current_LineStyle = LSolid;
    Current_LineWidth = 1;
    Graph_Opened = false;
    OpenGraphBW (x, y, width, height, title);
}

XWin::XWin (int width, int height, char *title,
        char * foreground,char * background)
{
    Current_FGColor = Current_FGColor = 0;
    Current_LineStyle = LSolid;
    Current_LineWidth = 1;
    Graph_Opened = false;
    OpenGraph (0, 0, width, height, foreground,background,0, title);
}


XWin::XWin (int x,int y,int width, int height, char *title,
        char * foreground,char * background)
{
    Current_FGColor = Current_FGColor = 0;
    Current_LineStyle = LSolid;
    Current_LineWidth = 1;
    Graph_Opened = false;
    OpenGraph (x, y, width, height, foreground,background,0, title);
}



XWin::~XWin ()
{
    CloseGraph ();
}


    long
XWin::RGBGetColor (int red, int green, int blue)
{
    XColor
        xc;
    xc.blue = blue;
    xc.red = red;
    xc.green = green;
    xc.flags = DoRed | DoGreen | DoBlue;
    if (XAllocColor
            (display, DefaultColormap (display, DefaultScreen (display)), &xc) == 0)
        xc.pixel = WhitePixel (display, DefaultScreen (display));
    return xc.pixel;
}

    long
XWin::GetColor (char *nom)
{
    XColor
        xc;

    if (XParseColor
            (display, DefaultColormap (display, DefaultScreen (display)), nom,
             &xc) == 0)
        xc.pixel = WhitePixel (display, DefaultScreen (display));
    if (XAllocColor
            (display, DefaultColormap (display, DefaultScreen (display)), &xc) == 0)
        xc.pixel = WhitePixel (display, DefaultScreen (display));
    //printf("couleur %s : %x",nom,xc.pixel);
    return xc.pixel;
}


int LStyleToXLStyle(XWin::LineStyle ls)
{
    switch (ls)
    {
        case XWin::LDash : return LineOnOffDash;
        case XWin::LSolid : 
        default : return LineSolid;
    }
}


void XWin::SetLineWidth(int width)
{
    if (width < 1) return;
    Current_LineWidth = width;
    XSetLineAttributes(display, graphic_context, Current_LineWidth,
            LStyleToXLStyle(Current_LineStyle),CapRound,JoinRound);
}


void XWin::SetLineStyle(XWin::LineStyle ls)
{
    Current_LineStyle = ls;
    XSetLineAttributes(display, graphic_context, Current_LineWidth,
            LStyleToXLStyle(Current_LineStyle),CapRound,JoinRound);
}




    void
XWin::SetColor (char *nom)
{
    Current_FGColor = GetColor (nom);
    XSetForeground (display, graphic_context, Current_FGColor);
}

    void
XWin::SetBkColor (char *nom)
{
    Current_BGColor = GetColor (nom);
    XSetBackground (display, graphic_context, Current_BGColor);

}

    void
XWin::RGBSetColor (int red, int green, int blue)
{
    Current_FGColor = RGBGetColor (red, green, blue);
    XSetForeground (display, graphic_context, Current_FGColor);
}

    void
XWin::RGBSetBkColor (int red, int green, int blue)
{
    Current_BGColor = RGBGetColor (red, green, blue);
    XSetBackground (display, graphic_context, Current_BGColor);

}


    void
XWin::PutPixel (int x, int y)
{
    XDrawPoint (display, DrawingScreen, graphic_context, x, y);
}

    void
XWin::DrawLine (int x1, int y1, int x2, int y2)
{
    XDrawLine (display, DrawingScreen, graphic_context, x1, y1, x2, y2);
}

    void
XWin::DrawRectangle (int x, int y, int width, int height)
{
    XDrawRectangle (display, DrawingScreen, graphic_context, x, y, width, height);
}

    void
XWin::DrawArc (int x, int y, int a, int b, int debut, int fin)
{
    XDrawArc (display, DrawingScreen, graphic_context, x - a, y - b, 2 * a, 2 * b,
            debut * 64, fin * 64);
}


    void
XWin::DrawCircle (int x, int y, int r)
{
    XDrawArc (display, DrawingScreen, graphic_context, x - r, y - r, 2 * r, 2 * r, 0,
            360 * 64);
}


    void
XWin::DrawString (int x, int y, char *s)
{
    XDrawString (display, DrawingScreen, graphic_context, x, y, s, strlen (s));
}


    void
XWin::DrawImageString (int x, int y, char *s)
{
    XDrawImageString (display, DrawingScreen, graphic_context, x, y, s, strlen (s));
}


    void
XWin::FillRectangle (int x, int y, int width, int height)
{
    XFillRectangle (display, DrawingScreen, graphic_context, x, y, width, height);
}

    void
XWin::ClearGraph ()
{
    XSetForeground (display, graphic_context, Current_BGColor);
    FillRectangle (0, 0, winWidth, winHeight);
    XSetForeground (display, graphic_context, Current_FGColor);
    //  XClearWindow (display, DrawingScreen);
}

    void
XWin::FillCircle (int x, int y, int r)
{
    XFillArc (display, DrawingScreen, graphic_context, x - r, 
            y - r, 2 * r, 2 * r, 0, 360 * 64);
}


    void
XWin::FillArc (int x, int y, int a, int b, int debut, int fin)
{
    XFillArc (display, DrawingScreen, graphic_context, x - a, y - b, 2 * a, 2 * b,
            debut * 64, fin * 64);
}



    void
XWin::FillPolygon (XPoint * points, int npoints, int shape, int mode)
{
    XFillPolygon (display, DrawingScreen, graphic_context, points, npoints, shape, mode);
}



    void
XWin::DrawTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
{
    DrawLine (x1, y1, x2, y2);
    DrawLine (x2, y2, x3, y3);
    DrawLine (x3, y3, x1, y1);
}


    void
XWin::FillTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
{
    XPoint
        liste[] = { {x1, y1}, {x2, y2}, {x3, y3} };
    FillPolygon (liste, 3, Convex, CoordModeOrigin);
}


    void
XWin::SetColorByIndex (int i)
{
    XSetForeground (display, graphic_context, i);
}


    void
XWin::StoreColor (int red, int green, int short blue, int position)
{
    XColor
        xc;
    xc.red = red;
    xc.green = green;
    xc.blue = blue;
    xc.pixel = position;
    xc.flags = DoRed | DoGreen | DoBlue;
    if (XStoreColor (display, clm, &xc) == 0)
    {
        printf ("Unable to create colormap \n");
        exit (1);
    };
}







char
XWin::OpenGraph (int x, int y, int width, int height, char *fgcolor,
        char *bgcolor, bool colmap_create, char *title)
{
    unsigned short
        i;
    XEvent
        e;
    XSetWindowAttributes
        xsw;
    XColor
        xcolor;
    XWindowAttributes
        xwa;
    XSizeHints
        hint;
    XWMHints
        Shint;


    if (!Graph_Opened)
    {
#ifdef DEBUG
        printf ("Opening connexion \n");
#endif
        hint.x = x;
        hint.y = y;
        Shint.initial_state = InactiveState;
        hint.width = width;
        hint.height = height;
        hint.flags = PPosition | PSize;
        Shint.flags = StateHint;

        winX = x;
        winY = y;
        winHeight = height;
        winWidth = width;
        if ((display = XOpenDisplay (getenv ("DISPLAY"))) == NULL)
        {
            fprintf (stderr, "Impossible de contacter le serveur\n");
            return 1;
        }


        BitDepth = DefaultDepth (display, DefaultScreen (display));
        //printf("color depth %d \n",BitDepth);
        DrawingScreen = 
            XCreatePixmap(display,RootWindow(display, DefaultScreen(display)),
                    width,height,BitDepth);

        Screen_Save =
            XCreatePixmap (display, RootWindow (display, DefaultScreen (display)),
                    width, height, BitDepth);



        xsw.background_pixmap = Screen_Save;
        xsw.border_pixel = BlackPixel (display, DefaultScreen (display));

#ifdef DEBUG
        printf ("Creating window\n");
#endif

        win =
            XCreateWindow (display, RootWindow (display, DefaultScreen (display)),
                    x, y, width, height, 2, BitDepth, InputOutput,
                    CopyFromParent, CWBackPixmap, &xsw);

        if ((fd = XLoadQueryFont (display, "fixed")) == NULL)
        {
            fprintf (stderr, "Impossible de charger la police fixed\n");
            return 2;
        }
        if (colmap_create)
        {
            //creation d'une palette perso
            XGetWindowAttributes (display, win, &xwa);
#ifdef DEBUG
            printf ("Creating color map\n");
#endif
            clm = XCreateColormap (display, win, xwa.visual, AllocAll);
            XSetWindowColormap (display, win, clm);
            xcolor.flags = DoRed | DoGreen | DoBlue;

            for (i = 0x00; i <= 0xFF; i++)
            {
                xcolor.pixel = i;
                XQueryColor (display,
                        DefaultColormap (display, DefaultScreen (display)),
                        &xcolor);
                if (XStoreColor (display, clm, &xcolor) == 0)
                {
                    printf ("Unable to create colormap \n");
                    return 3;
                };
            }
        }


#ifdef DEBUG
        printf ("looking for Foreground and Background \n");
#endif
        Current_FGColor = GetColor (fgcolor);
        Current_BGColor = GetColor (bgcolor);


#ifdef DEBUG
        printf ("creating graphic context \n");
#endif
        gcv.font = fd->fid;
        gcv.foreground = Current_FGColor;
        gcv.background = Current_BGColor;
        graphic_context =
            XCreateGC (display, win, GCFont | GCForeground | GCBackground, &gcv);

        ClearGraph ();
        SetLineStyle(LSolid);
        SetLineWidth(1);

        XSetStandardProperties (display, win, title, title, None, NULL, 0,
                &hint);
        XSetWMHints (display, win, &Shint);
        XMapWindow (display, win);
        Graph_Opened = true;
        XSelectInput (display, win, ExposureMask);
        XNextEvent (display, &e);
        return 0;
    }
    return 8;

}

    void
XWin::SaveImage (int x, int y, int width, int height, char *nom)
{
    int
        fhandle, i, j, k;
    XImage *
        img;
    XColor
        xc;
    const int
        size = 18 + 3 * width * (height);
    char
        cmap[3][256];
    char *
        fbuff;
    char
        buff[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            (char) width, (char) (width >> 8),
            (char) height, (char) (height >> 8),
            24, 0
        };
    fbuff = (char *) malloc (size);
    for (i = 0; i < 18; i++)
        fbuff[i] = buff[i];
    //printf("\ndefinition OK\n");
    for (i = 0; i < 256; i++)
    {
        xc.pixel = i;
        XQueryColor (display, clm, &xc);
        cmap[0][i] = (char) (xc.blue >> 8);
        cmap[1][i] = (char) (xc.green >> 8);
        cmap[2][i] = (char) (xc.red >> 8);
    }
    /*printf("Creation ColorMAP OK\n"); */

    fhandle = creat (nom, 0644);
    /*printf("creation fichier OK\n"); */
    img = XGetImage (display, Screen_Save, x, y, width, height, 0xFF, ZPixmap); 
    /*printf("creation image OK \n"); */
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            k = XGetPixel (img, j, height - i);
            fbuff[18 + (i * width + j) * 3] = cmap[0][k];
            fbuff[19 + (i * width + j) * 3] = cmap[1][k];
            fbuff[20 + (i * width + j) * 3] = cmap[2][k];
        }
    }
    write (fhandle, fbuff, size);
    free (fbuff);
    close (fhandle);
}

    void
XWin::Flush ()
{
    XSync (display, 0);
}

    void
XWin::ClearEvents ()
{
    XSync (display, 1);
}


void XWin::DisplayDrawingScreen()
{
    XCopyArea(display,DrawingScreen,win,graphic_context,0,0,
            winWidth,winHeight,0,0);
    XCopyArea(display,DrawingScreen,Screen_Save,graphic_context,0,0,
            winWidth,winHeight,0,0);
    //        XRaiseWindow(display,win);
    XSync(display,0);
}




    void
XWin::Redraw ()
{
    XCopyArea (display, Screen_Save, win, graphic_context, 0, 0, winWidth,
            winHeight, 0, 0);
    //  XRaiseWindow (display, win);
    XSync (display, 0);
}




    char
XWin::OpenGraphBW (int x, int y, int width, int height, char *title)
{
    return OpenGraph (x, y, width, height, "#000000", "#FFFFFF", false, title);
}

    void
XWin::CloseGraph ()
{
    if (Graph_Opened)
    {
        Graph_Opened = 0;
        XFreeFont (display, fd);
        XFreePixmap (display, Screen_Save);
        XFreePixmap (display, DrawingScreen);
        XFreeGC(display,graphic_context);
        XDestroyWindow (display, win);
        XCloseDisplay (display);
    }
}



    void
XWin::WaitLClick ()
{
    XEvent
        e;
#ifdef DEBUG
    printf ("Waiting...\n");
#endif
    XSelectInput (display, win, ButtonReleaseMask);
#ifdef DEBUG
    printf ("Waiting a button...\n");
#endif
    for (;;)
    {
        XNextEvent (display, &e);
        if (e.type == ButtonRelease)
        {
            if (e.xbutton.button == Button1)
                return;
            else
                Redraw ();
        }
    }
}


    void
XWin::WaitMClick ()
{
    XEvent
        e;
    XSelectInput (display, win, ButtonReleaseMask);
    for (;;)
    {
        XNextEvent (display, &e);
        if (e.type == ButtonRelease)
        {
            if (e.xbutton.button == Button2)
                return;
            else
                Redraw ();
        }
    }
}


    void
XWin::WaitRClick ()
{
    XEvent
        e;
    XSelectInput (display, win, ButtonReleaseMask);
    for (;;)
    {
        XNextEvent (display, &e);
        if (e.type == ButtonRelease)
        {
            if (e.xbutton.button == Button3)
                return;
            else
                Redraw ();
        }
    }
}

    char
XWin::MouseClick (int L, int M, int R)
{
    XEvent
        e;
    int
        clickOK;
    char
        res = 0;
#ifdef DEBUG
    printf ("Waiting...\n");
#endif
    XSelectInput (display, win, ButtonReleaseMask);
#ifdef DEBUG
    printf ("Waiting a button...\n");
#endif
    clickOK = XCheckWindowEvent (display, win, ButtonReleaseMask, &e);
#ifdef DEBUG
    printf ("An event ?\n");
#endif
    if (clickOK && (e.type == ButtonRelease))
    {
        if (L && (e.xbutton.button == Button1))
            res |= 4;
        if (M && (e.xbutton.button == Button2))
            res |= 2;
        if (R && (e.xbutton.button == Button3))
            res |= 1;
    }
    return res;
}





    char
XWin::WaitClick (int L, int M, int R)
{
    char res = 0;
    XEvent
        e;
    XSelectInput (display, win, ButtonReleaseMask);
    for (;;)
    {
        XNextEvent (display, &e);
        if (e.type == ButtonRelease)
        {
            if (((e.xbutton.button == Button1) && L) ||
                    ((e.xbutton.button == Button2) && M) ||
                    ((e.xbutton.button == Button3) && R))
            {
                if (L && (e.xbutton.button == Button1))
                    res |= 4;
                if (M && (e.xbutton.button == Button2))
                    res |= 2;
                if (R && (e.xbutton.button == Button3))
                    res |= 1;
                return res;
            }
            else
                Redraw ();
        }
    }
    return 0;
}

/*
   int main()
   {
   printf("Au moins ca compile\n");
   }
 */



/* A faire

#ClearWindow
#SetColor
#SetBkColor
#PutPixel
GetPixel
#DrawLine
#DrawCircle
#DrawRectangle
#DrawArc
#DrawString
#DrawImageString
#FillRectangle
FillArc




 */