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

📄 ui_x11.c

📁 另一个分形程序
💻 C
字号:
/*  *     XaoS, a fast portable realtime fractal zoomer  *                  Copyright (C) 1996,1997 by * *      Jan Hubicka          (hubicka@paru.cas.cz) *      Thomas Marsh         (tmarsh@austin.ibm.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "aconfig.h"#ifdef X11_DRIVER#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <string.h>#include <X11/Xlib.h>#include <X11/cursorfont.h>#include "xlib.h"#ifdef MITSHM#include <sys/ipc.h>#include <sys/shm.h>#include <X11/extensions/XShm.h>#endif#include <fconfig.h>#include <ui.h>xlibparam xparams = { 0, 0, 0, 0, NULL, -1 };static int allocated;Cursor normal, xwait, replay;struct ui_driver x11_driver;static xdisplay *d;static char *size;static int Xsync;static int busy;static int sharedcolormap;#if 0static char *selection;#endif#ifdef MITSHMstatic int Completion;#endif#ifdef AMIGA#define XFlush(x) while(0)#endifstatic voidx11_setpaletterange (ui_palette p, int s, int e){  xsetpaletterange (d, p, s, e);}static intx11_set_color (int r, int g, int b, int init){  if (init)    xfree_colors (d);  return (xalloc_color (d, r * 256, g * 256, b * 256, init));}static voidx11_print (int x, int y, CONST char *text){  xmoveto (d, x, y + x11_driver.textheight - 2);  xouttext (d, text);}static voidx11_flush (void){  XFlush (d->display);}static int display;static int flipped = 0;static voidx11_display (void){  XFlush (d->display);#ifdef MITSHM  if (d->SharedMemFlag)    {      if (busy)	{	  display = 1;	  return;	}      busy++;      display = 0;    }#endif  if (Xsync)    XSync (d->display, 0);  if (flipped)    xflip_buffers (d), flipped = 0;  draw_screen (d);#ifdef MITSHM  if (d->SharedMemFlag)    {      XSync (d->display, 0);    }#endif}static voidx11_flip_buffers (void){  flipped ^= 1;}static voidx11_free_buffers (char *b1, char *b2){  if (allocated)    {      XSync (d->display, 0);      allocated = 0;      free_image (d);    }}static intx11_alloc_buffers (char **b1, char **b2){  if (!allocated)    {      XSync (d->display, 0);      allocated = 1;      if (!alloc_image (d))	{	  return (0);	}      xflip_buffers (d);    }  *b1 = d->vbuff;  *b2 = d->back;  flipped = 0;#if 0  if (d->SharedMemFlag)    {      x11_driver.flags |= UI_KEEP_BUFFER;    }#endif  return (d->linewidth);}static voidx11_getsize (int *w, int *h){  XSync (d->display, 0);  xupdate_size (d);  *w = d->width;  *h = d->height;}static voidx11_processevents (int wait, int *mx, int *my, int *mb, int *k){  static int mousex = 100, mousey = 0;  static int iflag = 0;  static unsigned int mousebuttons = 0;  static int resized;  XEvent ev;  if (XPending (d->display) || busy >= 2 || wait)    {      do	{	  XNextEvent (d->display, &ev);	  switch (ev.type)	    {	    case ClientMessage:	      if ((int) ev.xclient.format == 32		  && ev.xclient.data.l[0] == wmDeleteWindow)		ui_quit ();	      break;	    case ButtonRelease:	      mousex = ev.xbutton.x;	      mousey = ev.xbutton.y;	      switch (ev.xbutton.button)		{		case 1:		  mousebuttons &= ~BUTTON1;		  break;		case 2:		  mousebuttons &= ~BUTTON2;		  break;		case 3:		  mousebuttons &= ~BUTTON3;		  break;		}	      break;	    case ButtonPress:	      mousex = ev.xbutton.x;	      mousey = ev.xbutton.y;	      if (!		  (mousex < 0 || mousey < 0 || mousex > (int) d->width		   || mousey > (int) d->height))		{		  switch (ev.xbutton.button)		    {		    case 1:		      mousebuttons |= BUTTON1;		      break;		    case 2:		      mousebuttons |= BUTTON2;		      break;		    case 3:		      mousebuttons |= BUTTON3;		      break;		    }		}	      break;	    case MotionNotify:	      mousex = ev.xmotion.x;	      mousey = ev.xmotion.y;	      mousebuttons = ev.xmotion.state & (BUTTON1 | BUTTON2 | BUTTON3);	      break;	    case Expose:	      if (resized)		break;	      x11_display ();	      break;	    case ResizeRequest:	      XResizeWindow (d->display, d->window,			     ev.xresizerequest.width,			     ev.xresizerequest.height);	      XResizeWindow (d->display, d->parent_window,			     ev.xresizerequest.width,			     ev.xresizerequest.height);	      XSync (d->display, 0);	      resized = 2;	      ui_resize ();	      resized = 0;	      break;	    case ConfigureNotify:	      {		int oldw = d->width, oldh = d->height;		XSync (d->display, 0);		xupdate_size (d);		if ((int) d->width != oldw || (int) d->height != oldh)		  {		    resized = 2;		    ui_resize ();		    resized = 0;		  }	      }	      break;	    case KeyRelease:	      {		switch (XLookupKeysym (&ev.xkey, 0))		  {		  case XK_Left:		    iflag &= ~1;		    break;		  case XK_Right:		    iflag &= ~2;		    break;		  case XK_Up:		    iflag &= ~4;		    break;		  case XK_Down:		    iflag &= ~8;		    break;		  }	      }	      break;	    case KeyPress:	      {		KeySym ksym;		switch (ksym = XLookupKeysym (&ev.xkey, 0))		  {		  case XK_Left:		    iflag |= 1;		    ui_key (UIKEY_LEFT);		    break;		  case XK_Right:		    iflag |= 2;		    ui_key (UIKEY_RIGHT);		    break;		  case XK_Up:		    iflag |= 4;		    ui_key (UIKEY_UP);		    break;		  case XK_Down:		    iflag |= 8;		    ui_key (UIKEY_DOWN);		    break;#ifdef XK_Page_Up		  case XK_Page_Up:		    iflag |= 4;		    ui_key (UIKEY_PGUP);		    break;		  case XK_Page_Down:		    iflag |= 8;		    ui_key (UIKEY_PGDOWN);		    break;#endif		  case XK_Escape:		    ui_key (UIKEY_ESC);		  case XK_BackSpace:		    ui_key (UIKEY_BACKSPACE);		  default:		    {		      CONST char *name;		      char buff[256];		      if (ksym == XK_F1)			name = "h";		      else			{			  name = buff;			  buff[XLookupString			       (&ev.xkey, buff, 256, &ksym, NULL)] = 0;			}		      if (strlen (name) == 1)			{			  if (ui_key (*name) == 2)			    {			      return;			    }			}		    }		  }	      }	      break;	    default:#ifdef MITSHM	      if (ev.xany.type == Completion)		{		  busy--;		  if (display)		    x11_display ();		}#endif	      break;	    }	}      while (busy >= 2 ||	/*XEventsQueued (d->display, QueuedAlready) */	     XPending (d->display));    }  *mx = mousex;  *my = mousey;  *mb = mousebuttons;  *k = iflag;}/*static int defined; */static voidx11_cursor (int mode){  /*if(defined)     XUndefineCursor(d->display,d->window),defined=0; */  switch (mode)    {    case NORMALMOUSE:      XDefineCursor (d->display, d->window, normal);      /*defined=1; */      break;    case WAITMOUSE:      XDefineCursor (d->display, d->window, xwait);      /*defined=1; */      break;    case REPLAYMOUSE:      XDefineCursor (d->display, d->window, replay);      /*defined=1; */      break;    }  XFlush (d->display);}#if 0static Atom atom;voidx11_copy (){  if (slection)    free (selection), selection = NULL;  selection = ui_getpos ();  atom = XInternAtom (d->display, "image/x-xaos.position", False);  printf ("%i\n", atom);  XSetSelectionOwner (d->display, atom, d->window, CurrentTime);}#endifstatic intx11_init (void){  if (xparams.fullscreen || xparams.rootwindow)    sharedcolormap = 1;		/*private colormap is broken in fullscreen				   mode (at least at my X) */  xparams.privatecolormap = !sharedcolormap;  if (xparams.display == NULL)    {				/*solaris stuff */      xparams.display = getenv ("DISPLAY");    }  if (size != NULL)    {      int x, y;      sscanf (size, "%ix%i", &x, &y);      if (x < 0)	x = XSIZE;      if (y < 0)	y = YSIZE;      d = xalloc_display ("XaoS", x, y, &xparams);    }  else    d = xalloc_display ("XaoS", XSIZE, YSIZE, &xparams);  if (d == NULL)    return 0;  /*normal=XCreateFontCursor(d->display,XC_arrow); */  normal = XCreateFontCursor (d->display, XC_left_ptr);  xwait = XCreateFontCursor (d->display, XC_watch);  replay = XCreateFontCursor (d->display, XC_dot);  if (d->truecolor || d->privatecolormap)    x11_driver.flags &= ~RANDOM_PALETTE_SIZE;  if (!alloc_image (d))    {      xfree_display (d);      return (0);    }  allocated = 1;  switch (d->visual->class)    {    case StaticGray:      if (d->depth == 1)	{	  if (BitmapBitOrder (d->display) == LSBFirst)	    if (WhitePixel (d->display, d->screen))	      x11_driver.imagetype = UI_LBITMAP;	    else	      x11_driver.imagetype = UI_LIBITMAP;	  else if (WhitePixel (d->display, d->screen))	    x11_driver.imagetype = UI_MBITMAP;	  else	    x11_driver.imagetype = UI_MIBITMAP;	}      else	{	  /*Warning! this is untested. I believe it works */	  /*x11_driver.set_color = x11_set_color; */	  x11_driver.palettestart = 0;	  x11_driver.paletteend = 256;	  x11_driver.maxentries = 256;	  x11_driver.imagetype = UI_GRAYSCALE;	}      break;    case StaticColor:    smallcolor:      {	int end = 256;	int start = 0;	int entries = d->visual->map_entries;	if (d->visual->class == TrueColor)	  {	    entries = (int) (d->image[0]->red_mask |			     d->image[0]->green_mask |			     d->image[0]->blue_mask);	  }	x11_driver.imagetype = UI_FIXEDCOLOR;	if (end > entries)	  end = entries;	if (end < 64)	  start = 0;	x11_driver.set_range = x11_setpaletterange;	x11_driver.palettestart = start;	x11_driver.paletteend = end;	x11_driver.maxentries = end - start;      }      break;    case PseudoColor:    case GrayScale:      if (d->privatecolormap)	{	  int end = 256;	  int start = 16;	  if (end > d->visual->map_entries)	    end = d->visual->map_entries;	  if (end < 64)	    start = 0;	  x11_driver.set_range = x11_setpaletterange;	  x11_driver.palettestart = start;	  x11_driver.paletteend = end;	  x11_driver.maxentries = end - start;	}      else	{	  int end = 256;	  if (end > d->visual->map_entries)	    end = d->visual->map_entries;	  x11_driver.set_color = x11_set_color, x11_driver.flags |=	    RANDOM_PALETTE_SIZE;	  x11_driver.palettestart = 0;	  x11_driver.paletteend = end;	  x11_driver.maxentries = end;	}      break;    case TrueColor:      x11_driver.rmask = d->image[0]->red_mask;      x11_driver.gmask = d->image[0]->green_mask;      x11_driver.bmask = d->image[0]->blue_mask;      {	unsigned char c[4];	int order = MSBFirst;	*(unsigned short *) c = 0xff;	if (c[0] == (unsigned char) 0xff)	  order = LSBFirst;	if (order != d->image[0]->byte_order)	  {	    int shift = 32 - d->image[0]->bits_per_pixel;#define SWAPE(c)  (((c&0xffU)<<24)|((c&0xff00U)<<8)|((c&0xff0000U)>>8)|((c&0xff000000U)>>24))	    x11_driver.rmask = SWAPE (x11_driver.rmask) >> shift;	    x11_driver.gmask = SWAPE (x11_driver.gmask) >> shift;	    x11_driver.bmask = SWAPE (x11_driver.bmask) >> shift;	  }      }      switch (d->image[0]->bits_per_pixel)	{	case 8:	  goto smallcolor;	case 16:	  x11_driver.imagetype = UI_TRUECOLOR16;	  break;	case 24:	  x11_driver.imagetype = UI_TRUECOLOR24;	  break;	case 32:	  x11_driver.imagetype = UI_TRUECOLOR;	  break;	default:	  printf ("Fatal error:unsupported bits per pixel!\n");	}    }  x11_driver.maxwidth = XDisplayWidth (d->display, d->screen);  x11_driver.maxheight = XDisplayHeight (d->display, d->screen);  x11_driver.width =    ((double) ((unsigned int) XDisplayWidthMM (d->display, d->screen))) /    x11_driver.maxwidth / 10.0;  x11_driver.height =    ((double) ((unsigned int) XDisplayHeightMM (d->display, d->screen))) /    x11_driver.maxheight / 10.0;  x11_driver.textheight = xsetfont (d, "fixed");  x11_driver.textwidth =    d->font_struct->max_bounds.rbearing - d->font_struct->min_bounds.lbearing;#ifdef MITSHM  Completion = XShmGetEventBase (d->display) + ShmCompletion;#endif  if (d->privatecolormap)    {      x11_driver.flags |= PALETTE_ROTATION | ROTATE_INSIDE_CALCULATION;    }  return (1);}static voidx11_uninitialise (void){#if 0  if (selection)    free (selection), selection = NULL;#endif  xfree_colors (d);  xfree_display (d);}static voidx11_getmouse (int *x, int *y, int *b){  int rootx, rooty;  Window rootreturn, childreturn;  XQueryPointer (d->display, d->window,		 &rootreturn, &childreturn,		 &rootx, &rooty, x, y, (unsigned int *) b);}static CONST struct params params[] = {  {"", P_HELP, NULL, "X11 driver options:"},  {"-display", P_STRING, &xparams.display, "Select display"},  {"-size", P_STRING, &size, "Select size of window (WIDTHxHEIGHT)."},  {"-sync", P_SWITCH, &Xsync,   "Generate sync signals before looking for events. This\n\t\t\thelps on old and buggy HP-UX X servers."},  {"-shared", P_SWITCH, &sharedcolormap,   "Use shared colormap on pseudocolor display."},  {"-usedefault", P_SWITCH, &xparams.usedefault,   "Use default visual if autodetection causes troubles."},  {"-nomitshm", P_SWITCH, &xparams.nomitshm, "Disable MITSHM extension."},  {"-fullscreen", P_SWITCH, &xparams.fullscreen, "Enable fullscreen mode."},  {"-windowid", P_NUMBER, &xparams.windowid, "Use selected window."},  {"-root", P_SWITCH, &xparams.rootwindow, "Use root window."},  {NULL, 0, NULL, NULL}};struct ui_driver x11_driver = {  "X11",  x11_init,  x11_getsize,  x11_processevents,  x11_getmouse,  x11_uninitialise,  NULL,  NULL,  x11_print,  x11_display,  x11_alloc_buffers,  x11_free_buffers,  x11_flip_buffers,  x11_cursor,  x11_flush,  8,  8,  params,  RESOLUTION | PIXELSIZE | NOFLUSHDISPLAY /*| UPDATE_AFTER_RESIZE */ ,  0.0, 0.0,  0, 0,  UI_C256,  16, 254, 254 - 16};#endif

⌨️ 快捷键说明

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