/*===========================================================================
  Copyright (C) 1990-2009 European Southern Observatory (ESO)
 
  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 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/


/* 
	Xtest.c  K.Banse   901206 creation

	execute via:  Xtest.exe [visual]
        with visual = P (PseudoColor)
                      T (TrueColor)
                      D (DirectColor)
                      X (Default Visual)
                      ? (for help))


  another way of obtaining the X11 capabilities of the display is to use
  the command: xdpyinfo


 090709		last modif

*/

# include <stdio.h>
# include <stdlib.h>
# include <idi.h>
# include <x11defs.h>

unsigned int border = 2;            /* pad border */
Window w, fw;

char  *cpntr, root;

static char   *display = "";  
static char midas[6] = "MIDAS";
char  cbuf[24], defbuf[24];

int   once, i, j, k, n;	
int   redget[2], redput[2];
int   option, dwidth, dheight, ddepth, reqclass;
int   oldx, oldy, RGBord;
int   xoff , yoff , status;
int   cbufsiz, count;
int   nf, winfla, dplanes;
int   colormapsize, sys_colors, plot_colors;
int   kred, jalloc, ioff, revert_to, iend;
int   visid[6], visex[6], visdepth[6], viscolsize[6];
int   reqvis, redm, greenm, bluem, redsz, greensz, bluesz;
int   swapit;

unsigned int   xdim , ydim;
unsigned long int  mywhite, myblack, pixels[256], plane_mask[2], maska;
unsigned long int  valuemask;
long int    backpixel, mypixel;

GC     gcimb, newgc;
XColor wh1, wh2, bbl1, bbl2, bl1, bl2, red1, red2;
XColor green1, green2, yel1, yel2, blu1, blu2;
XColor mag1, mag2, cyan1, cyan2;
XKeyEvent   *xkeypntr;
XMappingEvent  *mapevent;
XVisualInfo *vlist, *vl;
XImage  *txima[2];
Status  logstat;

static int   visclass[6] = {TrueColor, DirectColor, PseudoColor,
                    StaticColor, GrayScale, StaticGray};

static char *red_col = "red", *bl_col = "black", *wh_col = "white";
static char *blu_col = "blue", *yel_col = "yellow", *green_col = "green";
static char *mag_col = "magenta", *cyan_col = "cyan";

unsigned short int  XSWAP_SHORT();
unsigned int  XSWAP_INT();
int getvisual(), build32(), build24(), build16(), build8();
int findendian(), test_swap(), curs_demo(), text_demo(), own_test();
int getsomecols();

/*

*/

int main(argc,argv)
int argc;
char *argv[];

