[comp.sources.x] v11i082: Xdrop - drag and drop application, Part01/01

M.R.Dobie@ecs.southampton.ac.uk (Mark Dobie) (02/17/91)

Submitted-by: Mark Dobie <M.R.Dobie@ecs.southampton.ac.uk>
Posting-number: Volume 11, Issue 82
Archive-name: xdrop/part01

Xdrop is an openwindows utility that allows conventional UNIX
applications to be invoked by the open look drag and drop metaphor.

Xdrop is an icon onto which files and text can be dropped. When a file
(or text) is dropped onto xdrop, a command is executed. The icon and command are
specified by the user when xdrop is invoked. The command can refer to
$FILE which is expanded to the full path and filename of the file (or a
piece of text for a text selection).

Examples
--------

xdrop -icon edit.icon 'xterm -e vi $FILE &' &

This creates an xdrop which will edit files. When a file is dropped
from the file manager onto xdrop, xterm is started and runs vi to edit
the file. Notice xterm is run in the background (so multiple editors
can be run at once) and that xdrop is run in the background so it sits
on the desktop.
-- 

Mark Dobie                              M.Dobie@uk.ac.soton.ecs (JANET)
University of Southampton		M.Dobie@ecs.soton.ac.uk (Bitnet)

#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 02/15/1991 10:57 UTC by mrd@marr
# Source directory /home/hilliard/3/users/mrd/X/xdrop
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    235 -rw-r--r-- Imakefile
#    187 -rw-r--r-- Makefile.noimake
#   2543 -rw-r--r-- README
#     69 -rw-r--r-- patchlevel.h
#  32768 -rwxr-xr-x xdrop
#   2183 -rw-r--r-- xdrop.1
#   6851 -rw-r--r-- xdrop.c
#
# ============= Imakefile ==============
if test -f 'Imakefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Imakefile (File already exists)'
else
echo 'x - extracting Imakefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Imakefile' &&
X    OPENWINHOME = /usr/openwin
X
X       INCLUDES = -I$(OPENWINHOME)/include
X      CCOPTIONS = -L$(OPENWINHOME)/lib
LOCAL_LIBRARIES = -lxview -lolgx $(XLIB)
X           SRCS = xdrop.c
X           OBJS = xdrop.o
X
SimpleProgramTarget(xdrop)
SHAR_EOF
chmod 0644 Imakefile ||
echo 'restore of Imakefile failed'
Wc_c="`wc -c < 'Imakefile'`"
test 235 -eq "$Wc_c" ||
	echo 'Imakefile: original size 235, current size' "$Wc_c"
fi
# ============= Makefile.noimake ==============
if test -f 'Makefile.noimake' -a X"$1" != X"-c"; then
	echo 'x - skipping Makefile.noimake (File already exists)'
else
echo 'x - extracting Makefile.noimake (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile.noimake' &&
#
# Makefile for xdrop
#
# Mark Dobie 10-1-90
#
X
OPENWINHOME = /usr/openwin
X
xdrop	: xdrop.c
X	cc -I${OPENWINHOME}/include -L${OPENWINHOME}/lib\
X	   -o xdrop xdrop.c -lxview -lolgx -lX11
X
SHAR_EOF
chmod 0644 Makefile.noimake ||
echo 'restore of Makefile.noimake failed'
Wc_c="`wc -c < 'Makefile.noimake'`"
test 187 -eq "$Wc_c" ||
	echo 'Makefile.noimake: original size 187, current size' "$Wc_c"
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
	echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
