#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include "BitmapP.h"
#include <stdio.h>
#include <math.h>
#define min(x, y) (((x) < (y)) ? (x) : (y))
#define max(x, y) (((x) > (y)) ? (x) : (y))
extern Boolean DEBUG;
static Boolean
ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
XtPointer *val_ret, unsigned long *length, int *format)
{
XPointer *value = (XPointer *)val_ret;
BitmapWidget BW = (BitmapWidget) w;
Pixmap *pixmap;
char *data;
XImage *image;
Dimension width, height;
switch (*target) {
case XA_BITMAP:
case XA_PIXMAP:
if (BWQueryMarked(w)) {
width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1;
height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1;
data = CreateCleanData(Length(width, height));
image = CreateBitmapImage(BW, data, width, height);
CopyImageData(BW->bitmap.image, image,
BW->bitmap.mark.from_x, BW->bitmap.mark.from_y,
BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 0, 0);
pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap));
*pixmap = GetPixmap(BW, image);
DestroyBitmapImage(&image);
}
else if (BWQueryStored(w)) {
pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap));
*pixmap = GetPixmap(BW, BW->bitmap.storage);
}
else return False;
*type = XA_PIXMAP;
*value = (XPointer) pixmap;
*length = 1;
*format = 32;
return True;
default:
return False;
}
}
static void
LoseSelection(Widget w, Atom selection)
{
BitmapWidget BW = (BitmapWidget) w;
if (DEBUG)
fprintf(stderr, "Lost Selection\n");
BW->bitmap.selection.own = False;
BWUnmark(w);
}
static void
SelectionDone(Widget w, Atom *selection, Atom *target)
{
}
void
BWGrabSelection(Widget w, Time btime)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.selection.own = XtOwnSelection(w, XA_PRIMARY, btime,
ConvertSelection,
(XtLoseSelectionProc)LoseSelection,
SelectionDone);
if (DEBUG && BW->bitmap.selection.own)
fprintf(stderr, "Own the selection\n");
}
static void
SelectionCallback(Widget w, XtPointer cldat, Atom *selection, Atom *type,
XtPointer val, unsigned long *length, int *format)
{
XPointer value = (XPointer)val;
BitmapWidget BW = (BitmapWidget) w;
Pixmap *pixmap;
switch (*type) {
case XA_BITMAP:
case XA_PIXMAP:
DestroyBitmapImage(&BW->bitmap.storage);
pixmap = (Pixmap *) value;
BW->bitmap.storage = GetImage(BW, *pixmap);
XFree((char *)pixmap);
break;
default:
XtWarning(" selection request failed. BitmapWidget");
break;
}
BW->bitmap.selection.limbo = FALSE;
}
void
BWRequestSelection(Widget w, Time btime, Boolean wait)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.selection.own)
BWStore(w);
else {
XtGetSelectionValue(w, XA_PRIMARY, XA_PIXMAP,
SelectionCallback, NULL, btime);
BW->bitmap.selection.limbo = TRUE;
if (wait)
while (BW->bitmap.selection.limbo) {
XEvent event;
XtNextEvent(&event);
XtDispatchEvent(&event);
}
}
}
Boolean
BWQuerySelection(Widget w, Time btime)
{
return True;
}