/******************************************
*
* 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 <unistd.h>
Display *display;
Window win;
Colormap clm;
GC graphic_context;
Pixmap Screen_Save;
XImage Screen_Mem;
XFontStruct *fd;
XGCValues gcv;
long Current_FGColor, Current_BGColor;
int Graph_Opened = 0;
int winX, winY, winHeight, winWidth;
char BitDepth;
long 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;
}
void SetColor (char *nom)
{
Current_FGColor = GetColor (nom);
XSetForeground (display, graphic_context, Current_FGColor);
}
void SetBkColor (char *nom)
{
Current_BGColor = GetColor (nom);
XSetBackground (display, graphic_context, Current_BGColor);
}
void PutPixel (int x, int y)
{
XDrawPoint (display, Screen_Save, graphic_context, x, y);
XDrawPoint (display, win, graphic_context, x, y);
}
void DrawLine (int x1, int y1, int x2, int y2)
{
XDrawLine (display, Screen_Save, graphic_context, x1, y1, x2, y2);
XDrawLine (display, win, graphic_context, x1, y1, x2, y2);
}
void DrawRectangle (int x, int y, int width, int height)
{
XDrawRectangle (display, Screen_Save, graphic_context, x, y, width, height);
XDrawRectangle (display, win, graphic_context, x, y, width, height);
}
void DrawArc (int x, int y, int a, int b, int debut, int fin)
{
XDrawArc (display, Screen_Save, graphic_context, x - a, y - b, 2 * a, 2 * b,
debut * 64, fin * 64);
XDrawArc (display, win, graphic_context, x - a, y - b, 2 * a, 2 * b,
debut * 64, fin * 64);
}
void DrawCircle (int x, int y, int r)
{
XDrawArc (display, Screen_Save, graphic_context, x - r, y - r, 2 * r, 2 * r,
0, 360 * 64);
XDrawArc (display, win, graphic_context, x - r, y - r, 2 * r, 2 * r, 0,
360 * 64);
}
void DrawString (int x, int y, char *s)
{
XDrawString (display, Screen_Save, graphic_context, x, y, s, strlen (s));
XDrawString (display, win, graphic_context, x, y, s, strlen (s));
}
void DrawImageString (int x, int y, char *s)
{
XDrawImageString (display, Screen_Save, graphic_context, x, y, s,
strlen (s));
XDrawImageString (display, win, graphic_context, x, y, s, strlen (s));
}
void FillRectangle (int x, int y, int width, int height)
{
XFillRectangle (display, Screen_Save, graphic_context, x, y, width, height);
XFillRectangle (display, win, graphic_context, x, y, width, height);
}
void ClearGraph ()
{
XSetForeground (display, graphic_context, Current_BGColor);
FillRectangle (0, 0, winWidth, winHeight);
XSetForeground (display, graphic_context, Current_FGColor);
XClearWindow (display, win);
}
void FillArc (int x, int y, int a, int b, int debut, int fin)
{
XFillArc (display, Screen_Save, graphic_context, x - a, y - b, 2 * a, 2 * b,
debut * 64, fin * 64);
XFillArc (display, win, graphic_context, x - a, y - b, 2 * a, 2 * b,
debut * 64, fin * 64);
}
void FillCircle(int x,int y,int r)
{
FillArc(x,y,r,r,0,360);
}
/*
* typedef struc {
* short x,y;
* } XPoint;
*
*/
void FillPolygon (XPoint * points, int npoints, int shape, int mode)
{
XFillPolygon (display, Screen_Save, graphic_context, points, npoints, shape,
mode);
XFillPolygon (display, win, graphic_context, points, npoints, shape, mode);
}
void 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 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 SetColorByIndex (int i)
{
XSetForeground (display, graphic_context, i);
}
void 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 OpenGraph (int x, int y, int width, int height, char *fgcolor, char *bgcolor,
char colmap_create)
{
unsigned short i;
XEvent e;
XSetWindowAttributes xsw;
XColor xcolor;
XWindowAttributes xwa;
XSizeHints hint;
XWMHints Shint;
if (Graph_Opened == 0)
{
printf ("Opening connexion \n");
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);
Screen_Save =
XCreatePixmap (display, RootWindow (display, DefaultScreen (display)),
width, height, BitDepth);
xsw.background_pixmap = Screen_Save;
xsw.border_pixel = BlackPixel (display, DefaultScreen (display));
printf ("Creating window\n");
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);
printf ("Creating color map\n");
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;
};
}
}
printf ("looking for Foreground and Background \n");
Current_FGColor = GetColor (fgcolor);
Current_BGColor = GetColor (bgcolor);
printf ("creating graphic context \n");
gcv.font = fd->fid;
gcv.foreground = Current_FGColor;
gcv.background = Current_BGColor;
graphic_context =
XCreateGC (display, win, GCFont | GCForeground | GCBackground, &gcv);
ClearGraph ();
XSetStandardProperties (display, win, "Etat processeur",
"Etat processeur", None, NULL, 0, &hint);
XSetWMHints (display, win, &Shint);
XMapWindow (display, win);
Graph_Opened = 1;
XSelectInput (display, win, ExposureMask);
XNextEvent (display, &e);
return 0;
}
}
void 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, 0x9BBB);
/*printf("creation fichier OK\n"); */
img = XGetImage (display, Screen_Save, x, y, width, height, 0xFF, ZPixmap); /* are you sure? */
/*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 Flush ()
{
XSync (display, 0);
}
void ClearEvents ()
{
XSync (display, 1);
}
void Redraw ()
{
XCopyArea (display, Screen_Save, win, graphic_context, 0, 0, winWidth,
winHeight, 0, 0);
XRaiseWindow (display, win);
XSync (display, 0);
}
char OpenGraphBW (int x, int y, int width, int height)
{
return OpenGraph (x, y, width, height, "#000000", "#FFFFFF", 0);
}
void CloseGraph ()
{
if (Graph_Opened)
{
Graph_Opened = 0;
XFreeFont (display, fd);
XFreePixmap (display, Screen_Save);
XDestroyWindow (display, win);
XCloseDisplay (display);
}
}
void WaitLClick ()
{
XEvent e;
XSelectInput (display, win, ButtonReleaseMask);
for (;;)
{
XNextEvent (display, &e);
if (e.type == ButtonRelease)
{
if (e.xbutton.button == Button1)
return;
else
Redraw ();
}
}
}
void WaitMClick ()
{
XEvent e;
XSelectInput (display, win, ButtonReleaseMask);
for (;;)
{
XNextEvent (display, &e);
if (e.type == ButtonRelease)
{
if (e.xbutton.button == Button2)
return;
else
Redraw ();
}
}
}
void WaitRClick ()
{
XEvent e;
XSelectInput (display, win, ButtonReleaseMask);
for (;;)
{
XNextEvent (display, &e);
if (e.type == ButtonRelease)
{
if (e.xbutton.button == Button3)
return;
else
Redraw ();
}
}
}
char MouseClick (int L, int M, int R)
{
XEvent e;
int clickOK;
char res = 0;
XSelectInput (display, win, ButtonReleaseMask);
clickOK = XCheckWindowEvent (display, win, ButtonReleaseMask, &e);
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;
}
void WaitClick (int L, int M, int R)
{
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))
return;
else
Redraw ();
}
}
}