{
int  kargc;

char  *disp_var, *kargv;



(void) printf("\n******   X Window test program of Midas  ******\n");



/* Connect to X server */

#if vms
mydisp[0] = XOpenDisplay("DECW$DISPLAY");
#else

if (!(disp_var = getenv("DISPLAY")))
   {
   printf("\n<<<<<   You have to set the variable DISPLAY first!   >>>>>\n");
   exit(1);
   }
mydisp[0] = XOpenDisplay(display);
#endif

if (!mydisp[0])
   {
   printf("we got an error in XOpenDisplay!\n");
   return (-1);
   }


oldx = -99;
root = 0;
sys_colors = 0;
plot_colors = 0;

myscreen = DefaultScreen(mydisp[0]);
mywhite = WhitePixel(mydisp[0],myscreen);
myblack = BlackPixel(mydisp[0],myscreen);
rw[0] = RootWindow(mydisp[0],myscreen);

dwidth = DisplayWidth(mydisp[0],myscreen);
dheight = DisplayHeight(mydisp[0],myscreen);
ddepth = DefaultDepth(mydisp[0],myscreen);
dplanes = DisplayPlanes(mydisp[0],myscreen);
printf ("\nOn screen %d we have:\n", myscreen);
printf("Display width, height, depth, no_planes = %d, %d, %d, %d \n",
        dwidth,dheight,ddepth,dplanes);

option = 0;
myvis[0] = XDefaultVisual(mydisp[0],myscreen);
if (myvis[0]->class == GrayScale)
   strcpy(defbuf,"GrayScale");
else if (myvis[0]->class == StaticGray)
   strcpy(defbuf,"StaticGray");
else if (myvis[0]->class == PseudoColor)
   strcpy(defbuf,"PseudoColor");
else if (myvis[0]->class == StaticColor)
   strcpy(defbuf,"StaticColor");
else if (myvis[0]->class == TrueColor)
   {
   option = 2;
   strcpy(defbuf,"TrueColor");
   }
else if (myvis[0]->class == DirectColor)
   {
   option = 1;
   strcpy(defbuf,"DirectColor");
   }
else
   {
   printf("class looks exotic, value = %d\n",myvis[0]->class);
   exit(1);
   }

(void) printf("\nDefault Visual (id = 0x%x) is %s\n",(unsigned int) myvis[0]->visualid,defbuf);



/*  get list of all possible Visuals */

vlist = XGetVisualInfo(mydisp[0],VisualNoMask,&vinfo,&nf);
if (nf < 1)
   {
   (void) printf("\nNo Visuals available...\n");
   exit(1);
   }


k = 0;
for (vl=vlist; vl<vlist+nf; vl++)
   {
   if (vl->screen == myscreen) k++;
   }
(void) printf("\nNo. of Visuals: %d\n",k);

for (n=0; n<6; n++) visex[n] = 0;		/* = 1 if exists */

for (vl=vlist; vl<vlist+nf; vl++)
   {
   if (vl->screen == myscreen)
      {
      for (n=0; n<6; n++)
         {
         if (vl->class == visclass[n])
            {
            if (visclass[n] == GrayScale)
               {
               strcpy(cbuf,"GrayScale");		/* j = 0 */
               j = 0;
               }
            else if (visclass[n] == StaticGray)
               {
               strcpy(cbuf,"StaticGray");		/* j = 1 */
               j = 1;
               }
            else if (visclass[n] == PseudoColor)
               {
               strcpy(cbuf,"PseudoColor");		/* j = 2 */
               j = 2;
               }
            else if (visclass[n] == StaticColor)
               {
               strcpy(cbuf,"StaticColor");		/* j = 3 */
               j = 3;
               }
            else if (visclass[n] == TrueColor)
               {
               strcpy(cbuf,"TrueColor");		/* j = 4 */
               j = 4;
               }
            else if (visclass[n] == DirectColor)
               {
               strcpy(cbuf,"DirectColor");		/* j = 5 */
               j = 5;
               }
            visex[j] ++;
            if (visex[j] == 1)
               {
               visid[j] = vl->visualid;
               visdepth[j] = vl->depth;
               viscolsize[j] = vl->colormap_size;
               }
            }
         }
      j = vl->colormap_size;
      (void) printf("visual id: 0x%x\n",(unsigned int)vl->visualid); 
      (void) printf("  class: %s\n",cbuf);
      (void) printf("  depth: %d planes, colormap size: %d entries\n",vl->depth,j);
      }
   }

(void) printf("\n\n");


winfla = 1;

if (argc > 1)
   {
   cpntr = argv[1];
   if ((*cpntr == '?') || (*cpntr == 'h'))
      {
      (void) printf("usage:\nXtest.exe arg1\n");
      (void) 
      printf("arg1 = T for using TrueColor visual mode (if available)\n");
      (void) 
      printf("     = D for using DirectColor visual mode (if available)\n");
      (void) printf
      ("     = P for using PseudoColor visual mode - which is the default\n");
      (void) printf
      ("     = P_L for using PseudoColor without color LUT\n");
      (void) printf("     = X for using the default Visual\n");
      (void) exit(1);
      }

   if ((*cpntr == 'T') || (*cpntr == 't'))
      {
      reqclass = TrueColor;
      reqvis = 4;
      option = 2;
      }
   else if ((*cpntr == 'D') || (*cpntr == 'd'))
      {
      reqclass = DirectColor;
      reqvis = 5;
      option = 1;
      }
   else if ((*cpntr == 'P') || (*cpntr == 'p'))
      {
      reqclass = PseudoColor;
      reqvis = 2;
      option = 0;
      cpntr += 2;
      if ((*cpntr == 'L') || (*cpntr == 'l')) option = -1;
      }
  
   else if ((*cpntr == 'X') || (*cpntr == 'x'))
      {
      reqvis = 99;
      goto get_visual;
      }

   if (visex[reqvis] == -1)
      {
      printf("required visual not found...\n");
      exit(1);
      }
   }

else
   reqvis = 99;			/* take the default visual */


get_visual:
getvisual(reqvis);


xdim = 512;
ydim = 512;
xoff = 0;
yoff = dheight - 1 - ydim - (2*border) + 200;


/* we have to set the border, background pixel (default is CopyFromParent,
   which could lead to BadMatch) ... */

valuemask = CWBorderPixel | CWBackPixel | CWColormap | CWOverrideRedirect;
backpixel = myblack;
sattributes.border_pixel = (unsigned long int) backpixel;
sattributes.background_pixel = (unsigned long int) backpixel;
sattributes.colormap = cmap[0][winfla];
sattributes.override_redirect = False;
w = XCreateWindow (mydisp[0],rw[0],
                   xoff, yoff, xdim, ydim, border,ddepth,
                   InputOutput,myvis[0],valuemask,&sattributes);
if (w == 0)
   {
   printf("we got an error in XCreateWindow!\n");
   exit(1);
   }

XFlush (mydisp[0]);


/* set Window Manager hints  */

xwmh.initial_state = NormalState;
xwmh.input = True;
xwmh.flags = InputHint | StateHint;
XSetWMHints(mydisp[0],w,&xwmh);

myhint[0].x = xoff, myhint[0].y = yoff;
myhint[0].width = xdim;
myhint[0].height = ydim;
myhint[0].flags = USPosition | USSize;

kargc = 0;
XSetStandardProperties(mydisp[0],w,midas,midas,
                       None,&kargv,kargc,&myhint[0]);

gcimb = XCreateGC(mydisp[0],w,0,&xgcvals);
maska = 0xffffffff;
XSetBackground(mydisp[0],gcimb,0);
XSetForeground(mydisp[0],gcimb,0xffffffff);
XSetPlaneMask(mydisp[0],gcimb,maska);
XSetFunction(mydisp[0],gcimb,GXxor);

red1.pixel = mycolr[0][kred].pixel;
mycurs[0][0] = XCreateFontCursor(mydisp[0],XC_arrow);
XRecolorCursor(mydisp[0],mycurs[0][0],&red1,&wh1);
XDefineCursor(mydisp[0],w,mycurs[0][0]);

event_mask = KeyPressMask | PointerMotionMask | ButtonPressMask | ExposureMask;

XSync(mydisp[0],1);
XSelectInput(mydisp[0],w,event_mask);

XMapRaised (mydisp[0],w);

printf("we now make a %d*%d window\n",xdim,ydim);
xdim = 512, ydim = 200;
printf("and fill it with a %d*%d intensity image at the top\n",xdim,ydim);

XWindowEvent(mydisp[0],w,event_mask,&myevent);
XFlush (mydisp[0]);


/* prepare the image  */

nf = ddepth;                       /* bitmap pad */
if (nf == 24) nf = 32;

txima[0] = XCreateImage(mydisp[0],myvis[0],ddepth,ZPixmap,0,None,
                     xdim,ydim,nf,0);

(void) printf("\nImage structure attributes:\n");
(void) printf("width = %d, height = %d\n",txima[0]->width,txima[0]->height);
(void) printf("xoffset = %d, format = %d\n",txima[0]->xoffset,txima[0]->format);
(void) printf("bitmap_unit = %d, bitmap_pad = %d, depth = %d\n",
       txima[0]->bitmap_unit,txima[0]->bitmap_pad,txima[0]->depth);
if (txima[0]->byte_order == LSBFirst)
   (void) strcpy(cbuf,"LSBFirst");
else
   (void) strcpy(cbuf,"MSBFirst");
(void) printf("bytes_per_line = %d, bits_per_pixel = %d, byte_order = %s\n",
       txima[0]->bytes_per_line,txima[0]->bits_per_pixel,cbuf);


n = txima[0]->bytes_per_line * ydim;
txima[0]->data = malloc((size_t)n);

if (txima[0]->data == (char *)0)
   {
   (void) printf("problems allocating %d bytes\n",n);
   exit(1);
   }

txima[1] = XCreateImage(mydisp[0],myvis[0],ddepth,ZPixmap,0,None,
                     xdim,ydim,nf,0);
txima[1]->data = malloc((size_t)n);

if (txima[1]->data == (char *)0)
   {
   (void) printf("problems allocating %d bytes\n",n);
   exit(1);
   }



/***************************************************/
/* now build the image  */
/***************************************************/

xoff = 0;
yoff = 0;
once = 0;
swapit = 0;			/* swap bytes flag */
newgc = XCreateGC(mydisp[0],w,0,&xgcvals);

byte_swap_loop:
if (ddepth == 32)
   redm = build32(txima[once]->data,xdim,ydim,root,1);
else if (ddepth == 24)
   {
   redm = build24(txima[once]->data,xdim,ydim,root,1);
   redm = redm & 0x00ffffff;
   }
else if (ddepth == 16)
   {
   redm = build16(txima[once]->data,xdim,ydim,root,1);
   redm = redm & 0x0000ffff;
   }
else
   (void) build8(txima[once]->data,xdim,ydim,root,1);


XPutImage(mydisp[0],w,newgc,txima[once],0,0,xoff,yoff,xdim,ydim);
mypixel = XGetPixel(txima[once],510,70);
printf("XGetPixel returns %x at (510,70)\n",(unsigned int)mypixel);

if (ddepth > 8)
   {
   redget[once] = mypixel;
   redput[once] = redm;

   yoff += 200;
   once ++;

   if (once < 2)
      {
      (void) findendian();

      swapit = test_swap(mydisp[0]);
      if (swapit == 0)
         (void) printf("no byte swapping needed... \n");
      else
         (void) printf("Yes - byte swapping needed... \n");
      if (swapit == 1) goto byte_swap_loop;
      }
   }

(void) 
printf("\n>> move the pointer into the window + press any mouse button\n");
(void) 
printf(">> the pointer should be a red arrow inside the mapped window\n");


/***************************************************/
/* now set up the event loop for mouse buttons */
/***************************************************/

event_loop:
XWindowEvent(mydisp[0],w,event_mask,&myevent);
XRecolorCursor(mydisp[0],mycurs[0][0],&red1,&wh1);
XDefineCursor(mydisp[0],w,mycurs[0][0]);

switch (myevent.type)
   {
   case MotionNotify:
   /* (void) printf(" the pointer moved ...\n"); */
   event_mask = ButtonPressMask ;
   XSync(mydisp[0],1);
   XSelectInput(mydisp[0],w,event_mask);
   goto event_loop;

   case ButtonPress:
   (void) printf(" button no., x, y, state: %d, %d, %d, %d \n",
   myevent.xbutton.button,
   myevent.xbutton.x,myevent.xbutton.y,myevent.xbutton.state);
   if (myevent.xbutton.button == 1)
      {
      n = 0;				/* if within the 2 loaded images */
      j = myevent.xbutton.y;		/* get the pixel value */
      if (j > 199)
         {
         j -= 200;
         n = 1;
         }
      if (j < 200)
         {
         mypixel = XGetPixel(txima[n],myevent.xbutton.x,j);
         printf("XGetPixel returns %x \n",(unsigned int)mypixel);
         }

      event_mask = ButtonPressMask ;
      XSync(mydisp[0],1);
      XSelectInput(mydisp[0],w,event_mask);
      }
   if (myevent.xbutton.button == 2)
      {
      XRecolorCursor(mydisp[0],mycurs[0][0],&bl1,&wh1);
      XDefineCursor(mydisp[0],w,mycurs[0][0]);
      XSetFunction(mydisp[0],gcimb,GXxor);
      XFlush(mydisp[0]);
      if (oldx != -99)
         {
         XDrawLine(mydisp[0],w,gcimb,0,oldy,511,oldy);
         XDrawLine(mydisp[0],w,gcimb,oldx,0,oldx,511);
         XFlush(mydisp[0]);
         }
      XDrawLine(mydisp[0],w,gcimb,0,myevent.xbutton.y,511,myevent.xbutton.y);
      XDrawLine(mydisp[0],w,gcimb,myevent.xbutton.x,0,myevent.xbutton.x,511);
      oldx = myevent.xbutton.x;
      oldy = myevent.xbutton.y;
      event_mask = ButtonPressMask ;
      XSync(mydisp[0],1);
      XSelectInput(mydisp[0],w,event_mask);
      }
   if (myevent.xbutton.button == 3)
      {
      (void) printf("\n>> with pointer in the window\n");
      (void) printf(">> press any key on the keyboard (RETURN to exit),\n");
      (void) printf(">> press 'up_arrow' for a demo of the X cursors,\n");
      (void) printf(">> press 'down_arrow' for a demo of the X fonts\n");
      goto next_step;
      }
   }
goto event_loop;

next_step:
(void) printf("\n");
XGetInputFocus(mydisp[0],&fw,&revert_to);
if (fw == None)
   (void) printf("focus window = None\n");
else
   (void) printf("focus window, root window, image window = %d, %d, %d\n",
          (int)fw,(int)rw[0],(int)w);
if (revert_to == RevertToParent)
   (void) printf("revert_to = RevertToParent\n");
else if (revert_to == RevertToPointerRoot)
   (void) printf("revert_to = RevertToPointerRoot\n");
else if (revert_to == RevertToNone)
   (void) printf("revert_to = RevertToNone\n");
else
   (void) printf("revert_to = %d (what is it?)\n",revert_to);

(void) printf("\n>> with pointer in the window\n");
(void) printf(">> press any key on the keyboard (RETURN to exit),\n");
(void) printf(">> press 'up_arrow' for a demo of the X cursors,\n");
(void) printf(">> press 'down_arrow' for a demo of the X fonts\n");

XSetInputFocus(mydisp[0],w,RevertToParent,CurrentTime);
(void) printf("\n");

mapevent = (XMappingEvent *) &myevent;
xkeypntr = (XKeyEvent *) &myevent;
XRefreshKeyboardMapping(mapevent);
XSync(mydisp[0],1);
event_mask = KeyPressMask ;
XSync(mydisp[0],1);
XSelectInput(mydisp[0],w,event_mask);

nevent_loop:
XWindowEvent(mydisp[0],w,event_mask,&myevent);
cbufsiz = 20;

switch (myevent.type)
   {
   case KeyPress:
   count = XLookupString(xkeypntr,cbuf,cbufsiz,&mykey,&xcstat);
   cbuf[count] = '\0';
   (void) printf("count, cbuf = %d, %s\n",count,cbuf);
   (void) printf(".xkey.keycode = %d\n",myevent.xkey.keycode);
   (void) printf(".xkey.x, .xkey.y = %d,%d\n",myevent.xkey.x,myevent.xkey.y);
   if (mykey == XK_Up)
      {
      (void) printf("key is XK_Up\n");
      curs_demo(w);
      (void) printf("with pointer in the window\n");
      (void) printf("press any key on the keyboard, RETURN to exit\n");
      }
   else if (mykey == XK_Down)
      {
      (void) printf("key is XK_Down\n");
      text_demo(w,gcimb);
      (void) printf("with pointer in the window\n");
      printf("press any key on the keyboard, RETURN to exit\n");
      }
   else if (mykey == XK_Left)
      (void) printf("key is XK_Left\n");
   else if (mykey == XK_Right)
      {
      (void) printf("key is XK_Right\n");
      own_test(1);
      (void) printf("\npress any key on the keyboard, RETURN to exit\n");
      }

   if (mykey == XK_Return) goto end_of_it;
   break;

   case MappingNotify:
   XRefreshKeyboardMapping(mapevent);
   break;

   default:
   (void) printf("default case: eventtype = %d\n",myevent.type);
   break;
   }

goto nevent_loop;


end_of_it:
(void) printf("\n\nAdios muchachos - this is the end ... \n");

exit(0);
}

