TD X-Window numero 2: graphe.c
#include <stdio.h>
#include <X11/Xlib.h>
#include "graphe.h"
#define FONT "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1"
main(argc, argv)
int argc;
char **argv;
{
Display *dpy;
Window win;
GC draw_gc; /* GC to draw with */
GC fill_gc; /* GC to fill with */
GC xor_gc; /* GC to draw in xor mode */
XFontStruct *fontstruct; /* Font descriptor */
XGCValues gcv; /* Struct for creating GC */
Node selected_node = 0;
Edge related_edges = 0;
int drawing = 0;
int mouse_offset_x, mouse_offset_y;
/* on lit le graphe */
Graph graph = ReadGraph(stdin);
/* on ouvre une connection avec le serveur X */
if ((dpy = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], XDisplayName(NULL));
exit(1);
}
/* on charge une police pour les labels */
if ((fontstruct = XLoadQueryFont(dpy, FONT)) == NULL) {
fprintf(stderr, "%s: display %s doesn't know font %s\n",
argv[0], DisplayString(dpy), FONT);
exit(1);
}
/* on calcule la taille des noeuds pour la police chargee */
FixGraphLabelDimensions(dpy, graph, fontstruct->fid);
/* on cree une fenetre */
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
100, 100, 300, 200,
1, BlackPixel(dpy, DefaultScreen(dpy)),
WhitePixel(dpy, DefaultScreen(dpy)));
XStoreName(dpy, win, graph->title);
XSelectInput(dpy, win, ExposureMask
| ButtonPressMask | ButtonReleaseMask
| Button1MotionMask);
XMapWindow(dpy, win);
/* on cree les 3 gc : fill_gc, draw_gc, xor_gc */
gcv.font = fontstruct->fid;
gcv.foreground = WhitePixel(dpy, DefaultScreen(dpy));
gcv.background = BlackPixel(dpy, DefaultScreen(dpy));
fill_gc = XCreateGC(dpy, win,
(GCFont | GCForeground | GCBackground), &gcv);
gcv.foreground = BlackPixel(dpy, DefaultScreen(dpy));
gcv.background = WhitePixel(dpy, DefaultScreen(dpy));
draw_gc = XCreateGC(dpy, win,
(GCFont | GCForeground | GCBackground), &gcv);
gcv.function = GXxor;
xor_gc = XCreateGC(dpy, win,
(GCFunction | GCForeground | GCBackground), &gcv);
/* on gere les evenements X */
while (1) {
XEvent event;
XNextEvent(dpy, &event);
/* expose */
if (event.type == Expose && event.xexpose.count == 0) {
XClearWindow(dpy, win);
DisplayGraph(graph, dpy, win, draw_gc, fill_gc);
} else if (event.type == ButtonPress) { /* appui bouton */
/* bouton 1 = move */
if (event.xbutton.button == Button1) {
selected_node =
FindNode(graph, event.xbutton.x, event.xbutton.y);
if (selected_node) {
mouse_offset_x = event.xbutton.x - selected_node->x;
mouse_offset_y = event.xbutton.y - selected_node->y;
related_edges = RelatedEdges(graph, selected_node);
}
/* bouton 2 = print graph */
} else if (event.xbutton.button == Button2) {
PrintGraph(graph, stdout);
/* bouton 3 = quit */
} else if (event.xbutton.button == Button3) {
exit(0);
}
/* release bouton = redisplay */
} else if (event.type == ButtonRelease &&
event.xbutton.button == Button1
&& selected_node) {
drawing = 0;
XClearWindow(dpy, win);
DisplayGraph(graph, dpy, win, draw_gc, fill_gc);
FreeEdges(related_edges);
/* mouse tracking */
} else if (event.type == MotionNotify && selected_node) {
if (drawing) { /* erase old */
DisplayNode(selected_node, dpy, win, xor_gc, 0);
DisplayEdges(related_edges, dpy, win, xor_gc);
} else {
drawing = 1;
}
/* calculate new */
selected_node->x = event.xmotion.x - mouse_offset_x;
selected_node->y = event.xmotion.y - mouse_offset_y;
/* draw new */
DisplayNode(selected_node, dpy, win, xor_gc, 0);
DisplayEdges(related_edges, dpy, win, xor_gc);
}
}
}
michel.buffa@essi.fr