X
X				XDROP
X				-----
X
XXdrop is an openwindows utility that allows conventional UNIX
applications to be invoked by the open look drag and drop metaphor.
X
XXdrop is an icon onto which files and text can be dropped. When a file
(or text) is dropped onto xdrop, a command is executed. The icon and command are
specified by the user when xdrop is invoked. The command can refer to
$FILE which is expanded to the full path and filename of the file (or a
piece of text for a text selection).
X
Examples
--------
X
xdrop -icon edit.icon 'xterm -e vi $FILE &' &
X
This creates an xdrop which will edit files. When a file is dropped
from the file manager onto xdrop, xterm is started and runs vi to edit
the file. Notice xterm is run in the background (so multiple editors
can be run at once) and that xdrop is run in the background so it sits
on the desktop.
X
xdrop -icon mincer.icon 'rm -rf $FILE' &
X
This command creates an xdrop which deletes files. This is an
alternative to the wastebasket which REALLY deletes files.
X
xdrop -label 'Spell check' 'echo $FILE | spell -b | xless' &
X
This one creates an xdrop onto which selected text can be dropped and
spell checked.
X
Now you have got the idea I would like you to tell me about all the
wonderful uses you come up with for xdrop and any improvements you
would like to see.
X
The motivation for xdrop was the fact that the filemgr/binder
combination only allows you to associate ONE action with double
clicking on a file icon. Typically, the user may want to have several
actions associated with an icon. For example, a makefile will want to
be 'made' (by running make with it) or it might want to be edited.
X
I find xdrop useful for operations which apply to many types of files
(eg editing) and I use binder for operations which are specific to a
file type.
X
Installation
------------
X
Edit the Imakefile to reflect where your openwindows hierarchy is and
run xmkmf to create a Makefile, then run make. Since this is my first
Imakefile I may have got it wrong, so I have included a simple
Makefile called Makefile.noimake which can used as a last resort.
X
XXdrop requires the xview toolkit to compile. Xdrop does not rely on
the xnews X server and it does not require the olwm window manager. It
does need some openwindows tools as a source for selections though.
X
Author
------
X
The author of xdrop is Mark Dobie (mrd@ecs.soton.ac.uk)
X
I would like to thank Joan Cragun for kindly telling me how to read an
icon into the program.
X
xdrop is free for anyone to copy and modify. See the notice in xdrop.c.
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 2543 -eq "$Wc_c" ||
	echo 'README: original size 2543, current size' "$Wc_c"
fi
# ============= patchlevel.h ==============
if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
	echo 'x - skipping patchlevel.h (File already exists)'
else
echo 'x - extracting patchlevel.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
/*
X	This defines that patchlevel for xdrop.
*/
X
#define PATCHLEVEL	0
SHAR_EOF
chmod 0644 patchlevel.h ||
echo 'restore of patchlevel.h failed'
Wc_c="`wc -c < 'patchlevel.h'`"
test 69 -eq "$Wc_c" ||
	echo 'patchlevel.h: original size 69, current size' "$Wc_c"
fi
# ============= xdrop ==============
if test -f 'xdrop' -a X"$1" != X"-c"; then
	echo 'x - skipping xdrop (File already exists)'
else
echo 'x - extracting xdrop (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdrop' &&
XX
SHAR_EOF
chmod 0755 xdrop ||
echo 'restore of xdrop failed'
Wc_c="`wc -c < 'xdrop'`"
test 32768 -eq "$Wc_c" ||
	echo 'xdrop: original size 32768, current size' "$Wc_c"
fi
# ============= xdrop.1 ==============
if test -f 'xdrop.1' -a X"$1" != X"-c"; then
	echo 'x - skipping xdrop.1 (File already exists)'