/*

*/

int getvisual(novis)
int  novis;

{
int  isw;

void makeLUT(), makeRGBLUT();

char   visbuf[16];



isw = 0;
if (novis == 99)		/* we take the default visual */
   {
   (void) printf("We take default Visual (id 0x%x) with default depth = %d,",
                  (unsigned int)myvis[0]->visualid,ddepth);
   (void) strcpy(visbuf,defbuf);
   for (j=0; j<6; j++)
      {
      if (myvis[0]->visualid == visid[j])
         {
         colormapsize = viscolsize[j];
         reqvis = j;
         }
      }
   (void) printf("colormap_size = %d\n",colormapsize);
   reqclass = myvis[0]->class;
   }
else
   {
   if (novis == 5)
      {
      (void) strcpy(visbuf,"DirectColor");
      isw = DirectColor;
      }
   else if (novis == 4)
      {
      (void) strcpy(visbuf,"TrueColor");
      isw = TrueColor;
      }
   else
      {
      (void) strcpy(visbuf,"PseudoColor");
      isw = PseudoColor;
      }
   ddepth = visdepth[novis];
   }

(void) printf("\n******   using %s Mode   ******\n\n",visbuf);


if (myvis[0]->class != reqclass)
   {
   logstat = XMatchVisualInfo(mydisp[0],myscreen,ddepth,isw,&vinfo);
   if (logstat)
      {
      myvis[0] = vinfo.visual;
      (void) printf
         ("We found %sVisual (id 0x%x) with depth = %d, colormap_size = %d\n",
         visbuf,(unsigned int)vinfo.visualid,vinfo.depth,vinfo.colormap_size);
      colormapsize = vinfo.colormap_size;
      }
   else
      {
      printf("we could not get a %s Visual ...!\n",visbuf);
      exit(1);
      }
   }


redm = myvis[0]->red_mask;
greenm = myvis[0]->green_mask;
bluem = myvis[0]->blue_mask;
(void) printf("red_mask = %8.8x, green_mask = %8.8x, blue_mask = %8.8x\n",
              redm,greenm,bluem);

if (redm < bluem)
   {
   RGBord = 0;
   (void) printf("RGBord = %d (B G R)\n",RGBord);
   }
else
   {
   RGBord = 1;
   (void) printf("RGBord = %d (R G B)\n",RGBord);
   }

count = myvis[0]->bits_per_rgb;
if (reqvis != 2)
   {
   redsz = greensz = bluesz = 0;
   k = 0x0001;			/* only bit 0 set */
   for (n=0; n<ddepth; n++)
      {
      if ((redm & k) > 0) redsz ++;
      if ((greenm & k) > 0) greensz ++;
      if ((bluem & k) > 0) bluesz ++;
      k = k << 1;
      }
   }

(void) 
printf("bits_per_rgb = %d   -   redsz = %d, greensz = %d, bluesz = %d\n\n",
       count,redsz,greensz,bluesz);


printf("option used internally for choosing colors = %d\n",option);

cmap[0][0] = DefaultColormap(mydisp[0],myscreen);
if (option < 1)
   {
   if (option == 0)
      winfla = 0;
   else
      cmap[0][1] = XCreateColormap(mydisp[0],rw[0],myvis[0],AllocNone);
   }
else
   cmap[0][1] = XCreateColormap(mydisp[0],rw[0],myvis[0],AllocNone);


if (option == 1)
   makeRGBLUT(myvis[0]->map_entries);
else if (option == 2)
   getsomecols(1);
else
   {
   if (option == -1)
      {
      makeRGBLUT(myvis[0]->map_entries);
      getsomecols(0);
      }
   else
      makeLUT();
   }

return 0;
}

