/********************************************************************
This file is part of the abs 0.907 distribution.  abs is a spreadsheet
with graphical user interface.

Copyright (C) 1998-2001  André Bertin (Andre.Bertin@ping.be) 

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 if in the same spirit as version 2.

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.

Concact: abs@pi.be
         http://home.pi.be/bertin/abs.shtml

*********************************************************************/



























#include "callback.h"
#include "callback_decl.h"
#include "inputbox.h"
#include "gr_interf.h"
#include "main.h"
#include "mainwin.h"
#include "memory.h"

#include "cursor.h"
#include "application.h"

#include "finite_state.h"

extern void setscrollv (double v);
extern void setscrollh (double v);

#include "newplot.h"

extern int rebuild_thumb ();

#define StDebug(a) state_print((a))

#define AW ActiveWorksheet
#define CW worksheet_getcolw
#define LH worksheet_getrowh
#define SW worksheet_setcolw
#define SH worksheet_setrowh
#define Letext ActiveMainwin->commandline_obj->text
#define Drawarea ActiveMainwin->draw
#define linindex ActiveMainwin->linindex
#define colindex ActiveMainwin->colindex
#define corner ActiveMainwin->corner
#define toplevel ActiveMainwin->toplevel
#define Infoarea ActiveMainwin->info	
#define DrawAreaPixmap ActiveMainwin->DrawAreaPixmap
#define linpixmap ActiveMainwin->LinPixmap
#define colpixmap ActiveMainwin->ColPixmap
#define cornerpixmap ActiveMainwin->CornerPixmap

#define dpy ActiveMainwin->dpy
#define screen ActiveMainwin->screen
#define AMwin  ActiveMainwin->draw_window
#define Height ActiveMainwin->height
#define Width ActiveMainwin->width



static int Shift = 0;
static int Control = 0;

static Cell *EditedCell = NULL;	


int
cbsetup (Dimension width, Dimension height)
{
  TEXT_WIDGET = Letext;
  setzoom (100);
  init_application ();
  FS->l1 = StCell;
  return 0;
}



int 
DoUndoFormula (int r, int c, char *formula)
{
  char *old = (char *) get_formula (r, c);
  char redo[256];
  char undo[256];

  if (old == NULL)
    sprintf (undo, "Cells(%d,%d).Formula = \"\"\n", r, c);
  else
    {
      sprintf (undo, "Cells(%d,%d).Formula = \"%s\"\n", r, c, old);
    }
  if (formula != NULL)
    sprintf (redo, "Cells(%d,%d).Formula = \"%s\"\n", r, c, formula);
  else
    sprintf (redo, "Cells(%d,%d).Formula = \"\"\n", r, c);

  newmacroline (redo);

  return 0;
}

void
echofct (char *buf)
{
  long p = XawTextGetInsertionPoint (Letext);
  if (p == 0)
    {
      insertstring (Letext, "=");
      KeyPressed (-1);
    }
  insertstring (Letext, buf);
  KeyPressed (-2);
  moveinsertionpoint (Letext, -1);

}

void 
stopedit ()
{
  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    a_update ();
}

void
a_update ()
{
  char *buf;
  char *str;



  if (ActiveWorksheet != NULL)
    {
      if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
	{
	  str = GetEntryString (Letext);
	  if (str == NULL)
	    return;
	  
	  
	  
	  
	  
	  

	  
	  
	  
	  
	  
	  
	  
	  
	  
	  
	  
	  
	  
	  buf = str;

	  cell_activate ((Cell *) applicationcell (AW->cur_r, AW->cur_c, 1));
	  DoUndoFormula (AW->cur_r, AW->cur_c, buf);
	  set_formula (AW->cur_r, AW->cur_c, buf);


	}
    }

  if (FS->l1 == StCell && FS->l2 == EDITING)
    {
      SetEntryString (Letext, "");
      SetEntryString (ActiveMainwin->cell, "");
      LetextLooseFocus ();

      state_reset_levels ();
      FS->l1 = StCell;

      popdownactivecell ();
      xdrawcell (AW->cur_r, AW->cur_c, 4, 0);
    }
  return;
}


int
inform (char *str)
{
  return mainwin_inform (str);
}





int 
repaint_activesheet (char *message)
{
  char tmp[256];
  sprintf (tmp, "repaint_activesheet(%s)", message);
  if (FS->l1 != StGrap)
    resetselect (0, 0, 0);
  xrepaint (tmp);
  return 0;
}

int 
selectingto0 ()
{
  
  return 0;
}



int
setcursor (int r, int c)
{
  int oldr, oldc;
  char *label;

  if (AW == NULL)
    return -1;
  if (FS->l1 == StGrap || FS->l1 == StBatch)
    return 0;			

  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    a_update ();

  LetextGetFocus ();
  FS->l1 = StCell;
  FS->l2 = 0;
  FS->l3 = 0;

  oldr = AW->cur_r;
  oldc = AW->cur_c;
  worksheet_setcursor (AW, r, c);

  xdrawlincell (oldr, 0, 0);
  xdrawcolcell (0, oldc, 0);
  xdrawlincell (AW->cur_r, 0, 0);
  xdrawcolcell (0, AW->cur_c, 0);
  clearwin (linindex);
  clearwin (colindex);

  setselection (AW->cur_r, AW->cur_c, AW->cur_r, AW->cur_c);

  set_visible (AW->cur_r, AW->cur_c);
  label = (char *) get_formula (AW->cur_r, AW->cur_c);
  if (label != NULL)
    {
      SetEntryString (Letext, label);
      SetEntryString (ActiveMainwin->cell, label);
    }
  else
    {
      SetEntryString (Letext, "");
      SetEntryString (ActiveMainwin->cell, "");
    }

  xdrawcursor (0, 0);
  copypix ("setcursor:after xdrawcursor");
  return 0;
}


int
movecursor (int dr, int dc)
{
  int oldr, oldc;
  char *label;

  if (AW == NULL)
    return -1;


  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    a_update ();


  LetextGetFocus ();

  if (FS->l2 != HAND)		
    {
      FS->l1 = StCell;
      FS->l2 = 0;
      FS->l3 = 0;
    }

  oldr = AW->cur_r;
  oldc = AW->cur_c;
  worksheet_movecursor (AW, dr, dc);
  xdrawlincell (oldr, 0, 0);
  xdrawcolcell (0, oldc, 0);
  xdrawlincell (AW->cur_r, 0, 0);
  xdrawcolcell (0, AW->cur_c, 0);
  clearwin (linindex);
  clearwin (colindex);

  if (FS->l2 != HAND)
    {
      setselection (AW->cur_r, AW->cur_c, AW->cur_r, AW->cur_c);
      
      set_visible (AW->cur_r, AW->cur_c);
    }

  label = (char *) get_formula (AW->cur_r, AW->cur_c);
  if (label != NULL)
    {
      SetEntryString (Letext, label);
      SetEntryString (ActiveMainwin->cell, label);
    }
  else
    {
      SetEntryString (Letext, "");
      SetEntryString (ActiveMainwin->cell, label);
    }

  xdrawcursor (0, 0);
  copypix ("movecursor:after xdrawcursor");
  return 0;
}

static int hnumover = 0;
static int vnumover = 0;

int
popupactivecell ()
{
  int cheight, cwidth;
  int width, height;
  int i = AW->cur_r;
  int j = AW->cur_c;
  char *str = GetEntryString (Letext);
  int font = cell_getfont (ActiveCell);
  int fontw = cell_getfontw (ActiveCell);
  int fonts = cell_getfonts (ActiveCell);

  int x1 = CW (AW, j) - CW (AW, AW->cc) - 1;
  int y1 = LH (AW, i) - LH (AW, AW->ll) - 1;
  int x2, y2;

  x2 = CW (AW, j + 1 + hnumover) - CW (AW, AW->cc);
  y2 = LH (AW, i + 1 + vnumover) - LH (AW, AW->ll);
  width = x2 - x1;
  height = y2 - y1;

  cheight = gettexth (str, strlen (str), font, fontw, fonts);
  cwidth = gettextw (str, strlen (str), font, fontw, fonts) + 5;

  SetEntryString (ActiveMainwin->cell, GetEntryString (Letext));

  if (width < cwidth || height < cheight)
    {
      popdowncell ();

    }

  while (width < cwidth && hnumover < 50)
    {
      hnumover++;
      x2 = CW (AW, j + 1 + hnumover) - CW (AW, AW->cc);
      width = x2 - x1;

    }
  while (height < cheight && vnumover < 50)
    {
      vnumover++;
      y2 = LH (AW, i + 1 + vnumover) - LH (AW, AW->ll);
      height = y2 - y1;
    }

  popupcell (x1 * AW->zoom / 100, y1 * AW->zoom / 100, width, height);
  return 0;
}

int
popdownactivecell ()
{
  hnumover = 0;
  vnumover = 0;
  popdowncell ();
  return 0;
}







void
cb_TextChange ()
{				
  KeyPressed (-3);
}

