CutPaste.c revision 433d0511
1/*
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * Author:  Davor Matic, MIT X Consortium
31 */
32
33#ifdef HAVE_CONFIG_H
34# include "config.h"
35#endif
36
37#include <X11/IntrinsicP.h>
38#include <X11/StringDefs.h>
39#include <X11/Xatom.h>
40#include "BitmapP.h"
41
42#include <stdio.h>
43#include <math.h>
44
45#define min(x, y)                     (((x) < (y)) ? (x) : (y))
46#define max(x, y)                     (((x) > (y)) ? (x) : (y))
47
48
49
50/*****************************************************************************
51 *                               Cut and Paste                               *
52 *****************************************************************************/
53
54/* ARGSUSED */
55static Boolean
56ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
57		 XtPointer *val_ret, unsigned long *length, int *format)
58{
59    XPointer *value = (XPointer *)val_ret;
60    BitmapWidget BW = (BitmapWidget) w;
61    Pixmap *pixmap;
62    char *data;
63    XImage *image;
64    Dimension width, height;
65
66    switch (*target) {
67
68/*  XA_TARGETS undefined ?!?
69
70    case XA_TARGETS:
71	*type = XA_ATOM;
72	*value = (XPointer) bitmapClassRec.bitmap_class.targets;
73	*length = bitmapClassRec.bitmap_class.num_targets;
74	*format = 32;
75	return True;
76
77*/
78
79    case XA_BITMAP:
80    case XA_PIXMAP:
81	if (BWQueryMarked(w)) {
82	  width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1;
83	  height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1;
84	  data = CreateCleanData(Length(width, height));
85	  image = CreateBitmapImage(BW, data, width, height);
86	  CopyImageData(BW->bitmap.image, image,
87			BW->bitmap.mark.from_x, BW->bitmap.mark.from_y,
88			BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 0, 0);
89	  pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap));
90	  *pixmap = GetPixmap(BW, image);
91	  DestroyBitmapImage(&image);
92	}
93	else if (BWQueryStored(w)) {
94	  pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap));
95	  *pixmap = GetPixmap(BW, BW->bitmap.storage);
96	}
97	else return False;
98	*type = XA_PIXMAP;
99	*value = (XPointer) pixmap;
100	*length = 1;
101	*format = 32;
102	return True;
103
104    default:
105	return False;
106    }
107}
108
109/* ARGSUSED */
110static void
111LoseSelection(Widget w, Atom selection)
112{
113    BitmapWidget BW = (BitmapWidget) w;
114
115    if (DEBUG)
116	fprintf(stderr, "Lost Selection\n");
117    BW->bitmap.selection.own = False;
118
119    BWUnmark(w);
120}
121
122/* ARGSUSED */
123static void
124SelectionDone(Widget w, Atom *selection, Atom *target)
125{
126/*  Done Automatically ?!?
127
128    BitmapWidget BW = (BitmapWidget) w;
129
130    if (*target != XA_TARGETS)
131	XtFree(BW->bitmap.value);
132
133*/
134}
135
136void
137BWGrabSelection(Widget w, Time btime)
138{
139    BitmapWidget BW = (BitmapWidget) w;
140
141    BW->bitmap.selection.own = XtOwnSelection(w, XA_PRIMARY, btime,
142					      ConvertSelection,
143					      (XtLoseSelectionProc)LoseSelection,
144					      SelectionDone);
145	if (DEBUG && BW->bitmap.selection.own)
146	    fprintf(stderr, "Own the selection\n");
147}
148
149
150/* ARGSUSED */
151static void
152SelectionCallback(Widget w, XtPointer cldat, Atom *selection, Atom *type,
153		  XtPointer val, unsigned long *length, int *format)
154{
155    XPointer value = (XPointer)val;
156    BitmapWidget BW = (BitmapWidget) w;
157    Pixmap *pixmap;
158
159   switch (*type) {
160
161    case XA_BITMAP:
162    case XA_PIXMAP:
163	DestroyBitmapImage(&BW->bitmap.storage);
164	pixmap = (Pixmap *) value;
165	BW->bitmap.storage = GetImage(BW, *pixmap);
166	XFree((char *)pixmap);
167	break;
168
169    default:
170	XtWarning(" selection request failed.  BitmapWidget");
171	break;
172    }
173
174    BW->bitmap.selection.limbo = FALSE;
175}
176
177void
178BWRequestSelection(Widget w, Time btime, Boolean wait)
179{
180  BitmapWidget BW = (BitmapWidget) w;
181
182  if (BW->bitmap.selection.own)
183    BWStore(w);
184  else {
185    XtGetSelectionValue(w, XA_PRIMARY, XA_PIXMAP,
186			SelectionCallback, NULL, btime);
187
188    BW->bitmap.selection.limbo = TRUE;
189
190    if (wait)
191      while (BW->bitmap.selection.limbo) {
192	XEvent event;
193	XtNextEvent(&event);
194	XtDispatchEvent(&event);
195      }
196  }
197}
198
199/* ARGSUSED */
200/* Returns true if there is a transferable selection */
201Boolean
202BWQuerySelection(Widget w, Time btime)
203{
204/* To be written.  XA_TARGETS to be used.  So far undefined ?!? */
205
206  return True;
207}
208/*****************************************************************************/
209