/*

*/

int build8(data,xsiz,ysiz,root,incr)
unsigned char  *data, root, incr;
int            xsiz, ysiz;

{
int   nx,ny;

unsigned char shred, shgreen, shblue, modred, modgreen, modblue;
unsigned char pixval, jred, jgreen, jblue;
unsigned char  *jdata, myroot;

unsigned char shift80[3] = { 0,3,6};	/* red,green,blue for RGBord 0 */
unsigned char shift81[3] = { 5,2,0};	/* red,green,blue for RGBord 1 */




myroot = 0;
jdata = data;

printf("\nbuilding 8 bit image...\n");

if (reqvis == 2)			/* pseudocolor */
   {
   for (ny=0; ny<ysiz; ny++)
      {
      myroot = root;
      for (nx=0; nx<xsiz; nx+=2)
         {
         *jdata++ = myroot;
         *jdata++ = myroot;
         myroot ++;
         }
      }
   return (int) myroot;
   }


/* here for true/direct colour with 8 bits */

if (RGBord != 1)
   {
   shred = shift80[0];
   shgreen = shift80[1];
   shblue = shift80[2];
   }
else
   {
   shred = shift81[2];
   shgreen = shift81[1];
   shblue = shift81[0];
   }

modred = 5;            /* red size = 3 bits */
modgreen = 5;          /* green size = 3 bits */
modblue = 6;           /* blue size = 2 bits */


/* first we show a grayscale */

printf("displaying a grayscale band on top \n");

for (ny=0; ny<50; ny++)
   {
   myroot = (unsigned char) root;	/* that should be a grayscale */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jred = jgreen = jblue = myroot;
      jred = jred >> modred;
      jgreen = jgreen >> modgreen;
      jblue = jblue >> modblue;

      jred   = jred << shred;
      jgreen = jgreen << shgreen;
      jblue = jblue << shblue;
      pixval = jred | jgreen | jblue;

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot ++;
      }
   }


