The macro dnd_is_local(drop_event) returns TRUE if the source and destination of
the drag and drop are the same application. This macro is available so that local (occurring
within a single client) drag and drops can be optimized.
19.4.0.1 The move operation
If the application receives an ACTION_DRAG_MOVE, it should simulate a move by performing
a copy followed by a delete. The delete is initiated by the requestor asking the holder to
convert the DELETE target. For example, a blocking selection transfer uses the following
code:
xv_set(sel_object, SEL_TYPE_NAME, "DELETE", NULL);
(void)xv_get(sel_object, SEL_DATA, &length, &format);
A non-blocking selection transfer would be initiated as follows:
xv_set(sel_object, SEL_TYPE_NAME, "DELETE", NULL);
sel_post_request(sel_object);
The application should only ask the owner to delete the selection if the drop event indicates a
move operation and the application determines it is appropriate to do so. This will typically
happen after the application has successfully transferred the data. To avoid data loss, it is very
important to assure that the data was successfully transferred to the destination application
before the data is deleted from the application that is the source of the drag.
19.4.0.2 The done procedure
At the end of the drag and drop operation, after the data has been transferred, the application
received the drop must inform XView that the drag and drop operation has been completed.
It does so by calling dnd_done():
dnd_done(sel_object);
Selection_requestor sel_object;
Drag and Drop
Drag and Drop 443
19.5 Sample Program—Sourcing a Drag
Example 19-1 shows a program that sources a drag. This program and Example 19-2 show
how to implement a drop-site item and receive a drop.
Example 19-1. Sourcing a drag
/*
* source1.c - Example of how to source a drag and drop operation.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/canvas.h>
#include <xview/cursor.h>
#include <xview/dragdrop.h>
#include <xview/sel_pkg.h>
#include <xview/xv_xrect.h>
#include <xview/svrimage.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
short drop_icon[ ] = {
#include "./drop.icon"
};
#define POINT_IN_RECT(px, py, rx, ry, rw, rh) \
((px) >= rx && (py) >= ry && \
(px) < rx+rw && (py) < ry+rh)
#define STRING_MSG "chromosome: DNA-containing body of the nucleus."
#define HOST 0
#define STRING 1
#define LENGTH 2
Frame frame;
Canvas canvas;
Dnd dnd;
Cursor arrow_cursor;
Server_image arrow_image;
Server_image arrow_image_mask;
Server_image box_image;
Server_image drop_here_image;
Cursor drop_here_cursor;
Selection_owner sel;
Selection_item selItem[5];
Atom selAtom[5];
int SelectionConvert();
extern int sel_convert_proc();
static XColor fg = {0L, 65535, 65535, 65535};
444 XView Programming Manual
Example 19-1. Sourcing a drag (continued)
static XColor bg = {0L, 0, 0, 0};
typedef struct _DragObject {
Server_image image;
int x, y;
unsigned int w, h;
int inverted;
} DragObject;
DragObject dO;
main(argc, argv)
int argc;
char **argv;
{
void EventProc(),
SelectionLose(),
PaintCanvas();
Xv_Server server;
Cursor arror_cursor;
server = xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0);
frame = xv_create((Window)NULL, FRAME,
XV_LABEL, "Drag & Drop Source",
XV_X, 10,
XV_Y, 10,
FRAME_SHOW_FOOTER, True,
0);
canvas = xv_create(frame, CANVAS,
XV_HEIGHT, 100,
XV_WIDTH, 300,
CANVAS_REPAINT_PROC, PaintCanvas,
CANVAS_X_PAINT_WINDOW, TRUE,
0);
xv_set(canvas_paint_window(canvas),
WIN_BIT_GRAVITY, ForgetGravity,
WIN_CONSUME_EVENTS,
WIN_MOUSE_BUTTONS,
LOC_DRAG,
WIN_RESIZE,
0,
WIN_EVENT_PROC, EventProc,
0);
/* Create the drag cursor images */
arrow_image = xv_create(NULL, SERVER_IMAGE,
SERVER_IMAGE_BITMAP_FILE, "arrow.bm", NULL);
arrow_image_mask = xv_create(NULL, SERVER_IMAGE,
SERVER_IMAGE_BITMAP_FILE, "arrow_mask.bm", NULL);
/* Create a cursor to use in dnd ops. */
arrow_cursor = XCreatePixmapCursor(XV_DISPLAY_FROM_WINDOW(canvas),
(XID)xv_get(arrow_image, XV_XID),
(XID)xv_get(arrow_image_mask, XV_XID),
&fg, &bg, 61, 3);
Drag and Drop
Drag and Drop 445
Example 19-1. Sourcing a drag (continued)
drop_here_image = xv_create(NULL, SERVER_IMAGE,
XV_WIDTH, 64,
XV_HEIGHT, 64,
SERVER_IMAGE_BITS, drop_icon,
0);
drop_here_cursor = XCreatePixmapCursor(
XV_DISPLAY_FROM_WINDOW(canvas),
(XID)xv_get(drop_here_image, XV_XID),
(XID)xv_get(drop_here_image, XV_XID),
&fg, &bg, 32, 32);
dO.image = xv_create(NULL, SERVER_IMAGE,
SERVER_IMAGE_BITMAP_FILE, "arrowb.bm", NULL);
dO.w = xv_get(dO.image, XV_WIDTH);
dO.h = xv_get(dO.image, XV_HEIGHT);
dO.inverted = False;
CreateSelection(server, canvas_paint_window(canvas));
window_fit(frame);
xv_main_loop(frame);
exit(0);
}
CreateSelection(server, window)
Xv_Server server;
{
char name[15];
int len;
/* Primary selection, acquired whenever the arrow
* bitmap is selected by the user.
* This is not a requirement for dnd to work.
*/
sel = xv_create(window, SELECTION_OWNER,
SEL_RANK, XA_PRIMARY,
SEL_LOSE_PROC, SelectionLose,
0);
/* Create the drag and drop object. */
dnd = xv_create(window, DRAGDROP,
DND_TYPE, DND_COPY,
DND_X_CURSOR, arrow_cursor,
DND_ACCEPT_X_CURSOR, drop_here_cursor,
SEL_CONVERT_PROC, SelectionConvert,
0);
/* Associate some selection items with the dnd object.*/
(void) gethostname(name, 15);
selAtom[HOST] = (Atom)xv_get(server, SERVER_ATOM, "HOST_NAME");
selItem[HOST] = xv_create(dnd, SELECTION_ITEM,
SEL_TYPE, selAtom[HOST],
SEL_DATA, (Xv_opaque)name,
446 XView Programming Manual
Example 19-1. Sourcing a drag (continued)
0);
selAtom[STRING] = (Atom)XA_STRING;
selItem[STRING] = xv_create(dnd, SELECTION_ITEM,
SEL_TYPE, selAtom[STRING],
SEL_DATA, (Xv_opaque)STRING_MSG,
0);
len = strlen(STRING_MSG);
selAtom[LENGTH] = (Atom)xv_get(server, SERVER_ATOM, "LENGTH");
selItem[LENGTH] = xv_create(dnd, SELECTION_ITEM,
SEL_TYPE, selAtom[LENGTH],
SEL_FORMAT, sizeof(int)*NBBY,
SEL_LENGTH, 1,
SEL_DATA, (Xv_opaque)&len,
0);
}
void
EventProc(window, event)
Xv_Window window;
Event *event;
{
static int drag_pixels = 0;
static int dragging = False;
switch (event_action(event)) {
case ACTION_SELECT:
if (event_is_down(event)) {
dragging = False;
/* If the user selected our dnd object, highlight
* the box and acquire the primary selection.
*/
if (POINT_IN_RECT(event_x(event), event_y(event),
dO.x, dO.y, dO.w, dO.h)) {
xv_set(sel, SEL_OWN, True, 0);
dO.inverted = True;
PaintObject(dO, xv_get(window, XV_XID),
XV_DISPLAY_FROM_WINDOW(window));
} else
/* If the user selected outside of the dnd object,
* de-highlight the object. And release the primary
* selection.
*/
xv_set(sel, SEL_OWN, False, 0);
} else
drag_pixels = 0;
break;
case LOC_DRAG:
/* If the user dragged at least five pixel over our
* dnd object, begin the dnd operation.
*/
if (event_left_is_down(event)) {
if (POINT_IN_RECT(event_x(event),
event_y(event),dO.x,dO.y,dO.w,dO.h))
dragging = True;
Drag and Drop
Drag and Drop 447
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.