else
echo 'x - extracting xdrop.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdrop.1' &&
.TH XDROP 1 "14 December 1990
.SH NAME
xdrop
- allow drag and drop functionality for normal UNIX applications
.SH SYNOPSIS
.B xdrop
[ 
.I standard \s-1XV\s0view command line arguments 
]
.B [-icon|i icon_file] [-label|l icon_label] command
.SH DESCRIPTION
.LP
.B xdrop
is an OpenWindows \s-1XV\s0iew utility that 
allows users invoke normal UNIX applications using the openlook drag
and drop metaphor. When xdrop is running, the user can drag and drop a
file onto it and the command will be executed.
A reference to $FILE in the command will be expanded to the
full path and filename of the file that was dropped onto xdrop.
While the command is being executed, xdrop inverts its icon.
X
It is important to enclose the command argument in single quotes to
prevent references to $FILE being expanded by the shell on the command
line. Also, if you want to be able to invoke independent applications
from xdrop, remember to add a trailing & to the command to execute it
in the background.
X
When the xdrop application is opened, the command that is executed is
displayed and can be edited. Files can also be dropped in the open
xdrop window.
X
.SH OPTIONS
The -icon (or -i) and -label (or -l) options control the appearance of
the xdrop icon.
X
The -icon (or -i) option specifies the filename of an OpenWindows \s-1XV\s0iew
icon, perhaps created by
.B iconedit.
xdrop will start as this icon and files can be dropped onto it.
X
The -label (or -l) option specifies the label of the xdrop icon. You
can have one or the other or neither or both of these options. If you
have both, the label will overwrite the lower portion of the icon.
X
.SH USAGE
.B xdrop [-icon|i icon_file][-label|l icon_label] command
.SH EXAMPLE
xdrop -icon edit.icon 'xterm -e vi $FILE &'
X
xdrop -icon speak.icon -label Speak 'play $FILE'
.SH BUGS
xdrop dumps core if the DISPLAY environment variable is not set.
This is a known Xview bug.
X
xdrop doesn't differentiate between files dropped from filemgr and
text cut from a text application. Currently, $FILE will expand to the
full path and filename (for a file) and to the text (for a text
selection).
.SH AUTHOR
The author of xdrop is Mark Dobie (mrd@ecs.soton.ac.uk)
SHAR_EOF
chmod 0644 xdrop.1 ||
echo 'restore of xdrop.1 failed'
Wc_c="`wc -c < 'xdrop.1'`"
test 2183 -eq "$Wc_c" ||
	echo 'xdrop.1: original size 2183, current size' "$Wc_c"
fi
# ============= xdrop.c ==============
if test -f 'xdrop.c' -a X"$1" != X"-c"; then
	echo 'x - skipping xdrop.c (File already exists)'