printf("displaying a scale in red below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in red */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jred = myroot;
      jred = jred >> modred;
      jred   = jred << shred;

      *jdata++ = jred;
      *jdata++ = jred;
      myroot ++;
      }
   }


printf("displaying a scale in green below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in green */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jgreen = myroot;
      jgreen = jgreen >> modgreen;
      jgreen   = jgreen << shgreen;

      *jdata++ = jgreen;
      *jdata++ = jgreen;
      myroot ++;
      }
   }


printf("displaying a scale in blue below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in blue */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jblue = myroot;
      jblue = jblue >> modblue;
      jblue   = jblue << shblue;

      *jdata++ = jblue;
      *jdata++ = jblue;
      myroot ++;
      }
   }

return 0;				/* return value not needed here */
}

/*

*/

int build16(data,xsiz,ysiz,root,incr)

char  *data, root, incr;
int            xsiz, ysiz;

{
int   nx, ny, retval;
short int pixval, jblue, jgreen, jred;
short int *jdata;
short int myroot, myincr;
short int shred, shgreen, shblue, modred, modgreen, modblue;

static int shift16[3] =
        {
         0,               /* red/blue for RGBord 0/1 */
         5,               /* green */
         11               /* blue/red for RGBord 0/1 */
        };



pixval = 0;
jdata = (short int *) data;
myincr = (short int) incr;

printf("\nbuilding 16 bit image...\n");


if (RGBord != 1)
   {
   shred = shift16[0];
   shgreen = shift16[1];
   shblue = shift16[2];
   }
else
   {
   shred = shift16[2];
   shgreen = shift16[1];
   shblue = shift16[0];
   }

modred = 3;            /* red size = 5 bits */
modgreen = 2;          /* green size = 6 bits */
modblue = 3;           /* blue size = 5 bits */


/* first we show a grayscale */

printf("displaying a grayscale band on top \n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a grayscale */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jred = jgreen = jblue = myroot;
      jred = jred >> modred;
      jgreen = jgreen >> modgreen;
      jblue = jblue >> modblue;

      jred   = jred << shred;
      jgreen = jgreen << shgreen;
      jblue = jblue << shblue;
      pixval = jred | jgreen | jblue;

if (swapit != 0) pixval = XSWAP_SHORT(pixval);

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot ++;
      }
   }

