/*
 * Copyright 1990 by Baylor College of Medicine ALL RIGHTS RESERVED. 
 *
 * This program is subject to a license agreement between 
 * Baylor College of Medicine and MIT. Any use inconsistent with
 * said license and any use by persons other than the faculty, 
 * students and staff at MIT or any use on a computer not operated 
 * as part of the Athena Computing Environment (ACE) is expressly 
 * prohibited.
 */
/*
 *  Selectable Raster Widget by Janet Carson,  9-14-89
 */
/*
 *  X11 includes
 */
#include <X11/IntrinsicP.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/ObjectP.h>
#include <X11/CoreP.h>
#include <X11/Xatom.h>
#ifndef X11R4
#include <X11/Selection.h>
#endif

/*
 *  Local includes 
 */
#include <vnsStringDefs.h>
#include <SelRasterP.h>
#include <SelRaster.h>
#include <malloc.h>
#include <wlib.h>

/*
 *  Misc. defines
 */

#define MININT(a,b) ((a) < (b) ? (a): (b))
#define MIN(a,b)    MININT((int)a, (int)b)

#define MAXINT(a,b) ((a) > (b) ? (a) : (b))
#define MAX(a,b)    MAXINT((int)a, (int)b)

#define ABS(x)      ((x) > 0 ? (x) : -(x))

#define DRAG_START -1

#define JSR(w) (((JSelRasterWidget)(w))->selraster)
#define SRW  register JSelRasterPart *srw = &JSR(w)

#define MULTI_CLICK_WAIT_TIME 300

/* 
 * Forward declarations of routines declared in here
 */
static ClassInitialize();
static Initialize();
static Destroy();
static Resize();
static Redisplay();
static Boolean SetValues();

static Select();
static Extend();
static Release();
static Message();

static Boolean Convert();
static void Lose();

static MakeGCs();

/*
 *  Translations and actions
 */
static char defaultTranslations[] =
    "None<Btn1Down>:   select()\n\
     <Btn1Motion>: extend()\n\
     <Btn1Up>:     release()\n\
     <Message>:    message()";

static XtActionsRec actionsList[] = {
  {"select", (XtActionProc) Select },
  {"extend", (XtActionProc) Extend },
  {"release",(XtActionProc) Release },
  {"message",(XtActionProc) Message }
};

/*
 *  Resources
 */
static XtResource resources[] = {

  {XtNselect, XtCCallback, XtRCallback, sizeof(caddr_t), 
   XtOffset(JSelRasterWidget, selraster.select), XtRCallback, NULL},

  {XtNrelease, XtCCallback, XtRCallback, sizeof(caddr_t), 
   XtOffset(JSelRasterWidget, selraster.release), XtRCallback, NULL},

  {XtNimage, XtCImage, XtRImage, sizeof(XImage *), 
   XtOffset(JSelRasterWidget, selraster.image), XtRImage, NULL},

  {XtNlRImage, XtCLRImage, XtRImage, sizeof(XImage *), 
   XtOffset(JSelRasterWidget, selraster.lowres), XtRImage, NULL},

  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 
   XtOffset(JSelRasterWidget, selraster.foreground), XtRString, XtDefaultForeground},

  {XtNobjectid, XtCObjectid, XtRInt, sizeof(int),
   XtOffset(JSelRasterWidget, selraster.objectid), XtRImmediate, (caddr_t) -1}
};

/*
 *  Class declaration 
 */
JSelRasterClassRec JselRasterClassRec = {
  /* core part */
  {  (WidgetClass) &widgetClassRec,  /* superclass */
     "SelRaster",                    /* class name */
     sizeof(JSelRasterRec),          /* widget_size */
     (XtWidgetClassProc)ClassInitialize, /* class_initialize */
     NULL,                           /* class_part_initialize */
     FALSE,                          /* class_inited */
     (XtInitProc)Initialize,         /* initialize */
     NULL,                           /* initialize_hook */
     XtInheritRealize,               /* realize */
     actionsList,                    /* actions */
     XtNumber(actionsList),          /* num_actions */
     resources,                      /* resources */
     XtNumber(resources),            /* num_resources */
     NULLQUARK,                      /* xrm_class */
     TRUE,                           /* compress_motion */
     TRUE,                           /* compress_exposure */
     FALSE,                          /* compress_enterleave */
     TRUE,                           /* visible_interest */
     (XtWidgetProc)Destroy,          /* destroy */
     (XtWidgetProc)Resize,           /* resize */
     (XtExposeProc) Redisplay,       /* expose */
     SetValues,                      /* set_values */
     NULL,                           /* set_values_hook */
     XtInheritSetValuesAlmost,       /* set_values_almost */
     NULL,                           /* get_values_hook */
     XtInheritAcceptFocus,           /* accept_focus */
     XtVersion,                      /* version */
     NULL,                           /* callback private */
     defaultTranslations,            /* tm_table */
     NULL,                           /* query_geometry */
     XtInheritDisplayAccelerator,    /* display_accelerator */
     NULL                            /* extension */
  },
  /* SelRasterClassPart */
  {
     0
  }
};

