/* This module, and the entire ModuleDebugger program, and the concept for
 * interfacing this module to the Window Manager, are all original work
 * by Robert Nation
 *
 * Copyright 1994, Robert Nation. No guarantees or warantees or anything
 * are provided or implied in any way whatsoever. Use this program at your
 * own risk. Permission to use this program for any purpose is given,
 * as long as the copyright is kept intact. */

/* Modified for AfterStep by Dan Weeks, 1996
 */

#define TRUE 1
#define FALSE 

#include "../../configure.h"

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <ctype.h>
#ifdef ISC /* Saul */
#include <sys/bsdtypes.h> /* Saul */
#endif /* Saul */
 
#include <stdlib.h>
#if defined ___AIX || defined _AIX || defined __QNX__ || defined ___AIXV3 || defined AIXV3 || defined _SEQUENT_
#include <sys/select.h>
#endif

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>

#include "../../afterstep/module.h"

#include "../../lib/aftersteplib.h"       
#include "Pager.h"
#include "../../version.h"
#include "../../afterstep/afterstep.h"

char *MyName;
int fd_width;
int fd[2];

/*************************************************************************
 * 
 * Screen, font, etc info
 *
 **************************************************************************/
ScreenInfo Scr;
PagerWindow *Start = NULL;
PagerWindow *FocusWin = NULL;

Display *dpy;			/* which display are we talking to */
int x_fd,fd_width;

char *PagerFore = "black";
char *PagerBack="white";
char *font_string = "fixed";
char *smallFont = NULL;
char *HilightC = "black";

char *HiBack = "white";
char *HiFore = "black";

int window_w=0, window_h=0, window_x=0, window_y=0;
int icon_x=-10000, icon_y=-10000, icon_w=0, icon_h=0;
int usposition = 0,uselabel = 1;
extern DeskInfo *Desks;
int StartIconic = 0;
int Rows = -1, Columns = -1;
int desk1=0, desk2 =0;
int ndesks = 0;
int StickyIcons = 0;
/***********************************************************************
 *
 *  Procedure:
 *	main - start of module
 *
 ***********************************************************************/
void main(int argc, char **argv)
{
  char *temp, *s, *cptr;
  char *display_name = NULL;
  int itemp,i;
  char line[100];
  char mask_mesg[50];

  /* Save our program  name - for error messages */
  temp = argv[0];
  s=strrchr(argv[0], '/');
  if (s != NULL)
    temp = s + 1;
  
  MyName = safemalloc(strlen(temp)+2);
  strcpy(MyName, temp);
  
  if((argc != 7)&&(argc != 6))
    {
      fprintf(stderr,"%s Version %s should only be executed by afterstep!\n",MyName,
	      VERSION);
      exit(1);
    }
  if(argc != 7)
    { 
      fprintf(stderr,"%s Version %s requires an argument: %s n m\n",
	      MyName,VERSION,MyName);
      fprintf(stderr,"   where desktops n through m are displayed\n");
      exit(1);
    }
  
  /* Dead pipe == AS died */
  signal (SIGPIPE, DeadPipe);  
  
  fd[0] = atoi(argv[1]);
  fd[1] = atoi(argv[2]);
  
  fd_width = GetFdWidth();
  
  cptr = argv[6];
  while((isspace(*cptr))&&(*cptr != 0))cptr++;
  desk1 = atoi(cptr);
  while(!(isspace(*cptr))&&(*cptr != 0))cptr++;
  while((isspace(*cptr))&&(*cptr != 0))cptr++;
  desk2 = atoi(cptr);
  if(desk2 < desk1)
    {
      itemp = desk1;
      desk1 = desk2;
      desk2 = itemp;
    }
  ndesks = desk2 - desk1 + 1;
  
  Desks = (DeskInfo *)malloc(ndesks*sizeof(DeskInfo));
  for(i=0;i<ndesks;i++)
    {
      sprintf(line,"Desk %d",i+desk1);
      CopyString(&Desks[i].label,line);
    }
  
  /* Initialize X connection */
  if (!(dpy = XOpenDisplay(display_name))) 
    {
      fprintf(stderr,"%s: can't open display %s", MyName,
	      XDisplayName(display_name));
      exit (1);
    }
  x_fd = XConnectionNumber(dpy);
  
  Scr.screen= DefaultScreen(dpy);
  Scr.Root = RootWindow(dpy, Scr.screen);
  if(Scr.Root == None) 
    {
      fprintf(stderr,"%s: Screen %d is not valid ", MyName, (int)Scr.screen);
      exit(1);
    }
  Scr.d_depth = DefaultDepth(dpy, Scr.screen);

  sprintf(mask_mesg,"SET_MASK %lu\n",(unsigned long)(M_ADD_WINDOW|
    M_CONFIGURE_WINDOW|
    M_DESTROY_WINDOW|
    M_FOCUS_CHANGE|
    M_NEW_PAGE|
    M_NEW_DESK|
    M_RAISE_WINDOW|
    M_LOWER_WINDOW|
    M_ICONIFY|
    M_ICON_LOCATION|
    M_DEICONIFY|
    M_ICON_NAME|
    M_END_WINDOWLIST));
  SendInfo(fd,mask_mesg,0);

  ParseOptions(argv[3]);
  
  /* open a pager window */
  initialize_pager();
  
  /* Create a list of all windows */
  /* Request a list of all windows,
   * wait for ConfigureWindow packets */
  SendInfo(fd,"Send_WindowList",0);
  
  Loop(fd);
}

