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