int 
KeyPressed (int key)
{
  char message[64];
  sprintf (message, "KeyPressed(%d)", key);
  StDebug (message);

  if (FS->l1 == StGrap && FS->l2 == StCell)
    {
      restoretopleft ();
      popupactivecell ();
      return -3;
    }

  if (FS->l1 == StButton && FS->l3 == StUp)
    {
    };

  if (FS->l1 != StCell)
    return -1;
  if (FS->l2 == StMotion)
    {
      FS->l2 = 0;
      return -2;
    }

  if (FS->l2 != EDITING)
    {
      if (key != 22 &&		
	  key != 98 &&		
	  key != 100 &&		
	  key != 102 &&		
	  key != 104)		
	{
	  char label[3];
	  char *buf = GetEntryString (Letext);

	  if (key != -3)	
	    {

	      strncpy (label, buf, 1);	
	      label[1] = '\0';
	      SetEntryString (Letext, label);
	    }
	  popupactivecell ();
	  moveinsertionpoint (Letext, 1);	
	  FS->l2 = EDITING;
	  FS->l3 = MODIFIED;
	  storetopleft ();
	}
    }

  if (FS->l3 == MODIFIED)
    {
      if (key == 105 ||		
	  key == 97 ||		
	  key == 99 ||		
	  key == 103)		
	{
	  popdownactivecell ();
	  return 0;
	}
      else
	{
	  restoretopleft ();
	  popupactivecell ();
	  
	}
    }

  return 0;
}

void
cb_TextReturn (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  movecursor (1, 0);
  FS->l2 = StMotion;
}

void
cb_TextUp (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  movecursor (-1, 0);
  FS->l2 = StMotion;
}

void
cb_TextDown (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  movecursor (1, 0);
  FS->l2 = StMotion;
}

void
cb_TextLeft (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  
  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    {
      if (!moveinsertionpoint (Letext, -1))
	return;
    }
  movecursor (0, -1);
  FS->l2 = StMotion;
}

void
cb_TextRight (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  
  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    {
      if (!moveinsertionpoint (Letext, 1))
	return;
    }
  movecursor (0, 1);
  FS->l2 = StMotion;
}

void
cb_Delete (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  if ((FS->l1 == StCell && FS->l2 != EDITING) || FS->l1 == StSelection)
    {
      m_cut ();
      return;
    }

  if (FS->l1 == StCell && FS->l2 == EDITING)
    w = Letext;
  
  if (!EntryDelChr (w) && FS->l1 == StCell && FS->l2 == EDITING)
    FS->l3 = MODIFIED;
  return;
}

void
cb_BackSpace (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  if ((FS->l1 == StCell && FS->l2 != EDITING) || FS->l1 == StSelection)
    {
      return;
    }

  if (FS->l1 == StCell && FS->l2 == EDITING)
    w = Letext;
  if (!EntryBackChr (w) && FS->l1 == StCell && FS->l2 == EDITING)
    FS->l3 = MODIFIED;
  return;
}

void
cb_DocDelete ()
{
  stopedit ();
  m_cut ();
}




void
cb_Shift (int shift)
{
  Shift = shift;

}
void
cb_Control (int control)
{				
  Control = control;
}

void
cb_PageHome (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  settopleft (1, 1);
  if (!(FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED))
    {
      setcursor (1, 1);
      FS->l2 = StMotion;
    }
}

void
cb_PageUp (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i1, j1, i2, j2;
  int h;
  get_visible_cells (&i1, &j1, &i2, &j2);
  h = i2 - i1 - 1;
  if (i1 - h < 1)
    h = i1 + 1;
  settopleft (i1 - h, -1);
  if (!(FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED))
    {
      movecursor (-h, 0);
      FS->l2 = StMotion;
    }
}

void
cb_PageDown (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i1, j1, i2, j2;
  get_visible_cells (&i1, &j1, &i2, &j2);

  settopleft (i2 - 1, -1);

  if (!(FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED))
    {
      movecursor ((i2 - i1 - 1), 0);
      FS->l2 = StMotion;
    }
}

void
cb_PageLeft (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i1, j1, i2, j2;
  int h;
  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    return;

  get_visible_cells (&i1, &j1, &i2, &j2);
  h = j2 - j1;
  j1 -= h + 1;
  if (j1 < 1)
    j1 = 1;

  settopleft (-1, j1);
  movecursor (0, -(j2 - j1 - 2));
  FS->l2 = StMotion;
}

void
cb_PageRight (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i1, j1, i2, j2;
  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    return;

  get_visible_cells (&i1, &j1, &i2, &j2);

  settopleft (-1, j2 - 1);
  movecursor (0, (j2 - j1 - 2));
  FS->l2 = StMotion;

}






void
cb_DocMotion (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int x, y, absx, absy;
  int xmin, xmax, ymin, ymax;
  int i1, i2, j1, j2, k;

  


  if (FS->l1 == StCell && FS->l2 == EDITING)
    return;


  x = event->xbutton.x * 100 / AW->zoom;
  y = event->xbutton.y * 100 / AW->zoom;
  absx = x + CW (AW, AW->cc);
  absy = y + LH (AW, AW->ll);


  if (FS->l1 == StDrawing)
    {
      Drawing *dr;
      movex = x;
      movey = y;
      absmovex = movex + CW (AW, AW->cc);
      absmovey = movey + LH (AW, AW->ll);

      if (FS->l2 == READYEDITDRAWING)
	{
	  for (k = 0; k < getnumdra (); k++)
	    {
	      dr = (Drawing *) getdra (k);
	      if (drawing_pointed (dr, absmovex, absmovey, 5, 5) && ActiveDrawing != dr)
		{
		  ActivateDrawing (dr);
		  worksheet_select_drawing (AW, dr);
		  clearnflush ();
		  drawselect ();
		}
	    }
	}
      return;
    }


  if (FS->l1 == StChart)
    {
      if (ActiveGraph == NULL)
	return;			
      xa = ActiveGraph->x;
      ya = ActiveGraph->y;
      xb = xa + ActiveGraph->w;
      yb = ya + ActiveGraph->h;
      FS->l4 = TurnOnLimitCursor (Drawarea, xa, ya, xb, yb, absx, absy);
      StDebug ("cursor set for chart");
      return;
    }


  if (w == colindex)
    {				
      TurnOnHand (colindex);
      return;
    }
  if (w == linindex)
    {				
      TurnOnHand (linindex);
      return;
    }
  if (w == corner)
    {				
      TurnOnHand (corner);
      return;
    }



  if (FS->l1 == StBrush)
    return;

  if (FS->l1 == StUndefined)
    {
      state_reset_levels ();
      get_select (&i1, &j1, &i2, &j2);
      if (i1 == 0 && j1 == 0)
	FS->l1 = StCell;
      else
	FS->l1 = StSelection;
    }


  get_select (&i1, &j1, &i2, &j2);
  if (i1 == 0 && j1 == 0 && ActiveCell != NULL)
    {
      i1 = i2 = ActiveCell->r;
      j1 = j2 = ActiveCell->c;
    }

  ijtoxy (i1, j1, &xmin, &ymin);
  ijtoxy (i2 + 1, j2 + 1, &xmax, &ymax);

  if ((FS->l1 == StCell || FS->l1 == StSelection))
    {
      if (xmin < x && x < xmax && ymin - 3 < y && y < ymin + 3)
	{
	  if (FS->l2 != HAND)
	    {
	      TurnOnHand (Drawarea);
	      FS->l2 = HAND;
	    }
	  return;
	}

      if (FS->l2 == HAND)
	{
	  TurnOffCursor (Drawarea);
	  FS->l2 = 0;
	}

      if (xmax - 3 < x && x < xmax + 3 && ymax - 3 < y && y < ymax + 3)
	{
	  if (FS->l2 != EXTEND_SELECT)
	    {
	      TurnOnBottomRight (Drawarea);
	      FS->l2 = EXTEND_SELECT;
	    }
	  return;
	}

      if (FS->l2 == EXTEND_SELECT)
	{
	  TurnOffCursor (Drawarea);
	  FS->l2 = 0;
	}
    }

}