/***********************************************************************
 *
 *  Procedure:
 *	Loop - wait for data to process
 *
 ***********************************************************************/
void Loop(int *fd)
{
  XEvent Event;
  
  while(1)
    {
      if(My_XNextEvent(dpy,&Event))
	DispatchEvent(&Event);
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	Process message - examines packet types, and takes appropriate action
 *
 ***********************************************************************/
void process_message(unsigned long type,unsigned long *body)
{
  switch(type)
    {
    case M_ADD_WINDOW:
      list_configure(body);
      break;
    case M_CONFIGURE_WINDOW:
      list_configure(body);
      break;
    case M_DESTROY_WINDOW:
      list_destroy(body);
      break;
    case M_FOCUS_CHANGE:
      list_focus(body);
      break;
    case M_NEW_PAGE:
      list_new_page(body);
      break;
    case M_NEW_DESK:
      list_new_desk(body);
      break;
    case M_RAISE_WINDOW:
      list_raise(body);
      break;
    case M_LOWER_WINDOW:
      list_lower(body);
      break;
    case M_ICONIFY:
    case M_ICON_LOCATION:
      list_iconify(body);
      break;
    case M_DEICONIFY:
      list_deiconify(body);
      break;
    case M_ICON_NAME:
      list_icon_name(body);
      break;
    case M_END_WINDOWLIST:
      list_end();
      break;
    default:
      list_unknown(body);
      break;
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	SIGPIPE handler - SIGPIPE means afterstep is dying
 *
 ***********************************************************************/
void DeadPipe(int nonsense)
{
  exit(0);
}

/***********************************************************************
 *
 *  Procedure:
 *	list_add - displays packet contents to stderr
 *
 ***********************************************************************/
void list_add(unsigned long *body)
{
  PagerWindow *t,**prev;
  int i=0;
  
  t = Start;
  prev = &Start;
  while(t!= NULL)
    {
      prev = &(t->next);
      t = t->next;
      i++;
    }
  *prev = (PagerWindow *)safemalloc(sizeof(PagerWindow));
  (*prev)->w = body[0];
  (*prev)->t = (char *)body[2];
  (*prev)->frame = body[1];
  (*prev)->x = body[3];
  (*prev)->y = body[4];
  (*prev)->width = body[5];
  (*prev)->height = body[6];
  (*prev)->desk = body[7];
  (*prev)->next = NULL;
  (*prev)->flags = body[8];
  (*prev)->icon_name = NULL;
  (*prev)->title_height = body[9];
  (*prev)->border_width = body[10];
  (*prev)->icon_w = body[19];
  (*prev)->icon_pixmap_w = body[20];
  (*prev)->text = body[22];
  (*prev)->back = body[23];
  AddNewWindow(*prev);
}

/***********************************************************************
 *
 *  Procedure:
 *	list_configure - displays packet contents to stderr
 *
 ***********************************************************************/
void list_configure(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t== NULL)
    {
      list_add(body);

    }
  else
    {
      t->t = (char *)body[2];
      t->frame = body[1];
      t->frame_x = body[3];
      t->frame_y = body[4];
      t->frame_width = body[5];
      t->frame_height = body[6];
      t->title_height = body[9];
      t->border_width = body[10];
      t->flags = body[8];
      t->icon_w = body[19];
      t->icon_pixmap_w = body[20];
      t->text = body[22];
      t->back = body[23];
      if(t->flags & ICONIFIED)
	{
	  t->x = t->icon_x;
	  t->y = t->icon_y;
	  t->width = t->icon_width;
	  t->height = t->icon_height;
	  if(t->flags & SUPPRESSICON)
	    {
	      t->x = -10000;
	      t->y = -10000;
	    }
	}
      else
	{
	  t->x = t->frame_x;
	  t->y = t->frame_y;
	  t->width = t->frame_width;
	  t->height = t->frame_height;
	}
      if(t->desk != body[7])
	{
	  ChangeDeskForWindow(t,body[7]);
	}
      
      else
	MoveResizePagerView(t);
      if(FocusWin == t)
	Hilight(t,ON);
      else
	Hilight(t,OFF);
    }
}

/***********************************************************************
 *
 *  Procedure:
 *	list_destroy - displays packet contents to stderr
 *
 ***********************************************************************/
void list_destroy(unsigned long *body)
{
  PagerWindow *t,**prev;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  prev = &Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      prev = &(t->next);
      t = t->next;
    }
  if(t!= NULL)
    {
      if(prev != NULL)
	*prev = t->next;
      /* remove window from the chain */
      if(t->PagerView != None)
	XDestroyWindow(dpy,t->PagerView);
      XDestroyWindow(dpy,t->IconView);
      if(FocusWin == t)
	FocusWin = NULL;
      
      free(t);
    }
}

/***********************************************************************
 *
 *  Procedure:
 *	list_focus - displays packet contents to stderr
 *
 ***********************************************************************/
void list_focus(unsigned long *body)
{
  PagerWindow *t,*temp;
  Window target_w;
  
  target_w = body[0];
  
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t != FocusWin)
    {
      temp = FocusWin;
      FocusWin = t;
      
      if(temp != NULL)
	Hilight(temp,OFF);
      if(FocusWin != NULL)
	Hilight(FocusWin,ON);
    }
}

/***********************************************************************
 *
 *  Procedure:
 *	list_new_page - displays packet contents to stderr
 *
 ***********************************************************************/
void list_new_page(unsigned long *body)
{
  Scr.Vx = (long)body[0];
  Scr.Vy = (long)body[1];
  Scr.CurrentDesk = (long)body[2];
  MovePage();
  MoveStickyWindows();
  Hilight(FocusWin,OFF);
  Hilight(FocusWin,ON);
}

/***********************************************************************
 *
 *  Procedure:
 *	list_new_desk - displays packet contents to stderr
 *
 ***********************************************************************/
void list_new_desk(unsigned long *body)
{
  int oldDesk;
  
  oldDesk = Scr.CurrentDesk;
  Scr.CurrentDesk = (long)body[0];
  
  MovePage();
  
  DrawGrid(oldDesk - desk1,1);
  DrawGrid(Scr.CurrentDesk - desk1,1);
  MoveStickyWindows();
  Hilight(FocusWin,OFF);
  Hilight(FocusWin,ON);
}

/***********************************************************************
 *
 *  Procedure:
 *	list_raise - displays packet contents to stderr
 *
 ***********************************************************************/
void list_raise(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t!= NULL)
    {
      if(t->PagerView != None)
	XRaiseWindow(dpy,t->PagerView);
      XRaiseWindow(dpy,t->IconView);      
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	list_lower - displays packet contents to stderr
 *
 ***********************************************************************/
void list_lower(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t!= NULL)
    {
      if(t->PagerView != None)
	XLowerWindow(dpy,t->PagerView);
      if((t->desk - desk1>=0)&&(t->desk - desk1<ndesks))
	XLowerWindow(dpy,Desks[t->desk - desk1].CPagerWin);
      XLowerWindow(dpy,t->IconView);
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	list_unknow - handles an unrecognized packet.
 *
 ***********************************************************************/
void list_unknown(unsigned long *body)
{
  /*  fprintf(stderr,"Unknown packet type\n");*/
}

/***********************************************************************
 *
 *  Procedure:
 *	list_iconify - displays packet contents to stderr
 *
 ***********************************************************************/
void list_iconify(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t== NULL)
    {
      return;
    }
  else
    {
      t->t = (char *)body[2];
      t->frame = body[1];
      t->icon_x = body[3];
      t->icon_y = body[4];
      t->icon_width = body[5];
      t->icon_height = body[6];
      t->flags |= ICONIFIED;
      t->x = t->icon_x;
      t->y = t->icon_y;
      if(t->flags & SUPPRESSICON)
	{
	  t->x = -10000;
	  t->y = -10000;
	}
      t->width = t->icon_width;
      t->height = t->icon_height;
      MoveResizePagerView(t);
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	list_deiconify - displays packet contents to stderr
 *
 ***********************************************************************/

void list_deiconify(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t== NULL)
    {
      return;
    }
  else
    {
      t->flags &= ~ICONIFIED;
      t->x = t->frame_x;
      t->y = t->frame_y;
      t->width = t->frame_width;
      t->height = t->frame_height;
      MoveResizePagerView(t);
      if(FocusWin == t)
	Hilight(t,ON);
      else
	Hilight(t,OFF);
    }
}


/***********************************************************************
 *
 *  Procedure:
 *	list_icon_name - displays packet contents to stderr
 *
 ***********************************************************************/
void list_icon_name(unsigned long *body)
{
  PagerWindow *t;
  Window target_w;
  
  target_w = body[0];
  t = Start;
  while((t!= NULL)&&(t->w != target_w))
    {
      t = t->next;
    }
  if(t!= NULL)
    {
      if(t->icon_name != NULL)
	free(t->icon_name);
      CopyString(&t->icon_name,(char *)(&body[3]));
      LabelWindow(t);
      LabelIconWindow(t);
    }
}




/***********************************************************************
 *
 *  Procedure:
 *	list_end - displays packet contents to stderr
 *
 ***********************************************************************/
void list_end(void)
{
  unsigned int nchildren,i;
  Window root, parent, *children;
  PagerWindow *ptr;
  
  if(!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren))
    return;
  
  for(i=0; i<nchildren;i++)
    {
      ptr = Start;
      while(ptr != NULL)
	{
	  if((ptr->frame == children[i])||(ptr->icon_w == children[i])||
	     (ptr->icon_pixmap_w == children[i]))
	    {
	      if(ptr->PagerView != None)
		XRaiseWindow(dpy,ptr->PagerView);
	      XRaiseWindow(dpy,ptr->IconView);
	    }
	  ptr = ptr->next;
	}
    }
  
  
  if(nchildren > 0)
    XFree((char *)children);
}




/***************************************************************************
 *
 * Waits for next X event, or for an auto-raise timeout.
 *
 ****************************************************************************/
int My_XNextEvent(Display *dpy, XEvent *event)
{
  fd_set in_fdset;
  unsigned long header[3];
  int body_length;
  int count,count2 = 0;
  static int miss_counter = 0;
  unsigned long *body;
  int total;
  char *cbody;
  
  if(XPending(dpy))
    {
      XNextEvent(dpy,event);
      return 1;
    }
  
  FD_ZERO(&in_fdset);
  FD_SET(x_fd,&in_fdset);
  FD_SET(fd[1],&in_fdset);
  
#ifdef __hpux
  select(fd_width,(int *)&in_fdset, 0, 0, NULL);
#else
  select(fd_width,&in_fdset, 0, 0, NULL);
#endif  
  
  if(FD_ISSET(x_fd, &in_fdset))
    {
      if(XPending(dpy))
	{
	  XNextEvent(dpy,event);
	  miss_counter = 0;
	  return 1;
	}
      else
	miss_counter++;
      if(miss_counter > 100)
	DeadPipe(0);
    }
  
  if(FD_ISSET(fd[1], &in_fdset))
    {
      if(count = ReadASPacket(fd[1],header,&body) > 0)
	 {
	   process_message(header[1],body);
	   free(body);
	 }
    }
  return 0;
}



/*****************************************************************************
 * 
 * This routine is responsible for reading and parsing the config file
 *
 ****************************************************************************/
void ParseOptions(char *filename)
{
  FILE *fd = (FILE *)0;
  char line[256];
  char *tline,*orig_tline,*tmp;
  int Clength,n,desk;
  
  Scr.ASRoot = NULL;
  Scr.Hilite = NULL;
  Scr.VScale = 32;
  
  Scr.MyDisplayWidth = DisplayWidth(dpy, Scr.screen);
  Scr.MyDisplayHeight = DisplayHeight(dpy, Scr.screen);
  
  Scr.VxMax = 3*Scr.MyDisplayWidth - Scr.MyDisplayWidth;
  Scr.VyMax = 3*Scr.MyDisplayHeight - Scr.MyDisplayHeight;
  if(Scr.VxMax <0)
    Scr.VxMax = 0;
  if(Scr.VyMax <0)
    Scr.VyMax = 0;
  Scr.Vx = 0;
  Scr.Vy = 0;
  
  fd = fopen(filename,"r");
  if(fd == (FILE *)0)
    {
      fprintf(stderr,"%s: can't open config file %s",MyName,filename);
      exit(1);
    }
  
  tline = fgets(line,(sizeof line)-1,fd);
  orig_tline = tline;
  Clength = strlen(MyName);
  while(tline != (char *)0)
    {
      int g_x, g_y, flags;
      unsigned width,height;
      
      while(isspace(*tline))tline++;
      
      if((strlen(&tline[0])>1)&&
	 (mystrncasecmp(tline, CatString3("*", MyName, "Geometry"),Clength+9)==0))
	{
	  tmp = &tline[Clength+9];
	  while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
	    {
	      tmp++;
	    }
	  tmp[strlen(tmp)-1] = 0;
	  
	  flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height);
	  if (flags & WidthValue) 
	    window_w = width;
	  if (flags & HeightValue) 
	    window_h = height;
	  if (flags & XValue) 
	    {
	      window_x = g_x;
	      usposition = 1;
	    }
	  if (flags & YValue) 
	    {
	      window_y = g_y;
	      usposition = 1;
	    }
	}
      else if((strlen(&tline[0])>1)&&
	 (mystrncasecmp(tline, CatString3("*", MyName, "IconGeometry"),
		      Clength+13)==0))
	{
	  tmp = &tline[Clength+13];
	  while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
	    {
	      tmp++;
	    }
	  tmp[strlen(tmp)-1] = 0;
	  
	  flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height);
	  if (flags & WidthValue) 
	    icon_w = width;
	  if (flags & HeightValue) 
	    icon_h = height;
	  if (flags & XValue) 
	    {
	      icon_x = g_x;
	    }
	  if (flags & YValue) 
	    {
	      icon_y = g_y;
	    }
	}
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"Label"),Clength+6)==0))
	{
	  desk = desk1;
	  sscanf(&tline[Clength+6],"%d",&desk);
	  if((desk >= desk1)&&(desk <=desk2))
	    {
	      n = 0;
	      while(isspace(tline[Clength+6+n]))n++;
	      while(!isspace(tline[Clength+6+n]))n++;
	      free(Desks[desk - desk1].label);
	      CopyString(&Desks[desk - desk1].label,&tline[Clength+6+n]);
	    }
	}
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline, CatString3("*", MyName, "Font"),Clength+5)==0))
	{
	  CopyString(&font_string,&tline[Clength+5]);
	  if(mystrncasecmp(font_string,"none",4) == 0)
	    uselabel = 0;

	}
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline, CatString3("*", MyName, "Fore"),Clength+5)==0))
	{
	  CopyString(&PagerFore,&tline[Clength+5]);
	}
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*", MyName, "Back"),Clength+5)==0))
	{
	  CopyString(&PagerBack,&tline[Clength+5]);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"Hilight"),Clength+8)==0))
	{
	  if(Scr.d_depth > 1)
	    CopyString(&HilightC,&tline[Clength+8]);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"SmallFont"),
			   Clength+10)==0))
	{
	  CopyString(&smallFont,&tline[Clength+10]);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"StartIconic"),
			   Clength+12)==0))
	{
	  StartIconic = 1;
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"Rows"),
			   Clength+5)==0))
	{
	  sscanf(&tline[Clength+5],"%d",&Rows);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,CatString3("*",MyName,"Columns"),
			   Clength+8)==0))
	{
	  sscanf(&tline[Clength+8],"%d",&Columns);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,"HiBackColor",11)==0))
	{
	  if(Scr.d_depth > 1)
	    CopyString(&HiBack,&tline[11]);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,"HiForeColor",11)==0))
	{
	  if(Scr.d_depth > 1)
	    CopyString(&HiFore,&tline[11]);
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,"StickyIcons",11)==0))
	{
	  StickyIcons = 1;
	}	
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,"DeskTopSize",11)==0))
	{
	  sscanf(&tline[11],"%dx%d",&Scr.VxMax,&Scr.VyMax);
	  Scr.VxMax = Scr.VxMax*Scr.MyDisplayWidth - Scr.MyDisplayWidth;
	  Scr.VyMax = Scr.VyMax*Scr.MyDisplayHeight - Scr.MyDisplayHeight;
	}
      else if((strlen(&tline[0])>1)&&
	      (mystrncasecmp(tline,"DeskTopScale",12)==0))
	{
	  sscanf(&tline[12],"%d",&Scr.VScale);
	}
      tline = fgets(line,(sizeof line)-1,fd);
      orig_tline = tline;
    }
  return;
}





syntax highlighted by Code2HTML, v. 0.9.1