WidgetClass JselRasterWidgetClass = (WidgetClass) &JselRasterClassRec;

/*
 *  Class Initialize
 */
static ClassInitialize()
{
}
      
/*
 *  Initialize
 */
static Initialize(request, new)
  register Widget request, new;
{

  /* set width and height */

  if (JSR(request).image != NULL) {
     new->core.width = 
         (Dimension)MAX(request->core.width, JSR(request).image->width);
     new->core.height = 
         (Dimension)MAX(request->core.height, JSR(request).image->height);
  }

  if (new->core.width == 0)
     new->core.width = 10;
  if (new->core.height == 0)
     new->core.height = 10;

  /* initialize state variables */

  JSR(new).own_selection = False;
  JSR(new).selecting = False;
  JSR(new).dragging = False;
  JSR(new).old_cmap_exists = False;
  JSR(new).which_image = 0 ;

  MakeGCs(new);
  return;
}

/*
 *  Destroy
 */
static Destroy(w)
  register Widget w;
{
  SRW;

  XtReleaseGC(w, srw->normal_gc);
  XtReleaseGC(w, srw->outline_gc);
  XtReleaseGC(w, srw->drag_gc);

  XtRemoveAllCallbacks(w, XtNselect, srw->select);
  XtRemoveAllCallbacks(w, XtNrelease, srw->release);

  Resize(w);

  return;
}

/*
 *  Resize--I don't want to try to figure out what a resize does to my
 *  selected area, so I just disown the selection if I have it!
 */
static Resize(w)
  register Widget w;
{
  SRW;

  if (srw->own_selection) {

     XtDisownSelection(w, XA_PRIMARY, srw->selection_time + 1);
     /* clean up is handled by the Lose proc below */
  }
}

static
redisplay(w,begin_x,begin_y,len_x,len_y)
	Widget w ;
{
	if (XtWindow(w))
	{
		SRW;
		XImage *image = (srw->lowres == NULL || srw->which_image) ? srw->image : srw->lowres ;

		if ((image == NULL) || (image->data == NULL))
		{
			return ;
		}
		else
		{
			if (begin_x >= image->width || begin_y >= image->height)
			{
				return ;
			}
			if (begin_x + len_x > image->width)
			{
				len_x = image->width - begin_x ;
			}
			if (begin_y + len_y > image->height)
			{
				len_y = image->height - begin_y ;
			}

			XPutImage(XtDisplay(w), XtWindow(w), srw->normal_gc,
				image, begin_x, begin_y, begin_x, begin_y, 
				(unsigned)len_x,(unsigned)len_y);

			if (srw->own_selection && srw->sel_width && srw->sel_height) {
				XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
					srw->sel_x, srw->sel_y,
					(unsigned)srw->sel_width, (unsigned)srw->sel_height);
			}
		}
	}
}

/*
 *  Redisplay
 */
static Redisplay(w,event)
	register Widget w ;
	XExposeEvent *event ;
{
	redisplay(w,event->x,event->y,event->width,event->height) ;
}

/*
 *  SetValues 
 */