void
cb_DocBtn1Down (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i, j, k;
  int x, y;
  Graph *gr;
  Button *btn;

  x = event->xbutton.x * 100 / AW->zoom;
  y = event->xbutton.y * 100 / AW->zoom;

  downx = x;
  downy = y;
  absdownx = downx + CW (AW, AW->cc);
  absdowny = downy + LH (AW, AW->ll);

  FS->downx = x;
  FS->downy = y;
  StDebug ("Btn1Down");

  xytoij (downx, downy, &i, &j);

  downi = i;
  downj = j;
  lasti = i;
  lastj = j;

  BTN1_STATE = DOWN;

  if (FS->l1 == StDrawing)
    {
      if (w != Drawarea)
	return;			

      if (FS->l2 == READYEDITDRAWING && ActiveDrawing != NULL)
	{
	  FS->l2 = EDITINGDRAWING;
	  lx = x;
	  ly = y;
	  if (abs (ActiveDrawing->x1 - absdownx) <= 5 && abs (ActiveDrawing->y1 - absdowny) <= 5)
	    {
	      TurnOnTopLeft (Drawarea);
	      FS->l3 = TOP_LEFT;
	    }
	  else if (abs (ActiveDrawing->x2 - absdownx) <= 5 && abs (ActiveDrawing->y2 - absdowny) <= 5)
	    {
	      TurnOnBottomRight (Drawarea);
	      FS->l3 = BOTTOM_RIGHT;
	    }
	  else
	    {
	      TurnOnMove (Drawarea);
	      FS->l3 = CROSS;
	    }
	}
      return;
    }


  if (w == colindex)
    {
      stopedit ();		
      FS->l1 = StBorder;	
      FS->l2 = StColindex;
      FS->l3 = StDown;

      xytoclotherij (downx, downy, &i, &j);
      cj = j;
      lx = downx;
      
      return;
    }
  if (w == linindex)
    {
      stopedit ();		
      FS->l1 = StBorder;	
      FS->l2 = StLinindex;
      FS->l3 = StDown;

      xytoclotherij (downx, downy, &i, &j);
      li = i;
      ly = downy;
      
      return;
    }
  if (w == corner)
    {
      stopedit ();		
      FS->l1 = StBorder;	
      FS->l2 = StCorner;
      FS->l3 = StDown;

      
      return;
    }



  if (FS->l1 == StChart)
    {
      if (FS->l2 == CREATE_CHART)
	{
	  FS->l3 = StDown;
	  return;
	}
      if (FS->l2 == SELECT_CHART)
	{
	  if (FS->l4 == BOTTOM_LEFT ||
	      FS->l4 == BOTTOM_RIGHT ||
	      FS->l4 == TOP_RIGHT ||
	      FS->l4 == TOP_SIDE ||
	      FS->l4 == RIGHT_SIDE ||
	      FS->l4 == BOTTOM_SIDE ||
	      FS->l4 == LEFT_SIDE ||
	      FS->l4 == TOP_LEFT)
	    {
	      lx = downx;
	      ly = downy;
	      return;
	    }

	  gr = worksheet_getchart_at (ActiveWorksheet, absdownx, absdowny);
	  if (gr == ActiveGraph)
	    {
	      TurnOnMove (Drawarea);
	      FS->l4 = CMOVE;
	      lx = downx;
	      ly = downy;
	      return;
	    }
	  else
	    {			
	      worksheet_select_graph (ActiveWorksheet, NULL);
	      ActiveGraph = NULL;
	      state_reset_levels ();
	      copypix ("cb_docbtn1down:after click out of the active chart");	
	    }
	}
    }


  if (FS->l1 == StGrap)
    {
      copypix ("cb_docbtn1down:StGrap basic state");
      drawselectbox (downi, downj, downi, downj);
      FS->l3 = StDown;
      return;
    }

  if (FS->l1 == StBrush)
    {
      copypix ("cb_docbtn1down:StBrush basic state");
      drawselectbox (downi, downj, downi, downj);
      FS->l3 = StDown;
      return;
    }



  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == HAND)
    {
      FS->l3 = StDown;
      return;
    }

  if (FS->l1 == StCell && FS->l2 == EXTEND_SELECT)
    {
      FS->l3 = StDown;
      FS->downr = ActiveCell->r;
      FS->downc = ActiveCell->c;
      StDebug ("start extend select");
      return;
    }

  if (FS->l1 == StSelection && FS->l2 == EXTEND_SELECT)
    {
      int i1, i2, j1, j2;
      get_select (&i1, &j1, &i2, &j2);
      if (i1 == i2 && j1 == j2)
	return;			

      FS->upr = i1;
      FS->upc = j1;
      FS->downr = i2;
      FS->downc = j2;
      FS->l3 = StDown;
      return;
    }

  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 == MODIFIED)
    {
      FS->l1 = StGrap;
      FS->l2 = StCell;
      FS->l3 = StDown;
      copypix ("cb_docbtn1down:StCell, Editing, modified");
      drawselectbox (downi, downj, downi, downj);
      return;
    }

  if (FS->l1 == StCell && FS->l2 == EDITING && FS->l3 != MODIFIED)
    {
      a_update ();
    }


  gr = worksheet_getchart_at (ActiveWorksheet, absdownx, absdowny);
  if (gr != NULL)
    {
      lx = downx;
      ly = downy;
      
      if (ActiveGraph != gr || !(FS->l1 == StChart && FS->l2 == SELECT_CHART))
	{
	  worksheet_select_graph (AW, gr);
	  ActiveGraph = gr;
	  grx = gr->x;
	  gry = gr->y;
	  grh = gr->h;
	  grw = gr->w;
	  FS->l1 = StChart;
	  FS->l2 = SELECT_CHART;
	  FS->l3 = StDown;
	  FS->l4 = CMOVE;
	  TurnOnMove (Drawarea);
	}
      return;
    }


  if (FS->l1 == StUndefine ||
      FS->l1 == StCell ||
      FS->l1 == StBorder ||
      FS->l1 == StSelection ||
      FS->l1 == StChart)
    {
      for (k = 0; k < getnumbtn (); k++)
	{
	  btn = (Button *) getbtn (k);

	  if (downx > btn->x1 - CW (AW, AW->cc) && downy > btn->y1 - LH (AW, AW->ll) &&
	      downx < btn->x2 - CW (AW, AW->cc) && downy < btn->y2 - LH (AW, AW->ll)
	    )
	    {

	      lx = downx;
	      ly = downy;
	      state_reset_levels ();
	      FS->l1 = StButton;
	      FS->l2 = StDown;
	      StDebug ("buttondown");
	      setactivebtn (k);
	      redrawbtdown (btn);
	      copypix ("cb_btn1down:redrawbtdown");
	      return;
	    }
	}
    }



  if (Shift)			
    {
      FS->l2 = StShift;
      FS->l3 = StDown;
      StDebug ("shift btn1 down");
      return;
    }
  else
    
    {
      FS->l1 = StCell;
    }
  FS->l2 = 0;
  FS->l3 = StDown;
}


