|
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 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef REV_INFO
|
|
Packit |
b099d7 |
#ifndef lint
|
|
Packit |
b099d7 |
static char rcsid[] = "$TOG: TextSel.c /main/24 1998/12/07 11:12:08 mgreess $"
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
Packit |
b099d7 |
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <X11/Xatom.h>
|
|
Packit |
b099d7 |
#include <Xm/AtomMgr.h>
|
|
Packit |
b099d7 |
#include <Xm/DragC.h>
|
|
Packit |
b099d7 |
#include <Xm/DropTrans.h>
|
|
Packit |
b099d7 |
#include <Xm/TraitP.h> /* for XmeTraitSet() */
|
|
Packit |
b099d7 |
#include <Xm/TransferT.h>
|
|
Packit |
b099d7 |
#include <Xm/XmosP.h>
|
|
Packit |
b099d7 |
#include "TextI.h"
|
|
Packit |
b099d7 |
#include "TextInI.h"
|
|
Packit |
b099d7 |
#include "TextSelI.h"
|
|
Packit |
b099d7 |
#include "TextStrSoI.h"
|
|
Packit |
b099d7 |
#include "TransferI.h" /* for _XmConvertComplete() */
|
|
Packit |
b099d7 |
#include "TraversalI.h"
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/******** Static Function Declarations ********/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void InsertSelection(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
Atom *seltype,
|
|
Packit |
b099d7 |
Atom *type,
|
|
Packit |
b099d7 |
XtPointer value,
|
|
Packit |
b099d7 |
unsigned long *length,
|
|
Packit |
b099d7 |
int *format,
|
|
Packit |
b099d7 |
XtPointer tid) ;
|
|
Packit |
b099d7 |
static void HandleInsertTargets(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
Atom *seltype,
|
|
Packit |
b099d7 |
Atom *type,
|
|
Packit |
b099d7 |
XtPointer value,
|
|
Packit |
b099d7 |
unsigned long *length,
|
|
Packit |
b099d7 |
int *format,
|
|
Packit |
b099d7 |
XtPointer tid) ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void HandleDrop(Widget w,
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *cb,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void HandleTargets(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void DoStuff(Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void DropDestroyCB(Widget w,
|
|
Packit |
b099d7 |
XtPointer clientData,
|
|
Packit |
b099d7 |
XtPointer callData);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void DropTransferProc(Widget w, XtPointer ignore,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void SetDropContext(Widget w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void DeleteDropContext(Widget w);
|
|
Packit |
b099d7 |
static void TextSecondaryWrapper(Widget, XtPointer,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *);
|
|
Packit |
b099d7 |
static void TextConvertCallback(Widget, XtPointer,
|
|
Packit |
b099d7 |
XmConvertCallbackStruct*);
|
|
Packit |
b099d7 |
static void TextDestinationCallback(Widget, XtPointer,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct*);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/******** End Static Function Declarations ********/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Transfer Trait record for Text */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmConst XmTransferTraitRec TextTransfer = {
|
|
Packit |
b099d7 |
0, /* version */
|
|
Packit |
b099d7 |
(XmConvertCallbackProc) TextConvertCallback,
|
|
Packit |
b099d7 |
(XmDestinationCallbackProc) TextDestinationCallback,
|
|
Packit |
b099d7 |
(XmDestinationCallbackProc) NULL,
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XContext _XmTextDNDContext = 0;
|
|
Packit |
b099d7 |
static _XmTextPrimSelect *prim_select;
|
|
Packit |
b099d7 |
static _XmInsertSelect insert_select;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SetPrimarySelection(Widget w,
|
|
Packit |
b099d7 |
XtEnum op, /* unused */
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts) /* unused */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
InputData data = tw->text.input->data;
|
|
Packit |
b099d7 |
XmTextPosition cursorPos = tw->text.cursor_position;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (!prim_select) {
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (prim_select->num_chars > 0) {
|
|
Packit |
b099d7 |
data->anchor = prim_select->position;
|
|
Packit |
b099d7 |
cursorPos = prim_select->position + prim_select->num_chars;
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition(w, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection(w, tw->text.cursor_position,
|
|
Packit |
b099d7 |
False, prim_select->time);
|
|
Packit |
b099d7 |
(*tw->text.source->SetSelection)(tw->text.source, data->anchor,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (--prim_select->ref_count == 0) {
|
|
Packit |
b099d7 |
XtFree((char *)prim_select);
|
|
Packit |
b099d7 |
prim_select = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
CleanPrimarySelection(Widget w,
|
|
Packit |
b099d7 |
XtEnum op, /* unused */
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts) /* unused */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (!prim_select) {
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (--prim_select->ref_count == 0) {
|
|
Packit |
b099d7 |
XtFree((char *)prim_select);
|
|
Packit |
b099d7 |
prim_select = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
TextSecondaryWrapper(Widget w, XtPointer closure,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Atom XA_TARGETS = XInternAtom(XtDisplay(w), XmSTARGETS, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds -> target == XA_TARGETS)
|
|
Packit |
b099d7 |
HandleInsertTargets(w, closure, &(ds -> selection), &(ds -> type),
|
|
Packit |
b099d7 |
ds -> value, &(ds -> length), &(ds -> format),
|
|
Packit |
b099d7 |
ds -> transfer_id);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
InsertSelection(w, closure, &(ds -> selection), &(ds -> type),
|
|
Packit |
b099d7 |
ds -> value, &(ds -> length), &(ds -> format),
|
|
Packit |
b099d7 |
ds -> transfer_id);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
InsertSelection(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
Atom *seltype,
|
|
Packit |
b099d7 |
Atom *type,
|
|
Packit |
b099d7 |
XtPointer value,
|
|
Packit |
b099d7 |
unsigned long *length,
|
|
Packit |
b099d7 |
int *format,
|
|
Packit |
b099d7 |
XtPointer tid)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
_XmInsertSelect *insert_select = (_XmInsertSelect *)closure;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
XmTextPosition left = 0;
|
|
Packit |
b099d7 |
XmTextPosition right = 0;
|
|
Packit |
b099d7 |
Boolean dest_disjoint = False;
|
|
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 |
char * total_value = NULL;
|
|
Packit |
b099d7 |
XmTextBlockRec block, newblock;
|
|
Packit |
b099d7 |
XmTextPosition cursorPos;
|
|
Packit |
b099d7 |
Boolean freeBlock;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!value) {
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Don't do replace if there is no text to add */
|
|
Packit |
b099d7 |
if (*(char *)value == '\0' || *length == 0){
|
|
Packit |
b099d7 |
XtFree((char*)value);
|
|
Packit |
b099d7 |
value = NULL;
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (insert_select->select_type == XmPRIM_SELECT) {
|
|
Packit |
b099d7 |
if (!(*tw->text.source->GetSelection)(tw->text.source, &left, &right) ||
|
|
Packit |
b099d7 |
left == right) {
|
|
Packit |
b099d7 |
XBell(XtDisplay(w), 0);
|
|
Packit |
b099d7 |
XtFree((char*)value);
|
|
Packit |
b099d7 |
value = NULL;
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
insert_select->success_status = False;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else if (insert_select->select_type == XmDEST_SELECT) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
|
|
Packit |
b099d7 |
left != right) {
|
|
Packit |
b099d7 |
if (tw->text.cursor_position < left ||
|
|
Packit |
b099d7 |
tw->text.cursor_position > right ||
|
|
Packit |
b099d7 |
!tw->text.input->data->pendingdelete) {
|
|
Packit |
b099d7 |
left = right = tw->text.cursor_position;
|
|
Packit |
b099d7 |
dest_disjoint = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
left = right = tw->text.cursor_position;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*type == COMPOUND_TEXT || *type == XA_STRING
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
|| *type == UTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
) {
|
|
Packit |
b099d7 |
if ((total_value =
|
|
Packit |
b099d7 |
_XmTextToLocaleText(w, value, *type, *format,
|
|
Packit |
b099d7 |
*length, NULL)) != NULL) {
|
|
Packit |
b099d7 |
block.ptr = total_value;
|
|
Packit |
b099d7 |
block.length = strlen(block.ptr);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
insert_select->success_status = False;
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else { /* it must be either CS_OF_ENCODING or TEXT */
|
|
Packit |
b099d7 |
block.ptr = (char*)value;
|
|
Packit |
b099d7 |
/* NOTE: casting *length could result in a truncated long. */
|
|
Packit |
b099d7 |
block.length = (unsigned) *length;
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmTextModifyVerify(tw, (XEvent *)insert_select->event, &left, &right,
|
|
Packit |
b099d7 |
&cursorPos, &block, &newblock, &freeBlock)) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->Replace)(tw, (XEvent *)insert_select->event,
|
|
Packit |
b099d7 |
&left, &right,
|
|
Packit |
b099d7 |
&newblock, False) != EditDone) {
|
|
Packit |
b099d7 |
if (tw->text.verify_bell) XBell(XtDisplay(w), 0);
|
|
Packit |
b099d7 |
insert_select->success_status = False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
insert_select->success_status = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!tw->text.add_mode) tw->text.input->data->anchor = left;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tw->text.add_mode && cursorPos >= left && cursorPos <= right)
|
|
Packit |
b099d7 |
tw->text.pendingoff = FALSE;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
tw->text.pendingoff = TRUE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition(w, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection(w, tw->text.cursor_position, False,
|
|
Packit |
b099d7 |
insert_select->event->time);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (insert_select->select_type == XmDEST_SELECT) {
|
|
Packit |
b099d7 |
if (left != right) {
|
|
Packit |
b099d7 |
if (!dest_disjoint || !tw->text.add_mode) {
|
|
Packit |
b099d7 |
(*tw->text.source->SetSelection)(tw->text.source,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
insert_select->event->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmTextValueChanged(tw, (XEvent *)insert_select->event);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
|
|
Packit |
b099d7 |
if (total_value) XtFree(total_value);
|
|
Packit |
b099d7 |
XtFree((char*)value);
|
|
Packit |
b099d7 |
value = NULL;
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
HandleInsertTargets(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
Atom *seltype,
|
|
Packit |
b099d7 |
Atom *type,
|
|
Packit |
b099d7 |
XtPointer value,
|
|
Packit |
b099d7 |
unsigned long *length,
|
|
Packit |
b099d7 |
int *format,
|
|
Packit |
b099d7 |
XtPointer tid )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmATEXT, XmACOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmInsertSelect *insert_select = (_XmInsertSelect *) closure;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
Atom target;
|
|
Packit |
b099d7 |
Atom *atom_ptr;
|
|
Packit |
b099d7 |
Boolean supports_encoding_data = False;
|
|
Packit |
b099d7 |
Boolean supports_CT = False;
|
|
Packit |
b099d7 |
Boolean supports_text = False;
|
|
Packit |
b099d7 |
Boolean supports_utf8_string = False;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (0 == *length) {
|
|
Packit |
b099d7 |
XtFree((char *)value);
|
|
Packit |
b099d7 |
insert_select->done_status = True;
|
|
Packit |
b099d7 |
return; /* Supports no targets, so don't bother sending anything */
|
|
Packit |
b099d7 |
}
|
|
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 |
atom_ptr = (Atom *)value;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (i = 0; i < *length; i++, atom_ptr++) {
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmATEXT])
|
|
Packit |
b099d7 |
supports_text = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*atom_ptr == CS_OF_ENCODING)
|
|
Packit |
b099d7 |
supports_encoding_data = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmACOMPOUND_TEXT])
|
|
Packit |
b099d7 |
supports_CT = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmAUTF8_STRING])
|
|
Packit |
b099d7 |
supports_utf8_string = True;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (supports_text && supports_encoding_data)
|
|
Packit |
b099d7 |
target = atoms[XmATEXT];
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
else if (supports_utf8_string)
|
|
Packit |
b099d7 |
target = atoms[XmAUTF8_STRING];
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
else if (supports_CT)
|
|
Packit |
b099d7 |
target = atoms[XmACOMPOUND_TEXT];
|
|
Packit |
b099d7 |
else if (supports_encoding_data)
|
|
Packit |
b099d7 |
target = CS_OF_ENCODING;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
target = XA_STRING;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTransferValue(tid, target,
|
|
Packit |
b099d7 |
(XtCallbackProc) TextSecondaryWrapper,
|
|
Packit |
b099d7 |
closure, insert_select -> event -> time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmTextConvert(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
Atom *selection,
|
|
Packit |
b099d7 |
Atom *target,
|
|
Packit |
b099d7 |
Atom *type,
|
|
Packit |
b099d7 |
XtPointer *value,
|
|
Packit |
b099d7 |
unsigned long *length,
|
|
Packit |
b099d7 |
int *format,
|
|
Packit |
b099d7 |
Widget drag_context,
|
|
Packit |
b099d7 |
XEvent *event )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmA_MOTIF_DESTINATION, XmAINSERT_SELECTION, XmADELETE,
|
|
Packit |
b099d7 |
XmATARGETS, XmATEXT, XmACOMPOUND_TEXT, XmATIMESTAMP,
|
|
Packit |
b099d7 |
XmA_MOTIF_DROP, XmACLIPBOARD, XmANULL,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = {
|
|
Packit |
b099d7 |
XmS_MOTIF_DESTINATION, XmSINSERT_SELECTION, XmSDELETE,
|
|
Packit |
b099d7 |
XmSTARGETS, XmSTEXT, XmSCOMPOUND_TEXT, XmSTIMESTAMP,
|
|
Packit |
b099d7 |
XmS_MOTIF_DROP, XmSCLIPBOARD, XmSNULL,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
XmTextSource source;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING;
|
|
Packit |
b099d7 |
XSelectionRequestEvent * req_event = (XSelectionRequestEvent *) event;
|
|
Packit |
b099d7 |
Boolean has_selection = False;
|
|
Packit |
b099d7 |
XmTextPosition left = 0;
|
|
Packit |
b099d7 |
XmTextPosition right = 0;
|
|
Packit |
b099d7 |
Boolean is_primary;
|
|
Packit |
b099d7 |
Boolean is_secondary;
|
|
Packit |
b099d7 |
Boolean is_destination;
|
|
Packit |
b099d7 |
Boolean is_drop;
|
|
Packit |
b099d7 |
int target_count = 0;
|
|
Packit |
b099d7 |
XTextProperty tmp_prop;
|
|
Packit |
b099d7 |
int status = 0;
|
|
Packit |
b099d7 |
char * tmp_value;
|
|
Packit |
b099d7 |
Time _time;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (w == NULL) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (req_event == NULL)
|
|
Packit |
b099d7 |
_time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
_time = req_event -> time;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
source = tw->text.source;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*selection == XA_PRIMARY || *selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
|
|
Packit |
b099d7 |
is_primary = True;
|
|
Packit |
b099d7 |
is_secondary = is_destination = is_drop = False;
|
|
Packit |
b099d7 |
} else if (*selection == atoms[XmA_MOTIF_DESTINATION]) {
|
|
Packit |
b099d7 |
has_selection = tw->text.input->data->has_destination;
|
|
Packit |
b099d7 |
is_destination = True;
|
|
Packit |
b099d7 |
is_secondary = is_primary = is_drop = False;
|
|
Packit |
b099d7 |
} else if (*selection == XA_SECONDARY) {
|
|
Packit |
b099d7 |
has_selection = _XmTextGetSel2(tw, &left, &right);
|
|
Packit |
b099d7 |
is_secondary = True;
|
|
Packit |
b099d7 |
is_destination = is_primary = is_drop = False;
|
|
Packit |
b099d7 |
} else if (*selection == atoms[XmA_MOTIF_DROP]) {
|
|
Packit |
b099d7 |
has_selection = (*tw->text.source->GetSelection)(source, &left, &right);
|
|
Packit |
b099d7 |
is_drop = True;
|
|
Packit |
b099d7 |
is_destination = is_primary = is_secondary = False;
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* TARGETS identifies what targets the text widget can
|
|
Packit |
b099d7 |
* provide data for.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (*target == atoms[XmATARGETS]) {
|
|
Packit |
b099d7 |
Atom *targs = XmeStandardTargets(w, 10, &target_count);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*value = (XtPointer) targs;
|
|
Packit |
b099d7 |
if (XA_STRING != CS_OF_ENCODING) {
|
|
Packit |
b099d7 |
targs[target_count] = CS_OF_ENCODING; target_count++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (is_primary || is_destination) {
|
|
Packit |
b099d7 |
targs[target_count] = atoms[XmAINSERT_SELECTION]; target_count++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (is_primary || is_secondary || is_drop) {
|
|
Packit |
b099d7 |
targs[target_count] = atoms[XmACOMPOUND_TEXT]; target_count++;
|
|
Packit |
b099d7 |
targs[target_count] = atoms[XmATEXT]; target_count++;
|
|
Packit |
b099d7 |
targs[target_count] = XA_STRING; target_count++;
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
targs[target_count] = atoms[XmAUTF8_STRING]; target_count++;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (is_primary || is_drop) {
|
|
Packit |
b099d7 |
targs[target_count] = atoms[XmADELETE]; target_count++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
*type = XA_ATOM;
|
|
Packit |
b099d7 |
*length = target_count;
|
|
Packit |
b099d7 |
*format = 32;
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmATIMESTAMP]) {
|
|
Packit |
b099d7 |
Time *timestamp;
|
|
Packit |
b099d7 |
timestamp = (Time *) XtMalloc(sizeof(Time));
|
|
Packit |
b099d7 |
if (is_primary)
|
|
Packit |
b099d7 |
*timestamp = source->data->prim_time;
|
|
Packit |
b099d7 |
else if (is_destination)
|
|
Packit |
b099d7 |
*timestamp = tw->text.input->data->dest_time;
|
|
Packit |
b099d7 |
else if (is_secondary)
|
|
Packit |
b099d7 |
*timestamp = tw->text.input->data->sec_time;
|
|
Packit |
b099d7 |
else if (is_drop)
|
|
Packit |
b099d7 |
*timestamp = tw->text.input->data->sec_time;
|
|
Packit |
b099d7 |
*value = (XtPointer) timestamp;
|
|
Packit |
b099d7 |
*type = XA_INTEGER;
|
|
Packit |
b099d7 |
*length = sizeof(Time) / 4;
|
|
Packit |
b099d7 |
*format = 32;
|
|
Packit |
b099d7 |
} else if (*target == XA_STRING) {
|
|
Packit |
b099d7 |
/* Provide data for XA_STRING requests */
|
|
Packit |
b099d7 |
*type = (Atom) XA_STRING;
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
if (is_destination || !has_selection) return False;
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
tmp_value = _XmStringSourceGetString(tw, left, right, False);
|
|
Packit |
b099d7 |
status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XStringStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (status == Success || status > 0){
|
|
Packit |
b099d7 |
/* NOTE: casting tmp_prop.nitems could result in a truncated long. */
|
|
Packit |
b099d7 |
if (0 >= tmp_prop.nitems)
|
|
Packit |
b099d7 |
*value = (XtPointer) XtMalloc(1);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
*value = (XtPointer) XtMalloc((unsigned)tmp_prop.nitems);
|
|
Packit |
b099d7 |
memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
|
|
Packit |
b099d7 |
if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
|
|
Packit |
b099d7 |
*length = tmp_prop.nitems;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmATEXT] || *target == CS_OF_ENCODING) {
|
|
Packit |
b099d7 |
*type = CS_OF_ENCODING;
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
if (is_destination || !has_selection) return False;
|
|
Packit |
b099d7 |
*value = (XtPointer)_XmStringSourceGetString(tw, left, right, False);
|
|
Packit |
b099d7 |
*length = strlen((char*) *value);
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmACOMPOUND_TEXT]) {
|
|
Packit |
b099d7 |
*type = atoms[XmACOMPOUND_TEXT];
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
if (is_destination || !has_selection) return False;
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
tmp_value =_XmStringSourceGetString(tw, left, right, False);
|
|
Packit |
b099d7 |
status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XCompoundTextStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (status == Success || status > 0) {
|
|
Packit |
b099d7 |
/* NOTE: casting tmp_prop.nitems could result in a truncated long. */
|
|
Packit |
b099d7 |
*value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
|
|
Packit |
b099d7 |
memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
|
|
Packit |
b099d7 |
if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
|
|
Packit |
b099d7 |
*length = tmp_prop.nitems;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmAUTF8_STRING]) {
|
|
Packit |
b099d7 |
*type = atoms[XmAUTF8_STRING];
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
if (is_destination || !has_selection) return False;
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
tmp_value =_XmStringSourceGetString(tw, left, right, False);
|
|
Packit |
b099d7 |
status = XmbTextListToTextProperty(XtDisplay(tw), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XUTF8StringStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (status == Success || status > 0) {
|
|
Packit |
b099d7 |
/* NOTE: casting tmp_prop.nitems could result in a truncated long. */
|
|
Packit |
b099d7 |
*value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
|
|
Packit |
b099d7 |
memcpy((void*)*value, (void*)tmp_prop.value,(size_t)tmp_prop.nitems);
|
|
Packit |
b099d7 |
if (tmp_prop.value != NULL) XFree((char*)tmp_prop.value);
|
|
Packit |
b099d7 |
*length = tmp_prop.nitems;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmAINSERT_SELECTION]) {
|
|
Packit |
b099d7 |
if (is_secondary)
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
/* Delete the selection */
|
|
Packit |
b099d7 |
} else if (*target == atoms[XmADELETE]) {
|
|
Packit |
b099d7 |
XmTextBlockRec block, newblock;
|
|
Packit |
b099d7 |
XmTextPosition cursorPos;
|
|
Packit |
b099d7 |
Boolean freeBlock;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!(is_primary || is_drop)) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* The on_or_off flag is set to prevent unecessary
|
|
Packit |
b099d7 |
cursor shifting during the Replace operation */
|
|
Packit |
b099d7 |
tw->text.on_or_off = off;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block.ptr = "";
|
|
Packit |
b099d7 |
block.length = 0;
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmTextModifyVerify(tw, event, &left, &right,
|
|
Packit |
b099d7 |
&cursorPos, &block, &newblock, &freeBlock)) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->Replace)(tw, event, &left, &right,
|
|
Packit |
b099d7 |
&newblock, False) != EditDone) {
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (is_drop) {
|
|
Packit |
b099d7 |
if (_XmTextGetDropReciever((Widget)tw) != (Widget) tw)
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition((Widget)tw, cursorPos);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if ((*selection == atoms[XmACLIPBOARD]) ||
|
|
Packit |
b099d7 |
(req_event != NULL &&
|
|
Packit |
b099d7 |
req_event->requestor != XtWindow((Widget) tw)))
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition(w, cursorPos);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmTextValueChanged(tw, (XEvent *) req_event);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (!tw->text.input->data->has_destination)
|
|
Packit |
b099d7 |
tw->text.input->data->anchor = tw->text.cursor_position;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(*tw->text.source->SetSelection)(tw->text.source,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
_time);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*type = atoms[XmANULL];
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tw->text.on_or_off = on;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* unknown selection type */
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
return FALSE;
|
|
Packit |
b099d7 |
return TRUE;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmTextLoseSelection(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
Atom *selection )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
XmTextSource source = tw->text.source;
|
|
Packit |
b099d7 |
Atom MOTIF_DESTINATION = XInternAtom(XtDisplay(w),
|
|
Packit |
b099d7 |
XmS_MOTIF_DESTINATION, False);
|
|
Packit |
b099d7 |
/* Losing Primary Selection */
|
|
Packit |
b099d7 |
if (*selection == XA_PRIMARY && _XmStringSourceHasSelection(source)) {
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, 1, -999,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
cb.reason = XmCR_LOSE_PRIMARY;
|
|
Packit |
b099d7 |
cb.event = NULL;
|
|
Packit |
b099d7 |
XtCallCallbackList(w, tw->text.lose_primary_callback, (XtPointer) &cb;;
|
|
Packit |
b099d7 |
/* Losing Destination Selection */
|
|
Packit |
b099d7 |
} else if (*selection == MOTIF_DESTINATION) {
|
|
Packit |
b099d7 |
tw->text.input->data->has_destination = False;
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, off);
|
|
Packit |
b099d7 |
tw->text.output->data->blinkstate = on;
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position, on);
|
|
Packit |
b099d7 |
/* Losing Secondary Selection */
|
|
Packit |
b099d7 |
} else if (*selection == XA_SECONDARY && tw->text.input->data->hasSel2){
|
|
Packit |
b099d7 |
_XmTextSetSel2(tw, 1, -999, XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
HandleDrop(Widget w,
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *cb,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Widget drag_cont, initiator;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
Cardinal numExportTargets, n;
|
|
Packit |
b099d7 |
Atom *exportTargets;
|
|
Packit |
b099d7 |
Atom desiredTarget = None;
|
|
Packit |
b099d7 |
Arg args[10];
|
|
Packit |
b099d7 |
XmTextPosition insert_pos, left, right;
|
|
Packit |
b099d7 |
Boolean doTransfer = False;
|
|
Packit |
b099d7 |
XtPointer tid = ds->transfer_id;
|
|
Packit |
b099d7 |
_XmTextDropTransferRec *transfer_rec = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
drag_cont = cb->dragContext;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
n = 0;
|
|
Packit |
b099d7 |
XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
|
|
Packit |
b099d7 |
XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
|
|
Packit |
b099d7 |
XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
|
|
Packit |
b099d7 |
XtGetValues((Widget) drag_cont, args, n);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
insert_pos = (*tw->text.output->XYToPos)(tw, cb->x, cb->y);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cb->operation & XmDROP_MOVE && w == initiator &&
|
|
Packit |
b099d7 |
((*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
|
|
Packit |
b099d7 |
left != right && insert_pos >= left && insert_pos <= right)) {
|
|
Packit |
b099d7 |
XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
enum { XmATEXT, XmACOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
Boolean encoding_found = False;
|
|
Packit |
b099d7 |
Boolean c_text_found = False;
|
|
Packit |
b099d7 |
Boolean string_found = False;
|
|
Packit |
b099d7 |
Boolean text_found = False;
|
|
Packit |
b099d7 |
Boolean utf8_string_found = False;
|
|
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 |
/* intialize data to send to drop transfer callback */
|
|
Packit |
b099d7 |
transfer_rec = (_XmTextDropTransferRec *)
|
|
Packit |
b099d7 |
XtMalloc(sizeof(_XmTextDropTransferRec));
|
|
Packit |
b099d7 |
transfer_rec->widget = w;
|
|
Packit |
b099d7 |
transfer_rec->insert_pos = insert_pos;
|
|
Packit |
b099d7 |
transfer_rec->num_chars = 0;
|
|
Packit |
b099d7 |
transfer_rec->timestamp = cb->timeStamp;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cb->operation & XmDROP_MOVE) {
|
|
Packit |
b099d7 |
transfer_rec->move = True;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
transfer_rec->move = False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (n = 0; n < numExportTargets; n++) {
|
|
Packit |
b099d7 |
if (exportTargets[n] == CS_OF_ENCODING) {
|
|
Packit |
b099d7 |
desiredTarget = CS_OF_ENCODING;
|
|
Packit |
b099d7 |
encoding_found = True;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
if (exportTargets[n] == atoms[XmAUTF8_STRING]) utf8_string_found = True;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
if (exportTargets[n] == atoms[XmACOMPOUND_TEXT]) c_text_found = True;
|
|
Packit |
b099d7 |
if (exportTargets[n] == XA_STRING) string_found = True;
|
|
Packit |
b099d7 |
if (exportTargets[n] == atoms[XmATEXT]) text_found = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
n = 0;
|
|
Packit |
b099d7 |
if (encoding_found || c_text_found || string_found || text_found
|
|
Packit |
b099d7 |
|| utf8_string_found) {
|
|
Packit |
b099d7 |
if (!encoding_found) {
|
|
Packit |
b099d7 |
if (c_text_found)
|
|
Packit |
b099d7 |
desiredTarget = atoms[XmACOMPOUND_TEXT];
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
else if (utf8_string_found)
|
|
Packit |
b099d7 |
desiredTarget = atoms[XmAUTF8_STRING];
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
else if (string_found)
|
|
Packit |
b099d7 |
desiredTarget = XA_STRING;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
desiredTarget = atoms[XmATEXT];
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cb->operation & XmDROP_MOVE || cb->operation & XmDROP_COPY) {
|
|
Packit |
b099d7 |
doTransfer = True;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XmTransferDone(tid, XmTRANSFER_DONE_FAIL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
SetDropContext(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (doTransfer) {
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc(tid, (XmSelectionFinishedProc) DropDestroyCB);
|
|
Packit |
b099d7 |
XmTransferValue(tid, desiredTarget,
|
|
Packit |
b099d7 |
(XtCallbackProc) DropTransferProc,
|
|
Packit |
b099d7 |
(XtPointer) transfer_rec, 0);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Request targets from selection receiver; move the rest of this
|
|
Packit |
b099d7 |
* to a new routine (the name of which is passed during the request
|
|
Packit |
b099d7 |
* for targets). The new routine will look at the target list and
|
|
Packit |
b099d7 |
* determine what target to place in the pair. It will then do
|
|
Packit |
b099d7 |
* any necessary conversions before "thrusting" the selection value
|
|
Packit |
b099d7 |
* onto the receiver. This will guarantee the best chance at a
|
|
Packit |
b099d7 |
* successful exchange.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
HandleTargets(Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmACOMPOUND_TEXT, XmACLIPBOARD, XmATEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSCOMPOUND_TEXT, XmSCLIPBOARD, XmSTEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Boolean supports_encoding_data = False;
|
|
Packit |
b099d7 |
Boolean supports_CT = False;
|
|
Packit |
b099d7 |
Boolean supports_text = False;
|
|
Packit |
b099d7 |
Boolean supports_utf8_string = False;
|
|
Packit |
b099d7 |
Atom *atom_ptr;
|
|
Packit |
b099d7 |
XPoint *point = (XPoint *)closure;
|
|
Packit |
b099d7 |
Atom targets[2];
|
|
Packit |
b099d7 |
XmTextPosition select_pos;
|
|
Packit |
b099d7 |
XmTextPosition left, right;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!ds->length) {
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
assert(XtNumber(atom_names) == NUM_ATOMS);
|
|
Packit |
b099d7 |
XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
|
|
Packit |
b099d7 |
CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
atom_ptr = (Atom *)ds->value;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (i = 0; i < ds->length; i++, atom_ptr++) {
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmATEXT])
|
|
Packit |
b099d7 |
supports_text = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*atom_ptr == CS_OF_ENCODING)
|
|
Packit |
b099d7 |
supports_encoding_data = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmACOMPOUND_TEXT])
|
|
Packit |
b099d7 |
supports_CT = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
if (*atom_ptr == atoms[XmAUTF8_STRING])
|
|
Packit |
b099d7 |
supports_utf8_string = True;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Set stuff position to the x and y position of
|
|
Packit |
b099d7 |
* the button pressed event for primary pastes.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD] && point) {
|
|
Packit |
b099d7 |
select_pos =
|
|
Packit |
b099d7 |
(*tw->text.output->XYToPos)(tw, (Position)point->x, (Position)point->y);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
select_pos = tw->text.cursor_position;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
|
|
Packit |
b099d7 |
left != right && select_pos > left &&
|
|
Packit |
b099d7 |
select_pos < right) {
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (prim_select) {
|
|
Packit |
b099d7 |
prim_select->ref_count++;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
prim_select = (_XmTextPrimSelect *)
|
|
Packit |
b099d7 |
XtMalloc((unsigned) sizeof(_XmTextPrimSelect));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
prim_select->position = select_pos;
|
|
Packit |
b099d7 |
prim_select->time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
prim_select->num_chars = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If owner supports TEXT and the current locale, ask for TEXT.
|
|
Packit |
b099d7 |
* If not, and if the owner supports compound text, ask for
|
|
Packit |
b099d7 |
* compound text. If not, and owner and I have the same encoding,
|
|
Packit |
b099d7 |
* ask for that encoding. If not, fall back position is to ask for
|
|
Packit |
b099d7 |
* STRING and try to convert it locally.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (supports_text && supports_encoding_data)
|
|
Packit |
b099d7 |
prim_select->target = targets[0] = atoms[XmATEXT];
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
else if (supports_utf8_string)
|
|
Packit |
b099d7 |
prim_select->target = targets[0] = atoms[XmAUTF8_STRING];
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
else if (supports_CT)
|
|
Packit |
b099d7 |
prim_select->target = targets[0] = atoms[XmACOMPOUND_TEXT];
|
|
Packit |
b099d7 |
else if (supports_encoding_data)
|
|
Packit |
b099d7 |
prim_select->target = targets[0] = CS_OF_ENCODING;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
prim_select->target = targets[0] = XA_STRING;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
prim_select->ref_count = 1;
|
|
Packit |
b099d7 |
/* Make request to call DoStuff() with the primary selection. */
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id, targets[0], (XtCallbackProc) DoStuff,
|
|
Packit |
b099d7 |
(XtPointer) prim_select, prim_select->time);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Pastes the primary selection to the stuff position. */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DoStuff(Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmANULL, XmACLIPBOARD, XmATEXT, XmACOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = {
|
|
Packit |
b099d7 |
XmSNULL, XmSCLIPBOARD, XmSTEXT, XmSCOMPOUND_TEXT,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) w;
|
|
Packit |
b099d7 |
InputData data = tw->text.input->data;
|
|
Packit |
b099d7 |
OutputData o_data = tw->text.output->data;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
XmTextBlockRec block, newblock;
|
|
Packit |
b099d7 |
XmTextPosition cursorPos = tw->text.cursor_position;
|
|
Packit |
b099d7 |
XmTextPosition right, left, replace_from, replace_to;
|
|
Packit |
b099d7 |
_XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
|
|
Packit |
b099d7 |
char * total_value = NULL;
|
|
Packit |
b099d7 |
Boolean freeBlock;
|
|
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 (!o_data->hasfocus && _XmGetFocusPolicy(w) == XmEXPLICIT)
|
|
Packit |
b099d7 |
(void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD] &&
|
|
Packit |
b099d7 |
!(ds->length) && ds->type != atoms[XmANULL]) {
|
|
Packit |
b099d7 |
/* Backwards compatibility for 1.0 Selections */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (prim_select->target == atoms[XmATEXT]) {
|
|
Packit |
b099d7 |
prim_select->target = XA_STRING;
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id, XA_STRING, (XtCallbackProc) DoStuff,
|
|
Packit |
b099d7 |
(XtPointer) prim_select, prim_select->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if length == 0 and ds->type is the NULL atom we are assuming
|
|
Packit |
b099d7 |
* that a DELETE target is requested.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (ds->type == atoms[XmANULL]) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (prim_select->num_chars > 0 && data->selectionMove) {
|
|
Packit |
b099d7 |
data->anchor = prim_select->position;
|
|
Packit |
b099d7 |
cursorPos = prim_select->position + prim_select->num_chars;
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition(w, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection(w, tw->text.cursor_position,
|
|
Packit |
b099d7 |
False, prim_select->time);
|
|
Packit |
b099d7 |
(*tw->text.source->SetSelection)(tw->text.source, data->anchor,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XmTextSource source = GetSrc(w);
|
|
Packit |
b099d7 |
int max_length = 0;
|
|
Packit |
b099d7 |
Boolean local = _XmStringSourceHasSelection(source);
|
|
Packit |
b099d7 |
Boolean *pendingoff = NULL;
|
|
Packit |
b099d7 |
Boolean dest_disjoint = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->type == atoms[XmACOMPOUND_TEXT] ||
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
ds->type == atoms[XmAUTF8_STRING] ||
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
ds->type == XA_STRING) {
|
|
Packit |
b099d7 |
if ((total_value =
|
|
Packit |
b099d7 |
_XmTextToLocaleText(w, ds->value, ds->type, ds->format,
|
|
Packit |
b099d7 |
ds->length, NULL)) != NULL) {
|
|
Packit |
b099d7 |
block.ptr = total_value;
|
|
Packit |
b099d7 |
block.length = strlen(block.ptr);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
block.ptr = total_value = XtMalloc((unsigned)1);
|
|
Packit |
b099d7 |
*(block.ptr) = '\0';
|
|
Packit |
b099d7 |
block.length = 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
block.ptr = (char*)ds->value;
|
|
Packit |
b099d7 |
block.length = (int) ds->length; /* NOTE: this causes a truncation on
|
|
Packit |
b099d7 |
some architectures */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->selectionMove && local) {
|
|
Packit |
b099d7 |
max_length = _XmStringSourceGetMaxLength(source);
|
|
Packit |
b099d7 |
_XmStringSourceSetMaxLength(source, INT_MAX);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
replace_from = replace_to = prim_select->position;
|
|
Packit |
b099d7 |
pendingoff = _XmStringSourceGetPending(tw);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
|
|
Packit |
b099d7 |
if (tw->text.input->data->pendingdelete &&
|
|
Packit |
b099d7 |
replace_from >= left && replace_to <= right){
|
|
Packit |
b099d7 |
replace_from = left;
|
|
Packit |
b099d7 |
replace_to = right;
|
|
Packit |
b099d7 |
dest_disjoint = False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* The on_or_off flag is set to prevent unnecessary
|
|
Packit |
b099d7 |
cursor shifting during the Replace operation */
|
|
Packit |
b099d7 |
tw->text.on_or_off = off;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(tw, (Boolean *)FALSE);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmTextModifyVerify(tw, ds->event, &replace_from, &replace_to,
|
|
Packit |
b099d7 |
&cursorPos, &block, &newblock, &freeBlock)) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = _XmTextCountCharacters(newblock.ptr,
|
|
Packit |
b099d7 |
newblock.length);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
if ((*tw->text.source->Replace)(tw, ds->event,
|
|
Packit |
b099d7 |
&replace_from, &replace_to,
|
|
Packit |
b099d7 |
&newblock, False) != EditDone) {
|
|
Packit |
b099d7 |
XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
|
|
Packit |
b099d7 |
anything */
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(tw, pendingoff);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if ((newblock.length > 0 && !data->selectionMove) ||
|
|
Packit |
b099d7 |
ds->selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition(w, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection(w, tw->text.cursor_position,
|
|
Packit |
b099d7 |
False, prim_select->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
data->anchor = replace_from;
|
|
Packit |
b099d7 |
if (left != right && (!dest_disjoint || !tw->text.add_mode))
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, tw->text.cursor_position,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (data->selectionMove) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (left < replace_from) {
|
|
Packit |
b099d7 |
prim_select->position = replace_from -
|
|
Packit |
b099d7 |
prim_select->num_chars;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
prim_select->position = replace_from;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (cursorPos < left || cursorPos > right)
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(tw, (Boolean *)TRUE);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(tw, pendingoff);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD])
|
|
Packit |
b099d7 |
data->anchor = replace_from;
|
|
Packit |
b099d7 |
else if (!data->selectionMove && !tw->text.add_mode &&
|
|
Packit |
b099d7 |
prim_select->num_chars != 0)
|
|
Packit |
b099d7 |
data->anchor = prim_select->position;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmTextValueChanged(tw, ds->event);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XtCallActionProc(w, "beep", NULL, (String *) NULL, (Cardinal) 0);
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
|
|
Packit |
b099d7 |
anything */
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(tw, pendingoff);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->selectionMove && local) {
|
|
Packit |
b099d7 |
_XmStringSourceSetMaxLength(source, max_length);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD])
|
|
Packit |
b099d7 |
tw->text.on_or_off = on;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (pendingoff) XtFree((char *)pendingoff);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (total_value) XtFree(total_value);
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DropDestroyCB(Widget w,
|
|
Packit |
b099d7 |
XtPointer clientData,
|
|
Packit |
b099d7 |
XtPointer callData)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts = (XmTransferDoneCallbackStruct *)callData;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
DeleteDropContext(w);
|
|
Packit |
b099d7 |
if (ts->client_data != NULL) XtFree((char*) ts->client_data);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DropTransferProc(Widget w,
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmACOMPOUND_TEXT, XmANULL, XmADELETE,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSCOMPOUND_TEXT, XmSNULL, XmSDELETE,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextDropTransferRec *transfer_rec = (_XmTextDropTransferRec *) closure;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) transfer_rec->widget;
|
|
Packit |
b099d7 |
InputData data = tw->text.input->data;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
XmTextPosition insertPosLeft, insertPosRight, left, right, cursorPos;
|
|
Packit |
b099d7 |
XmTextBlockRec block, newblock;
|
|
Packit |
b099d7 |
XmTextSource source = GetSrc((Widget)tw);
|
|
Packit |
b099d7 |
int max_length = 0;
|
|
Packit |
b099d7 |
Boolean local = _XmStringSourceHasSelection(source);
|
|
Packit |
b099d7 |
char * total_value = NULL;
|
|
Packit |
b099d7 |
Boolean pendingoff;
|
|
Packit |
b099d7 |
Boolean freeBlock;
|
|
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 |
/* When type = NULL, we are assuming a DELETE request has been requested */
|
|
Packit |
b099d7 |
if (ds->type == atoms[XmANULL]) {
|
|
Packit |
b099d7 |
if (transfer_rec->num_chars > 0 && transfer_rec->move) {
|
|
Packit |
b099d7 |
data->anchor = transfer_rec->insert_pos;
|
|
Packit |
b099d7 |
cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition((Widget)tw, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection((Widget)tw, tw->text.cursor_position,
|
|
Packit |
b099d7 |
False,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
(*tw->text.source->SetSelection)(tw->text.source, data->anchor,
|
|
Packit |
b099d7 |
tw->text.cursor_position,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
if (ds->value) {
|
|
Packit |
b099d7 |
XtFree((char *) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!ds->value ||
|
|
Packit |
b099d7 |
(ds->type != atoms[XmACOMPOUND_TEXT] &&
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
ds->type != atoms[XmAUTF8_STRING] &&
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
ds->type != CS_OF_ENCODING &&
|
|
Packit |
b099d7 |
ds->type != XA_STRING)) {
|
|
Packit |
b099d7 |
XmTransferDone(ds->transfer_id, XmTRANSFER_DONE_FAIL);
|
|
Packit |
b099d7 |
if (ds->value) {
|
|
Packit |
b099d7 |
XtFree((char*) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
insertPosLeft = insertPosRight = transfer_rec->insert_pos;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->type == XA_STRING || ds->type == atoms[XmACOMPOUND_TEXT]
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
|| ds->type == atoms[XmAUTF8_STRING]
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
) {
|
|
Packit |
b099d7 |
if ((total_value = _XmTextToLocaleText(w, ds->value, ds->type,
|
|
Packit |
b099d7 |
8, ds->length, NULL)) != NULL) {
|
|
Packit |
b099d7 |
block.ptr = total_value;
|
|
Packit |
b099d7 |
block.length = strlen(block.ptr);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (ds->value) {
|
|
Packit |
b099d7 |
XtFree((char*) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
block.ptr = (char *) ds->value;
|
|
Packit |
b099d7 |
block.length = (int) ds->length; /* NOTE: this causes a truncation on
|
|
Packit |
b099d7 |
some architectures */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->pendingdelete &&
|
|
Packit |
b099d7 |
(*tw->text.source->GetSelection)(tw->text.source, &left, &right) &&
|
|
Packit |
b099d7 |
(left != right)){
|
|
Packit |
b099d7 |
if(insertPosLeft > left && insertPosLeft < right) insertPosLeft = left;
|
|
Packit |
b099d7 |
if(insertPosRight < right && insertPosRight > left) insertPosRight = right;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (transfer_rec->move && local) {
|
|
Packit |
b099d7 |
max_length = _XmStringSourceGetMaxLength(source);
|
|
Packit |
b099d7 |
_XmStringSourceSetMaxLength(source, INT_MAX);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* The on_or_off flag is set to prevent unecessary
|
|
Packit |
b099d7 |
cursor shifting during the Replace operation */
|
|
Packit |
b099d7 |
tw->text.on_or_off = off;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
pendingoff = tw->text.pendingoff;
|
|
Packit |
b099d7 |
tw->text.pendingoff = FALSE;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmTextModifyVerify(tw, ds->event, &insertPosLeft, &insertPosRight,
|
|
Packit |
b099d7 |
&cursorPos, &block, &newblock, &freeBlock)) {
|
|
Packit |
b099d7 |
if ((*tw->text.source->Replace)(tw, ds->event,
|
|
Packit |
b099d7 |
&insertPosLeft, &insertPosRight,
|
|
Packit |
b099d7 |
&newblock, False) != EditDone) {
|
|
Packit |
b099d7 |
if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
|
|
Packit |
b099d7 |
tw->text.pendingoff = pendingoff;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
transfer_rec->num_chars = _XmTextCountCharacters(newblock.ptr,
|
|
Packit |
b099d7 |
newblock.length);
|
|
Packit |
b099d7 |
if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
|
|
Packit |
b099d7 |
_XmTextSetCursorPosition((Widget)tw, cursorPos);
|
|
Packit |
b099d7 |
_XmTextSetDestinationSelection((Widget)tw,
|
|
Packit |
b099d7 |
tw->text.cursor_position,False,
|
|
Packit |
b099d7 |
transfer_rec->timestamp);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if ((*tw->text.source->GetSelection)(tw->text.source, &left, &right)) {
|
|
Packit |
b099d7 |
if (transfer_rec->move && left < insertPosLeft)
|
|
Packit |
b099d7 |
transfer_rec->insert_pos = insertPosLeft -
|
|
Packit |
b099d7 |
transfer_rec->num_chars;
|
|
Packit |
b099d7 |
if (cursorPos < left || cursorPos > right)
|
|
Packit |
b099d7 |
tw->text.pendingoff = TRUE;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (!transfer_rec->move && !tw->text.add_mode &&
|
|
Packit |
b099d7 |
transfer_rec->num_chars != 0)
|
|
Packit |
b099d7 |
data->anchor = insertPosLeft;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (transfer_rec->move) {
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id,
|
|
Packit |
b099d7 |
atoms[XmADELETE],
|
|
Packit |
b099d7 |
(XtCallbackProc) DropTransferProc,
|
|
Packit |
b099d7 |
(XtPointer) transfer_rec, 0);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (transfer_rec->move && local) {
|
|
Packit |
b099d7 |
_XmStringSourceSetMaxLength(source, max_length);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextValueChanged(tw, (XEvent *) ds->event);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (tw->text.verify_bell) XBell(XtDisplay(tw), 0);
|
|
Packit |
b099d7 |
tw->text.pendingoff = pendingoff;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
tw->text.on_or_off = on;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (total_value) XtFree(total_value);
|
|
Packit |
b099d7 |
if (ds->value != NULL) XtFree((char*) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SetDropContext(Widget w)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Display *display = XtDisplay(w);
|
|
Packit |
b099d7 |
Screen *screen = XtScreen(w);
|
|
Packit |
b099d7 |
XContext loc_context;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (_XmTextDNDContext == 0)
|
|
Packit |
b099d7 |
_XmTextDNDContext = XUniqueContext();
|
|
Packit |
b099d7 |
loc_context = _XmTextDNDContext;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XSaveContext(display, (Window)screen,
|
|
Packit |
b099d7 |
loc_context, (XPointer)w);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DeleteDropContext(Widget w)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Display *display = XtDisplay(w);
|
|
Packit |
b099d7 |
Screen *screen = XtScreen(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
XDeleteContext(display, (Window)screen, _XmTextDNDContext);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Widget
|
|
Packit |
b099d7 |
_XmTextGetDropReciever(Widget w)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Display *display = XtDisplay(w);
|
|
Packit |
b099d7 |
Screen *screen = XtScreen(w);
|
|
Packit |
b099d7 |
Widget widget;
|
|
Packit |
b099d7 |
XContext loc_context;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
loc_context = _XmTextDNDContext;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
if (loc_context == 0) return NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!XFindContext(display, (Window)screen,
|
|
Packit |
b099d7 |
loc_context, (char **) &widget)) {
|
|
Packit |
b099d7 |
return widget;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/********************************************
|
|
Packit |
b099d7 |
* Transfer trait method implementation
|
|
Packit |
b099d7 |
********************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
TextConvertCallback(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore, /* unused */
|
|
Packit |
b099d7 |
XmConvertCallbackStruct *cs)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmADELETE, XmA_MOTIF_LOSE_SELECTION,
|
|
Packit |
b099d7 |
XmA_MOTIF_EXPORT_TARGETS, XmATEXT, XmACOMPOUND_TEXT,
|
|
Packit |
b099d7 |
XmATARGETS, XmA_MOTIF_CLIPBOARD_TARGETS, XmACLIPBOARD,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmAUTF8_STRING,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSDELETE, XmS_MOTIF_LOSE_SELECTION,
|
|
Packit |
b099d7 |
XmS_MOTIF_EXPORT_TARGETS, XmSTEXT, XmSCOMPOUND_TEXT,
|
|
Packit |
b099d7 |
XmSTARGETS, XmS_MOTIF_CLIPBOARD_TARGETS, XmSCLIPBOARD,
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
XmSUTF8_STRING
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Atom XA_CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
XtPointer value;
|
|
Packit |
b099d7 |
Atom type;
|
|
Packit |
b099d7 |
unsigned long size;
|
|
Packit |
b099d7 |
int format;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
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 |
value = NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs->target == atoms[XmA_MOTIF_LOSE_SELECTION]) {
|
|
Packit |
b099d7 |
_XmTextLoseSelection(w, &(cs->selection));
|
|
Packit |
b099d7 |
cs->status = XmCONVERT_DONE;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs->target == atoms[XmADELETE] &&
|
|
Packit |
b099d7 |
cs->selection == XA_SECONDARY) {
|
|
Packit |
b099d7 |
_XmTextHandleSecondaryFinished(w, cs->event);
|
|
Packit |
b099d7 |
cs->status = XmCONVERT_DONE;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* When this is called as a result of a clipboard copy link, we
|
|
Packit |
b099d7 |
don't have any available targets. Make sure to return immediately
|
|
Packit |
b099d7 |
without modification */
|
|
Packit |
b099d7 |
if (cs->selection == atoms[XmACLIPBOARD] &&
|
|
Packit |
b099d7 |
cs->parm == (XtPointer) XmLINK &&
|
|
Packit |
b099d7 |
(cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS] ||
|
|
Packit |
b099d7 |
cs->target == atoms[XmATARGETS])) return;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!_XmTextConvert(w, &cs->selection, &cs->target,
|
|
Packit |
b099d7 |
&type, &value, &size, &format,
|
|
Packit |
b099d7 |
(Widget) cs->source_data, cs->event)) {
|
|
Packit |
b099d7 |
value = NULL;
|
|
Packit |
b099d7 |
type = XA_INTEGER;
|
|
Packit |
b099d7 |
size = 0;
|
|
Packit |
b099d7 |
format = 8;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs->target == atoms[XmADELETE]) {
|
|
Packit |
b099d7 |
cs->status = XmCONVERT_DONE;
|
|
Packit |
b099d7 |
cs->type = type;
|
|
Packit |
b099d7 |
cs->value = value;
|
|
Packit |
b099d7 |
cs->length = size;
|
|
Packit |
b099d7 |
cs->format = format;
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cs->target == atoms[XmA_MOTIF_EXPORT_TARGETS] ||
|
|
Packit |
b099d7 |
cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS]) {
|
|
Packit |
b099d7 |
Atom *targs = (Atom *) XtMalloc(sizeof(Atom) * 5);
|
|
Packit |
b099d7 |
int n = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
value = (XtPointer) targs;
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
targs[n] = atoms[XmAUTF8_STRING]; n++;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
targs[n] = atoms[XmACOMPOUND_TEXT]; n++;
|
|
Packit |
b099d7 |
targs[n] = atoms[XmATEXT]; n++;
|
|
Packit |
b099d7 |
targs[n] = XA_STRING; n++;
|
|
Packit |
b099d7 |
if (XA_CS_OF_ENCODING != XA_STRING) {
|
|
Packit |
b099d7 |
targs[n] = XA_CS_OF_ENCODING; n++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
format = 32;
|
|
Packit |
b099d7 |
size = n;
|
|
Packit |
b099d7 |
type = XA_ATOM;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmConvertComplete(w, value, size, format, type, cs);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************
|
|
Packit |
b099d7 |
* Free data allocated for destination callback
|
|
Packit |
b099d7 |
************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
FreeLocationData(Widget w, /* unused */
|
|
Packit |
b099d7 |
XtEnum op, /* unused */
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *ds;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ds = _XmTransferGetDestinationCBStruct(ts->transfer_id);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtFree((char*) ds->location_data);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ds->location_data = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
TextDestinationCallback(Widget w,
|
|
Packit |
b099d7 |
XtPointer closure, /* unused */
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *ds)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
enum { XmATARGETS, XmA_MOTIF_DROP, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSTARGETS, XmS_MOTIF_DROP };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
XPoint DropPoint;
|
|
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 |
/*
|
|
Packit |
b099d7 |
** In case of a primary transfer operation where a location_data
|
|
Packit |
b099d7 |
** has been allocated, register a done proc to be called when
|
|
Packit |
b099d7 |
** the data transfer is complete to free the location_data
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (ds->selection == XA_PRIMARY && ds->location_data)
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc(ds->transfer_id, FreeLocationData);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If we aren't sensitive, don't allow transfer */
|
|
Packit |
b099d7 |
if (! w -> core.sensitive ||
|
|
Packit |
b099d7 |
! w -> core.ancestor_sensitive)
|
|
Packit |
b099d7 |
XmTransferDone(ds -> transfer_id, XmTRANSFER_DONE_FAIL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* We don't handle LINKs internally */
|
|
Packit |
b099d7 |
if (ds->operation == XmLINK) return;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection == XA_PRIMARY && ds->operation == XmMOVE)
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc(ds->transfer_id, SetPrimarySelection);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
XmeTransferAddDoneProc(ds->transfer_id, CleanPrimarySelection);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmA_MOTIF_DROP]) {
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *cb =
|
|
Packit |
b099d7 |
(XmDropProcCallbackStruct *) ds->destination_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
DropPoint.x = cb->x;
|
|
Packit |
b099d7 |
DropPoint.y = cb->y;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
ds->location_data = (XtPointer) &DropPoint;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cb->dropAction != XmDROP_HELP) {
|
|
Packit |
b099d7 |
HandleDrop(w, cb, ds);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else if (ds->selection == XA_SECONDARY) {
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
insert_select.done_status = False;
|
|
Packit |
b099d7 |
insert_select.success_status = False;
|
|
Packit |
b099d7 |
insert_select.event = (XSelectionRequestEvent *) ds->event;
|
|
Packit |
b099d7 |
insert_select.select_type = XmDEST_SELECT;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (((Atom) ds->location_data) != CS_OF_ENCODING) {
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Make selection request to find out which targets
|
|
Packit |
b099d7 |
* the selection can provide.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id, atoms[XmATARGETS],
|
|
Packit |
b099d7 |
(XtCallbackProc) TextSecondaryWrapper,
|
|
Packit |
b099d7 |
(XtPointer) &insert_select, ds->time);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Make selection request to replace the selection
|
|
Packit |
b099d7 |
* with the insert selection.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id, ((Atom) ds->location_data),
|
|
Packit |
b099d7 |
(XtCallbackProc) TextSecondaryWrapper,
|
|
Packit |
b099d7 |
(XtPointer) &insert_select, ds->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
/* CLIPBOARD or PRIMARY */
|
|
Packit |
b099d7 |
XmTransferValue(ds->transfer_id, atoms[XmATARGETS],
|
|
Packit |
b099d7 |
(XtCallbackProc) HandleTargets,
|
|
Packit |
b099d7 |
ds->location_data, ds->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmTextInstallTransferTrait(void)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmeTraitSet((XtPointer)xmTextWidgetClass, XmQTtransfer,
|
|
Packit |
b099d7 |
(XtPointer) &TextTransfer);
|
|
Packit |
b099d7 |
}
|