static Boolean SetValues(current, request, new)
  register Widget current, request, new;
{
  Boolean need_redraw = False;

  /* If the foreground or background color changed, re-do the GC's */

  if ((new->core.background_pixel != current->core.background_pixel) ||
      (JSR(new).foreground != JSR(current).foreground))    {

     XtReleaseGC(new, JSR(new).normal_gc);
     XtReleaseGC(new, JSR(new).outline_gc);
     XtReleaseGC(new, JSR(new).drag_gc);
     MakeGCs(new);
     need_redraw = True;
  }

  /* If the image changed, need a redraw */

  if (JSR(new).image != JSR(current).image) {

     need_redraw = True;
     Resize(new);

     if ((JSR(new).image != NULL) && 
         (JSR(new).image->data != NULL)) {

       new->core.width = (Dimension) JSR(new).image->width;
       new->core.height = (Dimension) JSR(new).image->height;
     }
  }

  return(need_redraw);
}

JSelNewImage(w,image)
	Widget w ;
	XImage *image ;
{
	JSR(w).image = image ;
	redisplay(w,0,0,w->core.width,w->core.height) ;
}

/*
 *  Select action routine
 */
static Select(w, event)
  register Widget w;
  XEvent *event;
{
    SRW;
    int	 x, y;
	Boolean multi_click;

    if (event->type  != ButtonPress) {
       XtAppWarning(XtWidgetToApplicationContext(w),
			"SelRaster: Select should always be a ButtonPress");
       return;
    }

   if ((srw->image == NULL) || (srw->image->data == NULL)) {
      return;
   }

    x = MAX(event->xbutton.x, 0);
    y = MAX(event->xbutton.y, 0);

   /*
    * If the event is a multi_click of the button...
    */

	multi_click = event->xbutton.time - srw->click_time < MULTI_CLICK_WAIT_TIME;
	srw->click_time = event->xbutton.time;

    if (multi_click) {

       /* if I own the selection, undraw the previous box */

       if (srw->own_selection) {
          if ((srw->sel_width) && (srw->sel_height)) {

             XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
                srw->sel_x, srw->sel_y,
                (unsigned)srw->sel_width,
                (unsigned)srw->sel_height);
          }
       }
       else {
          srw->selection_time = event->xmotion.time;
          srw->own_selection = XtOwnSelection(w, XA_PRIMARY, 
                     srw->selection_time, Convert, Lose, 
                     (XtSelectionDoneProc)NULL);
          srw->selection_pixmap = (Pixmap) 0;

          /* if I did not acquire selection, don't allow user to 
             continue sweep */

          if (srw->own_selection == False) {
              srw->selecting = False;
              return;
          }
       } /* end srw->own_selection */

       /* set the selection for the whole image */

       srw->sel_x = srw->sel_y = 0;
       srw->sel_width = srw->image->width;
       srw->sel_height = srw->image->height;

       /* draw new box */
       
       XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
                srw->sel_x, srw->sel_y,
                (unsigned)srw->sel_width,
                (unsigned)srw->sel_height);

       return;
    } /* end multi_click */

   /*
    * If the event which caused the select occurred within the
    * selected area, then this select is for drag
    */

    if ((srw->own_selection) && (x >= srw->sel_x) && 
           (y >= srw->sel_y)                      &&
           (x < srw->sel_x + srw->sel_width)      &&
           (y < srw->sel_y + srw->sel_height))       {

           srw->dragging = True;

           srw->pivot_x = x - srw->sel_x;
           srw->pivot_y = y - srw->sel_y;

           srw->drag_x = DRAG_START;
           srw->drag_y = DRAG_START;

    }

    /*
     * Otherwise, it is an ordinary select...
     */

    else {

       if (srw->own_selection) { /* lose the selected area so
                                                  user can start over */
          Resize(w);
       }

       srw->pivot_x = MIN(x, srw->image->width -1);
       srw->pivot_y = MIN(y, srw->image->height -1);

       srw->selecting  = True;
       XtCallCallbacks(w,XtNselect,(caddr_t)0);
    }

    return;

}

/*
 *  Release
 */