void
cb_DocBtn1Motion (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i, j;
  int x, y;
  int dx, dy;
  Drawing *dr;

  x = event->xbutton.x * 100 / AW->zoom;
  y = event->xbutton.y * 100 / AW->zoom;
  
  movex = x;
  movey = y;
  absmovex = movex + CW (AW, AW->cc);
  absmovey = movey + LH (AW, AW->ll);
  xytoij (x, y, &i, &j);
  movei = i;
  movej = j;

  FS->movex = x;
  FS->movey = y;
  StDebug ("Btn1Motion");

  

  if (Shift)
    return;


  if (FS->l1 == StDrawing)
    {				
      if (w != Drawarea)
	return;			
      if (FS->l2 == STARTCREATEDRAWING)
	FS->l2 = CREATINGDRAWING;

      if (FS->l2 == CREATINGDRAWING)
	{
	  set_visible (i, j);
	  drplot1 ();
	  return;
	}

      if (FS->l2 == EDITINGDRAWING)
	{
	  set_visible (i, j);
	  dx = x - lx;
	  dy = y - ly;

	  if (FS->l3 == CROSS)
	    {
	      dr = ActiveDrawing;
	      dr->x1 += dx;
	      dr->y1 += dy;
	      dr->x2 += dx;
	      dr->y2 += dy;
	    }
	  else if (FS->l3 == BOTTOM_RIGHT)
	    {
	      dr = ActiveDrawing;	
	      dr->x2 += dx;
	      dr->y2 += dy;
	    }
	  else if (FS->l3 == TOP_LEFT)
	    {
	      dr = ActiveDrawing;	
	      dr->x1 += dx;
	      dr->y1 += dy;
	    }
	  lx = x;
	  ly = y;
	  drplot1 ();		
	  copypix ("cb_docbtn1motion: modification d un dessin");
	}
      return;
    }


  if (FS->l1 == StBorder)
    {
      FS->l3 = StMotion;
      switch (FS->l2)
	{
	case StLinindex:
	  {
	    if ((ly - y) * (ly - y) < 9)
	      break;
	    dy = y - ly;
	    ly = y;

	    if (dy < 0 && LH (AW, li) + dy - LH (AW, li - 1) < 10)
	      break;

	    SH (AW, li - 1, LH (AW, li) + dy - LH (AW, li - 1));
	    border_repaint (1);
	    break;
	  };

	case StColindex:
	  {
	    if ((lx - x) * (lx - x) < 9)
	      break;
	    dx = x - lx;
	    lx = x;

	    if (dx < 0 && CW (AW, cj) + dx - CW (AW, cj - 1) < 10)
	      break;

	    SW (AW, cj - 1, CW (AW, cj) + dx - CW (AW, cj - 1));
	    border_repaint (1);
	    break;
	  }
	}			
      
      
      lasti = i;
      lastj = j;

      return;
    }


  if (FS->l1 == StChart)
    {
      if (FS->l2 == CREATE_CHART)
	{
	  FS->l3 = StMotion;
	  set_visible (i, j);
	  drplot ();
	}
      if (FS->l2 == SELECT_CHART)
	{
	  set_visible (i, j);
	  dx = x - lx;
	  dy = y - ly;

	  if (FS->l4 == CMOVE)
	    {
	      grx += dx;
	      gry += dy;
	      lx = x;
	      ly = y;
	      copypix ("cb_btn1motion: StChart: CMOVE");
	      return;
	    }
	  if (FS->l4 == BOTTOM_LEFT)
	    {
	      grx += dx;
	      grw -= dx;
	      grh += dy;
	    }
	  if (FS->l4 == BOTTOM_RIGHT)
	    {
	      grw += dx;
	      grh += dy;
	    }
	  if (FS->l4 == TOP_LEFT)
	    {
	      grx += dx;
	      gry += dy;
	      grw -= dx;
	      grh -= dy;
	    }
	  if (FS->l4 == TOP_RIGHT)
	    {
	      gry += dy;
	      grw += dx;
	      grh -= dy;
	    }
	  if (FS->l4 == LEFT_SIDE)
	    {
	      grx += dx;
	      grw -= dx;
	    }
	  if (FS->l4 == RIGHT_SIDE)
	    {
	      grw += dx;
	    }
	  if (FS->l4 == TOP_SIDE)
	    {
	      gry += dy;
	      grh -= dy;
	    }
	  if (FS->l4 == BOTTOM_SIDE)
	    {
	      grh += dy;
	    }
	  if (grw < 50)
	    grw = 50;
	  if (grh < 40)
	    grh = 40;
	  lx = x;
	  ly = y;
	  copypix ("cb_docbnt1motion:chart size modified");
	}

    }



  if (FS->l1 == StButton)
    return;


  if (FS->l1 == StGrap || FS->l1 == StBrush)
    {
      int di = i - lasti;
      int dj = j - lastj;
      FS->l3 = StMotion;

      if (!(di) && !(dj))
	return;

      xytoij (x, y, &i, &j);
      if (i != 0 && j != 0)
	set_visible (i, j);
      copypix ("cb_docbtn1motion: grap or brush, after set_visible");
      drawselectbox (downi, downj, i, j);
      return;
    }

  if (FS->l1 == StSelection && FS->l2 == HAND)
    {
      int i1, j1, i2, j2;
      int di = i - lasti;
      int dj = j - lastj;
      if (FS->l3 == StDown)
	TurnOnMove (Drawarea);
      FS->l3 = StMotion;
      if (!(di) && !(dj))
	return;
      copypix ("cb_docbtn1motion: moving a selection");

      getselection (&i1, &j1, &i2, &j2);
      di = i - downi;
      dj = j - downj;
      set_visible (i, j);
      drawselectbox (i1 + di, j1 + dj, i2 + di, j2 + dj);
      lasti = i;
      lastj = j;
      return;
    }
  if (FS->l1 == StCell && FS->l2 == HAND)
    {
      int i1, j1;
      int di = i - lasti;
      int dj = j - lastj;
      if (FS->l3 == StDown)
	TurnOnMove (Drawarea);
      FS->l3 = StMotion;
      if (!(di) && !(dj))
	return;
      copypix ("cb_docbtn1motion: moving a cell");

      i1 = ActiveCell->r;
      j1 = ActiveCell->c;
      di = i - i1;
      dj = j - j1;
      set_visible (i, j);
      drawselectbox (i1 + di, j1 + dj, i1 + di, j1 + dj);
      lasti = i;
      lastj = j;
      return;
    }
  if ((FS->l1 == StCell || FS->l1 == StSelection) && (FS->l2 == 0 || FS->l2 == SELECTING))
    {
      if (FS->l3 == StDown)
	{			
	  setcursor (downi, downj);
	  FS->l3 = StMotion;
	  lasti = downi;
	  lastj = downj;
	}
      else
	{
	  int di;
	  int dj;
	  xytoij (x, y, &i, &j);
	  di = i - lasti;
	  dj = j - lastj;

	  if (di || dj)
	    {
	      FS->l2 = SELECTING;
	      FS->l1 = StSelection;
	      if (i != 0 && j != 0)
		setselection (downi, downj, i, j);
	      copypix ("cb_docbtn1motion:after setselection");
	      set_visible (i, j);
	      
	    }
	  lasti = i;
	  lastj = j;
	}
      return;
    }

  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == EXTEND_SELECT)
    {
      int i1, j1, i2, j2, di, dj;
      di = i - FS->downr;
      dj = j - FS->downc;

      if (FS->l3 == StDown)
	{
	  FS->mover = FS->downr;
	  FS->movec = FS->downc;
	  lasti = 0;
	  lastj = 0;
	  if (FS->movey - FS->downy > 3)
	    {
	      FS->l4 = StDown;
	      FS->l3 = StMotion;
	    }
	  if (FS->movex - FS->downx > 3)
	    {
	      FS->l4 = StRight;
	      FS->l3 = StMotion;
	    }
	}

      if (FS->l3 == StMotion)
	{
	  if (FS->l4 == StDown && di <= 0)
	    {			
	      di = 0;
	      FS->mover = FS->downr;
	      FS->l4 = StFree;
	    };

	  if (FS->l4 == StRight && dj <= 0)
	    {			
	      dj = 0;
	      FS->movec = FS->downc;
	      FS->l4 = StFree;
	    };

	  if (FS->l4 == StFree)
	    {
	      if (di > 0)
		{
		  FS->l4 = StDown;
		}
	      else if (dj > 0)
		{
		  FS->l4 = StRight;
		}
	    }

	  if (FS->l4 == StDown)
	    {
	      i2 = i1 + di;
	      FS->mover = i;
	    }
	  else if (FS->l4 == StRight)
	    {
	      j2 = j1 + dj;
	      FS->movec = j;
	    }
	  if (i != lasti || j != lastj)
	    {
	      set_visible (FS->mover, FS->movec);
	      copypix ("cb_docbtn1motion: extend selection");
	      if (FS->l1 == StCell)
		drawselectbox (FS->downr, FS->downc, FS->mover, FS->movec);
	      if (FS->l1 == StSelection)
		drawselectbox (FS->upr, FS->upc, FS->mover, FS->movec);
	    }
	}
      lasti = i;
      lastj = j;

      return;
    }

}