printf("displaying a scale in red below - ");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in red */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jred = myroot;
      jred = jred >> modred;
      jred   = jred << shred;
      pixval = jred;

if (swapit != 0) pixval = XSWAP_SHORT(pixval);

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot ++;
      }
   }

printf("full red pixel: %x\n",pixval);
retval = (int) pixval;

printf("displaying a scale in green below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in green */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jgreen = myroot;
      jgreen = jgreen >> modgreen;
      jgreen = jgreen << shgreen;
      pixval = jgreen;

if (swapit != 0) pixval = XSWAP_SHORT(pixval);

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot ++;
      }
   }

printf("displaying a scale in blue below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;                 /* that should be a scale in blue */
   for (nx=0; nx<xsiz; nx+=2)
      {
      jblue = myroot;
      jblue = jblue >> modblue;
      jblue = jblue << shblue;
      pixval = jblue;

if (swapit != 0) pixval = XSWAP_SHORT(pixval);

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot ++;
      }
   }

return retval;
}


int build24(data,xsiz,ysiz,root,incr)

char  *data, root, incr;
int            xsiz, ysiz;

{
int *idata;
int nx, ny, pixval, ired, igreen, iblue;
int myroot, myincr, retval;
int shred, shgreen, shblue, modred, modgreen, modblue;

static int  shift24[3] =
        {
         0,               /* red/blue for RGBord 0/1 */
         8,               /* green */
         16               /* blue/red for RGBord 0/1 */
        };



pixval = 0;
idata = (int *) data;
myincr = (int) incr;

printf("\nbuilding 24 bit image...\n");


if (RGBord != 1)
   {
   shred = shift24[0];
   shgreen = shift24[1];
   shblue = shift24[2];
   }
else
   {
   shred = shift24[2];
   shgreen = shift24[1];
   shblue = shift24[0];
   }
modred = modgreen = modblue = 0;       /* all have size = 8 bits */


/* first we show a grayscale */

printf("displaying a grayscale band on top \n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;			/* that should be a grayscale */
   for (nx=0; nx<xsiz; nx+=2)
      {
      ired = igreen = iblue = myroot;
      ired = ired >> modred;
      igreen = igreen >> modgreen;
      iblue = iblue >> modblue;

      ired   = ired << shred;
      igreen = igreen << shgreen;
      iblue = iblue << shblue;
      pixval = ired | igreen | iblue;

      if (swapit != 0) pixval = XSWAP_INT(pixval);

      *idata++ = pixval;
      *idata++ = pixval;
      myroot ++;
      }
   }


printf("displaying a scale in red below - ");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;			/* that should be a scale in red */
   for (nx=0; nx<xsiz; nx+=2)
      {
      ired = myroot;
      ired = ired >> modred;
      pixval   = ired << shred;

      if (swapit != 0) pixval = XSWAP_INT(pixval);

      *idata++ = pixval;
      *idata++ = pixval;
      myroot ++;
      }
   }

printf("full red pixel: %x\n",pixval);
retval = (int) pixval;

printf("displaying a scale in green below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;			/* that should be a scale in green */
   for (nx=0; nx<xsiz; nx+=2)
      {
      igreen = myroot;
      igreen = igreen >> modgreen;
      pixval   = igreen << shgreen;

      if (swapit != 0) pixval = XSWAP_INT(pixval);

      *idata++ = pixval;
      *idata++ = pixval;
      myroot ++;
      }
   }


printf("displaying a scale in blue below\n");

for (ny=0; ny<50; ny++)
   {
   myroot = (int) root;			/* that should be a scale in blue */
   for (nx=0; nx<xsiz; nx+=2)
      {
      iblue = myroot;
      iblue = iblue >> modblue;
      pixval   = iblue << shblue;

      if (swapit != 0) pixval = XSWAP_INT(pixval);

      *idata++ = pixval;
      *idata++ = pixval;
      myroot ++;
      }
   }

