/*---------------------------------------------------------------------------*/
/*
 * xcolorbar -- draw colorbar on X screen
 * Version 1.1  1996/02/22
 * Version 1.4  1996/06/13, add BARCODE pattern
 *
 * (C) COPYRIGHT International Business Machines Corp. 1995, 1996
 * All Rights Reserved
 * Licensed Materials - Property of IBM
 *
 */

/*---------------------------------------------------------------------------*/
/* Header files */
/*---------------------------------------------------------------------------*/
#include	<stdio.h>	/* NULL */
#include	<string.h>	/* strrchr() */
#include	<X11/Xlib.h>	/* Display */
#include	<stdlib.h>	/* getopt() */

/*---------------------------------------------------------------------------*/
/* Similar to unix `basename' command */
/*---------------------------------------------------------------------------*/
const char *whoami(const char *argv0)
{
  char *ps = strrchr(argv0, '/');
  if (ps == NULL) {
    return argv0;
  } else {
    return ps + 1;
  }
}

/*---------------------------------------------------------------------------*/
/* Display short usage message */
/*---------------------------------------------------------------------------*/
static void usage(const char *argv0)
{
  fprintf(stderr, "SYNOPSYS\n");
  fprintf(stderr, "   %s [options]\n", whoami(argv0));
  fprintf(stderr, "\n");
  fprintf(stderr, "OPTIONS\n");
  fprintf(stderr, "   -h         Show this help.\n");
}

/*---------------------------------------------------------------------------*/
/* Allocate color cell and set it to graphics context */
/*---------------------------------------------------------------------------*/
void set_color(Display *display, Window window, Colormap cmap, GC gc,
	       int red, int green, int blue)
{
  XColor	xcolor;
  xcolor.red = red;
  xcolor.green = green;
  xcolor.blue = blue;
  xcolor.flags = DoRed | DoGreen | DoBlue;

  if (XAllocColor(display, cmap, &xcolor) == 0) {
    fprintf(stderr, "Can't allocate color.\n");
    exit(1);
  }
  XSetForeground(display, gc, xcolor.pixel);
}

/*---------------------------------------------------------------------------*/
/* Draw colorbar */
/*---------------------------------------------------------------------------*/
void draw_colorbar(Display *display, Window window, Colormap cmap)
{
  GC		gc = XCreateGC(display, window, 0, NULL);
  int		i;
  int		dx, dy;
  static int barcode[100]={1,1,1,1, 1,0,0,1, 0,1,0,1, 0,0,0,1 ,
                           0,1,1,0, 0,1,0,1, 0,0,1,1, 0,1,0,0, 
                           1,1,1,1, 0,1,0,0, 1,0,0,1, 0,1,0,0, 
                           0,0,1,0, 0,1,0,0, 1,1,0,1, 1,1,1,1} ;

#include "table.c"

  for (i = 0; i < NUM_BLOCKS_FOR_COLOR_BAR; i++) {
    int x = color_bar_table[i].upper_left_x;
    int y = color_bar_table[i].upper_left_y;
    int w = color_bar_table[i].width;
    int h = color_bar_table[i].height;
    int r = color_bar_table[i].red;
    int g = color_bar_table[i].green;
    int b = color_bar_table[i].blue;
    
    set_color(display, window, cmap, gc, r, g, b);
    XFillRectangle(display, window, gc, x, y, w, h);
  }

  set_color(display, window, cmap, gc, 0xffff, 0xffff, 0xffff);
  for (dx=1120 ; dx<=1280 ; dx++)
      for (dy=256 ; dy<768 ; dy++)
      if( ((dx+dy)/2)*2 == (dx+dy))
        XFillRectangle(display, window, gc, dx, dy, 1,1);

  set_color(display, window, cmap, gc, 0x0000, 0x0000, 0x0000);
  XFillRectangle(display, window, gc, 1270, 0, 10, 1000);

    /* draw colorbar */
  set_color(display, window, cmap, gc, 0xffff, 0xffff, 0xffff);
  for (dy=0 ; dy<64 ; dy++)
    {
    if (barcode[dy]==1)
      XFillRectangle(display, window, gc, 480, dy, 1265-480,1);
    }

  XFreeGC(display, gc);
}