void
cb_DocBtn1Up (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  char *label;
  char buf[64];
  char buf1[64];
  int x, y;
  int i, j;
  Graph *gr;
  Button *btn;

  FS->upx = event->xbutton.x * 100 / AW->zoom;
  FS->upy = event->xbutton.y * 100 / AW->zoom;
  StDebug ("Btn1Up");

  if (1)			
    {
      x = event->xbutton.x * 100 / AW->zoom;
      y = event->xbutton.y * 100 / AW->zoom;
      upx = x;
      upy = y;
      absupx = upx + CW (AW, AW->cc);
      absupy = upy + LH (AW, AW->ll);

      xytoij (x, y, &i, &j);
      upi = i;
      upj = j;
    }


  if (FS->l1 == StDrawing)
    {
      if (FS->l2 == EDITINGDRAWING)
	{
	  FS->l2 = READYEDITDRAWING;
	  TurnOnPencil (Drawarea);
	  xrepaint ("btn1up: editing drawing");
	  return;
	}

      if (FS->l2 == CREATINGDRAWING)
	{
	  FS->l2 = ENDCREATEDRAWING;
	  drplot1 ();
	  state_reset_levels ();
	  return;
	}
      FS->l2 = READYEDITDRAWING;
      TurnOnPencil (Drawarea);
      return;
    }


  if (FS->l1 == StBorder)
    {
      switch (FS->l2)
	{
	case StLinindex:
	  {
	    if (FS->l3 == StDown && w == linindex)	
	      {
		setcursor (i, 1);
		selectlin (i, Shift);
		state_reset_levels ();
		FS->l1 = StSelection;
		drawselect ();
		li = 0;
		cj = 0;
		return;
	      }
	    else
	      {
		xrepaint ("btn1up StBorder");
		cj = 0;
		li = 0;
		return;
	      }
	  }
	case StColindex:
	  {
	    if (FS->l3 == StDown && w == colindex)	
	      {
		setcursor (1, j);
		selectcol (j, Shift);
		state_reset_levels ();
		FS->l1 = StSelection;
		drawselect ();
		li = 0;
		cj = 0;
		return;
	      }
	    else
	      {
		xrepaint ("Btn1up StBorder");
		cj = 0;
		li = 0;
		return;
	      }
	  }
	case StCorner:
	  {
	    if (FS->l3 == StDown && w == corner)	
	      {
		setcursor (1, 1);
		selectall ();
		state_reset_levels ();
		FS->l1 = StSelection;
		drawselect ();
		li = 0;
		cj = 0;
		return;
	      }
	    else
	      {
		xrepaint ("btn1up Stcorner");
		cj = 0;
		li = 0;
		return;
	      }
	  }
	}			
      state_reset_levels ();
      return;
    }


  if (FS->l1 == StChart)
    {
      if (FS->l2 == CREATE_CHART)
	{
	  TurnOffCursor (Drawarea);
	  FS->l2 = END_CREATE_CHART;
	  FS->l3 = StUp;
	  drplot ();
	  state_reset_levels ();
	}

      if (FS->l2 == SELECT_CHART)
	{
	  StDebug ("UP - SELECT_CHART");
	  if (FS->l4 == CMOVE)
	    {
	      gr = ActiveGraph;
	      gr->x = grx;
	      gr->y = gry;
	      gr->h = grh;
	      gr->w = grw;
	      plot ();
	      TurnOffCursor (Drawarea);
	      FS->l4 = 0;
	      xrepaint ("btn1up:  StChart");
	    }
	  if (FS->l4 == BOTTOM_LEFT ||
	      FS->l4 == BOTTOM_RIGHT ||
	      FS->l4 == TOP_RIGHT ||
	      FS->l4 == TOP_SIDE ||
	      FS->l4 == RIGHT_SIDE ||
	      FS->l4 == BOTTOM_SIDE ||
	      FS->l4 == LEFT_SIDE ||
	      FS->l4 == TOP_LEFT)
	    {
	      gr = ActiveGraph;
	      gr->x = grx;
	      gr->y = gry;
	      gr->h = grh;
	      gr->w = grw;
	      resizegra ();
	      plot ();
	      xrepaint ("btn1up: StChart 2");
	    }
	  FS->l3 = StUp;
	}
      return;
    }



  if (FS->l1 == StButton)
    {
      FS->l2 = StUp;
      StDebug ("buttonup");
      
      btn = ActiveButton;
      if (btn == NULL)
	return;

      if (upx > btn->x1 - CW (AW, AW->cc) && upy > btn->y1 - LH (AW, AW->ll) &&
	  upx < btn->x2 - CW (AW, AW->cc) && upy < btn->y2 - LH (AW, AW->ll)
	)
	{
	  button_click (btn);
	}
      redrawbt (btn);
      copypix ("cb_docbtn1up: after redrawbtup");
      ActiveButton = NULL;
      state_reset_levels ();
      return;
    }


  if (FS->l1 == StGrap)
    {
      numtoalpha (buf, downi, downj);
      if (TEXT_WIDGET == Letext)
	{
	  if (ActiveCell != NULL)
	    {
	      if (ActiveCell->worksheet != NULL)
		{
		  if (EditedCell != NULL)
		    {		
		      if (ActiveWorksheet != EditedCell->worksheet)
			{
			  if (strchr (ActiveWorksheet->Name, ' '))
			    {
			      sprintf (buf1, "\'%s\'!%s", ActiveWorksheet->Name, buf);
			    }
			  else
			    {
			      sprintf (buf1, "%s!%s", ActiveWorksheet->Name, buf);
			    }
			  ActivateWorksheet (EditedCell->worksheet);
			  EditedCell = NULL;
			  insertstring (Letext, buf1);
			  KeyPressed (-9);
			  xdrawcursor (0, 0);
			  copypix ("btn1up : StGrap:after xdrawcursor");
			}
		      else
			
			{
			  insertstring (Letext, buf);
			  KeyPressed (-4);
			}
		    }
		  else
		    
		    {
		      insertstring (Letext, buf);
		      KeyPressed (-5);
		    }
		}		
	    }			
	}
      else
	
	{
	  if (DIALOG_WIDGET != NULL)
	    XtManageChild (DIALOG_WIDGET);
	  sprintf (buf1, "=%s", buf);
	  SetEntryString (TEXT_WIDGET, buf1);
	}

      if (downi != i || downj != j)
	{
	  numtoalpha (buf1, i, j);

	  if (TEXT_WIDGET != Letext)
	    {
	      sprintf (buf, "%s:%s", buf, buf1);
	      SetEntryString (TEXT_WIDGET, buf);
	    }
	  else
	    {
	      sprintf (buf, ":%s", buf1);
	      insertstring (Letext, buf);
	      KeyPressed (-6);
	    }
	}
      copypix ("cb_docbtn1up: after text inserted by Stgrap");	
      TEXT_WIDGET = Letext;

      BTN1_WHAT = CB_CELL;
      BTN1_STATE = UP;
      
      switch (FS->l2)
	{
	case StChart:
	  {
	    FS->l1 = StChart;
	    FS->l2 = SELECT_CHART;
	    FS->l3 = StUp;
	    break;
	  }
	case StCell:
	  {
	    FS->l1 = StCell;
	    FS->l2 = EDITING;
	    FS->l3 = MODIFIED;
	    break;
	  }
	default:
	  {
	    state_reset_levels ();
	    break;
	  }
	}
      return;
    }

  if (FS->l1 == StBrush)
    {
      makebrush (downi, downj, i, j);
      TurnOffCursor (Drawarea);
      switch (FS->l2)
	{
	case StCell:
	  {
	    FS->l1 = StCell;
	  }
	case StSelection:
	  {
	    FS->l1 = StSelection;
	  }
	default:
	  {
	    state_reset_levels ();
	  }
	}
      return;
    }



  if (FS->l1 == StSelection && FS->l2 == HAND)
    {
      FS->l3 = StUp;
      TurnOffMove (Drawarea);
      if (downi - i || downj - j)
	{
	  fprintf (stderr, "downi %d downj %d i%d j %d\n", downi, downj, i, j);
	  moveselect (downi, downj, i, j, 1);
	  movecursor (i - downi, j - downj);
	  
	  upi += i - downi;
	  upj += j - downj;
	  downi = i;
	  downj = j;
	  state_reset_levels ();
	  FS->l1 = StSelection;
	  return;
	}
    }
  if (FS->l1 == StCell && FS->l2 == HAND)
    {
      FS->l3 = StUp;
      TurnOffMove (Drawarea);
      downi = ActiveCell->r;
      downj = ActiveCell->c;
      if (downi - i || downj - j)
	{
	  moveselect (downi, downj, i, j, 1);
	  movecursor (i - downi, j - downj);
	  
	  upi += i - downi;
	  upj += j - downj;
	  downi = i;
	  downj = j;
	  state_reset_levels ();
	  FS->l1 = StCell;
	  return;
	}
    }

  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == SELECTING)
    {
      FS->l1 = StSelection;
      FS->l2 = 0;
      FS->l3 = 0;
      return;
    }

  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == EXTEND_SELECT)
    {

      TurnOffCursor (Drawarea);

      if (FS->l1 == StCell)
	setselection (FS->downr, FS->downc, FS->mover, FS->movec);
      if (FS->l1 == StSelection)
	setselection (FS->upr, FS->upc, FS->mover, FS->movec);

      if (FS->l4 == StDown)
	{
	  copyd ();
	}
      else if (FS->l4 == StRight)
	{
	  copyr ();
	}
      FS->l4 = 0;
      FS->l3 = 0;
      FS->l2 = 0;
      FS->l1 = StSelection;
      copypix ("cb_docbtn1up: extend select");
      
      return;
    }

  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == StShift)
    {
      int i1, j1, i2, j2;
      extendselection (downi, downj);

      get_select (&i1, &j1, &i2, &j2);

      state_reset_levels ();
      if (i1 == 0 && j1 == 0)
	FS->l1 = StCell;
      else
	FS->l1 = StSelection;
      copypix ("cb_docbtn1up: extend select Shift");
      return;
    }
  ijtoxy (i, j, &x, &y);	

  if (w == Drawarea)
    {
      label = (char *) get_formula (i, j);
      if (label != NULL)
	{
	  SetEntryString (Letext, label);
	  SetEntryString (ActiveMainwin->cell, label);
	}
      else
	{
	  SetEntryString (Letext, "");
	  SetEntryString (ActiveMainwin->cell, label);
	}

      left = 0;
      set_visible (i, j);
      if (FS->l1 == StSelection || FS->l1 == StChart)
	{
	  FS->l1 = StCell;
	  resetselect (0, 0, 0);
	  xrepaint ("btn1up StCell");
	}
      FS->l1 = StCell;
      if (AW->cur_r == i && AW->cur_c == j && (FS->l1 == StCell && FS->l2 != EDITING))
	{			
	  LetextGetFocus ();
	  FS->l2 = EDITING;
	  FS->l3 = MODIFIED;
	  storetopleft ();
	  KeyPressed (-8);
	}
      else
	{
	  setcursor (i, j);
	}
    }

}



void
cb_DocBtn2Down (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  downx = event->xbutton.x * 100 / AW->zoom;
  downy = event->xbutton.y * 100 / AW->zoom;
}

void
cb_DocBtn2Motion (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i0, j0, i1, j1;

  movex = event->xbutton.x * 100 / AW->zoom;
  movey = event->xbutton.y * 100 / AW->zoom;

  if (movex != downx || movey != downy)
    {
      xytoij (downx, downy, &i0, &j0);
      xytoij (movex, movey, &i1, &j1);
      i0 = AW->ll - (i1 - i0);
      j0 = AW->cc - (j1 - j0);
      if (i0 < 1)
	i0 = 1;
      if (j0 < 1)
	j0 = 1;
      settopleft (i0, j0);
    }

  downx = movex;
  downy = movey;
}

void
cb_DocBtn2Up (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  int i0, j0, i1, j1;

  upx = event->xbutton.x * 100 / AW->zoom;
  upy = event->xbutton.y * 100 / AW->zoom;

  if (upx != downx || upy != downy)
    {
      xytoij (downx, downy, &i0, &j0);
      xytoij (upx, upy, &i1, &j1);
      i0 = AW->ll - (i1 - i0);
      j0 = AW->cc - (j1 - j0);

      if (i0 < 1)
	i0 = 1;
      if (j0 < 1)
	j0 = 1;
      settopleft (i0, j0);
    }
}


void
cb_DocBtn3Up (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  event_DocBtn3Up (w, NULL, event, 0);
}

void
event_DocBtn3Up (Widget w, XtPointer cd, XEvent * event, Boolean * ctd)
{

  Arg args[20];			
  register int n;		
  int x, y;

  if (((XButtonEvent *) event)->button != Button3)
    return;

  n = 0;
  XtSetArg (args[n], XtNx, &x);
  n++;
  XtSetArg (args[n], XtNy, &y);
  n++;
  XtGetValues (ActiveMainwin->draw, args, n);

  x = event->xbutton.x_root - 30;
  y = event->xbutton.y_root - 10;
  
  XtSetArg (args[n], XtNx, x);
  n++;
  XtSetArg (args[n], XtNy, y);
  n++;
  XtSetValues (ActiveMainwin->popup, args, n);
  XtPopup (ActiveMainwin->popup, XtGrabNone);

}


void
cb_popdown (Widget w, XEvent * event, String * params, Cardinal * num_params)
{

  XtPopdown (ActiveMainwin->popup);

}





int
cb_changesheet (int sheet)
{
  if (FS->l1 == StCell && FS->l2 == EDITING)
    {
      FS->l1 = StGrap;
      FS->l2 = StCell;
      EditedCell = ActiveCell;
      popdownactivecell ();
    }
  if (application_changesheet (sheet))
    return -1;
  if (EditedCell == ActiveCell && FS->l1 != StGrap)
    {
      popupactivecell ();
    }
  return 0;
}

void
cb_BtnOk ()
{
  
  a_update ();
}

