/~platosin/source/pain/lab1/draw.cpp

źrodło - ostatnia modyfikacja: Mon, 18 Oct 2010 13:02:11 +0200

/*
	kompilacja galera
	g++ draw.cpp -I /usr/X11R6/include -L /usr/X11R6/lib64 -lX11
*/
 
#include <X11/Xlib.h>
#include <unistd.h>
#include <cstdlib>
 
class Line
{
public:
    int x1;
    int y1;
    int x2;
    int y2;    
    Line * next;
    Line()    
    {
        x1 = y1 = x2 = y2 = 0;
        next = NULL;
    }
    void draw( Display * display, Window window, GC gc )
    {
        XDrawLine( display, window, gc, x1, y2, x2, y1 );
        XDrawLine( display, window, gc, x1, y1, x2, y2 );
    }
};
 
main()
{
    Line * lines = NULL;
    // Open the display
    Display *dpy = XOpenDisplay( NULL );
    Display *dpy2 = XOpenDisplay( "p139-nt04:0.0" );
    // Get some colors
    int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
    int blackColor2 = BlackPixel(dpy2, DefaultScreen(dpy2));
    int whiteColor2 = WhitePixel(dpy2, DefaultScreen(dpy2));
    // Create the window
    Window w = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0, 0, 
                                    200, 100, 0, blackColor, blackColor );
    Window w2 = XCreateSimpleWindow( dpy2, DefaultRootWindow(dpy2), 0, 0, 
                                    200, 100, 0, blackColor2, blackColor2 );
    // "Map" the window (that is, make it appear on the screen)
    XMapWindow(dpy, w);
    XMapWindow(dpy2, w2);
    // Create a "Graphics Context"
    GC gc = XCreateGC(dpy, w, 0, NULL );
    GC gc2 = XCreateGC(dpy2, w2, 0, NULL );
    GC gcXor = XCreateGC(dpy, w, 0, NULL );    XSetFunction( dpy, gcXor, GXxor );     // Tell the GC we draw using the white color
    XSetForeground(dpy, gc, whiteColor);
    XSetForeground(dpy2, gc2, whiteColor2);
    XSetForeground(dpy, gcXor, whiteColor);    
 
    // We want to get Expose & ButtonPress & ButtonRelease & ButtonMotion events    
    XSelectInput(dpy, w, ExposureMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask );
    XSelectInput(dpy2, w2, ExposureMask );
    // Wait for the events    
    bool done = false;
    int x = 0;
    int y = 0;
    int xTmp = 0;
    int yTmp = 0;
    bool drawing = false;    
    while( ! done )     
    {
        XEvent e;
        if (XPending(dpy) ) {
            XNextEvent( dpy, & e );
            switch( e.type )
            {
                case MotionNotify :
                    if( drawing )
                        if( e.xmotion.state & Button1Mask )
                        {
                            int size;
                            XDrawLine( dpy, w, gcXor, x, yTmp, xTmp, y );
                            XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp );
                            xTmp = e.xmotion.x;
                            yTmp = e.xmotion.y;
                            if ( abs( xTmp - x) < abs( yTmp - y) )
                                size = abs( xTmp - x );
                            else
                                size = abs( yTmp - y);
                            if ( xTmp > x )
                                xTmp = x + size;
                            else
                                xTmp = x - size;
                            if ( yTmp > y )
                                yTmp = y + size;
                            else
                                yTmp = y - size;
                            XDrawLine( dpy, w, gcXor, x, yTmp, xTmp, y );
                            XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp );
                            XFlush( dpy );
                        }//if                   
                        break;             
                case ButtonPress :   
                    switch( e.xbutton.button )   
                    {  
                        case Button1 :    
                            x = xTmp = e.xbutton.x;   
                            y = yTmp = e.xbutton.y;   
                            XDrawLine( dpy, w, gcXor, x, yTmp, xTmp, y );
                            XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp );
                            XFlush( dpy );
                            drawing = true; 
                            break;
                        case Button2 :
                        case Button3 :
                            done = true;
                            break;
                    }//switch   
                    break;   
                case ButtonRelease :   
                    switch( e.xbutton.button ) 
                    { 
                        case Button1 :  
                            if( drawing )    
                            {
                                drawing = false;
                                XDrawLine( dpy, w, gcXor, x, yTmp, xTmp, y );
                                XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp );
                                Line * l = new Line; 
                                l->x1 = x;
                                l->y1 = y; 
                                l->x2 = xTmp; 
                                l->y2 = yTmp;
                                l->next = lines;
                                lines = l; 
                                l->draw( dpy, w, gc );
                                l->draw( dpy2, w2, gc2 );
                                XFlush( dpy );
                                XFlush( dpy2 );
                            }//block
                            break;
                    }//switch 
                    break;
                case Expose :
                    if( e.xexpose.count == 0 )
                    {
                        // Draw lines
                        Line * l = lines;
                        while( l != NULL )
                        {
                            l->draw( dpy, w, gc );
                            l = l->next; 
                        }//while
                        // Send requests to the server
                        XFlush( dpy );
                    }//if
                    break;
            }//switch
        }
        if (XPending(dpy2) ) {
            XNextEvent( dpy2, & e );
            switch( e.type )
            {
                case Expose :
                    if( e.xexpose.count == 0 )
                    {
                        // Draw lines
                        Line * l = lines;
                        while( l != NULL )
                        {
                            l->draw( dpy2, w2, gc2 );
                            l = l->next; 
                        }//while
                        // Send requests to the server
                        XFlush( dpy2 );
                    }//if
                    break;
            }//switch
        }
        if (!XPending(dpy) && !XPending(dpy2))
            usleep(100);
    }//while
    XFreeGC( dpy, gc );         // free GC
    XFreeGC( dpy, gcXor );
    XDestroyWindow( dpy2, w2 );   // destroy window
    XCloseDisplay( dpy2 );       // Close connection to the display
    XDestroyWindow( dpy, w );   // destroy window
    XCloseDisplay( dpy );       // Close connection to the display
}