static Release(w, event)
  register Widget w;
  XEvent *event;
{
  SRW;
  XClientMessageEvent myevent;
  XMotionEvent motevent;
  int data[4];
  Window child;
  int x, y;

  if (event->type != ButtonRelease) {
     XtAppWarning(XtWidgetToApplicationContext(w),
			"SelRaster: Release should always be a ButtonRelease");
     return;
  }

  /*
   *  First, make a fake event to the extend routine to catch up the
   *  screen to the mouse location
   */

  if (srw->selecting) {

     motevent.type = MotionNotify;
     motevent.send_event = True;
     motevent.window = event->xbutton.window;
     motevent.x = event->xbutton.x;
     motevent.y = event->xbutton.y;
     motevent.x_root = event->xbutton.x_root;
     motevent.y_root = event->xbutton.y_root;
     motevent.time = event->xbutton.time;

     Extend(w, (XEvent *)&motevent);
  }

  /*
   *  Case 1: release after sweeping a subarea
   */

  if (srw->selecting) {

     srw->selecting = False;

     if ((srw->own_selection) && ((!srw->sel_width) ||
         (!srw->sel_height))) {

         Resize(w);
      }

      if (srw->own_selection) {
          data[0] = srw->sel_x;
          data[1] = srw->sel_y;
          data[2] = srw->sel_width;
          data[3] = srw->sel_height;
      }
      else {
          data[0] = data[1] = data[2] = data[3] = 0;
      }

      XtCallCallbacks(w, XtNrelease, (caddr_t)data);
      return;

   } /* end if selecting */

   /*
    *  Case 2: release after dragging a subarea
    */

   if (srw->dragging) {

      srw->dragging = False;

      if (srw->drag_x != DRAG_START) {

         /* undraw the last box */

         XDrawRectangle(XtDisplay(w), RootWindowOfScreen(XtScreen(w)), 
              srw->drag_gc,
              srw->drag_x, srw->drag_y, 
              (unsigned)srw->sel_width, (unsigned)srw->sel_height);

         /* tell somebody about the drop */

         myevent.window = RootWindowOfScreen(XtScreen(w));

         /* find the window to send the event according to where the
            mouse pointer is */

         x = event->xbutton.x_root;
         y = event->xbutton.y_root;

         while (XTranslateCoordinates(XtDisplay(w), 
              RootWindowOfScreen(XtScreen(w)),
              myevent.window, event->xbutton.x_root, event->xbutton.y_root,
              &x, &y, &child)) {
                   if (child != None)
                      myevent.window = child;
                   else
                      break;
              }

         /* find the coordinates to send in the event packet according to
            where the upper left corner of the rubberband box is */

         x = event->xbutton.x - srw->pivot_x;
         y = event->xbutton.y - srw->pivot_y;

         fill_up_message(
			(long) (srw->selection_time + 1),
			(long)x,
			(long)y,
			(long)XtWindow(w),
			(long)XInternAtom(XtDisplay(w), "NOTEBOOK_DROP_IMAGE", False),
			&myevent) ;
         myevent.display = XtDisplay(w);
         myevent.message_type = XInternAtom(XtDisplay(w),"VNS_DRAG_DROP",False) ;

         XSendEvent(XtDisplay(w), myevent.window, True, 
                                              0L, (XEvent *)&myevent);

      } /* end if drag moved at least one pixel from starting position */
      else {

         /* drag did not move one pixel so lose the selection */

         if (srw->own_selection) {
            Resize(w);
         }
      }
   } /* end if dragging */
} /* end release */

