|
发表于 2006-2-19 14:30:15
|
显示全部楼层
摘自:http://users.actcom.co.il/%7Echo ... rogramming/events.c
也许对你有帮助。
编绎方法:cc events.c -o event -L/usr/X11R6/lib -lX11
运行方法:在X下
在Debian3下测试通过。- /*
- * events.c - demonstrate handling of X events using an events loop.
- */
- #include <X11/Xlib.h>
- #include <stdio.h>
- #include <stdlib.h> /* getenv(), etc. */
- /*
- * function: create_simple_window. Creates a window with a white background
- * in the given size.
- * input: display, size of the window (in pixels), and location of the window
- * (in pixels).
- * output: the window's ID.
- * notes: window is created with a black border, 2 pixels wide.
- * the window is automatically mapped after its creation.
- */
- Window
- create_simple_window(Display* display, int width, int height, int x, int y)
- {
- int screen_num = DefaultScreen(display);
- int win_border_width = 2;
- Window win;
- /* create a simple window, as a direct child of the screen's */
- /* root window. Use the screen's black and white colors as */
- /* the foreground and background colors of the window, */
- /* respectively. Place the new window's top-left corner at */
- /* the given 'x,y' coordinates. */
- win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
- x, y, width, height, win_border_width,
- BlackPixel(display, screen_num),
- WhitePixel(display, screen_num));
- /* make the window actually appear on the screen. */
- XMapWindow(display, win);
- /* flush all pending requests to the X server. */
- XFlush(display);
- return win;
- }
- GC
- create_gc(Display* display, Window win, int reverse_video)
- {
- GC gc; /* handle of newly created GC. */
- unsigned long valuemask = 0; /* which values in 'values' to */
- /* check when creating the GC. */
- XGCValues values; /* initial values for the GC. */
- unsigned int line_width = 2; /* line width for the GC. */
- int line_style = LineSolid; /* style for lines drawing and */
- int cap_style = CapButt; /* style of the line's edje and */
- int join_style = JoinBevel; /* joined lines. */
- int screen_num = DefaultScreen(display);
- gc = XCreateGC(display, win, valuemask, &values);
- if (gc < 0) {
- fprintf(stderr, "XCreateGC: \n");
- }
- /* allocate foreground and background colors for this GC. */
- if (reverse_video) {
- XSetForeground(display, gc, WhitePixel(display, screen_num));
- XSetBackground(display, gc, BlackPixel(display, screen_num));
- }
- else {
- XSetForeground(display, gc, BlackPixel(display, screen_num));
- XSetBackground(display, gc, WhitePixel(display, screen_num));
- }
- /* define the style of lines that will be drawn using this GC. */
- XSetLineAttributes(display, gc,
- line_width, line_style, cap_style, join_style);
- /* define the fill style for the GC. to be 'solid filling'. */
- XSetFillStyle(display, gc, FillSolid);
- return gc;
- }
- /*
- * function: handle_expose. handles an Expose event by redrawing the window.
- * input: display, 2 GCs, XExposeEvent event structure, dimensions of
- * the window, pixels array.
- * output: none.
- */
- void
- handle_expose(Display* display, GC gc, GC rev_gc, XExposeEvent* expose_event,
- unsigned int win_width, unsigned int win_height,
- short pixels[1000][1000])
- {
- /* if this is the first in a set of expose events - ignore this event. */
- if (expose_event->count != 0)
- return;
- /* draw the contents of our window. */
- /* draw one pixel near each corner of the window */
- XDrawPoint(display, expose_event->window, gc, 5, 5);
- XDrawPoint(display, expose_event->window, gc, 5, win_height-5);
- XDrawPoint(display, expose_event->window, gc, win_width-5, 5);
- XDrawPoint(display, expose_event->window, gc, win_width-5, win_height-5);
- /* draw two intersecting lines, one horizontal and one vertical, */
- /* which intersect at point "50,100". */
- XDrawLine(display, expose_event->window, gc, 50, 0, 50, 200);
- XDrawLine(display, expose_event->window, gc, 0, 100, 200, 100);
- /* now use the XDrawArc() function to draw a circle whose diameter */
- /* is 30 pixels, and whose center is at location '50,100'. */
- XDrawArc(display, expose_event->window, gc,
- 50-(30/2), 100-(30/2), 30, 30, 0, 360*64);
- {
- XPoint points[] = {
- {0, 0},
- {15, 15},
- {0, 15},
- {0, 0}
- };
- int npoints = sizeof(points)/sizeof(XPoint);
- /* draw a small triangle at the top-left corner of the window. */
- /* the triangle is made of a set of consecutive lines, whose */
- /* end-point pixels are specified in the 'points' array. */
- XDrawLines(display, expose_event->window, gc,
- points, npoints, CoordModeOrigin);
- }
- /* draw a rectangle whose top-left corner is at '120,150', its width is */
- /* 50 pixels, and height is 60 pixels. */
- XDrawRectangle(display, expose_event->window, gc, 120, 150, 50, 60);
- /* draw a filled rectangle of the same size as above, to the left of the */
- /* previous rectangle. */
- XFillRectangle(display, expose_event->window, gc, 60, 150, 50, 60);
- /* finally, draw all the pixels in the 'pixels' array. */
- {
- int x, y;
- for (x=0; x<win_width; x++)
- for (y=0; y<win_height; y++)
- switch(pixels[x][y]) {
- case 1: /* draw point. */
- XDrawPoint(display, expose_event->window, gc, x, y);
- break;
- case -1: /* erase point. */
- XDrawPoint(display, expose_event->window, rev_gc, x, y);
- break;
- }
- }
- }
- /*
- * function: handle_drag. handles a Mouse drag event - if the left button
- * is depressed - draws the pixel below the mouse pointer. if the
- * middle button is depressed - erases the pixel below the mouse
- * pointer.
- * input: display, 2 GCs, XButtonEvent event structure, dimensions of
- * the window, pixels array.
- * output: none.
- */
- void
- handle_drag(Display* display, GC gc, GC rev_gc, XButtonEvent* drag_event,
- unsigned int win_width, unsigned int win_height,
- short pixels[1000][1000])
- {
- int x, y;
- /* invert the pixel under the mouse. */
- x = drag_event->x;
- y = drag_event->y;
- switch (drag_event->state) {
- case Button1Mask: /* draw the given pixel in black color. */
- XDrawPoint(display, drag_event->window, gc, x, y);
- pixels[x][y] = 1;
- break;
- case Button2Mask: /* draw the given pixel in white color. */
- XDrawPoint(display, drag_event->window, rev_gc, x, y);
- pixels[x][y] = -1;
- break;
- }
- }
- /*
- * function: handle_button_down. handles a Mouse press event - if the left
- * button is depressed - draws the pixel below the mouse pointer.
- * if the middle button is depressed - erases the pixel below the
- * mouse pointer.
- * input: display, 2 GCs, XButtonEvent event structure, dimensions of
- * the window, pixels array.
- * output: none.
- */
- void
- handle_button_down(Display* display, GC gc, GC rev_gc,
- XButtonEvent* button_event,
- unsigned int win_width, unsigned int win_height,
- short pixels[1000][1000])
- {
- int x, y;
- /* invert the pixel under the mouse. */
- x = button_event->x;
- y = button_event->y;
- switch (button_event->button) {
- case Button1: /* draw the given pixel in black color. */
- XDrawPoint(display, button_event->window, gc, x, y);
- pixels[x][y] = 1;
- break;
- case Button2: /* draw the given pixel in white color. */
- XDrawPoint(display, button_event->window, rev_gc, x, y);
- pixels[x][y] = -1;
- break;
- }
- }
- void
- main(int argc, char* argv[])
- {
- Display* display; /* pointer to X Display structure. */
- int screen_num; /* number of screen to place the window on. */
- Window win; /* pointer to the newly created window. */
- unsigned int display_width,
- display_height; /* height and width of the X display. */
- unsigned int width, height; /* height and width for the new window. */
- char *display_name = getenv("DISPLAY"); /* address of the X display. */
- GC gc, rev_gc; /* GC (graphics context) used for drawing */
- /* in our window. */
- short pixels[1000][1000]; /* used to store pixels on screen that were */
- /* explicitly drawn or erased by the user. */
- /* initialize the 'pixels' array to contain 0 values. */
- {
- int x, y;
- for (x=0; x<1000; x++)
- for (y=0; y<1000; y++)
- pixels[x][y] = 0;
- }
- /* open connection with the X server. */
- display = XOpenDisplay(display_name);
- if (display == NULL) {
- fprintf(stderr, "%s: cannot connect to X server '%s'\n",
- argv[0], display_name);
- exit(1);
- }
- /* get the geometry of the default screen for our display. */
- screen_num = DefaultScreen(display);
- display_width = DisplayWidth(display, screen_num);
- display_height = DisplayHeight(display, screen_num);
- /* make the new window occupy 1/9 of the screen's size. */
- width = (display_width / 3);
- height = (display_height / 3);
- printf("window width - '%d'; height - '%d'\n", width, height);
- /* create a simple window, as a direct child of the screen's */
- /* root window. Use the screen's white color as the background */
- /* color of the window. Place the new window's top-left corner */
- /* at the given 'x,y' coordinates. */
- win = create_simple_window(display, width, height, 0, 0);
- /* allocate two new GCs (graphics contexts) for drawing in the window. */
- /* the first is used for drawing black over white, the second is used */
- /* for drawing white over black. */
- gc = create_gc(display, win, 0);
- rev_gc = create_gc(display, win, 1);
- /* subscribe to the given set of event types. */
- XSelectInput(display, win, ExposureMask | KeyPressMask |
- ButtonPressMask | Button1MotionMask |
- Button2MotionMask | StructureNotifyMask);
- /* perform an events loop */
- {
- int done = 0;
- XEvent an_event;
- while (!done) {
- XNextEvent(display, &an_event);
- switch (an_event.type) {
- case Expose:
- /* redraw our window. */
- handle_expose(display, gc, rev_gc, (XExposeEvent*)&an_event.xexpose,
- width, height, pixels);
- break;
-
- case ConfigureNotify:
- /* update the size of our window, for expose events. */
- width = an_event.xconfigure.width;
- height = an_event.xconfigure.height;
- break;
-
- case ButtonPress:
- /* invert the pixel under the mouse pointer. */
- handle_button_down(display, gc, rev_gc,
- (XButtonEvent*)&an_event.xbutton,
- width, height, pixels);
- break;
-
- case MotionNotify:
- /* invert the pixel under the mouse pointer. */
- handle_drag(display, gc, rev_gc,
- (XButtonEvent*)&an_event.xbutton,
- width, height, pixels);
- break;
-
- case KeyPress:
- /* exit the application by braking out of the events loop. */
- done = 1;
- break;
-
- default: /* ignore any other event types. */
- break;
- } /* end switch on event type */
- } /* end while events handling */
- }
- /* free the GCs. */
- XFreeGC(display, gc);
- XFreeGC(display, rev_gc);
- /* close the connection to the X server. */
- XCloseDisplay(display);
- }
复制代码 |
|