void
cb_BtnCancel ()
{
  if (FS->l1 == StCell && FS->l2 == EDITING)
    {
      xdrawcell (AW->cur_r, AW->cur_c, 4, 0);
      SetEntryString (Letext, "");
      SetEntryString (ActiveMainwin->cell, "");
      LetextLooseFocus ();
      state_reset_levels ();
      FS->l1 = StCell;
      popdownactivecell ();
      xdrawcursor (0, 0);
      copypix ("BtnCancel:after xdrawcursor");
      return;
    }
}

void
cb_grap (Widget w, Widget dialog)
{
  TEXT_WIDGET = w;
  DIALOG_WIDGET = dialog;

  if (FS->l1 == StChart && FS->l2 == SELECT_CHART && FS->l3 == StUp)
    {
      FS->l1 = StGrap;
      FS->l2 = StChart;
    }
  else if (FS->l1 == StCell && FS->l2 == EDITING)
    {
      FS->l1 = StGrap;
      FS->l2 = StCell;
    }
  else
    {
      FS->l1 = StGrap;
      FS->l2 = StUndefine;
    }
}



void
m_paste (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  stopedit ();
  paste ();
  xrepaint ("m_paste");
}

void
m_paste_special (int all, int formula, int value, int format, int none, int add, int sub, int div, int mul, int trans)
{
  stopedit ();
  paste_special (all, formula, value, format, none, add, sub, div, mul, trans);
  xrepaint ("m_paste special");
}

void
m_copy (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  stopedit ();
  copy ();
}


void
m_cut ()
{
  stopedit ();
  if (FS->l1 == StChart)
    {
      cut ();
      state_reset_levels ();
    }
  else if (FS->l1 == StDrawing)
    {
      cut ();
    }
  else
    {
      cut ();
    }
  resetselect (0, 0, 0);
  xrepaint ("m_cut");
}

void
m_copyd ()
{
  stopedit ();
  copyd ();
}

void
m_copyr ()
{
  stopedit ();
  copyr ();
}



void
m_color ()
{
  stopedit ();
  color ();
}

void
m_fit ()
{
  stopedit ();
  fit ();
  xrepaint ("m_fit");
}

void
m_brush (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  stopedit ();
  if (ActiveCell == NULL)
    return;
  setbrush (ActiveCell);
  resetselect (0, 0, 0);
  TurnOnSpray (Drawarea);
  FS->l1 = StBrush;
}

int
coldrag (double c)
{
  int C;
  C = c;
  settopleft (-1, C);
  return 0;
}

int
lindrag (double l)
{
  int L;
  L = l;
  settopleft (L, -1);
  return 0;
}

int
cb_setzoom (int z)
{
  Graph *gr;
  int i;

  if (AW->zoom == z)
    return 0;
  setzoom (z);			
  ActiveWorksheet->zoom = z;

  for (i = 0; i < getnumgra (); i++)
    {
      gr = (Graph *) getgra (i);
      gr->zoom = z;
      resizegra (i);
    }
  redrawgra ();
  xrepaint ("cb_setzoom");
  return 0;
}



void
m_sum (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  char buf[128];
  char buf2[8];
  int col, startr, endr;
  char *txt;

  if (!(FS->l1 == StCell && FS->l2 == EDITING))
    return;
  if (AW->cur_r < 2)
    return;

  col = AW->cur_c;
  endr = AW->cur_r - 1;
  startr = endr;

  txt = (char *) get_text (startr, col);
  if (txt == NULL)
    return;

  while (startr > 0 && txt != NULL)
    {
      startr--;
      txt = (char *) get_text (startr, col);

    }
  startr++;

  sprintf (buf, "+sum (");
  numtoalpha (buf2, startr, col);
  strcat (buf, buf2);
  strcat (buf, ":");
  numtoalpha (buf2, endr, col);
  strcat (buf, buf2);
  strcat (buf, ")");

  insertstring (Letext, buf);
  KeyPressed (-7);
}

void
m_sorta (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  stopedit ();
  makesorta ();
}

void
m_sortd (Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  stopedit ();
  makesortd ();
}




void
m_createplot ()
{
  stopedit ();
  state_reset_levels ();
  FS->l1 = StChart;
  FS->l2 = CREATE_CHART;
  TurnOnCross (Drawarea);
  return;
}

void
m_plotline ()
{
  stopedit ();
  WHAT = CB_LINE;
  TurnOnCross (Drawarea);

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = STARTCREATEDRAWING;
  FS->l3 = StLine;
  
  resetselect (0, 0, 0);
  return;
}

void
m_plotrect ()
{
  stopedit ();
  WHAT = CB_RECT;
  TurnOnCross (Drawarea);

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = STARTCREATEDRAWING;
  FS->l3 = StRect;
  
  resetselect (0, 0, 0);
  return;
}
void
m_plotarc ()
{
  stopedit ();
  WHAT = CB_ARC;
  TurnOnCross (Drawarea);

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = STARTCREATEDRAWING;
  FS->l3 = StArc;
  
  resetselect (0, 0, 0);
  return;
}
void
m_plotcircle ()
{
  stopedit ();
  WHAT = CB_CIRCLE;
  TurnOnCross (Drawarea);

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = STARTCREATEDRAWING;
  FS->l3 = StCircle;
  
  resetselect (0, 0, 0);
  return;
}
void
m_plotbutton ()
{
  stopedit ();
  WHAT = CB_BUTTON;
  TurnOnCross (Drawarea);

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = STARTCREATEDRAWING;
  FS->l3 = StButton;
  
  resetselect (0, 0, 0);
  return;
}

void
m_editdraw ()
{
  stopedit ();

  state_reset_levels ();
  FS->l1 = StDrawing;
  FS->l2 = READYEDITDRAWING;

  TurnOnPencil (Drawarea);
  
  resetselect (0, 0, 0);
  worksheet_select_drawing (AW, AW->activedrawing);
}

void
m_exitdraw ()
{
  stopedit ();
  TurnOffCursor (Drawarea);
  state_reset_levels ();
}





int
drplot ()
{
  Graph *gr;

  if (FS->l1 == StBatch)
    return 0;

  if (FS->l1 == StChart && FS->l2 == END_CREATE_CHART)
    {
      plotx = absdownx;
      ploty = absdowny;
      ploth = absupy - absdowny;
      if (ploth < 0)
	{
	  ploth = -ploth;
	  ploty = absupy;
	}
      plotw = absupx - absdownx;
      if (plotw < 0)
	{
	  plotw = -plotw;
	  plotx = absupx;
	}

      gr = (Graph *) newgra ();
      if (plotw < 50)
	plotw = 50;
      if (ploth < 40)
	ploth = 40;
      if (plotx < 0)
	plotx = 0;
      if (ploty < 0)
	ploty = 0;

      gr->x = plotx;
      gr->y = ploty;
      gr->w = plotw;
      gr->h = ploth;
      gr->pixmap = createpixmap (Drawarea, plotw, ploth);
      fillrectangle (dpy, gr->pixmap, 0, 0, 0, plotw, ploth, 0, 0, 0);
      plot ();
      copypix ("drplot: newchart");

    }

  if (FS->l1 == StChart && FS->l2 == CREATE_CHART)
    {
      clearnflush ();

      drawline (dpy, AMwin, 1, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), movex, absdowny - LH (AW, AW->ll), 0, 0);
      drawline (dpy, AMwin, 1, movex, absdowny, movex, movey, 0, 0);
      drawline (dpy, AMwin, 1, movex, movey, absdownx - CW (AW, AW->cc), movey, 0, 0);
      drawline (dpy, AMwin, 1, absdownx - CW (AW, AW->cc), movey, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), 0, 0);

    }
  return 0;
}