return retval;
}


int build32(data,xsiz,ysiz,root,incr)

char  *data, root, incr;
int            xsiz, ysiz;

{
int nx,ny;
int  *jdata, pixval;
int  myroot, myincr;

char  sroot;


pixval = 0;
jdata = (int *) data;
myincr = (int) incr;
sroot = root;

printf("\nbuilding 32 bit image...\n");

for (ny=0; ny<ysiz; ny++)
   {
   root = sroot;
   myroot = (long int) root;
   for (nx=0; nx<xsiz; nx+=2)
      {
      pixval = myroot;
      if (swapit != 0) pixval = XSWAP_INT(pixval);

      *jdata++ = pixval;
      *jdata++ = pixval;
      myroot += pixval;
      }
   }

return pixval;
}
/*

*/

int findendian(void)

{
/* my own version:

int  *endian;
unsigned char hilo[4];

endian = (int *) &hilo[0];
*endian = 0x1256abef;


if (hilo[0] == 0x12)
   {
   printf("\nWe have a big-endian architecture\n");
   return 1;
   }
else
   {
   printf("\nWe have a little-endian architecture\n");
   return 0;
   }
*/

/* the version from "Linux Kernel development": */

int  x = 1;



if (* (char *) &x == 1)
   {
   printf("\nWe have a little-endian architecture\n");
   return 0;
   }

else

   {
   printf("\nWe have a big-endian architecture\n");
   return 1;
   }
}



/* function `test_swap()' is also stored in the IDI-library,
   so it can be used in Xwstinit()  */

int test_swap(mydisp)
Display  *mydisp;

{
int   nn, mm;
int  *endian;
unsigned char hilo[4];



/* find byte order at Xhost */

nn = XImageByteOrder(mydisp);
if (nn == LSBFirst)
   nn = 0;				/* least signif. byte first */
else
   nn = 1;				/* most signif. byte first */


/* get byte order locally */

endian = (int *) &hilo[0];
*endian = 0x1256abef;
if (hilo[0] == 0x12)

   /* the most significant byte (0x12) is stored first,
      we have a big-endian architecture */
   mm = 1;

else
   
   /* the most significant byte (0x12) is stored last,
      we have a little-endian architecture */
   mm = 0;


if (mm == nn)
   return 0;
else
   return 1;
}
/*

*/

int  getsomecols(indx)
int  indx;

{
XAllocNamedColor(mydisp[0],cmap[0][indx],wh_col,&wh1,&wh2) ;
XAllocNamedColor(mydisp[0],cmap[0][indx],bl_col,&bl1,&bl2);
XAllocNamedColor(mydisp[0],cmap[0][indx],bl_col,&bbl1,&bbl2);
XAllocNamedColor(mydisp[0],cmap[0][indx],red_col,&red1,&red2);
XAllocNamedColor(mydisp[0],cmap[0][indx],green_col,&green1,&green2);
XAllocNamedColor(mydisp[0],cmap[0][indx],blu_col,&blu1,&blu2);
XAllocNamedColor(mydisp[0],cmap[0][indx],yel_col,&yel1,&yel2);
XAllocNamedColor(mydisp[0],cmap[0][indx],mag_col,&mag1,&mag2);
XAllocNamedColor(mydisp[0],cmap[0][indx],cyan_col,&cyan1,&cyan2);

printf
("XColor red:   pixel = %8.8x, red = %d, green = %d, blue = %d\n",
(int)red2.pixel,red2.red,red2.green,red2.blue);
printf
("XColor green: pixel = %8.8x, red = %d, green = %d, blue = %d\n",
(int)green2.pixel,green2.red,green2.green,green2.blue);
printf
("XColor blue:  pixel = %8.8x, red = %d, green = %d, blue = %d\n\n",
(int)blu2.pixel,blu2.red,blu2.green,blu2.blue);

return 0;
}

/*

*/

void makeLUT()

