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

📄 x11.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
字号:
/* * This software is copyrighted as noted below.  It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is".  Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. *//* * x11.c - Show images on X11 Window Systems. * * Author:      Raul Rivero *              Mathematics Dept. *              University of Oviedo * Date:        Sat Mar 14 1992 * Copyright (c) 1992, Raul Rivero * */#include "lug.h"#include "lugfnts.h"#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/cursorfont.h>#define BORDER_WIDTH    0Display         *dpy;Window          wnd;GC              gc;Colormap        Xcmap;int             screen;show_bitmap_x11( name, inbitmap )char *name;bitmap_hdr *inbitmap;{  int colors, levels, depth;  bitmap_hdr outbitmap;  bitmap_hdr *bitmap;  int cmapref[256], cmap_flag[256];  XSetWindowAttributes wattr;  long wmask;  XSizeHints whints;  XEvent event;  XExposeEvent *exp;  XComposeStatus statusio;  int totalsize = inbitmap->xsize * inbitmap->ysize;  byte *ptr, *iptr, *end;  XImage *Ximagebuffer;  byte *Xbitmap;  int loop;  double gamma = 1.0;  int used_colors;  Cursor normal_pointer, wait_pointer;  /* Connect with X11 */  if ( (dpy = (Display *) XOpenDisplay(getenv("DISPLAY")) )== NULL )    error( 15 );  /* Get some information */  screen = DefaultScreen( dpy );  gc = DefaultGC( dpy, screen );  depth = DisplayPlanes( dpy, screen );  Xcmap = DefaultColormap( dpy, screen );  XSetBackground( dpy, gc, BlackPixel( dpy, screen ) );  XSetForeground( dpy, gc, WhitePixel( dpy, screen ) );  /*   * We know # of colors of X11 display so we need adjust   * our # of colors to this.   */  if ( inbitmap->depth > depth ) {    colors = 1 << depth;    levels = compute_levels( colors );    used_colors = Xdither_image( inbitmap, &outbitmap,                                 levels, gamma, cmap_flag );    bitmap = &outbitmap;  }else {    bitmap = inbitmap;    used_colors = set_cmap_flags( inbitmap, cmap_flag );  }  /*   * We have a color map and we wanna use it but preserving the   * current X11 cmap.   */  setXcmap( bitmap, cmapref, cmap_flag );  /*   * We wanna predefine ...   */  whints.flags = PSize | PMinSize | PMaxSize;  whints.x = whints.y = 1;  whints.width = whints.min_width = whints.max_width = bitmap->xsize;  whints.height = whints.min_height = whints.max_height = bitmap->ysize;  wattr.event_mask = ExposureMask | ButtonPressMask;  wattr.border_pixel = WhitePixel( dpy, screen );  wattr.background_pixel = BlackPixel( dpy, screen );  wmask = CWBackPixel | CWBorderPixel | CWEventMask;  normal_pointer = XCreateFontCursor( dpy, XC_crosshair );  wait_pointer   = XCreateFontCursor( dpy, XC_coffee_mug );  /*   * We have all what we wanna, so ... DO IT !!!   */  wnd = XCreateWindow( dpy, RootWindow( dpy, screen ),                       0, 0, bitmap->xsize, bitmap->ysize,                       BORDER_WIDTH, depth,                       InputOutput,                       CopyFromParent,                       wmask,                       &wattr );  XStoreName( dpy, wnd, name );  XSetNormalHints( dpy, wnd, &whints );  XDefineCursor( dpy, wnd, wait_pointer);  /* XSetInput( dpy, wnd, ExposureMask | ButtonPressMask ); */  /*   * Allocate memory for the image and copy it with new   * references ( to X11 colormap ).   */  ptr = Xbitmap = (byte *) Malloc( totalsize );  iptr = bitmap->r;  end = iptr + totalsize;  while ( iptr < end ) {    *ptr++ = cmapref[ *iptr++ ];  }  Ximagebuffer = XCreateImage( dpy, DefaultVisual( dpy, screen ), depth,                               ZPixmap, 0, Xbitmap,                               bitmap->xsize, bitmap->ysize,                               8, 0 );  XMapWindow( dpy, wnd );  /*   * We left a process controlling the window.   */  XDefineCursor( dpy, wnd, normal_pointer );  loop = 1;  do {    XNextEvent( dpy, &event );    switch( event.type ) {        case Expose    :  XDefineCursor( dpy, wnd, wait_pointer );                          exp = (XExposeEvent *) &event;                          XPutImage( dpy, wnd, gc,                                     Ximagebuffer,                                     exp->x, exp->y,                                     exp->x, exp->y,                                     exp->width, exp->height );                          XDefineCursor( dpy, wnd, normal_pointer );                          break;        case ButtonPress: loop = ( event.xbutton.button != Button3 );                          break;    }  }while( loop );  /* End of this window's life ( ooopps ! ) */  XUndefineCursor( dpy, wnd );  XUnmapWindow( dpy, wnd );  XDestroyImage( Ximagebuffer );  XDestroyWindow( dpy, wnd );  XCloseDisplay( dpy );}setXcmap( image, cmapref, cmap_flag )bitmap_hdr *image;int *cmapref, *cmap_flag;{  register int i, j;  static XColor Xnewcmap[256];  int Error = 0;  color_map *cmap;  int r, g, b;  cmap = (color_map *) image->cmap;  bzero( cmapref, image->colors * sizeof(int) );  /*   * Lets go to get our colors!.   */  for ( i = 0, j = 0; i < image->colors; i++ ) {    if ( cmap_flag[i] ) {      /* This color is used */      Xnewcmap[j].red   = cmap[i][0] << 8;      Xnewcmap[j].green = cmap[i][1] << 8;      Xnewcmap[j].blue  = cmap[i][2] << 8;      Xnewcmap[j].flags = DoRed | DoGreen | DoBlue;      if ( XAllocColor( dpy, Xcmap, &Xnewcmap[j] ) ) {        /* Alloc acepted */        cmapref[i] = Xnewcmap[j].pixel;        j++;      }else Error = 1;    }  }  if ( Error ) {    /*     * We got errors allocating colors, then we get the current     * X11 cmap and aproximate those colors to nearest.     */    XColor *Xoldcmap;    int num_colors;    double distance, cd;    int r, g, b;    double *hue, *saturation, *level;    double h, s, l;    /* Get the server's number of colors */    num_colors = DisplayCells( dpy, screen );    /* Now get the current cmap of X11 */    Xoldcmap = (XColor *) Malloc( sizeof(XColor) * num_colors );    for ( i = 0; i < num_colors; i++ ) {      Xoldcmap[i].pixel = i;    }    XQueryColors( dpy, Xcmap, Xoldcmap, num_colors );    /*      * Ok, now we wanna the Hue value of this colors.     */    hue = (double *) Malloc( sizeof(double) * num_colors );    saturation = (double *) Malloc( sizeof(double) * num_colors );    level = (double *) Malloc( sizeof(double) * num_colors );    for ( i = 0; i < num_colors; i++ ) {      /* We need values scaled [0..255] */      r = Xoldcmap[i].red   >> 8;       g = Xoldcmap[i].green >> 8;       b = Xoldcmap[i].blue  >> 8;       RGB_to_HSL( r, g, b, &hue[i], &saturation[i], &level[i] );    }    /*     * All do it!. Lets go choose new colors.     */      for ( i = 0; i < image->colors; i++ ) {      if ( cmap_flag[i] && !cmapref[i] ) {        /*         * We got an error with this color, it's used by image         * but we cannot allocated.         */        /* Reset the distance value ... */        distance = 30.;          /* ... and convert the current color to HSL */        RGB_to_HSL( cmap[i][0], cmap[i][1], cmap[i][2], &h, &s, &l );        for ( j = 0; j < num_colors; j++ ) {          cd = LUGABS( h - hue[j] ) +                LUGABS( s - saturation[j] ) +               LUGABS( l - level[j] );          if ( cd < distance ) {            distance = cd;            cmapref[i] = j;          }        }      }    }    free( Xoldcmap );     free( hue );     free( saturation );     free( level );   }}set_cmap_flags( bitmap, cmap_flag )bitmap_hdr *bitmap;int *cmap_flag;{  register int used_colors = 0;  register int totalcolors = bitmap->colors;  byte *end, *ptr;  if ( bitmap->depth > 8 )    error( 10 );  bzero( cmap_flag, totalcolors * sizeof(int) );  /* Set pointers */  ptr = bitmap->r;  end = ptr + bitmap->xsize * bitmap->ysize;  /*   * Loop while not the end and we don't use   * all posible colors.   */  while ( ptr < end && used_colors != totalcolors ) {    if ( !cmap_flag[ *ptr ] ) {      cmap_flag[*ptr]++;      used_colors++;    }    ptr++;  }  return used_colors;}#define DMAP(v,x,y)             (modN[v] > dithermatrix[x][y] ? \                                 divN[v] + 1 : divN[v])Xdither_image(inbitmap, outbitmap, levels, gamma, cmap_flag)bitmap_hdr *inbitmap;bitmap_hdr *outbitmap;int levels;double gamma;int *cmap_flag;{  register int i, j;  int total_size;  byte *r, *g, *b;  byte *rout;  int divN[256], modN[256];  int dithermatrix[16][16];  int col, row;  int used_colors = 0;  if ( levels < 2 || levels > 6 )    error( 11 );  if ( inbitmap->depth <= 8 )    error( 10 );  /* Fill new header */  outbitmap->xsize = inbitmap->xsize;  outbitmap->ysize = inbitmap->ysize;  total_size = outbitmap->xsize * outbitmap->ysize;  outbitmap->depth = no_bits( levels*levels*levels ) + 1;  outbitmap->colors = ( 1 << outbitmap->depth );  outbitmap->cmap = (byte *) Malloc( 3 * outbitmap->colors );  rout = outbitmap->r = (byte *) Malloc( total_size );  /* Pointers to in image */  r = inbitmap->r;  g = inbitmap->g;  b = inbitmap->b;  bzero( cmap_flag, 256 * sizeof(int) );  /*   * Init the cmap of the dithered image ( and other   * parameters ).   */  create_dithermap( levels, gamma, outbitmap->cmap, divN, modN, dithermatrix);  /*   * Dither each pixels through the dither matrix.   */  for ( i = 0; i < outbitmap->ysize; i++ ) {    row = i % 16;    for ( j = 0; j < outbitmap->xsize; j++ ) {      col = j % 16;      *rout = DMAP(*r, col, row) + DMAP(*g, col, row) * levels +              DMAP(*b, col, row) * levels*levels;      if ( !cmap_flag[ *rout++ ]++ )        usesizelors++;      r++, g++, b++;    }  }  return used_colors;}

⌨️ 快捷键说明

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