int
drplot1 ()
{
  Drawing *dr;
  Button *btn;
  int centerx, centery, width, height, a1 = 0, a2 = 0;
  int pi = 90 * 64;

  if (FS->l1 == StBatch)
    return 0;

  if (FS->l1 == StDrawing && FS->l2 == ENDCREATEDRAWING)
    {
      StDebug ("drplot1 up");
      plotx = absdownx;
      ploty = absdowny;
      ploth = absupy - absdowny;
      if (ploth < 0)
	{
	  ploth = -ploth;
	  ploty = absupy;
	}
      plotw = absupx - absdownx;
      if (plotw < 0)
	{
	  plotw = -plotw;
	  plotx = absupx;
	}
      switch (FS->l3)
	{
	case StLine:
	  {
	    dr = (Drawing *) newdra ();
	    dr->x1 = absdownx;
	    dr->x2 = absupx;
	    dr->y1 = absdowny;
	    dr->y2 = absupy;
	    dr->type = LINE;
	    drawline (dpy, DrawAreaPixmap, 1, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), upx, upy, 0, 0);
	    worksheet_select_drawing (AW, dr);
	    break;
	  }
	case StRect:
	  {
	    dr = (Drawing *) newdra ();
	    dr->x1 = absdownx;
	    dr->x2 = absupx;
	    dr->y1 = absdowny;
	    dr->y2 = absupy;
	    dr->type = RECT;
	    drawline (dpy, DrawAreaPixmap, 1, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), upx, absdowny - LH (AW, AW->ll), 0, 0);
	    drawline (dpy, DrawAreaPixmap, 1, upx, absdowny, upx, upy, 0, 0);
	    drawline (dpy, DrawAreaPixmap, 1, upx, upy, absdownx - CW (AW, AW->cc), upy, 0, 0);
	    drawline (dpy, DrawAreaPixmap, 1, absdownx - CW (AW, AW->cc), upy, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), 0, 0);
	    worksheet_select_drawing (AW, dr);
	    break;
	  }
	case StButton:
	  {
	    char *label;
	    btn = (Button *) newbtn ();
	    label = inputbox ("Button label:", "Button Label", "button");
	    button_setlabel (btn, label);
	    label = inputbox ("Button macro:", "Button Macro", "macro1");
	    button_setmacro (btn, label);

	    btn->x1 = absdownx;
	    btn->x2 = absupx;
	    btn->y1 = absdowny;
	    btn->y2 = absupy;
	    fillrectangle (dpy, DrawAreaPixmap, 3, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll),
			   upx - (absdownx - CW (AW, AW->cc)), upy - (absdowny - LH (AW, AW->ll)), 0, 0, 0);
	    worksheet_select_button (AW, btn);
	    break;
	  }
	case StArc:
	  {
	    dr = (Drawing *) newdra ();
	    dr->x1 = absdownx;
	    dr->x2 = absupx;
	    dr->y1 = absdowny;
	    dr->y2 = absupy;
	    dr->type = ARC;
	    centerx = absdownx;
	    centery = absdowny;
	    width = 2 * abs (absdownx - absupx);
	    height = 2 * abs (absdowny - absupy);

	    if (absdownx <= absupx && absdowny <= absupy)
	      {
		a1 = 0;
		a2 = pi;
		centery += height / 2;
	      }
	    if (absdownx >= absupx && absdowny <= absupy)
	      {
		a1 = -pi;
		a2 = pi;
		centerx -= width / 2;
	      }
	    if (absdownx >= absupx && absdowny >= absupy)
	      {
		a1 = 2 * pi;
		a2 = pi;
		centery -= height / 2;
	      }
	    if (absdownx <= absupx && absdowny >= absupy)
	      {
		a1 = pi;
		a2 = pi;
		centerx += width / 2;
	      }
	    drawarc
	      (dpy, DrawAreaPixmap, 1, (centerx - width / 2) - CW (AW, AW->cc), (centery - height / 2) - LH (AW, AW->ll), width, height, a1, a2, 0, 0);
	    worksheet_select_drawing (AW, dr);
	    break;
	  }
	case StCircle:
	  {
	    dr = (Drawing *) newdra ();
	    dr->x1 = absdownx;
	    dr->x2 = absupx;
	    dr->y1 = absdowny;
	    dr->y2 = absupy;
	    dr->type = CIRCLE;
	    centerx = (absdownx + absupx) / 2;
	    centery = (absdowny + absupy) / 2;
	    width = abs (absdownx - absupx);
	    height = abs (absdowny - absupy);
	    drawarc
	      (dpy, DrawAreaPixmap, 1, (centerx - width / 2) - CW (AW, AW->cc), (centery - height / 2) - LH (AW, AW->ll), width, height, 0, 360 * 64, 0, 0);
	    worksheet_select_drawing (AW, dr);
	    break;
	  }
	}
      WHAT = -1;
      TurnOffCross (Drawarea);
      return 0;
    }

  if (FS->l1 == StDrawing && (FS->l2 == CREATINGDRAWING || FS->l2 == EDITINGDRAWING))
    {
      clearnflush ();
      
      switch (FS->l3)
	{
	case StLine:
	  {
	    drawline (dpy, AMwin, 1, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), movex, movey, 0, 0);
	    break;
	  }
	case StRect:
	  {
	    drawline (dpy, AMwin, 1, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), movex, absdowny - LH (AW, AW->ll), 0, 0);
	    drawline (dpy, AMwin, 1, movex, absdowny - LH (AW, AW->ll), movex, movey, 0, 0);
	    drawline (dpy, AMwin, 1, movex, movey, absdownx - CW (AW, AW->cc), movey, 0, 0);
	    drawline (dpy, AMwin, 1, absdownx - CW (AW, AW->cc), movey, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll), 0, 0);
	    break;
	  }
	case StButton:
	  {
	    fillrectangle (dpy, AMwin, 3, absdownx - CW (AW, AW->cc), absdowny - LH (AW, AW->ll),
			   movex - (absdownx - CW (AW, AW->cc)), movey - (absdowny - LH (AW, AW->ll)), 0, 0, 0);
	    break;
	  }
	case StArc:
	  {
	    absupx = movex + CW (AW, AW->cc);
	    absupy = movey + LH (AW, AW->ll);
	    centerx = absdownx;
	    centery = absdowny;
	    width = 2 * abs (absdownx - absupx);
	    height = 2 * abs (absdowny - absupy);
	    if (absdownx <= absupx && absdowny <= absupy)
	      {
		a1 = 0;
		a2 = pi;
		centery += height / 2;
	      }
	    if (absdownx >= absupx && absdowny <= absupy)
	      {
		a1 = -pi;
		a2 = pi;
		centerx -= width / 2;
	      }
	    if (absdownx >= absupx && absdowny >= absupy)
	      {
		a1 = 2 * pi;
		a2 = pi;
		centery -= height / 2;
	      }
	    if (absdownx <= absupx && absdowny >= absupy)
	      {
		a1 = pi;
		a2 = pi;
		centerx += width / 2;
	      }
	    drawarc
	      (dpy, AMwin, 1, (centerx - width / 2) - CW (AW, AW->cc), (centery - height / 2) - LH (AW, AW->ll), width, height, a1, a2, 0, 0);

	    break;
	  }
	case StCircle:
	  {
	    absupx = movex + CW (AW, AW->cc);
	    absupy = movey + LH (AW, AW->ll);
	    centerx = (absdownx + absupx) / 2;
	    centery = (absdowny + absupy) / 2;
	    width = abs (absdownx - absupx);
	    height = abs (absdowny - absupy);
	    drawarc
	      (dpy, AMwin, 1, (centerx - width / 2) - CW (AW, AW->cc), (centery - height /
		    2) - LH (AW, AW->ll), width, height, 0, 360 * 64, 0, 0);
	    break;
	  }
	}
    }
  return 0;
}


int
drawselect ()
{

  int i1, j1, i2, j2;
  Drawing *dr;

  if (FS->l1 == StBatch)
    return 0;

  if ((FS->l1 == StCell || FS->l1 == StSelection) && FS->l2 == HAND && FS->l3 == StMotion)
    return 0;

  if (FS->l1 == StDrawing && (FS->l2 == READYEDITDRAWING || FS->l2 == EDITINGDRAWING))
    {
      dr = ActiveDrawing;
      if (dr == NULL || !getnumdra ())
	{
	  return -1;
	}
      xa = dr->x1 - CW (AW, AW->cc);
      ya = dr->y1 - LH (AW, AW->ll);
      xb = dr->x2 - CW (AW, AW->cc);
      yb = dr->y2 - LH (AW, AW->ll);
      fillrectangle (dpy, AMwin, 1, xa - 4, ya - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xb - 4, yb - 4, 8, 8, 0, 0, 0);
      return 0;
    }

  if (FS->l1 == StChart && FS->l2 == SELECT_CHART)
    {
      xa = grx - CW (AW, AW->cc) - 4;
      ya = gry - LH (AW, AW->ll) - 4;
      xb = grx - CW (AW, AW->cc) + grw + 4;
      yb = gry - LH (AW, AW->ll) + grh + 4;
      drawline (dpy, AMwin, 1, xa, ya, xb, ya, 0, 0);
      drawline (dpy, AMwin, 1, xb, ya, xb, yb, 0, 0);
      drawline (dpy, AMwin, 1, xb, yb, xa, yb, 0, 0);
      drawline (dpy, AMwin, 1, xa, yb, xa, ya, 0, 0);
      fillrectangle (dpy, AMwin, 1, xa - 4, ya - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xa - 4, yb - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xb - 4, ya - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xb - 4, yb - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, (xa + xb) / 2, ya - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, (xa + xb) / 2, yb - 4, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xa - 4, (ya + yb) / 2, 8, 8, 0, 0, 0);
      fillrectangle (dpy, AMwin, 1, xb - 4, (ya + yb) / 2, 8, 8, 0, 0, 0);

      return 0;
    }

  if (!get_select (&i1, &j1, &i2, &j2))
    return 0;

  if (FS->l1 == StSelection)
    drawselectbox (i1, j1, i2, j2);
  xdrawcursor (0, 0);
  copypix ("drawselect:after xdrawcursor");

  return 0;
}




int
set_visible (int i, int j)
{
  int c, l;
  double fact;

  if (AW == NULL)
    return -1;
  fact = 100.0 / AW->zoom;

  if (i < 0 || i > AW->nblin || j < 0 || j > AW->nbcol)
    return -1;

  c = AW->cc;
  l = AW->ll;

  if (i >= l && j >= c && (CW (AW, c) + Width * fact) > (CW (AW, j + 1))
      && (LH (AW, l) + Height * fact) > (LH (AW, i + 1)))
    return 0;

  if (c > j)
    c = j;
  else
    while ((CW (AW, c) + Width * fact) < (CW (AW, j + 1)) && c < AW->nbcol)
      c++;

  if (l > i)
    l = i;
  else
    while ((LH (AW, l) + Height * fact) < (LH (AW, i + 1)) && l < AW->nblin)
      l++;

  if (l < 1)
    l = 1;
  if (c < 1)
    c = 1;

  settopleft (l, c);
  return 0;
}

int
storetopleft ()
{
  FS->row = AW->ll;
  FS->col = AW->cc;
  return 0;
}

int
restoretopleft ()
{
  settopleft (FS->row, FS->col);
  return 0;
}