{
float  lutval, rval, fval;


k = 512;

color_loop:			/* try to allocate `k' colors */
x11stat = XAllocColorCells(mydisp[0],cmap[0][winfla],0,plane_mask,0,pixels,k);
if (!x11stat)
   {
   k -= 2;
   if (k < 8)
      {
      printf("could not allocate at least %d colours... \n",k);
      k = 0;
      }
   else
      goto color_loop;
   }
   
jalloc = k;
k = myvis[0]->map_entries - k;

if (jalloc > 256)
   {
   n = jalloc / 256;
   if (n > 4) n = 4;			/* max 4 LUTs  */
   jalloc = 256;				/* max 256 colours */
   }
else if (jalloc > 0)
   n = 1;
else
   {
   jalloc = 256;
   n = 0;
   }

for (i=0; i<jalloc; i++)
   {
   mycolr[0][i].pixel = i;
   mycolr[0][i].flags = DoRed | DoGreen | DoBlue;
   }

getsomecols(winfla);

printf("%d colours already allocated by the XWindow Manager\n",k);
printf("first 5 color cells have index: %d, %d, %d, %d, %d\n",
(int)pixels[0],(int)pixels[1],(int)pixels[2],(int)pixels[3],(int)pixels[4]);

/*  get 16 default colours */

if (sys_colors > 0)
   {
   XQueryColors(mydisp[0],DefaultColormap(mydisp[0],myscreen),
             &mycolr[0][0],jalloc);
   XSync(mydisp[0],1);

   if (mywhite > 2)		/* we keep the high end of the LUT  */
      {
      k = jalloc - sys_colors - plot_colors;
      ioff = 0;
      iend = k;
      }
   else				/* we keep the low end of the LUT   */
      {
      k = sys_colors;
      ioff = sys_colors + plot_colors;
      iend = jalloc;
      }
   kred = k + 2;		/* save index  */
   }
else
   {
   ioff = 0;
   iend = jalloc;
   kred = 0;
   k = 0;
   }

mycolr[0][k].red = wh1.red;
mycolr[0][k].green = wh1.green;
mycolr[0][k].blue = wh1.blue;
mycolr[0][k+1].red = bl1.red;
mycolr[0][k+1].green = bl1.green;
mycolr[0][k+1].blue = bl1.blue;
mycolr[0][k+2].red = red1.red;
mycolr[0][k+2].green = red1.green;
mycolr[0][k+2].blue = red1.blue;
mycolr[0][k+3].red = green1.red;
mycolr[0][k+3].green = green1.green;
mycolr[0][k+3].blue = green1.blue;
mycolr[0][k+4].red = blu1.red;
mycolr[0][k+4].green = blu1.green;
mycolr[0][k+4].blue = blu1.blue;
mycolr[0][k+5].red = yel1.red;
mycolr[0][k+5].green = yel1.green;
mycolr[0][k+5].blue = yel1.blue;
mycolr[0][k+6].red = mag1.red;
mycolr[0][k+6].green = mag1.green;
mycolr[0][k+6].blue = mag1.blue;
mycolr[0][k+7].red = cyan1.red;
mycolr[0][k+7].green = cyan1.green;
mycolr[0][k+7].blue = cyan1.blue;


/* load grayscale LUT  */

for (i=0; i<jalloc; i++)			/* reset pixels  */
   mycolr[0][i].pixel = pixels[i];

fval = 0.0;
rval = 1.0 / (jalloc - sys_colors - plot_colors - 1);

for (i=ioff; i<iend; i++)
   {
   lutval = fval * XLUTFACT;
   mycolr[0][i].red = (unsigned short) lutval;
   mycolr[0][i].green = (unsigned short) lutval;
   mycolr[0][i].blue = (unsigned short) lutval;
   fval += rval;
   }

XStoreColors(mydisp[0],cmap[0][winfla],mycolr[0],jalloc);
XFlush(mydisp[0]);

if (sys_colors > 0)
   {
   printf("We copy %d system colours and use %d plot colours\n",
          sys_colors,plot_colors);
   jalloc -= (sys_colors+plot_colors);
   }
   
if (n == 0)
   {
   printf("so we can use no LUT for Midas - bye, bye...\n\n");
   exit(1);
   }
else if (n == 1)
   printf("so we can use a LUT of %d colours.\n\n",jalloc);
else
   {
   printf("We can use %d LUTs of %d colours each for Midas\n\n",n,jalloc);
   printf("You have to edit the file syskeys.dat (see the installation doc)");
   printf(" to modify\nthe contents of the keyword DAZDEVR:\n");
   printf("DAZDEVR(2) = %d, DAZDEVR(3) = %d\n",n,jalloc);
   printf("Another possibility is to execute the MIDAS command\n");
   printf("'initialize/display %d,%d' each time you get into MIDAS.\n\n",
       n,jalloc);
   }
}

/*

*/

void makeRGBLUT(mplen)
int mplen;

{
int    ifact, isw;



if (mplen>256) mplen=256;
 

/* let's build a grayscale LUT */ 
 
ifact = 0xffff / (mplen - 1);
j = 0;
isw = 0;
wh1.flags = DoRed | DoGreen | DoBlue;

for (i=0; i<mplen; i++) 
   {
   wh1.red = wh1.green = wh1.blue = j;
   j += ifact;

   if (XAllocColor(mydisp[0], cmap[0][winfla], &wh1)) isw++;
   }


if (isw != mplen)
   {
   if (isw == 0)
      {
      (void) printf("No entries in LUT!\n");
      exit(1);
      }
   else
      (void) 
      printf("Only %d entries in LUT (of size %d)!\n",isw,mplen);
   }

getsomecols(winfla);
}

unsigned short int  XSWAP_SHORT(jnni)
unsigned short int  jnni;

{
unsigned short int  ja, jb, jn;

jb = jnni & 0xff;               /* input: ab */
ja = (jnni >> 8) & 0xff;

jb = jb << 8;
jn = jb | ja;                   /* output: ba */

return jn;
}




unsigned int  XSWAP_INT(inni)
unsigned int  inni;

{
unsigned short int  ia, ib, ka, kb;
unsigned int  na, nb, nn;


/* input:  abcd */

ib = (short int) (inni & 0xffff);
kb = XSWAP_SHORT(ib);                            /* kb:  dc */
ia = (short int) ((inni >> 16) & 0xffff);
ka = XSWAP_SHORT(ia);                            /* ka: ba */

na = (unsigned int) ka;
nb = (unsigned int) kb;

nb = nb << 16;
nn = nb | na;                           /* output:  dcba */
return nn;
}