else
echo 'x - extracting xdrop.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdrop.c' &&
X
/*
X	xdrop.c
X
X	This program allows a drag and drop to interface to normal
X	UNIX applications. When a file is dropped onto xdrop, xdrop
X	will execute a command line to start up an application.
X
X	usage:
X		xdrop [-i|icon icon_file][-l|label icon_label] command
X
X	xdrop, 7-12-90, M.Dobie.
X
X	13-12-90	Inverting icon added
X	13-12-90	Handles the case where the icon cannot be opened
X	14-12-90	Argument processing added.
*/
X
/*
X	Copyright 1990 Mark Dobie
X
X	Permission to use, copy, modify, distribute, and sell this software
X	and its documentation for any purpose is hereby granted without fee,
X	provided that the above copyright notice appear in all copies and
X	that both that copyright notice and this permission notice appear
X	in supporting documentation.
*/
X
/****************************************************************/
X
#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/text.h>
#include <xview/xv_xrect.h>
#include <xview/seln.h>
#include <xview/icon_load.h>
X
#include <X11/Xresource.h>
X
#include <stdio.h>
X
/* The icon */
X
Server_image	base_icon_image ;
Icon            base_icon ;
X
/* Base frame */
X
Frame           base_frame ;
X
/* Base panel  */
X
Panel           base_panel ;
Panel_item	command ;
X
char		window_title[1000] ;	/* window title */
X
/* Procedure to handle dragging and dropping */
X
Notify_value    event_proc() ;
X
/* Graphics Stuff */
X
Display		*base_display ;
GC		invertGC ;
XXID		base_icon_drawable ;
X
/* What options have we got? and where are they? */
X
Bool	got_icon ;
char	*icon_file ;
Bool	got_label ;
char	*icon_label ;
char	*command_string ;
X
/* X resource variables */
X
XXrmOptionDescRec	optable[] = {
{"-icon",	".icon",		XrmoptionSepArg,	(caddr_t)NULL},
{"-i",		".icon",		XrmoptionSepArg,	(caddr_t)NULL},
{"-label",	".label",		XrmoptionSepArg,	(caddr_t)NULL},
{"-l",		".label",		XrmoptionSepArg,	(caddr_t)NULL},
X				    } ;
int			optable_n = sizeof(optable)/sizeof(XrmOptionDescRec) ;
X
XXrmDatabase		commandlineDB ;
X
/****************************************************************/
X
/*
X	Initialise the Graphics stuff
*/
X
void	init_graphics()
X
{
X	base_display       = (Display *)   xv_get(base_frame,XV_DISPLAY) ;
X
X	base_icon_drawable =               xv_get(base_icon_image, XV_XID) ;
X
X	invertGC           = XCreateGC(base_display,
X				       base_icon_drawable,
X				       0,
X				       NULL) ;
X
X	XSetFunction(base_display, invertGC, GXinvert) ;
}
X
/****************************************************************/
X
/*
X	Invert an image
X
X	Assumes init_graphics has been called first
*/
X
void	invert_icon()
X
{
X	/* Invert the Server_image */
X
X	XCopyArea(base_display,
X		  base_icon_drawable,
X		  base_icon_drawable,
X		  invertGC,
X		  0,0,
X		  64,64,
X		  0,0) ;
X
X	/* Re-assign the Server_image to the icon */
X
X	xv_set(base_icon,
X	       ICON_IMAGE,	base_icon_image,
X	       0) ;
}
X
/****************************************************************/
X
main(argc, argv)
X
int	argc ;
char	*argv[] ;
X
{
X	char	msg_buffer[512] ;
X
/* This core dumps if DISPLAY isn't set (an XView bug) */
X
X	if (xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0) == 0)
X	{
X		fprintf(stderr,"xdrop : cannot connect to server\n") ;
X		exit(1) ;
X	}
X
/* Process the options */
X
X	{
X		char		*str_type[20] ;
X		XrmValue	value ;
X
X		XrmInitialize() ;
X		XrmParseCommand(&commandlineDB,
X				optable, optable_n,
X				argv[0],
X				&argc, argv) ;
X
X		got_icon = XrmGetResource(commandlineDB,
X					  "xdrop.icon",
X					  "Xdrop.Icon",
X					  str_type,
X					  &value) ;
X		if (got_icon) icon_file = value.addr ;
X
X		got_label = XrmGetResource(commandlineDB,
X					  "xdrop.label",
X					  "Xdrop.Label",
X					  str_type,
X					  &value) ;
X		if (got_label) icon_label = value.addr ;
X	}
X
/* There should be 2 left, xdrop and command */
X
X	if (argc != 2)
X	{
X		fprintf(stderr, "usage : xdrop [-i|icon iconfile] [-l|label iconlabel] command\n") ;
X		exit(1) ;
X	}
X	command_string = argv[1] ;
X
/* Read in the icon to a Server_image */
X
X	if (got_icon && (base_icon_image = icon_load_svrim(icon_file,
X					                   msg_buffer)) == NULL)
X	{
X		fprintf(stderr, "xdrop : %s\n", msg_buffer) ;
X		got_icon = FALSE ;
X	}
X
/* Construct the window title */
X
X	sprintf(window_title, "Xdrop - %s", (got_label) ? icon_label
X							: "command") ;
X
/* Create the frame */
X
X	base_frame = xv_create(NULL,			FRAME,
X			       FRAME_LABEL,		window_title,
X			       FRAME_SHOW_LABEL,	TRUE,
X			       FRAME_CLOSED,		TRUE,
X			       FRAME_NO_CONFIRM,	TRUE,
X			       0) ;
X
X	if (got_icon)	/* Create icon if we want one */
X	{
X		base_icon  = xv_create(NULL,		ICON,
X				       ICON_IMAGE,	base_icon_image,
X				       0) ;
X	}
X	else		/* take note of what the system gave us */
X	{
X		base_icon = xv_get(base_frame,FRAME_ICON) ;
X	}
X
X	if (got_label)	/* Add in the label if we've got one */
X	{
X		xv_set(base_icon,
X		       ICON_LABEL,	icon_label,
X		       0) ;
X	}
X
X	if (got_icon)	/* Associate our icon with the frame */
X	{
X		xv_set(base_frame,
X		       FRAME_ICON,	base_icon,
X		       0) ;
X	}
X
/* Create code panel and buttons. */
X
X	base_panel = xv_create(base_frame,		PANEL,
X			       XV_WIDTH,		WIN_EXTEND_TO_EDGE,
X			       WIN_ROWS,		1,
X			       XV_X,			0,
X			       XV_Y,			0,
X			       0) ;
X
X	command = xv_create(base_panel,			PANEL_TEXT,
X			    PANEL_LABEL_STRING,		"command: ",
X			    PANEL_VALUE,		command_string,
X			    PANEL_VALUE_STORED_LENGTH,	5000,
X			    0) ;
X
X	window_fit(base_frame) ;
X
/* initialise the graphics if we have an icon */
X
X	if (got_icon) init_graphics() ;
X
/* Enter the notifier. */
X
X	notify_interpose_event_func(base_icon,  event_proc, NOTIFY_SAFE) ;
X	notify_interpose_event_func(base_panel, event_proc, NOTIFY_SAFE) ;
X	xv_main_loop(base_frame) ;
}
X
/****************************************************************/
X
/* Handle events. */
X
static	char	command_line[5000] ;	/* String to hold the command */
X
Notify_value	event_proc(win, event, arg, type)
X
XXv_Window		win ;
Event			*event ;
Notify_arg		arg ;
Notify_event_type	type ;
X
{
X	if (event_action(event) == ACTION_DRAG_LOAD ||
X	    event_action(event) == ACTION_DRAG_MOVE ||
X	    event_action(event) == ACTION_DRAG_COPY)
X	{
X		int n ;
X		char buffer[SELN_BUFSIZE] ;
X
X		if (got_icon) invert_icon() ;
X
X		n = xv_decode_drop(event, buffer, sizeof(buffer)) ;
X		if (n == -1)
X		{
X			fprintf(stderr, "xdrop : drop failed\n") ;
X		}
X		else
X		{
X			if (n >= SELN_BUFSIZE)
X			{
X				fprintf(stderr,
X				        "xdrop : data was truncated,\
X						 %d bytes lost.\n",
X					n - SELN_BUFSIZE + 1) ;
X			}
X
X			/*
X				Construct the command.
X			*/
X
X			sprintf(command_line,
X			        "FILE=\"%s\"; %s\n",
X				 buffer,
X				 xv_get(command, PANEL_VALUE)) ;
X
X			/*
X				Now execute the command with the FILE
X				environment variable set up.
X			*/
X
X			system(command_line) ;
X		}
X
X		if (got_icon) invert_icon() ;
X	}
return (notify_next_event_func(win, event, arg, type)) ;
}
X
/****************************************************************/
SHAR_EOF
chmod 0644 xdrop.c ||
echo 'restore of xdrop.c failed'
Wc_c="`wc -c < 'xdrop.c'`"
test 6851 -eq "$Wc_c" ||
	echo 'xdrop.c: original size 6851, current size' "$Wc_c"
fi
exit 0

--
Dan Heller
------------------------------------------------
O'Reilly && Associates 		      Zyrcom Inc
Senior Writer			       President
argv@ora.com			argv@zipcode.com