/******************************************
*
* 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
*/