|
Packit |
b099d7 |
/* $TOG: Transfer.c /main/17 1997/07/16 16:31:41 csn $ */
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <X11/Xatom.h>
|
|
Packit |
b099d7 |
#include <Xm/AtomMgr.h>
|
|
Packit |
b099d7 |
#include <Xm/DragDrop.h>
|
|
Packit |
b099d7 |
#include <Xm/SpecRenderT.h>
|
|
Packit |
b099d7 |
#include <Xm/TraitP.h>
|
|
Packit |
b099d7 |
#include <Xm/VendorSP.h>
|
|
Packit |
b099d7 |
#include <Xm/XmosP.h>
|
|
Packit |
b099d7 |
#include "CutPasteI.h"
|
|
Packit |
b099d7 |
#include "DragBSI.h"
|
|
Packit |
b099d7 |
#include "HashI.h"
|
|
Packit |
b099d7 |
#include "MessagesI.h"
|
|
Packit |
b099d7 |
#include "ResEncodI.h"
|
|
Packit |
b099d7 |
#include "TransferI.h"
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
typedef enum { DoXFree, DoFree } FreeType;
|
|
Packit |
b099d7 |
#define FreeSafeAtomName(val,how) if (1) { if (DoXFree==how) XFree(val); else free(val); }
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static ConvertContext LookupContextBlock(Display*, Atom);
|
|
Packit |
b099d7 |
static void ClearContextBlock(Display*, Atom);
|
|
Packit |
b099d7 |
static void ClipboardCallback(Widget, long*, long*, int*);
|
|
Packit |
b099d7 |
static void DisownCallback(Widget, XtPointer, XtPointer);
|
|
Packit |
b099d7 |
static void FreeTransferID(XtPointer);
|
|
Packit |
b099d7 |
static void CallDoneProcs(Widget, XtPointer, XmTransferDoneCallbackStruct*);
|
|
Packit |
b099d7 |
static XtPointer GetTransferID(void);
|
|
Packit |
b099d7 |
static void SelectionCallbackWrapper(Widget, XtPointer, Atom*, Atom*,
|
|
Packit |
b099d7 |
XtPointer, unsigned long*, int*);
|
|
Packit |
b099d7 |
static Boolean DragConvertHandler(Widget, Atom *, Atom *, Atom *,
|
|
Packit |
b099d7 |
XtPointer *, unsigned long *, int *);
|
|
Packit |
b099d7 |
static void SecondaryConvertHandler(Widget, XtPointer,
|
|
Packit |
b099d7 |
XmConvertCallbackStruct *);
|
|
Packit |
b099d7 |
static void ReleaseSecondaryLock(Widget, XtEnum, XmTransferDoneCallbackStruct*);
|
|
Packit |
b099d7 |
static void DropDestinationHandler(Widget, XtPointer,
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *);
|
|
Packit |
b099d7 |
static TransferBlock AddTransferBlock(TransferContext tc);
|
|
Packit |
b099d7 |
static void SecondaryDone(Widget, XtPointer, Atom*, Atom*,
|
|
Packit |
b099d7 |
XtPointer, unsigned long*, int*);
|
|
Packit |
b099d7 |
static void TransferWarning(Widget w, char* name, char* type, char* message);
|
|
Packit |
b099d7 |
static void DeleteDropCBStruct(Widget w, XtEnum ignored_status,
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *cs);
|
|
Packit |
b099d7 |
static void FinishTransfer(Widget wid, TransferContext tc);
|
|
Packit |
b099d7 |
static char* GetSafeAtomName(Display *display, Atom a, FreeType *howFree);
|
|
Packit |
b099d7 |
static void LoseProc(Widget w, Atom *selection);
|
|
Packit |
b099d7 |
static void ClipboardLoseProc(Widget w, Atom *selection);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define BAD_ATOM_MESSAGE _XmMMsgTransfer_0005
|
|
Packit |
b099d7 |
#define BAD_STATUS_MESSAGE _XmMMsgTransfer_0004
|
|
Packit |
b099d7 |
#define BAD_SCB_MESSAGE _XmMMsgTransfer_0000
|
|
Packit |
b099d7 |
#define BAD_MATCHED_CONVERT _XmMMsgTransfer_0002
|
|
Packit |
b099d7 |
#define BAD_STATUS _XmMMsgTransfer_0003
|
|
Packit |
b099d7 |
#define ERROR_MULTIPLE_IN_PROGRESS _XmMMsgTransfer_0006
|
|
Packit |
b099d7 |
#define ERROR_MULTIPLE_NOT_IN_PROGRESS _XmMMsgTransfer_0007
|
|
Packit |
b099d7 |
#define MERGE "XmeConvertMerge"
|
|
Packit |
b099d7 |
#define ATOM "XGetAtomName"
|
|
Packit |
b099d7 |
#define MATCH "Format or type mismatch"
|
|
Packit |
b099d7 |
#define ARG "Argument"
|
|
Packit |
b099d7 |
#define START_MULTIPLE "XmTransferStartRequest"
|
|
Packit |
b099d7 |
#define END_MULTIPLE "XmTransferSendRequest"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define XmS_MOTIF_SNAPSHOT "_MOTIF_SNAPSHOT"
|
|
Packit |
b099d7 |
#define XmSCLIPBOARD_MANAGER "CLIPBOARD_MANAGER"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define BYTELENGTH( length, format ) \
|
|
Packit |
b099d7 |
((format == 8) ? length : \
|
|
Packit |
b099d7 |
((format == 16) ? length * sizeof(short) : \
|
|
Packit |
b099d7 |
(length * sizeof(long))))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static int local_convert_flag = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmHashTable DataIdDictionary = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal(void)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
local_convert_flag = 1;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* */
|
|
Packit |
b099d7 |
/* Convert section. These functions provide an API to setting up */
|
|
Packit |
b099d7 |
/* selections, working with the clipboard and starting Drag and Drop. */
|
|
Packit |
b099d7 |
/* */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* ConvertHandler is a generalized version of the convert proc */
|
|
Packit |
b099d7 |
/* in Xt. It calls the convertCallbacks and the transferTrait */
|
|
Packit |
b099d7 |
/* on the particular widgetclass. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmConvertHandler(Widget wid, Atom *selection, Atom *target,
|
|
Packit |
b099d7 |
Atom *type, XtPointer *value,
|
|
Packit |
b099d7 |
unsigned long *size, int *fmt)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DESTINATION, XmAINSERT_SELECTION,
|
|
Packit |
b099d7 |
XmALINK_SELECTION, XmA_MOTIF_LOSE_SELECTION, XmA_MOTIF_DROP,
|
|
Packit |
b099d7 |
XmACLIPBOARD, XmA_MOTIF_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmA_MOTIF_DEFERRED_CLIPBOARD_TARGETS, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmS_MOTIF_DESTINATION, XmSINSERT_SELECTION,
|
|
Packit |
b099d7 |
XmSLINK_SELECTION, XmS_MOTIF_LOSE_SELECTION, XmS_MOTIF_DROP,
|
|
Packit |
b099d7 |
XmSCLIPBOARD, XmS_MOTIF_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmS_MOTIF_DEFERRED_CLIPBOARD_TARGETS };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTransferTrait ttrait;
|
|
Packit |
b099d7 |
XmConvertCallbackStruct cbstruct;
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom real_selection_atom = None; /* DND hides the selection atom from us */
|
|
Packit |
b099d7 |
int my_local_convert_flag;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(wid), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
my_local_convert_flag = local_convert_flag;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Find the context block */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(wid), *selection);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Setup the callback structure */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cbstruct.reason = XmCR_OK;
|
|
Packit |
b099d7 |
cbstruct.event = NULL;
|
|
Packit |
b099d7 |
cbstruct.selection = *selection;
|
|
Packit |
b099d7 |
cbstruct.target = *target;
|
|
Packit |
b099d7 |
cbstruct.source_data = (XtPointer) cc -> drag_context;
|
|
Packit |
b099d7 |
cbstruct.flags = XmCONVERTING_NONE;
|
|
Packit |
b099d7 |
cbstruct.location_data = cc -> location_data;
|
|
Packit |
b099d7 |
cbstruct.status = XmCONVERT_DEFAULT;
|
|
Packit |
b099d7 |
cbstruct.value = NULL;
|
|
Packit |
b099d7 |
cbstruct.type = XA_INTEGER;
|
|
Packit |
b099d7 |
cbstruct.format = 8;
|
|
Packit |
b099d7 |
cbstruct.length = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
/* Get the request event if we can */
|
|
Packit |
b099d7 |
if (my_local_convert_flag == 0) {
|
|
Packit |
b099d7 |
Arg args[1];
|
|
Packit |
b099d7 |
Widget req_widget;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*selection == atoms[XmA_MOTIF_DROP]) {
|
|
Packit |
b099d7 |
XtSetArg(args[0], XmNiccHandle, &real_selection_atom);
|
|
Packit |
b099d7 |
XtGetValues(cc -> drag_context, args, 1);
|
|
Packit |
b099d7 |
cbstruct.event = (XEvent *) XtGetSelectionRequest(cc -> drag_context,
|
|
Packit |
b099d7 |
real_selection_atom,
|
|
Packit |
b099d7 |
NULL);
|
|
Packit |
b099d7 |
req_widget = cc -> drag_context;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
cbstruct.event = (XEvent *) XtGetSelectionRequest(wid, *selection,
|
|
Packit |
b099d7 |
NULL);
|
|
Packit |
b099d7 |
req_widget = wid;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Get the parameters from this request. Use the correct
|
|
Packit |
b099d7 |
selection atom here as well */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom sel_atom = (real_selection_atom != None)
|
|
Packit |
b099d7 |
? real_selection_atom : *selection;
|
|
Packit |
b099d7 |
XtGetSelectionParameters(req_widget, sel_atom, NULL,
|
|
Packit |
b099d7 |
&cbstruct.parm_type, &cbstruct.parm,
|
|
Packit |
b099d7 |
&cbstruct.parm_length, &cbstruct.parm_format);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* We're called locally when XmeClipboardSource is invoked and there
|
|
Packit |
b099d7 |
is no CLIPBOARD_MANAGER. In this case we must pickup the operation
|
|
Packit |
b099d7 |
from the context block and put it in the parameter */
|
|
Packit |
b099d7 |
if (*selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
if (*target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS] ||
|
|
Packit |
b099d7 |
*target == atoms[XmA_MOTIF_DEFERRED_CLIPBOARD_TARGETS]) {
|
|
Packit |
b099d7 |
cbstruct.parm = (XtPointer) cc -> op;
|
|
Packit |
b099d7 |
cbstruct.parm_length = 1;
|
|
Packit |
b099d7 |
cbstruct.parm_format = 32;
|
|
Packit |
b099d7 |
cbstruct.parm_type = XA_INTEGER;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
cbstruct.parm = NULL;
|
|
Packit |
b099d7 |
cbstruct.parm_length = 0;
|
|
Packit |
b099d7 |
cbstruct.parm_format = 8;
|
|
Packit |
b099d7 |
cbstruct.parm_type = None;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cbstruct.event != NULL &&
|
|
Packit |
b099d7 |
((XSelectionRequestEvent *) cbstruct.event) -> requestor ==
|
|
Packit |
b099d7 |
((XSelectionRequestEvent *) cbstruct.event) -> owner) {
|
|
Packit |
b099d7 |
cbstruct.flags |= XmCONVERTING_SAME;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
/* Reset bypass flag */
|
|
Packit |
b099d7 |
local_convert_flag = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*selection != atoms[XmA_MOTIF_DESTINATION] ||
|
|
Packit |
b099d7 |
*target == atoms[XmA_MOTIF_LOSE_SELECTION]) {
|
|
Packit |
b099d7 |
/* First we call any convert callbacks */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (XtHasCallbacks(wid, XmNconvertCallback) == XtCallbackHasSome)
|
|
Packit |
b099d7 |
XtCallCallbacks(wid, XmNconvertCallback, &cbstruct);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cbstruct.status == XmCONVERT_MORE)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* Print error message, and revert this flag to
|
|
Packit |
b099d7 |
XmCONVERT_DEFAULT */
|
|
Packit |
b099d7 |
XmeWarning(wid, BAD_STATUS_MESSAGE);
|
|
Packit |
b099d7 |
cbstruct.status = XmCONVERT_DEFAULT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Now lookup the trait on this widget and call the
|
|
Packit |
b099d7 |
internal routine */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cbstruct.status == XmCONVERT_DEFAULT ||
|
|
Packit |
b099d7 |
cbstruct.status == XmCONVERT_MERGE) {
|
|
Packit |
b099d7 |
ttrait = (XmTransferTrait)
|
|
Packit |
b099d7 |
XmeTraitGet((XtPointer) XtClass(wid), XmQTtransfer);
|
|
Packit |
b099d7 |
if (ttrait != NULL)
|
|
Packit |
b099d7 |
ttrait -> convertProc(wid, NULL, &cbstruct);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If this is an INSERT_SELECTION or LINK_SELECTION then
|
|
Packit |
b099d7 |
we call SecondaryConvertHandler to finish the work */
|
|
Packit |
b099d7 |
if (cbstruct.status == XmCONVERT_DEFAULT &&
|
|
Packit |
b099d7 |
(*target == atoms[XmAINSERT_SELECTION] ||
|
|
Packit |
b099d7 |
*target == atoms[XmALINK_SELECTION]))
|
|
Packit |
b099d7 |
SecondaryConvertHandler(wid, NULL, &cbstruct);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Copy out the flags value for CLIPBOARD to use */
|
|
Packit |
b099d7 |
cc -> flags = cbstruct.flags;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cbstruct.status == XmCONVERT_DONE ||
|
|
Packit |
b099d7 |
cbstruct.status == XmCONVERT_DEFAULT)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* Copy out the data */
|
|
Packit |
b099d7 |
*value = cbstruct.value;
|
|
Packit |
b099d7 |
*size = cbstruct.length;
|
|
Packit |
b099d7 |
*fmt = cbstruct.format;
|
|
Packit |
b099d7 |
*type = cbstruct.type;
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*size = 0;
|
|
Packit |
b099d7 |
*fmt = 8;
|
|
Packit |
b099d7 |
*type = None;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* DragConvertHandler acts as a wrapper to convert handler for */
|
|
Packit |
b099d7 |
/* drag and drop. This is because drag and drop passes the */
|
|
Packit |
b099d7 |
/* DragContext as the widget to the convert proc in the drag */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static Boolean
|
|
Packit |
b099d7 |
DragConvertHandler(Widget drag_context, Atom *selection, Atom *target,
|
|
Packit |
b099d7 |
Atom *type, XtPointer *value,
|
|
Packit |
b099d7 |
unsigned long *size, int *fmt)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
Atom MOTIF_DROP = XInternAtom(XtDisplay(drag_context), XmS_MOTIF_DROP, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Find the context block */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(drag_context), MOTIF_DROP);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Originating widget was stored in client_data */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return(_XmConvertHandler((Widget) cc -> client_data,
|
|
Packit |
b099d7 |
selection, target,
|
|
Packit |
b099d7 |
type, value, size, fmt));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static int secondary_lock = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/********************************************************************/
|
|
Packit |
b099d7 |
/* SecondaryConvertHandler handles the detail of */
|
|
Packit |
b099d7 |
/* Secondary selection. This is because secondary is a synchronous */
|
|
Packit |
b099d7 |
/* mechanism which requires a spinlock. */
|
|
Packit |
b099d7 |
/********************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SecondaryConvertHandler(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignored, /* unused */
|
|
Packit |
b099d7 |
XmConvertCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmANULL, XmAINSERT_SELECTION, XmALINK_SELECTION, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = {XmSNULL, XmSINSERT_SELECTION, XmSLINK_SELECTION};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtAppContext app = XtWidgetToApplicationContext(w);
|
|
Packit |
b099d7 |
_XmTextInsertPair *pair;
|
|
Packit |
b099d7 |
XSelectionRequestEvent *req_event;
|
|
Packit |
b099d7 |
static unsigned long old_serial = 0;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
XtEnum operation;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (secondary_lock != 0) {
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_REFUSE;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
req_event = XtGetSelectionRequest(w, cs -> selection, NULL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> event = (XEvent *) req_event;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
/* Work around for intrinsics selection bug */
|
|
Packit |
b099d7 |
if (req_event != NULL && old_serial != req_event->serial)
|
|
Packit |
b099d7 |
old_serial = req_event->serial;
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_REFUSE;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs -> parm_length == 0)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_REFUSE;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
pair = (_XmTextInsertPair *) cs -> parm;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
/* Lock */
|
|
Packit |
b099d7 |
secondary_lock = 1;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs -> target == atoms[XmAINSERT_SELECTION])
|
|
Packit |
b099d7 |
operation = XmCOPY;
|
|
Packit |
b099d7 |
else if (cs -> target == atoms[XmALINK_SELECTION])
|
|
Packit |
b099d7 |
operation = XmLINK;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
operation = XmOTHER;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmDestinationHandler(w, pair -> selection,
|
|
Packit |
b099d7 |
operation, ReleaseSecondaryLock,
|
|
Packit |
b099d7 |
(XtPointer) pair -> target,
|
|
Packit |
b099d7 |
req_event -> time, req_event) != True) {
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_REFUSE;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Make sure the above selection request is completed
|
|
Packit |
b099d7 |
* before returning from the convert proc.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef XTHREADS
|
|
Packit |
b099d7 |
while (XtAppGetExitFlag(app) == False) {
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
for (;;) {
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
XEvent event;
|
|
Packit |
b099d7 |
XtInputMask mask;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (secondary_lock == 0) break;
|
|
Packit |
b099d7 |
#ifndef XTHREADS
|
|
Packit |
b099d7 |
XtAppNextEvent(app, &event);
|
|
Packit |
b099d7 |
XtDispatchEvent(&event);
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
while (!(mask = XtAppPending(app)))
|
|
Packit |
b099d7 |
; /* Busy waiting - so that we don't lose our lock */
|
|
Packit |
b099d7 |
if (mask & XtIMXEvent) { /* We have an XEvent */
|
|
Packit |
b099d7 |
/* Get the event since we know its there.
|
|
Packit |
b099d7 |
* Note that XtAppNextEvent would also process
|
|
Packit |
b099d7 |
* timers/alternate inputs.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
XtAppNextEvent(app, &event); /* no blocking */
|
|
Packit |
b099d7 |
XtDispatchEvent(&event); /* Process it */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else /* not an XEvent, process it */
|
|
Packit |
b099d7 |
XtAppProcessEvent(app, mask); /* non blocking */
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = NULL;
|
|
Packit |
b099d7 |
cs -> type = atoms[XmANULL];
|
|
Packit |
b099d7 |
cs -> format = 8;
|
|
Packit |
b099d7 |
cs -> length = 0;
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_DONE;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
ReleaseSecondaryLock(Widget w, /* unused */
|
|
Packit |
b099d7 |
XtEnum a, /* unused */
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts) /* unused */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
secondary_lock = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* ClipboardLoseProc allows us to perform the delete operation */
|
|
Packit |
b099d7 |
/* for the case where the user is performing a CUT to the */
|
|
Packit |
b099d7 |
/* CLIPBOARD, and the CLIPBOARD is owned by a */
|
|
Packit |
b099d7 |
/* CLIPBOARD_MANAGER. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
ClipboardLoseProc(Widget w, Atom *selection)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom DELETE = XInternAtom(XtDisplay(w), XmSDELETE, False);
|
|
Packit |
b099d7 |
XtPointer value;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
unsigned long size;
|
|
Packit |
b099d7 |
int fmt;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
_XmConvertHandler(w, selection, &DELETE,
|
|
Packit |
b099d7 |
&type, &value, &size, &fmt);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
LoseProc(w, selection);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* LoseProc is just a thin wrapper routine so */
|
|
Packit |
b099d7 |
/* we have a place to do bookkeeping. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
LoseProc(Widget w, Atom *selection)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XtPointer value;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
unsigned long size;
|
|
Packit |
b099d7 |
int fmt;
|
|
Packit |
b099d7 |
Atom MOTIF_LOSE = XInternAtom(XtDisplay(w), XmS_MOTIF_LOSE_SELECTION, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
_XmConvertHandler(w, selection, &MOTIF_LOSE,
|
|
Packit |
b099d7 |
&type, &value, &size, &fmt);
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
XtRemoveCallback(w, XmNdestroyCallback, DisownCallback,
|
|
Packit |
b099d7 |
(XtPointer) *selection);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/********************************************************************/
|
|
Packit |
b099d7 |
/* This gets run to disown the selection if the widget is destroyed */
|
|
Packit |
b099d7 |
/********************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DisownCallback(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore, /* unused */
|
|
Packit |
b099d7 |
XtPointer client_data)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Time time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtDisownSelection(w, (Atom) client_data, time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeConvertMerge merges the new data into the old return */
|
|
Packit |
b099d7 |
/* value in the callback structure. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmeConvertMerge(XtPointer data, Atom type, int format,
|
|
Packit |
b099d7 |
unsigned long size, XmConvertCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (cs -> status != XmCONVERT_MERGE) {
|
|
Packit |
b099d7 |
TransferWarning(NULL, MERGE, ARG, BAD_STATUS);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Merge the results. Format and type better agree */
|
|
Packit |
b099d7 |
if (format == cs -> format && type == cs -> type)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
int total_size, offset, user_bytes;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Calculate all sizes in bytes */
|
|
Packit |
b099d7 |
offset = BYTELENGTH(cs -> length, cs -> format);
|
|
Packit |
b099d7 |
user_bytes = BYTELENGTH(size, format);
|
|
Packit |
b099d7 |
total_size = offset + user_bytes;
|
|
Packit |
b099d7 |
/* Reallocate user data */
|
|
Packit |
b099d7 |
cs-> value = (XtPointer) XtRealloc((char*) cs -> value, total_size);
|
|
Packit |
b099d7 |
if (cs -> value == NULL) {
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* Copy widget data to cs.value from data */
|
|
Packit |
b099d7 |
memcpy(&((char*) cs -> value)[offset], (char*) data, user_bytes);
|
|
Packit |
b099d7 |
/* Add in the new size */
|
|
Packit |
b099d7 |
cs -> length += size;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else /* If not, print an error message */
|
|
Packit |
b099d7 |
TransferWarning(NULL, MERGE, MATCH, BAD_MATCHED_CONVERT);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeTransferAddDoneProc(tid, done_proc) */
|
|
Packit |
b099d7 |
/* Adds a new done proc to the end of the current list of done */
|
|
Packit |
b099d7 |
/* procs. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc(XtPointer id,
|
|
Packit |
b099d7 |
XmSelectionFinishedProc done_proc)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tid = (TransferContext) id;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
tid -> numDoneProcs++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tid -> numDoneProcs == 1)
|
|
Packit |
b099d7 |
tid -> doneProcs = (XmSelectionFinishedProc *)
|
|
Packit |
b099d7 |
XtMalloc(sizeof(XmSelectionFinishedProc*));
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
tid -> doneProcs = (XmSelectionFinishedProc *)
|
|
Packit |
b099d7 |
XtRealloc((char*) tid -> doneProcs,
|
|
Packit |
b099d7 |
sizeof(XmSelectionFinishedProc*) * tid -> numDoneProcs);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tid -> doneProcs[tid -> numDoneProcs - 1] = done_proc;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmePrimarySource(Widget, Time) */
|
|
Packit |
b099d7 |
/* Owns the primary selection and sets up the appropriate */
|
|
Packit |
b099d7 |
/* conversion handling */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmePrimarySource(Widget w, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
return(XmeNamedSource(w, XA_PRIMARY, time));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeNamedSource(Widget, Atom, Time) */
|
|
Packit |
b099d7 |
/* Owns the named selection and sets up the appropriate */
|
|
Packit |
b099d7 |
/* conversion handling */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeNamedSource(Widget w, Atom sel, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean status;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
ClearContextBlock(XtDisplay(w), sel);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (time == 0) time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
status = XtOwnSelection(w, sel, time, _XmConvertHandler,
|
|
Packit |
b099d7 |
LoseProc, NULL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status) XtAddCallback(w, XmNdestroyCallback, DisownCallback,
|
|
Packit |
b099d7 |
(XtPointer) sel);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(status);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeSecondarySource(Widget, Op, Time) */
|
|
Packit |
b099d7 |
/* Owns the secondary selection and sets up the appropriate */
|
|
Packit |
b099d7 |
/* conversion handling. This is the function to call when */
|
|
Packit |
b099d7 |
/* starting the secondary selection. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeSecondarySource(Widget w, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
return(XmeNamedSource(w, XA_SECONDARY, time));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeSecondaryTransfer(Widget, target, op, Time) */
|
|
Packit |
b099d7 |
/* Triggers the actual secondary transfer by requesting the */
|
|
Packit |
b099d7 |
/* target passed into XmeSecondarySource of the selection */
|
|
Packit |
b099d7 |
/* _MOTIF_DESTINATION */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmeSecondaryTransfer(Widget w, Atom target, XtEnum op, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DESTINATION, XmAINSERT_SELECTION,
|
|
Packit |
b099d7 |
XmALINK_SELECTION, XmAATOM_PAIR, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmS_MOTIF_DESTINATION, XmSINSERT_SELECTION,
|
|
Packit |
b099d7 |
XmSLINK_SELECTION, XmIATOM_PAIR };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
_XmTextInsertPair pair;
|
|
Packit |
b099d7 |
Atom transfer_target;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(w), XA_SECONDARY);
|
|
Packit |
b099d7 |
cc -> op = op;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (op == XmLINK)
|
|
Packit |
b099d7 |
transfer_target = atoms[XmALINK_SELECTION];
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
transfer_target = atoms[XmAINSERT_SELECTION];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
pair.selection = XA_SECONDARY;
|
|
Packit |
b099d7 |
pair.target = target;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSetSelectionParameters(w, atoms[XmA_MOTIF_DESTINATION], atoms[XmAATOM_PAIR],
|
|
Packit |
b099d7 |
(XtPointer) &pair, 2, 32);
|
|
Packit |
b099d7 |
XtGetSelectionValue(w, atoms[XmA_MOTIF_DESTINATION], transfer_target,
|
|
Packit |
b099d7 |
SecondaryDone, NULL, time);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*****************************************************************/
|
|
Packit |
b099d7 |
/* SecondaryDone deals with the completion of the */
|
|
Packit |
b099d7 |
/* convert selection request started in XmeSecondaryTransfer */
|
|
Packit |
b099d7 |
/* This also callback to a widget supplied routine to deal with */
|
|
Packit |
b099d7 |
/* issues surrounding the success or failure of the transfer */
|
|
Packit |
b099d7 |
/*****************************************************************/
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SecondaryDone(Widget wid,
|
|
Packit |
b099d7 |
XtPointer client_data, /* unused */
|
|
Packit |
b099d7 |
Atom *selection, /* unused */
|
|
Packit |
b099d7 |
Atom *type, XtPointer value,
|
|
Packit |
b099d7 |
unsigned long *length, int *format)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
Boolean success;
|
|
Packit |
b099d7 |
Atom convert_selection;
|
|
Packit |
b099d7 |
Atom DELETE = XInternAtom(XtDisplay(wid), XmSDELETE, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(wid), XA_SECONDARY);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*type == None && *length == 0 && value == NULL)
|
|
Packit |
b099d7 |
success = False;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
success = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
convert_selection = XA_SECONDARY;
|
|
Packit |
b099d7 |
/* Call the convertCallback with target DELETE if successful */
|
|
Packit |
b099d7 |
if (success && cc -> op == XmMOVE) {
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
_XmConvertHandler(wid, &convert_selection,
|
|
Packit |
b099d7 |
&DELETE,
|
|
Packit |
b099d7 |
type, (XtPointer*) &value, length, format);
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtDisownSelection(wid, convert_selection,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(wid)));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeClipboardSource(Widget, Op, Time) */
|
|
Packit |
b099d7 |
/* Puts data onto the clipboard. */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeClipboardSource(Widget w, XtEnum op, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DEFERRED_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmA_MOTIF_CLIPBOARD_TARGETS, XmACLIPBOARD,
|
|
Packit |
b099d7 |
XmACLIPBOARD_MANAGER, XmA_MOTIF_SNAPSHOT, XmADELETE, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmS_MOTIF_DEFERRED_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmS_MOTIF_CLIPBOARD_TARGETS, XmSCLIPBOARD,
|
|
Packit |
b099d7 |
XmSCLIPBOARD_MANAGER, XmS_MOTIF_SNAPSHOT, XmSDELETE };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
Atom type, type2, *targets;
|
|
Packit |
b099d7 |
XtPointer value;
|
|
Packit |
b099d7 |
unsigned long size, size2;
|
|
Packit |
b099d7 |
int format, format2;
|
|
Packit |
b099d7 |
int i, count, status, transferred = 0;
|
|
Packit |
b099d7 |
Display *display;
|
|
Packit |
b099d7 |
long itemid;
|
|
Packit |
b099d7 |
char *name;
|
|
Packit |
b099d7 |
FreeType howFree;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Window clipboard_owner;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
display = XtDisplay(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(display, atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (time == 0) time = XtLastTimestampProcessed(display);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ClearContextBlock(display, atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(display, atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
cc -> op = op;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If there is a clipboard manager, then just take
|
|
Packit |
b099d7 |
ownership of the clipboard selection and the manager
|
|
Packit |
b099d7 |
will do the rest. Otherwise we use the motif clipboard
|
|
Packit |
b099d7 |
code. */
|
|
Packit |
b099d7 |
clipboard_owner = XGetSelectionOwner(display, atoms[XmACLIPBOARD_MANAGER]);
|
|
Packit |
b099d7 |
if (clipboard_owner != None) {
|
|
Packit |
b099d7 |
int status;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (op == XmMOVE) {
|
|
Packit |
b099d7 |
/* We call a special lose proc for move which will call
|
|
Packit |
b099d7 |
_XmConvertHandler to delete the selection */
|
|
Packit |
b099d7 |
status = XtOwnSelection(w, atoms[XmACLIPBOARD], time,
|
|
Packit |
b099d7 |
_XmConvertHandler, ClipboardLoseProc, NULL);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
status = XtOwnSelection(w, atoms[XmACLIPBOARD], time,
|
|
Packit |
b099d7 |
_XmConvertHandler, LoseProc, NULL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XtAddCallback(w, XmNdestroyCallback, DisownCallback,
|
|
Packit |
b099d7 |
(XtPointer) atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Use Motif clipboard */
|
|
Packit |
b099d7 |
status = XmClipboardStartCopy(display, XtWindow(w), NULL,
|
|
Packit |
b099d7 |
time, w, ClipboardCallback, &itemid);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status == XmClipboardLocked) {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(False);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* OK. We've got the clipboard, now setup the targets items */
|
|
Packit |
b099d7 |
cc -> itemid = itemid;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Call the converter to get the targets for the clipboard
|
|
Packit |
b099d7 |
if _MOTIF_CLIPBOARD_TARGETS doesn't work then try
|
|
Packit |
b099d7 |
TARGETS target */
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if (_XmConvertHandler(w, &atoms[XmACLIPBOARD],
|
|
Packit |
b099d7 |
&atoms[XmA_MOTIF_CLIPBOARD_TARGETS],
|
|
Packit |
b099d7 |
&type, &value, &size, &format) == True &&
|
|
Packit |
b099d7 |
size != 0 &&
|
|
Packit |
b099d7 |
type == XA_ATOM) {
|
|
Packit |
b099d7 |
targets = (Atom *) value;
|
|
Packit |
b099d7 |
count = size;
|
|
Packit |
b099d7 |
/* For each item we register the format, ask to convert it
|
|
Packit |
b099d7 |
and if it is converted we put it on the clipboard */
|
|
Packit |
b099d7 |
for(i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
name = GetSafeAtomName(display, targets[i], &howFree);
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if (_XmConvertHandler(w, &atoms[XmACLIPBOARD], &targets[i],
|
|
Packit |
b099d7 |
&type2, &value, &size2, &format2) == True &&
|
|
Packit |
b099d7 |
! (cc -> flags & XmCONVERTING_PARTIAL)) {
|
|
Packit |
b099d7 |
XmClipboardRegisterFormat(display, name, format2);
|
|
Packit |
b099d7 |
/* format must be 8, 16 or 32. */
|
|
Packit |
b099d7 |
size2 = BYTELENGTH(size2, format2);
|
|
Packit |
b099d7 |
transferred++;
|
|
Packit |
b099d7 |
/* Critical section for MT */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmClipboardPassType(type2);
|
|
Packit |
b099d7 |
XmClipboardCopy(display, XtWindow(w), itemid, name, value, size2, 0, 0);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
/* End Critical section for MT */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
FreeSafeAtomName(name,howFree);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XtFree((char*) targets);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Call the converter to get the deferred targets for the
|
|
Packit |
b099d7 |
clipboard */
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if( _XmConvertHandler(w, &atoms[XmACLIPBOARD],
|
|
Packit |
b099d7 |
&atoms[XmA_MOTIF_DEFERRED_CLIPBOARD_TARGETS],
|
|
Packit |
b099d7 |
&type, &value, &size, &format) == True &&
|
|
Packit |
b099d7 |
size != 0 &&
|
|
Packit |
b099d7 |
type == XA_ATOM) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (DataIdDictionary == NULL) {
|
|
Packit |
b099d7 |
/* Create dictionary which stores data about particular
|
|
Packit |
b099d7 |
snapshots and particular dataids. Since it
|
|
Packit |
b099d7 |
takes an integer as a key, don't need match or hash
|
|
Packit |
b099d7 |
functions */
|
|
Packit |
b099d7 |
DataIdDictionary = _XmAllocHashTable(10, NULL, NULL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
targets = (Atom *) value;
|
|
Packit |
b099d7 |
count = size;
|
|
Packit |
b099d7 |
/* If there are deferred targets then the snapshot target
|
|
Packit |
b099d7 |
must be converted successfully. The value returned
|
|
Packit |
b099d7 |
by snapshot will be used as a unique id in the
|
|
Packit |
b099d7 |
clipboard callback to identify this deferred data
|
|
Packit |
b099d7 |
item */
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if (_XmConvertHandler(w, &atoms[XmACLIPBOARD], &atoms[XmA_MOTIF_SNAPSHOT],
|
|
Packit |
b099d7 |
&type2, &value, &size2, &format2) == True) {
|
|
Packit |
b099d7 |
long data_id;
|
|
Packit |
b099d7 |
SnapshotRequest req;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (count != 0) {
|
|
Packit |
b099d7 |
req = (SnapshotRequest) XtMalloc(sizeof(SnapshotRequestRec));
|
|
Packit |
b099d7 |
req -> outstanding = 0;
|
|
Packit |
b099d7 |
req -> distinguisher = * (Atom *) value;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
req = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for(i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
name = GetSafeAtomName(display, targets[i], &howFree);
|
|
Packit |
b099d7 |
transferred++;
|
|
Packit |
b099d7 |
/* Critical section for MT */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmClipboardPassType(type2);
|
|
Packit |
b099d7 |
XmClipboardCopy(display, XtWindow(w), itemid, name,
|
|
Packit |
b099d7 |
NULL, 0, targets[i], &data_id);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
/* End Critical section for MT */
|
|
Packit |
b099d7 |
/* Associate the data_id with this snapshot and increment
|
|
Packit |
b099d7 |
the number of requests outstanding */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmAddHashEntry(DataIdDictionary, (XmHashKey)data_id, (XtPointer)req);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
req -> outstanding++;
|
|
Packit |
b099d7 |
FreeSafeAtomName(name,howFree);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XtFree((char*) targets);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XmClipboardEndCopy(display, XtWindow(w), itemid);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (op == XmMOVE && transferred != 0) {
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
_XmConvertHandler(w, &atoms[XmACLIPBOARD], &atoms[XmADELETE],
|
|
Packit |
b099d7 |
&type, &value, &size, &format);
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (transferred != 0) {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(True);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(False);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
ClipboardCallback(Widget w, long *data_id, long *target, int *reason)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XtPointer value;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
unsigned long size;
|
|
Packit |
b099d7 |
int format;
|
|
Packit |
b099d7 |
Display *display;
|
|
Packit |
b099d7 |
Atom CLIPBOARD = XInternAtom(XtDisplay(w), XmSCLIPBOARD, False);
|
|
Packit |
b099d7 |
SnapshotRequest req;
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(w), CLIPBOARD);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
req = (SnapshotRequest) _XmGetHashEntry(DataIdDictionary,
|
|
Packit |
b099d7 |
(XmHashKey) *data_id);
|
|
Packit |
b099d7 |
/* Decrement count and remove this association */
|
|
Packit |
b099d7 |
req -> outstanding--;
|
|
Packit |
b099d7 |
_XmRemoveHashEntry(DataIdDictionary, (XtPointer)data_id);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
display = XtDisplay(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*reason != XmCR_CLIPBOARD_DATA_DELETE) {
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if (_XmConvertHandler(w, &req -> distinguisher, (Atom *) target,
|
|
Packit |
b099d7 |
&type, &value, &size, &format) == True &&
|
|
Packit |
b099d7 |
! (cc -> flags & XmCONVERTING_PARTIAL)) {
|
|
Packit |
b099d7 |
char *name;
|
|
Packit |
b099d7 |
FreeType howFree;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
size = BYTELENGTH( size, format );
|
|
Packit |
b099d7 |
if (format % 8 != 0) size++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
name = GetSafeAtomName(display, * (Atom *) target, &howFree);
|
|
Packit |
b099d7 |
XmClipboardRegisterFormat(display, name, format);
|
|
Packit |
b099d7 |
FreeSafeAtomName(name,howFree);
|
|
Packit |
b099d7 |
/* Critical section for MT */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmClipboardPassType(type);
|
|
Packit |
b099d7 |
XmClipboardCopyByName(display, XtWindow(w), *data_id,
|
|
Packit |
b099d7 |
value, size, 0L);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
XmClipboardCopyByName(display, XtWindow(w), *data_id,
|
|
Packit |
b099d7 |
NULL, 0, 0L);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (req -> outstanding == 0) {
|
|
Packit |
b099d7 |
Atom done = XInternAtom(display, XmIDONE, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If this was the last item, call _XmConvertHandler with
|
|
Packit |
b099d7 |
DELETE on the distinguisher and then free the req */
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
_XmConvertHandler(w, &req -> distinguisher,
|
|
Packit |
b099d7 |
(Atom *) &done, &type, &value, &size, &format);
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
XtFree((char*) req);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* XmeDragSource */
|
|
Packit |
b099d7 |
/* Sets up for drag and drop and calls XmDragStart */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Widget
|
|
Packit |
b099d7 |
XmeDragSource(Widget w, XtPointer location_data, XEvent *event,
|
|
Packit |
b099d7 |
ArgList in_args, Cardinal in_arg_count)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DROP, XmA_MOTIF_EXPORT_TARGETS, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmS_MOTIF_DROP, XmS_MOTIF_EXPORT_TARGETS };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Arg *args;
|
|
Packit |
b099d7 |
int arg_count;
|
|
Packit |
b099d7 |
XtPointer targets;
|
|
Packit |
b099d7 |
unsigned long size;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
int format;
|
|
Packit |
b099d7 |
Widget dragContext;
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* merge and copy arg list */
|
|
Packit |
b099d7 |
arg_count = in_arg_count + 10;
|
|
Packit |
b099d7 |
args = (Arg *) XtMalloc(sizeof(Arg) * arg_count);
|
|
Packit |
b099d7 |
for(arg_count = 0; arg_count < in_arg_count; arg_count++)
|
|
Packit |
b099d7 |
args[arg_count] = in_args[arg_count];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
arg_count = in_arg_count;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ClearContextBlock(XtDisplay(w), atoms[XmA_MOTIF_DROP]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(w), atoms[XmA_MOTIF_DROP]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc -> location_data = location_data;
|
|
Packit |
b099d7 |
cc -> client_data = (XtPointer) w;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSetArg(args[arg_count], XmNconvertProc, DragConvertHandler);
|
|
Packit |
b099d7 |
arg_count++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmConvertHandlerSetLocal();
|
|
Packit |
b099d7 |
if (_XmConvertHandler(w, &atoms[XmA_MOTIF_DROP],
|
|
Packit |
b099d7 |
&atoms[XmA_MOTIF_EXPORT_TARGETS],
|
|
Packit |
b099d7 |
&type, &targets, &size, &format) == True) {
|
|
Packit |
b099d7 |
XtSetArg(args[arg_count], XmNexportTargets, targets); arg_count++;
|
|
Packit |
b099d7 |
XtSetArg(args[arg_count], XmNnumExportTargets, size); arg_count++;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* Free copied arguments */
|
|
Packit |
b099d7 |
XtFree((char*) args);
|
|
Packit |
b099d7 |
XtFree((char*) targets);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(NULL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSetArg(args[arg_count], XmNclientData, location_data); arg_count++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
dragContext = XmDragStart(w, event, args, arg_count);
|
|
Packit |
b099d7 |
cc -> drag_context = dragContext;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Free copied arguments */
|
|
Packit |
b099d7 |
XtFree((char*) args);
|
|
Packit |
b099d7 |
XtFree((char*) targets);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(dragContext);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* Destination section */
|
|
Packit |
b099d7 |
/* */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* internal flag for transfer block setup */
|
|
Packit |
b099d7 |
static int TB_internal = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmDestinationHandler(Widget wid, Atom selection, XtEnum op,
|
|
Packit |
b099d7 |
XmSelectionFinishedProc done_proc,
|
|
Packit |
b099d7 |
XtPointer location_data, Time time,
|
|
Packit |
b099d7 |
XSelectionRequestEvent *event)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Window selection_owner;
|
|
Packit |
b099d7 |
TransferContext tc;
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *cbstruct;
|
|
Packit |
b099d7 |
XmTransferTrait ttrait;
|
|
Packit |
b099d7 |
Atom MOTIF_DROP = XInternAtom(XtDisplay(wid), XmS_MOTIF_DROP, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cbstruct = (XmDestinationCallbackStruct *)
|
|
Packit |
b099d7 |
XtMalloc(sizeof(XmDestinationCallbackStruct));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cbstruct -> reason = XmCR_OK;
|
|
Packit |
b099d7 |
cbstruct -> event = (XEvent *) event;
|
|
Packit |
b099d7 |
cbstruct -> selection = selection;
|
|
Packit |
b099d7 |
cbstruct -> flags = 0;
|
|
Packit |
b099d7 |
cbstruct -> operation = op;
|
|
Packit |
b099d7 |
cbstruct -> location_data = location_data;
|
|
Packit |
b099d7 |
cbstruct -> destination_data = NULL;
|
|
Packit |
b099d7 |
cbstruct -> time = time;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Setup transfer */
|
|
Packit |
b099d7 |
cbstruct -> transfer_id = (XtPointer) GetTransferID();
|
|
Packit |
b099d7 |
tc = (TransferContext) cbstruct -> transfer_id;
|
|
Packit |
b099d7 |
tc -> widget = wid;
|
|
Packit |
b099d7 |
tc -> numDoneProcs = 0;
|
|
Packit |
b099d7 |
tc -> doneProcs = NULL;
|
|
Packit |
b099d7 |
tc -> auto_proc = (XtCallbackProc) NULL;
|
|
Packit |
b099d7 |
tc -> status = XmTRANSFER_DONE_DEFAULT;
|
|
Packit |
b099d7 |
tc -> flags = TC_NONE;
|
|
Packit |
b099d7 |
tc -> selection = selection;
|
|
Packit |
b099d7 |
tc -> real_selection = selection;
|
|
Packit |
b099d7 |
tc -> op = op;
|
|
Packit |
b099d7 |
tc -> client_data = NULL;
|
|
Packit |
b099d7 |
tc -> drop_context = (Widget) NULL;
|
|
Packit |
b099d7 |
tc -> drag_context = (Widget) NULL;
|
|
Packit |
b099d7 |
tc -> callback_struct = cbstruct;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (done_proc != NULL)
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc((XtPointer) tc, done_proc);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ttrait = (XmTransferTrait)
|
|
Packit |
b099d7 |
XmeTraitGet((XtPointer) XtClass(wid), XmQTtransfer);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> selection == MOTIF_DROP) {
|
|
Packit |
b099d7 |
/* We pass the drop callback struct in through location_data */
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *ds = (XmDropProcCallbackStruct *) location_data;
|
|
Packit |
b099d7 |
XtPointer malloc_ds;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
Arg args[1];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
malloc_ds = XtMalloc(sizeof(XmDropProcCallbackStruct));
|
|
Packit |
b099d7 |
memcpy(malloc_ds, ds, sizeof(XmDropProcCallbackStruct));
|
|
Packit |
b099d7 |
location_data = malloc_ds;
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc((XtPointer) tc, DeleteDropCBStruct);
|
|
Packit |
b099d7 |
tc -> drag_context = ds -> dragContext;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
i = 0;
|
|
Packit |
b099d7 |
XtSetArg(args[i], XmNiccHandle, &tc -> real_selection); i++;
|
|
Packit |
b099d7 |
XtGetValues(ds->dragContext, args, i);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If this is a drop, we need to do more to figure out who
|
|
Packit |
b099d7 |
really owns the selection */
|
|
Packit |
b099d7 |
selection_owner = XGetSelectionOwner(XtDisplay(wid), tc -> real_selection);
|
|
Packit |
b099d7 |
if (XtWindowToWidget(XtDisplay(wid), selection_owner) != (Widget) NULL) {
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
cc = LookupContextBlock(XtDisplay(wid), MOTIF_DROP);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* We go get the origination information if this is in the same
|
|
Packit |
b099d7 |
client as the originator. We know its the same client if
|
|
Packit |
b099d7 |
XtWindowToWidget is successful */
|
|
Packit |
b099d7 |
if (cc -> client_data == (XtPointer) wid)
|
|
Packit |
b099d7 |
cbstruct -> flags |= XmCONVERTING_SAME;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* We pass this callback struct on through destination_data
|
|
Packit |
b099d7 |
and get new data from the widget trait for location_data */
|
|
Packit |
b099d7 |
cbstruct -> destination_data = location_data;
|
|
Packit |
b099d7 |
cbstruct -> location_data = NULL;
|
|
Packit |
b099d7 |
} else { /* Not D&D */
|
|
Packit |
b099d7 |
/* For regular selections, we can just use this info, otherwise
|
|
Packit |
b099d7 |
we need to get the real selection atom for D&D */
|
|
Packit |
b099d7 |
selection_owner = XGetSelectionOwner(XtDisplay(wid), selection);
|
|
Packit |
b099d7 |
if (selection_owner == XtWindow(wid))
|
|
Packit |
b099d7 |
cbstruct -> flags |= XmCONVERTING_SAME;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Call the prehook to allow the widget to setup information. This
|
|
Packit |
b099d7 |
is currently only envisioned to be useful in D&D */
|
|
Packit |
b099d7 |
if (ttrait != NULL && ttrait -> destinationPreHookProc != NULL)
|
|
Packit |
b099d7 |
ttrait -> destinationPreHookProc(wid, NULL, cbstruct);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* First we call any destination callbacks */
|
|
Packit |
b099d7 |
if (XtHasCallbacks(wid, XmNdestinationCallback) == XtCallbackHasSome)
|
|
Packit |
b099d7 |
XtCallCallbacks(wid, XmNdestinationCallback, cbstruct);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> flags |= TC_CALLED_CALLBACKS;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Now lookup the trait on this widget and call the
|
|
Packit |
b099d7 |
internal routine if there were no transfers via the
|
|
Packit |
b099d7 |
destination callbacks (or no destination callbacks) or
|
|
Packit |
b099d7 |
there were transfers and the user set the status to
|
|
Packit |
b099d7 |
DEFAULT and has finished (if it hasn't finished we'll
|
|
Packit |
b099d7 |
handle this in SelectionCallbackWrapper) */
|
|
Packit |
b099d7 |
if (ttrait != NULL &&
|
|
Packit |
b099d7 |
tc -> status == XmTRANSFER_DONE_DEFAULT &&
|
|
Packit |
b099d7 |
((tc -> count == 0) ||
|
|
Packit |
b099d7 |
(tc -> outstanding == 0 &&
|
|
Packit |
b099d7 |
! (TC_CALLED_WIDGET)))) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
TB_internal = 1;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
tc -> flags |= TC_CALLED_WIDGET;
|
|
Packit |
b099d7 |
if (ttrait -> destinationProc != 0)
|
|
Packit |
b099d7 |
ttrait -> destinationProc(wid, NULL, cbstruct);
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
TB_internal = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> count == 0 &&
|
|
Packit |
b099d7 |
tc -> selection == MOTIF_DROP) {
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *ds = (XmDropProcCallbackStruct *) location_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds -> dropAction == XmDROP_HELP) {
|
|
Packit |
b099d7 |
/* If a drop help occured, then we do not want to cleanup yet,
|
|
Packit |
b099d7 |
despite there being no transfers. Right at this moment,
|
|
Packit |
b099d7 |
the user is deciding whether to accept or cancel the drop
|
|
Packit |
b099d7 |
based on the presented dialog. */
|
|
Packit |
b099d7 |
tc -> flags |= TC_EXITED_DH; /* Indicate safe to free record */
|
|
Packit |
b099d7 |
/* Exit immediately to avoid freeing the transfer block below */
|
|
Packit |
b099d7 |
return(True);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* If no transfers occurred, and this is a drop,
|
|
Packit |
b099d7 |
then it failed */
|
|
Packit |
b099d7 |
Arg args[2];
|
|
Packit |
b099d7 |
XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
|
|
Packit |
b099d7 |
XtSetArg(args[1], XmNnumDropTransfers, 0);
|
|
Packit |
b099d7 |
XmDropTransferStart(tc -> drag_context, args, 2);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If we either have performed no transfers or we are finished
|
|
Packit |
b099d7 |
with the transfers, go finish the work */
|
|
Packit |
b099d7 |
if (tc -> count == 0 || tc -> outstanding == 0)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
FinishTransfer(wid, tc);
|
|
Packit |
b099d7 |
return(True);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
/* Otherwise set the flag so SelectionCallbackWrapper can
|
|
Packit |
b099d7 |
finish the work */
|
|
Packit |
b099d7 |
tc -> flags |= TC_EXITED_DH; /* Indicate safe to free record */
|
|
Packit |
b099d7 |
return(True);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
FinishTransfer(Widget wid, TransferContext tc)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct ts;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> flags |= TC_FLUSHED; /* Ignore any future requests */
|
|
Packit |
b099d7 |
ts.reason = XmCR_OK;
|
|
Packit |
b099d7 |
ts.event = (XEvent *) NULL;
|
|
Packit |
b099d7 |
ts.selection = tc -> selection;
|
|
Packit |
b099d7 |
ts.transfer_id = (XtPointer) tc;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> status == XmTRANSFER_DONE_FAIL)
|
|
Packit |
b099d7 |
ts.status = XmTRANSFER_DONE_FAIL;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
ts.status = XmTRANSFER_DONE_SUCCEED;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Override if no transfers have occurred */
|
|
Packit |
b099d7 |
if (tc -> count == 0) ts.status = XmTRANSFER_DONE_FAIL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ts.client_data = tc -> client_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
CallDoneProcs(wid, tc, &ts);
|
|
Packit |
b099d7 |
XtFree((char*) tc -> callback_struct);
|
|
Packit |
b099d7 |
FreeTransferID(tc);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* DropDestinationHandler acts as a wrapper to the destination */
|
|
Packit |
b099d7 |
/* handler for drag and drop. This is because drag and drop */
|
|
Packit |
b099d7 |
/* passes the DragContext as the widget to the destination proc */
|
|
Packit |
b099d7 |
/* in the drop */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DeleteDropCBStruct(Widget w, /* unused */
|
|
Packit |
b099d7 |
XtEnum ignored_status, /* unused */
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) cs -> transfer_id;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* The malloc'd structure is in the destination_data member */
|
|
Packit |
b099d7 |
XtFree((char*) tc -> callback_struct -> destination_data);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DropDestinationHandler(Widget w,
|
|
Packit |
b099d7 |
XtPointer client_data, /* unused */
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom MOTIF_DROP = XInternAtom(XtDisplay(w), XmS_MOTIF_DROP, False);
|
|
Packit |
b099d7 |
XtEnum op;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds -> dropAction == XmDROP_HELP ||
|
|
Packit |
b099d7 |
ds -> operation == XmDROP_NOOP)
|
|
Packit |
b099d7 |
op = XmOTHER;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
op = ds -> operation;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(void) _XmDestinationHandler(w, MOTIF_DROP, op, NULL,
|
|
Packit |
b099d7 |
(XtPointer) ds, ds -> timeStamp, NULL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
/* XmePrimarySink begins a transfer for the contents of the */
|
|
Packit |
b099d7 |
/* XA_PRIMARY selection. */
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmePrimarySink(Widget w, XtEnum op, XtPointer location_data, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean ret_val;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
ret_val = _XmDestinationHandler(w, XA_PRIMARY, op, NULL,
|
|
Packit |
b099d7 |
location_data, time, NULL);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return ret_val;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
/* XmeNamedSink begins a transfer for the contents of the */
|
|
Packit |
b099d7 |
/* named selection. */
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeNamedSink(Widget w, Atom sel, XtEnum op, XtPointer location_data, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean ret_val;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
ret_val = _XmDestinationHandler(w, sel, op, NULL,
|
|
Packit |
b099d7 |
location_data, time, NULL);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return ret_val;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
/* XmeSecondarySink takes ownership of the MOTIF_DESTINATION */
|
|
Packit |
b099d7 |
/* selection. */
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeSecondarySink(Widget w, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean status;
|
|
Packit |
b099d7 |
Atom MOTIF_DESTINATION = XInternAtom(XtDisplay(w), XmS_MOTIF_DESTINATION, False);
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
ClearContextBlock(XtDisplay(w), MOTIF_DESTINATION);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (time == 0) time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Setup our end of the secondary selection */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
status = XtOwnSelection(w, MOTIF_DESTINATION, time,
|
|
Packit |
b099d7 |
_XmConvertHandler, LoseProc, NULL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status) XtAddCallback(w, XmNdestroyCallback, DisownCallback,
|
|
Packit |
b099d7 |
(XtPointer) MOTIF_DESTINATION);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(status);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/**************************************************************/
|
|
Packit |
b099d7 |
/* XmeClipboardSink begins a transfer for the contents of the */
|
|
Packit |
b099d7 |
/* CLIPBOARD selection. */
|
|
Packit |
b099d7 |
/**************************************************************/
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
XmeClipboardSink(Widget w, XtEnum op, XtPointer location_data)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom CLIPBOARD = XInternAtom(XtDisplay(w), XmSCLIPBOARD, False);
|
|
Packit |
b099d7 |
Boolean ret_val;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
ret_val = _XmDestinationHandler(w, CLIPBOARD, op,
|
|
Packit |
b099d7 |
NULL, location_data, 0, NULL);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return ret_val;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
/* XmeDropSink creates a drop site that will use the */
|
|
Packit |
b099d7 |
/* destinationCallbacks to handle drops. */
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmeDropSink(Widget w, ArgList in_args, Cardinal in_arg_count)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Arg *args;
|
|
Packit |
b099d7 |
int arg_count;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/* merge and copy arg list */
|
|
Packit |
b099d7 |
arg_count = in_arg_count + 2;
|
|
Packit |
b099d7 |
args = (Arg *) XtMalloc(sizeof(Arg) * arg_count);
|
|
Packit |
b099d7 |
for(arg_count = 0; arg_count < in_arg_count; arg_count++)
|
|
Packit |
b099d7 |
args[arg_count] = in_args[arg_count];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
arg_count = in_arg_count;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSetArg(args[arg_count], XmNdropProc, DropDestinationHandler);
|
|
Packit |
b099d7 |
arg_count++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmDropSiteRegister(w, args, arg_count);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtFree((char*) args);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
/* Transfer routine section */
|
|
Packit |
b099d7 |
/*************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* XmTransferDone allows the user to control the transfer queue */
|
|
Packit |
b099d7 |
/* If the user calls XmTransferDone with a status of DEFAULT then */
|
|
Packit |
b099d7 |
/* all remaining non-internal transfers are ignored and the widget's */
|
|
Packit |
b099d7 |
/* internal transfers are done. SUCCEED, FAIL or CONTINUE cause the */
|
|
Packit |
b099d7 |
/* entire queue to be flushed, and the appropriate status to be set. */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmTransferDone(XtPointer transfer_id, XmTransferStatus status)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) transfer_id;
|
|
Packit |
b099d7 |
Atom MOTIF_DROP = XInternAtom(XtDisplay(tc -> widget), XmS_MOTIF_DROP, False);
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(tc->widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
tc -> status = status;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Make sure MULTIPLE request is unblocked */
|
|
Packit |
b099d7 |
if (tc -> flags & TC_IN_MULTIPLE) {
|
|
Packit |
b099d7 |
tc -> flags &= ~ TC_IN_MULTIPLE;
|
|
Packit |
b099d7 |
XtSendSelectionRequest(tc -> widget, tc -> selection,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(tc -> widget)));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status == XmTRANSFER_DONE_SUCCEED ||
|
|
Packit |
b099d7 |
status == XmTRANSFER_DONE_FAIL ||
|
|
Packit |
b099d7 |
status == XmTRANSFER_DONE_CONTINUE)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
tc -> flags |= TC_FLUSHED;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (status == XmTRANSFER_DONE_FAIL &&
|
|
Packit |
b099d7 |
tc -> selection == MOTIF_DROP) {
|
|
Packit |
b099d7 |
Arg args[2];
|
|
Packit |
b099d7 |
XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
|
|
Packit |
b099d7 |
XtSetArg(args[1], XmNnumDropTransfers, 0);
|
|
Packit |
b099d7 |
if (tc -> drop_context != (Widget) NULL)
|
|
Packit |
b099d7 |
XtSetValues(tc -> drop_context, args, 2);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
XmDropTransferStart(tc -> drag_context, args, 2);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Also, if there are no transfers, and we have exited
|
|
Packit |
b099d7 |
_XmDestinationHandler, we must cleanup the transfer
|
|
Packit |
b099d7 |
infomation here as SelectionCallbackWrapper, where the
|
|
Packit |
b099d7 |
data is normally freed, won't be called */
|
|
Packit |
b099d7 |
if (tc -> count == 0 &&
|
|
Packit |
b099d7 |
tc -> flags & TC_EXITED_DH ) {
|
|
Packit |
b099d7 |
FinishTransfer(tc -> widget, tc);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else if (status == XmTRANSFER_DONE_DEFAULT)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferBlock tb;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If we are going to default then we'll skip
|
|
Packit |
b099d7 |
all requests placed by callbacks */
|
|
Packit |
b099d7 |
for(tb = tc -> requests;
|
|
Packit |
b099d7 |
tb != NULL;
|
|
Packit |
b099d7 |
tb = (TransferBlock) tb -> next) {
|
|
Packit |
b099d7 |
if (!(tb -> flags & TB_INTERNAL))
|
|
Packit |
b099d7 |
tb -> flags = tb -> flags | TB_IGNORE;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* XmTransferSetParameters defines a set of parameters to be passed */
|
|
Packit |
b099d7 |
/* with the next call to XmTransferValue. */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmTransferSetParameters(XtPointer transfer_id,
|
|
Packit |
b099d7 |
XtPointer parm,
|
|
Packit |
b099d7 |
int parm_fmt,
|
|
Packit |
b099d7 |
unsigned long parm_length,
|
|
Packit |
b099d7 |
Atom parm_type)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) transfer_id;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(tc->widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
/* Return if we already finished this transfer set */
|
|
Packit |
b099d7 |
/* The problem is that if the flags are set then we */
|
|
Packit |
b099d7 |
/* are about to delete the transferContext in */
|
|
Packit |
b099d7 |
/* SelectionCallbackWrapper() */
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
if (tc -> flags & TC_FLUSHED) {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (parm_fmt == 0) parm_fmt = 8;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (parm != NULL)
|
|
Packit |
b099d7 |
XtSetSelectionParameters(tc -> widget, tc -> real_selection,
|
|
Packit |
b099d7 |
parm_type, parm, parm_length, parm_fmt);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* XmTransferValue allows the user to get data from the owner of the */
|
|
Packit |
b099d7 |
/* selection for which we started the destination callback. */
|
|
Packit |
b099d7 |
/* This takes care of the small details for getting the data from */
|
|
Packit |
b099d7 |
/* either the selection mechanism (user, PRIMARY, SECONDARY, or */
|
|
Packit |
b099d7 |
/* CLIPBOARD) or from another mechanism (Drag and Drop). */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmTransferValue(XtPointer transfer_id,
|
|
Packit |
b099d7 |
Atom target,
|
|
Packit |
b099d7 |
XtCallbackProc proc,
|
|
Packit |
b099d7 |
XtPointer client_data,
|
|
Packit |
b099d7 |
Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmACLIPBOARD, XmA_MOTIF_DROP, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSCLIPBOARD, XmS_MOTIF_DROP };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) transfer_id;
|
|
Packit |
b099d7 |
TransferBlock tb;
|
|
Packit |
b099d7 |
unsigned long length;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(tc->widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
/* Return if we already finished this transfer set */
|
|
Packit |
b099d7 |
/* The problem is that if the flags are set then we */
|
|
Packit |
b099d7 |
/* are about to delete the transferContext in */
|
|
Packit |
b099d7 |
/* SelectionCallbackWrapper() */
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
if (tc -> flags & TC_FLUSHED) {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(tc -> widget), atom_names, XtNumber(atom_names),
|
|
Packit |
b099d7 |
False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (time == 0)
|
|
Packit |
b099d7 |
time = XtLastTimestampProcessed(XtDisplay(tc -> widget));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tb = AddTransferBlock(tc);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tb -> client_data = client_data;
|
|
Packit |
b099d7 |
tb -> selection_proc = proc;
|
|
Packit |
b099d7 |
tb -> target = target;
|
|
Packit |
b099d7 |
tb -> location_data = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> outstanding++;
|
|
Packit |
b099d7 |
tc -> count++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
/* Assure the clipboard is owned to prevent orphan data
|
|
Packit |
b099d7 |
problems in the data transfer */
|
|
Packit |
b099d7 |
XmClipboardInquireLength(XtDisplay(tc -> widget),
|
|
Packit |
b099d7 |
XtWindow(tc -> widget),
|
|
Packit |
b099d7 |
XmSTARGETS,
|
|
Packit |
b099d7 |
&length);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> selection != atoms[XmA_MOTIF_DROP])
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XtGetSelectionValue(tc -> widget, tc -> real_selection, target,
|
|
Packit |
b099d7 |
SelectionCallbackWrapper, (XtPointer)tc, time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmDropTransferEntryRec transfers[1];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
transfers[0].client_data = (XtPointer) tc;
|
|
Packit |
b099d7 |
transfers[0].target = tb -> target;
|
|
Packit |
b099d7 |
if (tc -> drop_context == NULL)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Arg args[5];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSetArg(args[0], XmNdropTransfers, transfers);
|
|
Packit |
b099d7 |
XtSetArg(args[1], XmNnumDropTransfers, 1);
|
|
Packit |
b099d7 |
XtSetArg(args[2], XmNtransferProc, SelectionCallbackWrapper);
|
|
Packit |
b099d7 |
tc -> drop_context =
|
|
Packit |
b099d7 |
(Widget) XmDropTransferStart(tc -> drag_context, args, 3);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
XmDropTransferAdd(tc -> drop_context, transfers, 1);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* XmTransferStartRequest and XmTransferSendRequest bracket a MULTIPLE */
|
|
Packit |
b099d7 |
/* request. In between the user calls XmTransferSetParameters and */
|
|
Packit |
b099d7 |
/* XmTransferValue to arrange requests. */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmTransferStartRequest(XtPointer transfer_id)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) transfer_id;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(tc->widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
/* Return if we already finished this transfer set */
|
|
Packit |
b099d7 |
/* The problem is that if the flags are set then we */
|
|
Packit |
b099d7 |
/* are about to delete the transferContext in */
|
|
Packit |
b099d7 |
/* SelectionCallbackWrapper() */
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
if (tc -> flags & TC_FLUSHED) {
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> flags & TC_IN_MULTIPLE) {
|
|
Packit |
b099d7 |
char *sel;
|
|
Packit |
b099d7 |
FreeType howFree;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
sel = GetSafeAtomName(XtDisplay(tc -> widget), tc -> selection, &howFree);
|
|
Packit |
b099d7 |
/* Already doing a multiple */
|
|
Packit |
b099d7 |
TransferWarning(tc->widget, START_MULTIPLE,
|
|
Packit |
b099d7 |
sel,
|
|
Packit |
b099d7 |
ERROR_MULTIPLE_IN_PROGRESS);
|
|
Packit |
b099d7 |
FreeSafeAtomName(sel,howFree);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> flags |= TC_IN_MULTIPLE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtCreateSelectionRequest(tc -> widget, tc -> real_selection);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmTransferSendRequest(XtPointer transfer_id, Time time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) transfer_id;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(tc->widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
/* Return if we already finished this transfer set */
|
|
Packit |
b099d7 |
/* The problem is that if the flags are set then we */
|
|
Packit |
b099d7 |
/* are about to delete the transferContext in */
|
|
Packit |
b099d7 |
/* SelectionCallbackWrapper() */
|
|
Packit |
b099d7 |
/******************************************************/
|
|
Packit |
b099d7 |
if (tc -> flags & TC_FLUSHED) {
|
|
Packit |
b099d7 |
/* Assume that cleanup would be appropriate here */
|
|
Packit |
b099d7 |
XtCancelSelectionRequest(tc -> widget, tc -> real_selection);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (! (tc -> flags & TC_IN_MULTIPLE)) {
|
|
Packit |
b099d7 |
char *sel;
|
|
Packit |
b099d7 |
FreeType howFree;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
sel = GetSafeAtomName(XtDisplay(tc -> widget), tc -> selection, &howFree);
|
|
Packit |
b099d7 |
/* Not doing a multiple */
|
|
Packit |
b099d7 |
TransferWarning(tc->widget, END_MULTIPLE,
|
|
Packit |
b099d7 |
sel,
|
|
Packit |
b099d7 |
ERROR_MULTIPLE_NOT_IN_PROGRESS);
|
|
Packit |
b099d7 |
FreeSafeAtomName(sel, howFree);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> flags &= ~ TC_IN_MULTIPLE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (time == 0) time = XtLastTimestampProcessed(XtDisplay(tc -> widget));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtSendSelectionRequest(tc -> widget, tc -> real_selection, time);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
/* SelectionCallbackWrapper does the bookeeping for the transfer */
|
|
Packit |
b099d7 |
/* routines and makes sure that the TransferContext is deleted when */
|
|
Packit |
b099d7 |
/* there are no more outstanding transfers. */
|
|
Packit |
b099d7 |
/************************************************************************/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SelectionCallbackWrapper(Widget wid, XtPointer client_data,
|
|
Packit |
b099d7 |
Atom *selection, Atom *type,
|
|
Packit |
b099d7 |
XtPointer value, unsigned long *length,
|
|
Packit |
b099d7 |
int *format)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DROP, XmADELETE, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmS_MOTIF_DROP, XmSDELETE };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct cbstruct;
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) client_data;
|
|
Packit |
b099d7 |
TransferBlock tb = tc -> requests;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(wid), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Get the real widget if this is a drop transfer */
|
|
Packit |
b099d7 |
if (tc -> selection == atoms[XmA_MOTIF_DROP])
|
|
Packit |
b099d7 |
wid = tc -> widget;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tc -> outstanding == 0) {
|
|
Packit |
b099d7 |
XmeWarning(wid, BAD_SCB_MESSAGE);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tb != NULL) {
|
|
Packit |
b099d7 |
/* Unchain this transfer block */
|
|
Packit |
b099d7 |
tc -> requests = (TransferBlock) tb -> next;
|
|
Packit |
b099d7 |
/* If this is the last block then reset last */
|
|
Packit |
b099d7 |
if (tc -> last == tb) tc -> last = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (! (tc -> flags & TC_FLUSHED)) {
|
|
Packit |
b099d7 |
if (tb != NULL &&
|
|
Packit |
b099d7 |
! (tb -> flags & TB_IGNORE)) {
|
|
Packit |
b099d7 |
cbstruct.reason = XmCR_OK;
|
|
Packit |
b099d7 |
cbstruct.event = (XEvent *) NULL;
|
|
Packit |
b099d7 |
cbstruct.selection = *selection;
|
|
Packit |
b099d7 |
cbstruct.target = tb -> target;
|
|
Packit |
b099d7 |
cbstruct.transfer_id = (XtPointer) tc;
|
|
Packit |
b099d7 |
cbstruct.flags = XmSELECTION_DEFAULT;
|
|
Packit |
b099d7 |
cbstruct.remaining = tc -> outstanding;
|
|
Packit |
b099d7 |
cbstruct.type = *type;
|
|
Packit |
b099d7 |
cbstruct.value = value;
|
|
Packit |
b099d7 |
cbstruct.length = *length;
|
|
Packit |
b099d7 |
cbstruct.format = *format;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tb -> selection_proc != NULL)
|
|
Packit |
b099d7 |
tb -> selection_proc(wid, tb -> client_data, &cbstruct);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Free this transfer block */
|
|
Packit |
b099d7 |
if (tb != NULL) {
|
|
Packit |
b099d7 |
XtFree((char*) tb);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Ignore callbacks after we're done */
|
|
Packit |
b099d7 |
tc -> outstanding--;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* When outstanding is 0, check to see if the status is
|
|
Packit |
b099d7 |
XmTRANSFER_DONE_DEFAULT. This indicates that we
|
|
Packit |
b099d7 |
should attempt calling the widget's destination
|
|
Packit |
b099d7 |
proc. We'll set a flag in tc to indicate that
|
|
Packit |
b099d7 |
we've done this, so we don't repeat the action */
|
|
Packit |
b099d7 |
if (tc -> outstanding == 0 &&
|
|
Packit |
b099d7 |
tc -> status == XmTRANSFER_DONE_DEFAULT &&
|
|
Packit |
b099d7 |
tc -> flags & TC_CALLED_CALLBACKS &&
|
|
Packit |
b099d7 |
!(tc -> flags & TC_CALLED_WIDGET)) {
|
|
Packit |
b099d7 |
XmTransferTrait ttrait;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tc -> flags |= TC_CALLED_WIDGET;
|
|
Packit |
b099d7 |
ttrait = (XmTransferTrait)
|
|
Packit |
b099d7 |
XmeTraitGet((XtPointer) XtClass(wid), XmQTtransfer);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Now lookup the trait on this widget and call the
|
|
Packit |
b099d7 |
internal routine. */
|
|
Packit |
b099d7 |
if (ttrait != NULL) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
TB_internal = 1;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
if (ttrait -> destinationProc != 0)
|
|
Packit |
b099d7 |
ttrait -> destinationProc(wid, NULL, tc -> callback_struct);
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
TB_internal = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Send a delete if this is a move operation and we've complete
|
|
Packit |
b099d7 |
successfully for PRIMARY transfer */
|
|
Packit |
b099d7 |
if (tc -> selection == XA_PRIMARY &&
|
|
Packit |
b099d7 |
tc -> outstanding == 0 &&
|
|
Packit |
b099d7 |
tc -> count != 0 &&
|
|
Packit |
b099d7 |
(tc -> status == XmTRANSFER_DONE_SUCCEED ||
|
|
Packit |
b099d7 |
tc -> status == XmTRANSFER_DONE_DEFAULT) &&
|
|
Packit |
b099d7 |
tc -> op == XmMOVE &&
|
|
Packit |
b099d7 |
! (tc -> flags & TC_DID_DELETE)) {
|
|
Packit |
b099d7 |
tc -> flags |= TC_DID_DELETE;
|
|
Packit |
b099d7 |
XmTransferValue((XtPointer) tc, atoms[XmADELETE], NULL, NULL,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(wid)));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* When outstanding reaches 0, free context block. But don't
|
|
Packit |
b099d7 |
do this in the local case. There we can free in the caller,
|
|
Packit |
b099d7 |
so check the TC_EXITED_DH flag to see if we've exited
|
|
Packit |
b099d7 |
_XmDestinationHandler yet. */
|
|
Packit |
b099d7 |
if (tc -> outstanding == 0 &&
|
|
Packit |
b099d7 |
tc -> flags & TC_EXITED_DH ) {
|
|
Packit |
b099d7 |
FinishTransfer(wid, tc);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/**********************************************************/
|
|
Packit |
b099d7 |
/* Context block handlers for convert and transfer blocks */
|
|
Packit |
b099d7 |
/**********************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
typedef struct __XmCCKey {
|
|
Packit |
b099d7 |
Display *display;
|
|
Packit |
b099d7 |
Atom selection;
|
|
Packit |
b099d7 |
} _XmCCKeyRec, *_XmCCKey;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static Boolean
|
|
Packit |
b099d7 |
CCMatch(XtPointer x, XtPointer y)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmCCKey a, b;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
a = (_XmCCKey) x;
|
|
Packit |
b099d7 |
b = (_XmCCKey) y;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return(a -> display == b -> display &&
|
|
Packit |
b099d7 |
a -> selection == b -> selection);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmHashValue
|
|
Packit |
b099d7 |
CCHash(XtPointer x)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmCCKey a;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
a = (_XmCCKey) x;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return((XmHashValue) ((long) a -> display + (long) a -> selection));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmHashTable ConvertHashTable = (XmHashTable) NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static ConvertContext
|
|
Packit |
b099d7 |
LookupContextBlock(Display *d, Atom a)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
_XmCCKeyRec x;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
x.display = d;
|
|
Packit |
b099d7 |
x.selection = a;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (ConvertHashTable == (XmHashTable) NULL)
|
|
Packit |
b099d7 |
ConvertHashTable = _XmAllocHashTable(10, CCMatch, CCHash);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = (ConvertContext) _XmGetHashEntry(ConvertHashTable, (XmHashKey) &x);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cc == NULL) {
|
|
Packit |
b099d7 |
_XmCCKey new_k;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
new_k = (_XmCCKey) XtMalloc(sizeof(_XmCCKeyRec));
|
|
Packit |
b099d7 |
new_k -> display = d;
|
|
Packit |
b099d7 |
new_k -> selection = a;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Allocate a context block for this selection */
|
|
Packit |
b099d7 |
cc = (ConvertContext) XtMalloc(sizeof(ConvertContextRec));
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmAddHashEntry(ConvertHashTable, (XmHashKey)new_k, (XtPointer)cc);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return(cc);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
ClearContextBlock(Display *d, Atom a)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
ConvertContext cc;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc = LookupContextBlock(d, a);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cc -> flags = 0;
|
|
Packit |
b099d7 |
cc -> op = 0;
|
|
Packit |
b099d7 |
cc -> itemid = 0;
|
|
Packit |
b099d7 |
cc -> location_data = NULL;
|
|
Packit |
b099d7 |
cc -> client_data = NULL;
|
|
Packit |
b099d7 |
cc -> drag_context = (Widget) NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Functions to get and free transfer ids */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static TransferContext global_tc = NULL;
|
|
Packit |
b099d7 |
static TransferContext free_tc = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XtPointer
|
|
Packit |
b099d7 |
GetTransferID(void)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext rval;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If there is one on the free list, unchain it
|
|
Packit |
b099d7 |
and return it */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (free_tc != NULL)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
rval = free_tc;
|
|
Packit |
b099d7 |
free_tc = (TransferContext) rval -> next;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
rval = (TransferContext) XtMalloc(sizeof(TransferContextRec));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Put it on the chain */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
rval -> next = (XtPointer) global_tc;
|
|
Packit |
b099d7 |
rval -> prev = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (global_tc != NULL) global_tc -> prev = (XtPointer) rval;
|
|
Packit |
b099d7 |
global_tc = rval;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Initialize */
|
|
Packit |
b099d7 |
rval -> outstanding = 0;
|
|
Packit |
b099d7 |
rval -> count = 0;
|
|
Packit |
b099d7 |
rval -> flags = TC_NONE;
|
|
Packit |
b099d7 |
rval -> requests = NULL;
|
|
Packit |
b099d7 |
rval -> last = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return((XtPointer) rval);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
FreeTransferID(XtPointer id)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tid = (TransferContext) id;
|
|
Packit |
b099d7 |
TransferContext pid, nid;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Free done_proc list */
|
|
Packit |
b099d7 |
if (tid -> doneProcs != NULL) XtFree((char*) tid -> doneProcs);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* first unchain from global_tc */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (global_tc == tid)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
global_tc = (TransferContext) tid -> next;
|
|
Packit |
b099d7 |
if (global_tc != NULL)
|
|
Packit |
b099d7 |
global_tc -> prev = NULL;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* Get previous and next */
|
|
Packit |
b099d7 |
pid = (TransferContext) tid -> prev;
|
|
Packit |
b099d7 |
nid = (TransferContext) tid -> next;
|
|
Packit |
b099d7 |
/* Connect prev and next */
|
|
Packit |
b099d7 |
if (pid != NULL) pid -> next = (XtPointer) nid;
|
|
Packit |
b099d7 |
if (nid != NULL) nid -> prev = (XtPointer) pid;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
/* Put on free list */
|
|
Packit |
b099d7 |
tid -> next = (XtPointer) free_tc;
|
|
Packit |
b099d7 |
free_tc = tid;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
CallDoneProcs(Widget wid, XtPointer id, XmTransferDoneCallbackStruct *ts)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
TransferContext tid = (TransferContext) id;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for(i = 0; i < tid -> numDoneProcs; i++) {
|
|
Packit |
b099d7 |
(tid -> doneProcs[i])(wid, tid -> op, ts);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static TransferBlock
|
|
Packit |
b099d7 |
AddTransferBlock(TransferContext tc)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferBlock tb;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tb = (TransferBlock) XtMalloc(sizeof(TransferBlockRec));
|
|
Packit |
b099d7 |
tb -> next = NULL;
|
|
Packit |
b099d7 |
/* we append blocks to the end of the list */
|
|
Packit |
b099d7 |
if (tc -> requests == NULL)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
tc -> requests = tb;
|
|
Packit |
b099d7 |
tc -> last = tb;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
(tc -> last) -> next = (XtPointer) tb;
|
|
Packit |
b099d7 |
tc -> last = tb;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (TB_internal)
|
|
Packit |
b099d7 |
tb -> flags = TB_INTERNAL;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
tb -> flags = TB_NONE;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return(tb);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Warning routine */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
TransferWarning(Widget w, char* name, char* type, char* message)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmeWarning(w, message);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
/* Standard target support */
|
|
Packit |
b099d7 |
/* */
|
|
Packit |
b099d7 |
/* This support makes it easy for all widgets to support a set */
|
|
Packit |
b099d7 |
/* of targets which can be automatically converted to. */
|
|
Packit |
b099d7 |
/* */
|
|
Packit |
b099d7 |
/****************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* XmeStandardTargets takes a widget, and a count of the widget's
|
|
Packit |
b099d7 |
* private target list, and returns a list of standard targets.
|
|
Packit |
b099d7 |
* The count of standard targets is returned in the passed in
|
|
Packit |
b099d7 |
* integer
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define MAXBUILTIN 12
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Atom*
|
|
Packit |
b099d7 |
XmeStandardTargets(Widget w, int count, int *tcount)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmATARGETS, XmATIMESTAMP, XmAFOREGROUND, XmABACKGROUND,
|
|
Packit |
b099d7 |
XmACLASS, XmANAME, XmACLIENT_WINDOW, XmA_MOTIF_RENDER_TABLE,
|
|
Packit |
b099d7 |
XmA_MOTIF_ENCODING_REGISTRY, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = {
|
|
Packit |
b099d7 |
XmSTARGETS, XmSTIMESTAMP, XmIFOREGROUND, XmIBACKGROUND,
|
|
Packit |
b099d7 |
XmICLASS, XmINAME, XmSCLIENT_WINDOW, XmS_MOTIF_RENDER_TABLE,
|
|
Packit |
b099d7 |
XmS_MOTIF_ENCODING_REGISTRY };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
int i = 0;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom *targets;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
targets = (Atom *) XtMalloc(sizeof(Atom) * MAXBUILTIN);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
targets[i] = atoms[XmATARGETS]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmATIMESTAMP]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmAFOREGROUND]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmABACKGROUND]; i++;
|
|
Packit |
b099d7 |
targets[i] = XA_COLORMAP; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmACLASS]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmANAME]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmACLIENT_WINDOW]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmA_MOTIF_RENDER_TABLE]; i++;
|
|
Packit |
b099d7 |
targets[i] = atoms[XmA_MOTIF_ENCODING_REGISTRY]; i++;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Realloc the full size now */
|
|
Packit |
b099d7 |
targets = (Atom *) XtRealloc((char*) targets, sizeof(Atom) * (count + i));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*tcount = i; /* Return the builtin target count */
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(targets);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* XmeStandardConvert is called when receiving an unknown
|
|
Packit |
b099d7 |
* target. It should be called last in most convert procs.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmeStandardConvert(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore, /* unused */
|
|
Packit |
b099d7 |
XmConvertCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmATARGETS, XmAFOREGROUND, XmAPIXEL, XmABACKGROUND,
|
|
Packit |
b099d7 |
XmACLASS, XmANAME, XmACLIENT_WINDOW, XmA_MOTIF_RENDER_TABLE,
|
|
Packit |
b099d7 |
XmA_MOTIF_ENCODING_REGISTRY, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = {
|
|
Packit |
b099d7 |
XmSTARGETS, XmIFOREGROUND, XmIPIXEL, XmIBACKGROUND,
|
|
Packit |
b099d7 |
XmICLASS, XmINAME, XmSCLIENT_WINDOW, XmS_MOTIF_RENDER_TABLE,
|
|
Packit |
b099d7 |
XmS_MOTIF_ENCODING_REGISTRY };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Arg arg[1];
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (atoms[XmATARGETS] == cs -> target) {
|
|
Packit |
b099d7 |
int tcount;
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) XmeStandardTargets(w, 0, &tcount);
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = tcount;
|
|
Packit |
b099d7 |
cs -> type = XA_ATOM;
|
|
Packit |
b099d7 |
} else if (atoms[XmAFOREGROUND] == cs -> target) {
|
|
Packit |
b099d7 |
Pixel *fg;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (XmIsGadget(w)) w = XtParent(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
fg = (Pixel *) XtMalloc(sizeof(Pixel));
|
|
Packit |
b099d7 |
XtSetArg(arg[0], XtNforeground, fg);
|
|
Packit |
b099d7 |
XtGetValues(w, arg, 1);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) fg;
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = 1;
|
|
Packit |
b099d7 |
cs -> type = atoms[XmAPIXEL];
|
|
Packit |
b099d7 |
} else if (atoms[XmABACKGROUND] == cs -> target) {
|
|
Packit |
b099d7 |
Pixel *bg;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (XmIsGadget(w)) w = XtParent(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
bg = (Pixel *) XtMalloc(sizeof(Pixel));
|
|
Packit |
b099d7 |
XtSetArg(arg[0], XtNbackground, bg);
|
|
Packit |
b099d7 |
XtGetValues(w, arg, 1);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) bg;
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = 1;
|
|
Packit |
b099d7 |
cs -> type = atoms[XmAPIXEL];
|
|
Packit |
b099d7 |
} else if (XA_COLORMAP == cs -> target) {
|
|
Packit |
b099d7 |
Colormap *cmap;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (XmIsGadget(w)) w = XtParent(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cmap = (Colormap *) XtMalloc(sizeof(Colormap));
|
|
Packit |
b099d7 |
XtSetArg(arg[0], XtNcolormap, cmap);
|
|
Packit |
b099d7 |
XtGetValues(w, arg, 1);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) cmap;
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = 1;
|
|
Packit |
b099d7 |
cs -> type = XA_COLORMAP;
|
|
Packit |
b099d7 |
} else if (atoms[XmACLASS] == cs -> target) {
|
|
Packit |
b099d7 |
Widget current;
|
|
Packit |
b099d7 |
unsigned long bytesAfter;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = NULL;
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = 0;
|
|
Packit |
b099d7 |
cs -> type = XA_INTEGER;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for(current = w;
|
|
Packit |
b099d7 |
current != (Widget) NULL;
|
|
Packit |
b099d7 |
current = XtParent(current)) {
|
|
Packit |
b099d7 |
if (XtIsShell(current)) {
|
|
Packit |
b099d7 |
XGetWindowProperty(XtDisplay(current), XtWindow(current),
|
|
Packit |
b099d7 |
XA_WM_CLASS, 0L, 100000L, False,
|
|
Packit |
b099d7 |
(Atom) AnyPropertyType,
|
|
Packit |
b099d7 |
&cs -> type,
|
|
Packit |
b099d7 |
&cs -> format,
|
|
Packit |
b099d7 |
&cs -> length,
|
|
Packit |
b099d7 |
&bytesAfter,
|
|
Packit |
b099d7 |
(unsigned char**) &cs -> value);
|
|
Packit |
b099d7 |
if (cs -> value != NULL) break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else if (atoms[XmANAME] == cs -> target) {
|
|
Packit |
b099d7 |
Widget current;
|
|
Packit |
b099d7 |
unsigned long bytesAfter;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
int format;
|
|
Packit |
b099d7 |
unsigned char *value = NULL;
|
|
Packit |
b099d7 |
char *total_value;
|
|
Packit |
b099d7 |
unsigned long length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for(current = w;
|
|
Packit |
b099d7 |
current != (Widget) NULL;
|
|
Packit |
b099d7 |
current = XtParent(current)) {
|
|
Packit |
b099d7 |
if (XtIsShell(current)) {
|
|
Packit |
b099d7 |
XGetWindowProperty(XtDisplay(current), XtWindow(current),
|
|
Packit |
b099d7 |
XA_WM_NAME, 0L, 100000L, False,
|
|
Packit |
b099d7 |
(Atom) AnyPropertyType,
|
|
Packit |
b099d7 |
&type,
|
|
Packit |
b099d7 |
&format,
|
|
Packit |
b099d7 |
&length,
|
|
Packit |
b099d7 |
&bytesAfter,
|
|
Packit |
b099d7 |
&value);
|
|
Packit |
b099d7 |
if (value != NULL) break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
total_value = _XmTextToLocaleText(w, (XtPointer)value, type,
|
|
Packit |
b099d7 |
format, length, NULL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) total_value;
|
|
Packit |
b099d7 |
cs -> format = 8;
|
|
Packit |
b099d7 |
cs -> length = total_value != NULL ? strlen(total_value) : 0;
|
|
Packit |
b099d7 |
cs -> type = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
} else if (atoms[XmACLIENT_WINDOW] == cs -> target) {
|
|
Packit |
b099d7 |
Widget current;
|
|
Packit |
b099d7 |
Window *cw;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cw = (Window *) XtMalloc(sizeof(Window));
|
|
Packit |
b099d7 |
for(current = w; current != (Widget) NULL; current = XtParent(current))
|
|
Packit |
b099d7 |
if (XtIsShell(current)) break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*cw = XtWindow(current);
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) cw;
|
|
Packit |
b099d7 |
cs -> format = 32;
|
|
Packit |
b099d7 |
cs -> length = 1;
|
|
Packit |
b099d7 |
cs -> type = XA_WINDOW;
|
|
Packit |
b099d7 |
} else if (atoms[XmA_MOTIF_RENDER_TABLE] == cs -> target) {
|
|
Packit |
b099d7 |
XmRenderTable table;
|
|
Packit |
b099d7 |
Arg args[1];
|
|
Packit |
b099d7 |
char *value;
|
|
Packit |
b099d7 |
int size;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
table = (XmRenderTable) NULL;
|
|
Packit |
b099d7 |
XtSetArg(args[0], XmNrenderTable, &table);
|
|
Packit |
b099d7 |
XtGetValues(w, args, 1);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (table == NULL) {
|
|
Packit |
b099d7 |
/* If we didn't find a render table on this widget, then
|
|
Packit |
b099d7 |
go ahead and look up the chain for something which
|
|
Packit |
b099d7 |
does have one */
|
|
Packit |
b099d7 |
table = XmeGetDefaultRenderTable(w, XmTEXT_RENDER_TABLE);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (table != NULL) {
|
|
Packit |
b099d7 |
size = XmRenderTableCvtToProp(w, table, &value);
|
|
Packit |
b099d7 |
cs -> value = (XtPointer) value;
|
|
Packit |
b099d7 |
cs -> format = 8;
|
|
Packit |
b099d7 |
cs -> length = size;
|
|
Packit |
b099d7 |
cs -> type = XA_STRING;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else if (atoms[XmA_MOTIF_ENCODING_REGISTRY] == cs -> target) {
|
|
Packit |
b099d7 |
int len;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cs -> format = 8;
|
|
Packit |
b099d7 |
cs -> type = XA_STRING;
|
|
Packit |
b099d7 |
cs -> value = _XmGetEncodingRegistryTarget(&len;;
|
|
Packit |
b099d7 |
cs -> length = len;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Atom
|
|
Packit |
b099d7 |
XmeGetEncodingAtom(Widget w)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
int ret_status = 0;
|
|
Packit |
b099d7 |
XTextProperty tmp_prop;
|
|
Packit |
b099d7 |
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
|
|
Packit |
b099d7 |
Atom encoding;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
tmp_prop.value = NULL; /* just in case X doesn't do it */
|
|
Packit |
b099d7 |
ret_status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XTextStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
if (ret_status == Success)
|
|
Packit |
b099d7 |
encoding = tmp_prop.encoding;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
encoding = None; /* XmbTextList... should always be able
|
|
Packit |
b099d7 |
* to convert XPCS characters; but in
|
|
Packit |
b099d7 |
* case its broken, this prevents a core
|
|
Packit |
b099d7 |
* dump.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return(encoding);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
char *
|
|
Packit |
b099d7 |
_XmTextToLocaleText(Widget w,
|
|
Packit |
b099d7 |
XtPointer value,
|
|
Packit |
b099d7 |
Atom type,
|
|
Packit |
b099d7 |
int format,
|
|
Packit |
b099d7 |
unsigned long length,
|
|
Packit |
b099d7 |
Boolean *success)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
XTextProperty text_prop;
|
|
Packit |
b099d7 |
int status;
|
|
Packit |
b099d7 |
char ** values;
|
|
Packit |
b099d7 |
int num_values = 0;
|
|
Packit |
b099d7 |
char *total_value = NULL;
|
|
Packit |
b099d7 |
int malloc_size = 0;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (type == XA_STRING || type == COMPOUND_TEXT
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
|| type == UTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
) {
|
|
Packit |
b099d7 |
text_prop.value = (unsigned char *) value;
|
|
Packit |
b099d7 |
text_prop.encoding = type;
|
|
Packit |
b099d7 |
text_prop.format = format;
|
|
Packit |
b099d7 |
text_prop.nitems = length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
status = XmbTextPropertyToTextList(XtDisplay(w), &text_prop, &values,
|
|
Packit |
b099d7 |
&num_values);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (success != NULL) {
|
|
Packit |
b099d7 |
if (status == Success || status > 0)
|
|
Packit |
b099d7 |
*success = True;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
*success = False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (num_values) {
|
|
Packit |
b099d7 |
for (i = 0; i < num_values ; i++)
|
|
Packit |
b099d7 |
malloc_size += strlen(values[i]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
total_value = XtMalloc ((unsigned) malloc_size + 1);
|
|
Packit |
b099d7 |
total_value[0] = '\0';
|
|
Packit |
b099d7 |
for (i = 0; i < num_values ; i++)
|
|
Packit |
b099d7 |
strcat(total_value, values[i]);
|
|
Packit |
b099d7 |
XFreeStringList(values);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return total_value;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmConvertComplete(Widget wid, XtPointer value,
|
|
Packit |
b099d7 |
unsigned long size, int format, Atom type,
|
|
Packit |
b099d7 |
XmConvertCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (value == NULL && cs -> value == NULL) {
|
|
Packit |
b099d7 |
XmeStandardConvert(wid, NULL, cs);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (cs -> status == XmCONVERT_MERGE) {
|
|
Packit |
b099d7 |
XmeConvertMerge(value, type, format, size, cs);
|
|
Packit |
b099d7 |
XtFree((char*) value);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* Not merging */
|
|
Packit |
b099d7 |
if (cs -> value != NULL) XtFree((char*) cs -> value);
|
|
Packit |
b099d7 |
cs -> type = type;
|
|
Packit |
b099d7 |
cs -> value = value;
|
|
Packit |
b099d7 |
cs -> length = size;
|
|
Packit |
b099d7 |
cs -> format = format;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs -> value != NULL)
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_DONE;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
cs -> status = XmCONVERT_REFUSE;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct*
|
|
Packit |
b099d7 |
_XmTransferGetDestinationCBStruct(XtPointer tid)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
TransferContext tc = (TransferContext) tid;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return(tc -> callback_struct);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Error handler for XGetAtomName */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static int SIF_ErrorFlag;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static int
|
|
Packit |
b099d7 |
SIF_ErrorHandler(
|
|
Packit |
b099d7 |
Display *display, /* unused */
|
|
Packit |
b099d7 |
XErrorEvent *event)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
SIF_ErrorFlag = event -> type;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE! XGetAtomName return value MUST be freed with XFree; however, there
|
|
Packit |
b099d7 |
** isn't a good way to allocate data which can be freed with XFree. We could
|
|
Packit |
b099d7 |
** cache a static character pointer to NULL and check it to decide whether or
|
|
Packit |
b099d7 |
** not to free; for now, just pass information back on what to do with the
|
|
Packit |
b099d7 |
** returned value.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
static char*
|
|
Packit |
b099d7 |
GetSafeAtomName(Display *display, Atom a, FreeType *howFree)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XErrorHandler old_Handler;
|
|
Packit |
b099d7 |
char *returnvalue;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Setup error proc and reset error flag */
|
|
Packit |
b099d7 |
old_Handler = XSetErrorHandler((XErrorHandler) SIF_ErrorHandler);
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
SIF_ErrorFlag = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
returnvalue = XGetAtomName(display, a);
|
|
Packit |
b099d7 |
*howFree = DoXFree;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XSetErrorHandler(old_Handler);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (SIF_ErrorFlag != 0) {
|
|
Packit |
b099d7 |
returnvalue = (char*) malloc(1);
|
|
Packit |
b099d7 |
returnvalue[0] = 0; /* Create empty string to return */
|
|
Packit |
b099d7 |
*howFree = DoFree;
|
|
Packit |
b099d7 |
TransferWarning(NULL, ATOM, ARG, BAD_ATOM_MESSAGE);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return(returnvalue);
|
|
Packit |
b099d7 |
}
|