static Extend(w, event)
  register Widget w;
  XEvent *event;
{
  SRW;
  int x, y;
  int x_root, y_root;
  int width, height;
  int ignore;

  /* don't sweep or drag an empty image */

  if ((srw->image == NULL) || (srw->image->data == NULL)) {
      return;
  }

  if (event->type != MotionNotify) {
     XtAppWarning(XtWidgetToApplicationContext(w),
		"SelRaster: Extend should always be a MotionNotify event.");
     return;
  }

  /* don't waste time doing this if there is other work to be done */

  if ((!event->xmotion.send_event)  && 
		(XtAppPending(XtWidgetToApplicationContext(w))))
     return;

  /* set x, y, x_root and y_root to cursor location */

  if (event->xmotion.send_event) {
       x =  event->xmotion.x;
       y =  event->xmotion.y;
       x_root = event->xmotion.x_root;
       y_root = event->xmotion.y_root;
  }
  else {
     XQueryPointer(XtDisplay(w), XtWindow(w), (Window *)&ignore, 
        (Window *)&ignore, &x_root, &y_root, &x, &y, (unsigned *)&ignore);
  }

  /* 
   *  Case 1: extend select
   */

   if (srw->selecting) {


      /* If the coords have gone over the edge, so to speak, trim them
         back appropriately */

      x = x > 0 ? MIN(x, srw->image->width - 1) : 0;
      y = y > 0 ? MIN(y, srw->image->height - 1) : 0;

      width = ABS(srw->pivot_x - x);
      height = ABS(srw->pivot_y - y);

      /* If I've swept out a positive area now, but I haven't acquired
         the selection yet, now is the time to do so */

      if ( (!srw->own_selection) && width && height ) {

         srw->selection_time = event->xmotion.time;
         srw->own_selection = XtOwnSelection(w, XA_PRIMARY, 
                           srw->selection_time, Convert, Lose, (XtSelectionDoneProc)NULL);
         srw->selection_pixmap = (Pixmap) 0;

         /* if I did not acquire selection, don't allow user to 
            continue sweep */

         if (srw->own_selection == False) {
              srw->selecting = False;
              return;
         }

      }

      else if (srw->own_selection) {

         /* undraw prev box */

         if ((srw->sel_width) && (srw->sel_height)) {

            XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
                srw->sel_x, srw->sel_y,
                (unsigned)srw->sel_width,
                (unsigned)srw->sel_height);
          }
      }

      /* draw new box */

      srw->sel_width = width;
      srw->sel_height = height;

      if (width && height) {
            
            srw->sel_x = MIN(x, srw->pivot_x);
            srw->sel_y = MIN(y, srw->pivot_y);

            XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
                srw->sel_x, srw->sel_y,
                (unsigned)srw->sel_width,
                (unsigned)srw->sel_height);
      }
      return;

   } /* end extend-select */

   /*
    *  Case 2: extend drag
    */

    if (srw->dragging) {

       x_root -= srw->pivot_x;
       y_root -= srw->pivot_y;

       if ((srw->drag_x == x_root) && (srw->drag_y == y_root))
          return;

       if (srw->drag_x != DRAG_START) {

           /* undraw prev box */

            XDrawRectangle(XtDisplay(w), RootWindowOfScreen(XtScreen(w)), 
                  srw->drag_gc,
                  srw->drag_x, srw->drag_y, 
                  (unsigned)srw->sel_width, (unsigned)srw->sel_height);

       }

       srw->drag_x = x_root;
       srw->drag_y = y_root;

       /* draw new box */

       XDrawRectangle(XtDisplay(w), RootWindowOfScreen(XtScreen(w)), 
            srw->drag_gc,
            srw->drag_x, srw->drag_y, 
            (unsigned)srw->sel_width, (unsigned)srw->sel_height);

    }
}

/*
 *  Message action = propogate to parent
 */
static Message(w, event)
  register Widget w;
  XEvent *event;
{

  if (event->type != ClientMessage) {
      XtAppWarning(XtWidgetToApplicationContext(w),
		"SelRaster: Message action should be a ClientMessage event.");
      return;
  }

  event->xclient.window = XtWindow(XtParent(w));
  XSendEvent(XtDisplay(w), event->xclient.window, True, 0L, event);
  return;
}

/*
 *  Convert - return the value of the primary selection
 */