int
settopleft (int l, int c)
{
  double L, C;
  

  if (c < 1 || c > AW->nbcol)
    c = AW->cc;;
  if (l < 1 || l > AW->nblin)
    l = AW->ll;
  if (AW->cc == c && AW->ll == l)
    return 0;

  lx -= CW (AW, c) - CW (AW, AW->cc);
  ly -= LH (AW, l) - LH (AW, AW->ll);

  AW->cc = c;
  AW->ll = l;

  C = c;
  L = l;
  
  setscrollv (L);
  setscrollh (C);

  xrepaint ("settopleft");
  return 0;
}






int
border_repaint (int n)
{
  int i, j;
  if (BatchMode)
    return 0;

  if (FS->l1 == StBatch)
    return 0;

  setfont2 (0, 1, 0, 3);
  {
    desactivate_zoom ();
    fillrectangle (XtDisplay (corner), cornerpixmap, 2, 0, 0, 40, 20, 0, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 3, 0, 0, 0, 20, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 1, 1, 0, 1, 20, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 3, 0, 0, 40, 0, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 1, 1, 1, 40, 1, 0, 0);

    drawline (XtDisplay (corner), cornerpixmap, 0, 2, 2, 39, 2, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 0, 2, 2, 2, 18, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 3, 2, 19, 39, 19, 0, 0);
    drawline (XtDisplay (corner), cornerpixmap, 3, 39, 2, 39, 18, 0, 0);
    reactivate_zoom ();
    clearwin (corner);
  }
  if (n == 0 || (FS->l1 == StBorder && FS->l2 == StLinindex))
    {
      desactivate_zoom ();
      fillrectangle (XtDisplay (linindex), linpixmap, 2, 0, 0, 40, Height, 0, 0, 0);
      drawline (XtDisplay (linindex), linpixmap, 3, 0, 0, 0, Height, 0, 0);
      drawline (XtDisplay (linindex), linpixmap, 1, 1, 0, 1, Height, 0, 0);

      reactivate_zoom ();
      for (i = AW->ll; LH (AW, i) - LH (AW, AW->ll) < Height * 100 / AW->zoom; i++)
	xdrawlincell (i, 0, 0);
      clearwin (linindex);
    }
  if (n == 0 || (FS->l1 == StBorder && FS->l2 == StColindex))
    {
      desactivate_zoom ();
      fillrectangle (XtDisplay (colindex), colpixmap, 2, 0, 0, Width, 20, 0, 0, 0);
      drawline (XtDisplay (colindex), colpixmap, 3, 0, 0, Width, 0, 0, 0);
      drawline (XtDisplay (colindex), colpixmap, 1, 0, 1, Width, 1, 0, 0);

      reactivate_zoom ();
      for (j = AW->cc; CW (AW, j) - CW (AW, AW->cc) < Width * 100 / AW->zoom; j++)
	xdrawcolcell (0, j, 0);
      clearwin (colindex);
    }
  if (FS->l1 == StBorder && (FS->l2 == StLinindex || FS->l2 == StColindex))
    {
      xdrawcursor (0, 0);
      copypix ("Borderrepaint: StBorder :after xdrawcursor");
    }
  return 0;
}

int
xrepaint (char *message)
{
  int i, j;
  char tmp[256];

  if (FS->l1 == StBatch)
    return 0;

  sprintf (tmp, "xrepaint (%s)", message);
  StDebug (tmp);


  border_repaint (0);

  paint = 1;

  fillrectangle (dpy, DrawAreaPixmap, 0, 0, 0, Width * 100 / AW->zoom, Height * 100 / AW->zoom, 0, 0, 0);

  for (i = AW->ll + 1; LH (AW, i) - LH (AW, AW->ll) < Height * 100 / AW->zoom; i++)
    drawline (dpy, DrawAreaPixmap, 2, 0, LH (AW, i) - LH (AW, AW->ll), Width * 100 / AW->zoom, LH (AW, i) - LH (AW, AW->ll), 0, 0);
  for (j = AW->cc + 1; CW (AW, j) - CW (AW, AW->cc) < Width * 100 / AW->zoom; j++)
    drawline (dpy, DrawAreaPixmap, 2, CW (AW, j) - CW (AW, AW->cc), 0, CW (AW, j) - CW (AW, AW->cc), Height * 100 / AW->zoom, 0, 0);



  if (AW->maxcol != NULL)
    for (i = AW->ll; i <= AW->maxrow && LH (AW, i) - LH (AW, AW->ll) < Height * 100 / AW->zoom; i++)
      {
	for (j = AW->cc; j <= AW->maxcol[i] && CW (AW, j) - CW (AW, AW->cc) < Width * 100 / AW->zoom; j++)
	  xdrawcell (i, j, 4, 0);
      }

  redrawdra ();

  redrawbtn ();
  
  copypix ("xrepaint: after redrawbtn");

  paint = 0;

  return 0;
}

void
event_Repaint (Widget w, XtPointer cd, XEvent * event, Boolean * ctd)
{
  xrepaint ("event repaint");
}

void
cb_Repaint (Widget w, XtPointer data, XEvent * event)
{
  xrepaint ("cb repaint");
}

int
creategraphpixmap (Graph * gr)
{
  deletegraphpixmap (gr);
  gr->pixmap = createpixmap (Drawarea, gr->w, gr->h);
  fillrectangle (dpy, gr->pixmap, 0, 0, 0, gr->w, gr->h, 0, 0, 0);
  return 0;
}

int
deletegraphpixmap (Graph * gr)
{
  if (gr)
    if (gr->pixmap)
      {
	freepixmap (Drawarea, gr->pixmap);
	gr->pixmap = 0;
      }
  return 0;
}


void
cb_redrawdra ()
{
  redrawdra ();
}

int
redrawdra ()
{
  Drawing *gr;
  int i;

  int numdra;

  if (FS->l1 == StBatch)
    return 0;

  if (ActiveWorksheet == NULL)
    {
      fprintf (stderr, "ActiveWorksheet =NULL\n");
      return -1;
    }


  numdra = ActiveWorksheet->nbdrawing;
  for (i = 0; i < numdra; i++)
    {
      gr = (Drawing *) getdra (i);
      if (gr != NULL)
	redrawdr (gr);
      else
	fprintf (stderr, "dr =NULL\n");

    }
  return 0;
}

void
plot ()
{
  int j;
  Graph *gr;
  int i1, i2, j1, j2;
  gr = ActiveGraph;
  if (gr == NULL)
    return;
  getselection (&i1, &j1, &i2, &j2);

  if (gr->numrange == 0 && (i1 != i2 || j1 != j2) && (i1 != 0 && i2 != 0 && j1 != 0 &&
						      j2 != 0))
    for (j = 0; j <= j2 - j1; j++)
      {
	(gr->range[j]).i1 = i1;
	(gr->range[j]).i2 = i2;
	(gr->range[j]).j1 = j + j1;
	(gr->range[j]).j2 = j + j1;
	gr->numrange++;
      }

  newplot (Drawarea, gr);
  return;

}

void
doplot (Graph * gr)		
{
  newplot (Drawarea, gr);
  return;

}


void
cb_redrawgra ()
{
  redrawgra ();
}

int
redrawgra ()
{
  Graph *gr;
  int i;
  int numgra;

  if (FS->l1 == StBatch)
    return 0;

  if (ActiveWorksheet == NULL)
    {
      fprintf (stderr, "ActiveWorksheet =NULL\n");
      return -1;
    }
  numgra = ActiveWorksheet->nbgraph;

  for (i = 0; i < numgra; i++)
    {				
      gr = (Graph *) getgra (i);
      if (gr != NULL)
	newplot (Drawarea, gr);
      
      

    }
  return 0;

}

int
redrawbtn ()
{
  Button *gr;
  int i;
  int numbtn;

  if (FS->l1 == StBatch)
    return 0;

  if (ActiveWorksheet == NULL)
    {
      fprintf (stderr, "ActiveWorksheet =NULL\n");
      return -1;
    }
  numbtn = ActiveWorksheet->nbbutton;

  for (i = 0; i < numbtn; i++)
    {

      gr = (Button *) getbtn (i);
      if (gr != NULL)
	redrawbt (gr);
      else
	fprintf (stderr, "btn =NULL\n");

    }
  paint = 0;
  return 0;
}

static int incopypix = 0;

void
copypix (char *message)
{
  Graph *gr;
  int i;
  int numgra;
  char tmp[256];
  sprintf (tmp, "copypix (%s)", message);
  StDebug (tmp);
  if (FS->l1 == StBatch)
    return;

  if (incopypix)
    return;
  incopypix = 1;

  if (ActiveWorksheet == NULL)
    {
      fprintf (stderr, "ActiveWorksheet =NULL\n");
      return;
    }

  numgra = ActiveWorksheet->nbgraph;

  for (i = 0; i < numgra; i++)
    {
      gr = (Graph *) getgra (i);
      if (gr != NULL)
	{
	  if (gr->pixmap == 0)
	    {
	      creategraphpixmap (gr);
	    }
	  if (gr->pixmap != 0)
	    {
	      copyarea (gr->pixmap, DrawAreaPixmap, 1, 0, 0,
			gr->w * gr->zoom / 100, gr->h * gr->zoom / 100,
			(gr->x - CW (AW, AW->cc)) * gr->zoom / 100,
			(gr->y - LH (AW, AW->ll)) * gr->zoom / 100);
	    }
	}
    }

  clearnflush ();
  drawselect ();
  if (FS->l1 != StChart && FS->l1 != StDrawing && FS->l1 != StGrap &&
      !(FS->l1 == StSelection && FS->l2 == 1 && FS->l3 == StMotion))
    {
      xdrawcursor (0, 0);

    }

  incopypix = 0;
}