/*---------------------------------------------------------------------------*/
/* Main function */
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  Display		*display; /* Pointer to Display structure */
  int			screen;	  /* Default screen number */
  Window		root;	  /* Default root window */
  Window		window;	  /* Window to draw colorbar */
  Window		root_return; /* Dummy */
  XEvent		event;	     /* Event */
  XSetWindowAttributes	attributes;  /* to ignore window manager */
  unsigned long		valuemask;   /* Value Mask */
  Status		status;	/* Status of X request */
  Colormap		cmap;	/* Colormap */
  unsigned long		black;	/* Pixel value of black */
  unsigned int		root_width, root_height; /* Size of root window */
  unsigned int		border_width, depth; /* etc. */
  int			root_x, root_y;	/* dummy */
  int			done;	/* Flag */
  static char copyright[255]=" * (C) COPYRIGHT International Business Machines Corp. 1995, 1996 * All Rights Reserved * Licensed Materials - Property of IBM";


  /*-------------------------------------------------------------------------*/
  /* Parse options */
  /*-------------------------------------------------------------------------*/
  done = 0;
  while (! done) {
    switch (getopt(argc, argv, "h:")) {
    case 'h':
      usage(argv[0]);
      exit(0);
    default:
      done = 1;
    }
  }
  if (argc - optind != 0) {
    fprintf(stderr, "Too many arguments.\n");
    usage(argv[0]);
    exit(1);
  }
  
  /*-------------------------------------------------------------------------*/
  /* Open X Display connecton */
  /*-------------------------------------------------------------------------*/
  display = XOpenDisplay("");
  if (display == NULL) {
    fprintf(stderr, "Can't open display.\n");
    exit(1);
  }

  /* Default Screen of display */
  screen = XDefaultScreen(display);

  /* Pixel value of black */
  black = XBlackPixel(display, screen);

  /* Root window of default screen */
  root = XDefaultRootWindow(display);

  /* Get root window geometry */
  status = XGetGeometry(display, root, &root_return,
			&root_x, &root_y, &root_width, &root_height,
			&border_width, &depth);
  if (status != 1) {
    fprintf(stderr, "Can't get window geometry(status = %d).\n", status);
    return -1;
  }

  /*-------------------------------------------------------------------------*/
  /* Create window and set attributes */
  /*-------------------------------------------------------------------------*/
  /* Create simple window */
  window = XCreateSimpleWindow(display, root,
			       0, 0, root_width, root_height, 0,
			       black, black);
  if (window == None) {
    fprintf(stderr, "Can't create colorbar window.\n");
    exit(1);
  }

  /* Request window manager not to arbiter this window */
  valuemask = 0;
  attributes.override_redirect = True;
  valuemask |= CWOverrideRedirect;
  XChangeWindowAttributes(display, window, valuemask, &attributes);

  /* Map window */
  XMapRaised(display, window);

  /* Get focus to our window */
  XSetInputFocus(display, window, RevertToParent, 0);

  /*-------------------------------------------------------------------------*/
  /* Create own colormap and install it */
  /*-------------------------------------------------------------------------*/
#if USE_OWN_COLORMAP
  /* Create own colormap */
  cmap = XCreateColormap(display, window, XDefaultVisual(display, screen),
			 AllocNone);
  if (cmap == None) {
    fprintf(stderr, "Can't allocate color.\n");
    exit(1);
  }

  /* Install colormap to hardware palette */
  XSetWindowColormap(display, window, cmap);
  XInstallColormap(display, cmap);
#else
  cmap = XDefaultColormap(display, screen);
#endif

  /*-------------------------------------------------------------------------*/
  /* Change cursor */
  /*-------------------------------------------------------------------------*/
#if USE_SMALL_CURSOR
  {
    Pixmap csource;
    Cursor curs;
    XColor xcolor_fore, xcolor_back;

    xcolor_fore.red = 65535;
    xcolor_fore.green = 65535;
    xcolor_fore.blue = 65535;
    xcolor_fore.flags = DoRed | DoGreen | DoBlue;

    xcolor_back.red = 65535;
    xcolor_back.green = 65535;
    xcolor_back.blue = 65535;
    xcolor_back.flags = DoRed | DoGreen | DoBlue;

    csource = XCreatePixmap(display, root, 1, 1, 1);

    curs = XCreatePixmapCursor(display,
			       csource, None, &xcolor_fore, &xcolor_back,
			       0, 0);
    XDefineCursor(display, window, curs);
    XRecolorCursor(display, curs, &xcolor_fore, &xcolor_back);
    XWarpPointer(display, None, root, 0, 0, 0, 0, 0, 0);
  }

#endif

  /*-------------------------------------------------------------------------*/
  /* Draw colorbar */
  /*-------------------------------------------------------------------------*/
  draw_colorbar(display, window, cmap);
  
  /*-------------------------------------------------------------------------*/
  /* Event loop */
  /*-------------------------------------------------------------------------*/

  /* Request for events */
  XSelectInput(display, window,
	       ExposureMask
	       | KeyPressMask | KeyReleaseMask
	       | ButtonReleaseMask | ButtonPressMask
	       | VisibilityChangeMask
	       );
  
  /* To synchronize redrawing, send exposure event to our window */
  event.type = Expose;
  XSendEvent(display, window, True, ExposureMask, &event);

  done = 0;
  while (! done) {
    XNextEvent(display, &event);
    switch (event.type) {
    case VisibilityNotify:
      /* When other window is mapped on our window, raise window */
      /* and redraw colorbar */
      XMapRaised(display, window);
      draw_colorbar(display, window, cmap);
      break;
    case Expose:
      /* If part of our window was exposured, redraw */
      if (event.xexpose.count == 0) {
	draw_colorbar(display, window, cmap);
      }
      break;
    case ButtonPress:
      break;
    case ButtonRelease:
      /* done = 1; */
      break;
    case KeyPress:
      done = 1;
      break;
    case KeyRelease:
      done = 1;
      break;
    case MappingNotify:
      XRefreshKeyboardMapping((XMappingEvent *)(&event));
      break;
    default:
      break;
    }
  }

  return 0;
}

/*---------------------------------------------------------------------------*/
/* End of file */
/*---------------------------------------------------------------------------*/