static Boolean Convert(w, selection, target, type, value, length, format)
  register Widget w;
  Atom *selection;
  Atom *target;
  Atom *type;
  caddr_t *value;
  unsigned long *length;
  int *format;
{
  Display *d = XtDisplay(w);
  SRW;
  Atom objatom = XInternAtom(XtDisplay(w),"NOTEBOOK_OBJECTID",False) ;

  if ((!srw->own_selection) || (*selection != XA_PRIMARY))
     return(False);

  if (*target == XInternAtom(d,"TARGETS",False))
  {

     Atom *tmp ;

     /* Let Xmu tell the user the targets it understands */

     (void) XmuConvertStandardSelection(w, srw->selection_time,
               selection, target, type, value, length, format);

     /* Then add the extra targets I understand */

     *length += 3;
     *value = XtRealloc(*value, (unsigned)(*length * sizeof(Atom)));
     tmp = (Atom *) *value;
     tmp[*length - 1] = XA_PIXMAP;
     tmp[*length - 2] = objatom;
     tmp[*length - 3] = XA_COLORMAP;

     return(True);
     
  }

  else if (*target == XA_PIXMAP) {

     Pixmap *tmp;

     /* If this is the first time I've been asked to convert to a pixmap,
        I'll need to create the pixmap */

     if (srw->selection_pixmap == (Pixmap) 0) {


        srw->selection_pixmap = 
           XCreatePixmap(XtDisplay(w), XtWindow(w), (unsigned)srw->sel_width,
               (unsigned)srw->sel_height, w->core.depth);

        XPutImage(XtDisplay(w), srw->selection_pixmap, 
                   srw->normal_gc, srw->image,
                   srw->sel_x, srw->sel_y, 0, 0,
                   (unsigned) srw->sel_width, 
                   (unsigned) srw->sel_height);
     }

     *type = XA_PIXMAP;
     *length = 1;
     *format = sizeof(Pixmap) * 8;

     tmp = XtNew(Pixmap);
     *tmp = srw->selection_pixmap;
     *value = (caddr_t) tmp;

     return(True);
     
  }

  else if (*target == objatom) {

     int *tmp;

     *type = XA_INTEGER;
     *length = 1;
     *format = sizeof(int) * 8;

     tmp = XtNew(int);
     *tmp = srw->objectid;
     *value = (caddr_t) tmp;

     return(True);

  }

  else if (*target == XA_COLORMAP) {

     Colormap *tmp;

     *type = XA_COLORMAP;
     *length = 1;
     *format = sizeof(Colormap) * 8;

     tmp = XtNew(Colormap) ;
     *tmp = w->core.colormap ;
     *value = (caddr_t) tmp;

     return(True);

  }

  else {
     return(XmuConvertStandardSelection(w, srw->selection_time, 
                selection, target, type, value, length, format));
  }
}

static void Lose(w, selection)
  register Widget w;
  Atom *selection;
{
  SRW;

  srw->own_selection = False;

  if (srw->selection_pixmap != (Pixmap) 0)  {
     XFreePixmap(XtDisplay(w), srw->selection_pixmap);
     srw->selection_pixmap = (Pixmap) 0;
  }

  if (srw->dragging) {
      if (srw->drag_x != DRAG_START) {

            XDrawRectangle(XtDisplay(w), RootWindowOfScreen(XtScreen(w)),
                  srw->drag_gc,
                  srw->drag_x, srw->drag_y,
                  (unsigned)srw->sel_width, (unsigned)srw->sel_height);

       }
  }

  if (w->core.visible && srw->sel_width && srw->sel_height) {
      XDrawRectangle(XtDisplay(w), XtWindow(w), srw->outline_gc,
                srw->sel_x, srw->sel_y,
                (unsigned)srw->sel_width,
                (unsigned)srw->sel_height);
  }

  srw->dragging = False;
  srw->selecting = False;
  return;
}

/*
 *  Create graphics contexts for a selraster widget
 */
static MakeGCs(w)
  register Widget w;
{
  SRW;
  XGCValues values;
  Display *dpy = XtDisplay(w) ;
  int screen = DefaultScreen(dpy) ;

  values.foreground = BlackPixel(dpy,screen) ;
  values.background = WhitePixel(dpy,screen) ;
  values.line_width = 0;

  srw->normal_gc = XtGetGC((Widget)w ,
                                          (unsigned long) GCForeground |
                                          (unsigned long) GCBackground |
                                          (unsigned long) GCLineWidth,
                                            &values);


  values.plane_mask = values.foreground ^ values.background ;
  values.foreground = values.foreground ^ values.background ;
  values.function = GXxor ;


  srw->outline_gc = XtGetGC((Widget)w,
                                          (unsigned long) GCForeground |
                                          (unsigned long) GCBackground |
                                          (unsigned long) GCLineWidth |
                                          (unsigned long) GCFunction |
                                          (unsigned long) GCPlaneMask,
                                            &values);
   srw->drag_gc = make_gen_drag_gc(w) ;
}

/*
 *  Public convenience routines
 */

/*
 *  Tells the user if I own the selection or not
 */

Boolean JSelRasterOwnsSelection(w)
  register Widget w;
{
  SRW;

  if (XtClass(w) != JselRasterWidgetClass) {
     XtAppWarning(XtWidgetToApplicationContext(w),
		"JSelRasterOwnsSelection: not a SelRaster widget.");
     return(False);
  }
  else
     return(srw->own_selection);
}
