⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 events.c

📁 一系列在X窗口环境图形化编程的范例。基于GTK。看完这个教程
💻 C
字号:
/* * 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. */Windowcreate_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;}GCcreate_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. */voidhandle_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. */voidhandle_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. */voidhandle_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;  }}voidmain(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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -