|
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: TextFSel.c /main/22 1997/10/14 15:38:30 cshi $"
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
/* (c) Copyright 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/TraitP.h> /* for XmeTraitSet() */
|
|
Packit |
b099d7 |
#include <Xm/TransferP.h>
|
|
Packit |
b099d7 |
#include <Xm/TransferT.h>
|
|
Packit |
b099d7 |
#include <Xm/XmosP.h>
|
|
Packit |
b099d7 |
#include "TextFI.h"
|
|
Packit |
b099d7 |
#include "TextFSelI.h"
|
|
Packit |
b099d7 |
#include "TransferI.h" /* for _XmConvertComplete() */
|
|
Packit |
b099d7 |
#include "TraversalI.h" /* for _XmGetFocusPolicy() */
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
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 |
static void HandleDrop(Widget w,
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *cb,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *ds);
|
|
Packit |
b099d7 |
static void TextFieldConvertCallback(Widget,
|
|
Packit |
b099d7 |
XtPointer,
|
|
Packit |
b099d7 |
XmConvertCallbackStruct*);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void TextFieldDestinationCallback(Widget,
|
|
Packit |
b099d7 |
XtPointer,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct*);
|
|
Packit |
b099d7 |
static void SetDropContext(Widget w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void DeleteDropContext(Widget w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void HandleTargets(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void HandleDrop(Widget w,
|
|
Packit |
b099d7 |
XmDropProcCallbackStruct *cb,
|
|
Packit |
b099d7 |
XmDestinationCallbackStruct *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,
|
|
Packit |
b099d7 |
XtPointer ignore,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
static void DoStuff(Widget w,
|
|
Packit |
b099d7 |
XtPointer ignore,
|
|
Packit |
b099d7 |
XmSelectionCallbackStruct *ds);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/******** End Static Function Declarations ********/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Transfer Trait record for TextField */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmConst XmTransferTraitRec textFieldTT = {
|
|
Packit |
b099d7 |
0, /* version */
|
|
Packit |
b099d7 |
(XmConvertCallbackProc) TextFieldConvertCallback,
|
|
Packit |
b099d7 |
(XmDestinationCallbackProc) TextFieldDestinationCallback,
|
|
Packit |
b099d7 |
(XmDestinationCallbackProc) NULL,
|
|
Packit |
b099d7 |
};
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XContext _XmTextFDNDContext = 0;
|
|
Packit |
b099d7 |
static _XmInsertSelect insert_select;
|
|
Packit |
b099d7 |
static _XmTextPrimSelect *prim_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 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
Packit |
b099d7 |
XmTextPosition cursorPos = tf->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 |
tf->text.prim_anchor = prim_select->position;
|
|
Packit |
b099d7 |
cursorPos = prim_select->position + prim_select->num_chars;
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, tf->text.prim_anchor, cursorPos,
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
tf->text.pending_off = False;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, cursorPos, True, True);
|
|
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 |
{
|
|
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 |
TextFieldSecondaryWrapper(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 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
Packit |
b099d7 |
XmTextPosition left = 0;
|
|
Packit |
b099d7 |
XmTextPosition right = 0;
|
|
Packit |
b099d7 |
Boolean replace_res = False;
|
|
Packit |
b099d7 |
Boolean dest_disjoint = False;
|
|
Packit |
b099d7 |
wchar_t * wc_value;
|
|
Packit |
b099d7 |
char * temp;
|
|
Packit |
b099d7 |
int num_chars = 0;
|
|
Packit |
b099d7 |
Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
|
|
Packit |
b099d7 |
Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
|
|
Packit |
b099d7 |
char * total_value = NULL;
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
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 not text to add */
|
|
Packit |
b099d7 |
if (*(char *) value == (char)'\0' || *length == 0){
|
|
Packit |
b099d7 |
XtFree((char *)value);
|
|
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 (!tf->text.has_primary ||
|
|
Packit |
b099d7 |
tf->text.prim_pos_left == tf->text.prim_pos_right) {
|
|
Packit |
b099d7 |
XBell(XtDisplay(w), 0);
|
|
Packit |
b099d7 |
XtFree((char *)value);
|
|
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 (tf->text.has_primary &&
|
|
Packit |
b099d7 |
(left = tf->text.prim_pos_left) != (right = tf->text.prim_pos_right)) {
|
|
Packit |
b099d7 |
if ( TextF_CursorPosition(tf) < left ||
|
|
Packit |
b099d7 |
TextF_CursorPosition(tf) > right ||
|
|
Packit |
b099d7 |
!tf->text.pending_delete) {
|
|
Packit |
b099d7 |
left = right = TextF_CursorPosition(tf);
|
|
Packit |
b099d7 |
dest_disjoint = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
left = right = TextF_CursorPosition(tf);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*type == COMPOUND_TEXT || *type == XA_STRING || *type == UTF8_STRING) {
|
|
Packit |
b099d7 |
total_value = _XmTextToLocaleText(w, value, *type, *format,
|
|
Packit |
b099d7 |
*length, NULL);
|
|
Packit |
b099d7 |
if (total_value) {
|
|
Packit |
b099d7 |
if (tf->text.max_char_size == 1) {
|
|
Packit |
b099d7 |
num_chars = strlen(total_value);
|
|
Packit |
b099d7 |
replace_res = _XmTextFieldReplaceText(tf,
|
|
Packit |
b099d7 |
(XEvent *)insert_select->event,
|
|
Packit |
b099d7 |
left, right, total_value,
|
|
Packit |
b099d7 |
num_chars, True);
|
|
Packit |
b099d7 |
} else { /* must convert to wchar_t before passing to Replace */
|
|
Packit |
b099d7 |
int len = strlen(total_value) + 1;
|
|
Packit |
b099d7 |
wc_value = (wchar_t *)XtMalloc((unsigned) len * sizeof(wchar_t));
|
|
Packit |
b099d7 |
num_chars = mbstowcs(wc_value, total_value, len);
|
|
Packit |
b099d7 |
if (num_chars < 0)
|
|
Packit |
b099d7 |
num_chars = 0;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
replace_res = _XmTextFieldReplaceText(tf,
|
|
Packit |
b099d7 |
(XEvent *)insert_select->event,
|
|
Packit |
b099d7 |
left, right, (char*) wc_value,
|
|
Packit |
b099d7 |
num_chars, True);
|
|
Packit |
b099d7 |
XtFree((char *)wc_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XtFree(total_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else { /* it must be either TEXT or codeset of the locale */
|
|
Packit |
b099d7 |
if (tf->text.max_char_size == 1) {
|
|
Packit |
b099d7 |
/* NOTE: casting *length could result in a truncated long. */
|
|
Packit |
b099d7 |
num_chars = *length;
|
|
Packit |
b099d7 |
replace_res = _XmTextFieldReplaceText(tf,
|
|
Packit |
b099d7 |
(XEvent *)insert_select->event,
|
|
Packit |
b099d7 |
left, right, (char *)value,
|
|
Packit |
b099d7 |
(unsigned)*length, True);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
temp = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
/* NOTE: casting *length could result in a truncated long. */
|
|
Packit |
b099d7 |
(void)memcpy((void*)temp, (void*)value, (size_t)*length);
|
|
Packit |
b099d7 |
temp[*length] = '\0';
|
|
Packit |
b099d7 |
wc_value = (wchar_t*)XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(*length + 1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: casting *length could result in a truncated long. */
|
|
Packit |
b099d7 |
num_chars = mbstowcs(wc_value, temp, (unsigned)*length + 1);
|
|
Packit |
b099d7 |
if (num_chars < 0)
|
|
Packit |
b099d7 |
num_chars = 0;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
replace_res = _XmTextFieldReplaceText(tf,
|
|
Packit |
b099d7 |
(XEvent *)insert_select->event,
|
|
Packit |
b099d7 |
left, right, (char*) wc_value,
|
|
Packit |
b099d7 |
num_chars, True);
|
|
Packit |
b099d7 |
XtFree(temp);
|
|
Packit |
b099d7 |
XtFree((char *)wc_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!replace_res) {
|
|
Packit |
b099d7 |
insert_select->success_status = False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
insert_select->success_status = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!tf->text.add_mode) tf->text.prim_anchor = left;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tf->text.pending_off = True;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, left + num_chars, False, True);
|
|
Packit |
b099d7 |
(void) _XmTextFieldSetDestination(w, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
insert_select->event->time);
|
|
Packit |
b099d7 |
if (insert_select->select_type == XmDEST_SELECT) {
|
|
Packit |
b099d7 |
if (left != right) {
|
|
Packit |
b099d7 |
if (!dest_disjoint || !tf->text.add_mode) {
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
insert_select->event->time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
cb.reason = XmCR_VALUE_CHANGED;
|
|
Packit |
b099d7 |
cb.event = (XEvent *)insert_select->event;
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
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, XmAUTF8_STRING, NUM_ATOMS };
|
|
Packit |
b099d7 |
static char *atom_names[] = { XmSTEXT, XmSCOMPOUND_TEXT, XmSUTF8_STRING };
|
|
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 |
else if (supports_CT)
|
|
Packit |
b099d7 |
target = atoms[XmACOMPOUND_TEXT];
|
|
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_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) TextFieldSecondaryWrapper,
|
|
Packit |
b099d7 |
closure, insert_select -> event -> time);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmTextFieldConvert(
|
|
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, XmAUTF8_STRING,
|
|
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, XmSUTF8_STRING };
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTextFieldWidget tf;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
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 |
char *tmp_value;
|
|
Packit |
b099d7 |
int ret_status = 0;
|
|
Packit |
b099d7 |
Time _time;
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
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 (req_event == NULL)
|
|
Packit |
b099d7 |
_time = XtLastTimestampProcessed(XtDisplay(w));
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
_time = req_event -> time;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tf = (XmTextFieldWidget) w;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tf == NULL) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*selection == XA_PRIMARY || *selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
has_selection = tf->text.has_primary;
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_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 = tf->text.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 = tf->text.has_secondary;
|
|
Packit |
b099d7 |
left = tf->text.sec_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.sec_pos_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 = tf->text.has_primary;
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_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 textfield 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 |
targs[target_count] = atoms[XmAUTF8_STRING]; target_count++;
|
|
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 = tf->text.prim_time;
|
|
Packit |
b099d7 |
else if (is_destination)
|
|
Packit |
b099d7 |
*timestamp = tf->text.dest_time;
|
|
Packit |
b099d7 |
else if (is_secondary)
|
|
Packit |
b099d7 |
*timestamp = tf->text.sec_time;
|
|
Packit |
b099d7 |
else if (is_drop)
|
|
Packit |
b099d7 |
*timestamp = tf->text.prim_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 |
*type = (Atom) XA_STRING;
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
if (is_destination || !has_selection) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* put a char* value into tmp_value, then convert to 8859.1 */
|
|
Packit |
b099d7 |
if (tf->text.max_char_size != 1) {
|
|
Packit |
b099d7 |
int stat ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: casting (right - left) could result in a truncated long. */
|
|
Packit |
b099d7 |
*length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(int)(right - left));
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(unsigned)*length); /* NOTE: casting *length could
|
|
Packit |
b099d7 |
result in a truncated long. */
|
|
Packit |
b099d7 |
if (stat < 0) /* wcstombs will return neg value on conv failure */
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
else *length = (unsigned long) stat ;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*length = right - left;
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
/* get the selection value */
|
|
Packit |
b099d7 |
(void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left),
|
|
Packit |
b099d7 |
(size_t)*length); /* NOTE: casting *length could result
|
|
Packit |
b099d7 |
in a truncated long. */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
tmp_value[*length] = '\0';
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
/* convert tmp_value to 8859.1 */
|
|
Packit |
b099d7 |
ret_status = XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XStringStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (ret_status == Success || ret_status > 0){
|
|
Packit |
b099d7 |
*value = (XtPointer) 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 |
} 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 |
if (tf->text.max_char_size != 1) {
|
|
Packit |
b099d7 |
int stat ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: casting (right - left) could result in a truncated long. */
|
|
Packit |
b099d7 |
*length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(int)(right - left));
|
|
Packit |
b099d7 |
*value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
stat = wcstombs((char *)*value, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(unsigned)*length); /* NOTE: casting *length could
|
|
Packit |
b099d7 |
result in a truncated long */
|
|
Packit |
b099d7 |
if (stat < 0) /* wcstombs return neg value on conv failure */
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
else *length = (unsigned long) stat ;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*length = right - left;
|
|
Packit |
b099d7 |
*value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
/* get the selection value */
|
|
Packit |
b099d7 |
(void)memcpy((void*)*value, (void*)(TextF_Value(tf) + left),
|
|
Packit |
b099d7 |
(size_t)*length); /* NOTE: casting *length could result
|
|
Packit |
b099d7 |
in a truncated long. */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
(*(char **)value)[*length]='\0';
|
|
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 |
if (tf->text.max_char_size != 1) {
|
|
Packit |
b099d7 |
int stat ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* convert to char* before converting to CT. NOTE: casting
|
|
Packit |
b099d7 |
* (right - left) could result in a truncated long.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
*length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(int)(right - left));
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(unsigned)*length); /* NOTE: casting *length could
|
|
Packit |
b099d7 |
result in a truncated long. */
|
|
Packit |
b099d7 |
if (stat < 0) /* wcstombs will return neg value on conv failure */
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
else *length = (unsigned long) stat ;
|
|
Packit |
b099d7 |
} else { /* malloc the space and copy the data to be converted */
|
|
Packit |
b099d7 |
*length = right - left;
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
/* get the selection value */
|
|
Packit |
b099d7 |
(void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left),
|
|
Packit |
b099d7 |
(size_t)*length); /* NOTE: casting *length could result
|
|
Packit |
b099d7 |
in a truncated long. */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
tmp_value[*length] = '\0';
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
/* Convert to compound text */
|
|
Packit |
b099d7 |
ret_status =
|
|
Packit |
b099d7 |
XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XCompoundTextStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (ret_status == Success || ret_status > 0){
|
|
Packit |
b099d7 |
*length = tmp_prop.nitems;
|
|
Packit |
b099d7 |
*value = (XtPointer)tmp_prop.value;
|
|
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 |
if (tf->text.max_char_size != 1) {
|
|
Packit |
b099d7 |
int stat ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* convert to char* before converting to CT. NOTE: casting
|
|
Packit |
b099d7 |
* (right - left) could result in a truncated long.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
*length = _XmTextFieldCountBytes(tf, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(int)(right - left));
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
stat = wcstombs(tmp_value, TextF_WcValue(tf) + left,
|
|
Packit |
b099d7 |
(unsigned)*length); /* NOTE: casting *length could
|
|
Packit |
b099d7 |
result in a truncated long. */
|
|
Packit |
b099d7 |
if (stat < 0) /* wcstombs will return neg value on conv failure */
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
else *length = (unsigned long) stat ;
|
|
Packit |
b099d7 |
} else { /* malloc the space and copy the data to be converted */
|
|
Packit |
b099d7 |
*length = right - left;
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned) *length + 1);
|
|
Packit |
b099d7 |
/* get the selection value */
|
|
Packit |
b099d7 |
(void)memcpy((void*)tmp_value, (void*)(TextF_Value(tf) + left),
|
|
Packit |
b099d7 |
(size_t)*length); /* NOTE: casting *length could result
|
|
Packit |
b099d7 |
in a truncated long. */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
tmp_value[*length] = '\0';
|
|
Packit |
b099d7 |
tmp_prop.value = NULL;
|
|
Packit |
b099d7 |
/* Convert to compound text */
|
|
Packit |
b099d7 |
ret_status =
|
|
Packit |
b099d7 |
XmbTextListToTextProperty(XtDisplay(w), &tmp_value, 1,
|
|
Packit |
b099d7 |
(XICCEncodingStyle)XUTF8StringStyle,
|
|
Packit |
b099d7 |
&tmp_prop);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
if (ret_status == Success || ret_status > 0){
|
|
Packit |
b099d7 |
*length = tmp_prop.nitems;
|
|
Packit |
b099d7 |
*value = (XtPointer)tmp_prop.value;
|
|
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 |
XmTextPosition left, right;
|
|
Packit |
b099d7 |
Boolean move_cursor = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!(is_primary || is_drop)) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (is_drop) {
|
|
Packit |
b099d7 |
if (_XmTextFieldGetDropReciever((Widget)tf) == (Widget) tf)
|
|
Packit |
b099d7 |
move_cursor = False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (req_event != NULL &&
|
|
Packit |
b099d7 |
req_event->requestor == XtWindow((Widget)tf))
|
|
Packit |
b099d7 |
move_cursor = False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!_XmTextFieldReplaceText(tf, (XEvent *) req_event,
|
|
Packit |
b099d7 |
left, right, NULL, 0, move_cursor)) {
|
|
Packit |
b099d7 |
tf->text.has_primary = True;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, tf->text.prim_anchor,
|
|
Packit |
b099d7 |
tf->text.prim_anchor, _time);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cb.reason = XmCR_VALUE_CHANGED;
|
|
Packit |
b099d7 |
cb.event = (XEvent *) req_event;
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
tf->text.has_primary = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tf->text.has_destination)
|
|
Packit |
b099d7 |
tf->text.prim_anchor = TextF_CursorPosition(tf);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*type = atoms[XmANULL];
|
|
Packit |
b099d7 |
*value = NULL;
|
|
Packit |
b099d7 |
*length = 0;
|
|
Packit |
b099d7 |
*format = 8;
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
/* unknown selection type */
|
|
Packit |
b099d7 |
return FALSE;
|
|
Packit |
b099d7 |
return TRUE;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmTextFieldLoseSelection(
|
|
Packit |
b099d7 |
Widget w,
|
|
Packit |
b099d7 |
Atom *selection )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
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 && tf->text.has_primary) {
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
_XmTextFieldDeselectSelection(w, False, 0);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cb.reason = XmCR_LOSE_PRIMARY;
|
|
Packit |
b099d7 |
cb.event = NULL;
|
|
Packit |
b099d7 |
XtCallCallbackList(w, tf->text.lose_primary_callback, (XtPointer) &cb;;
|
|
Packit |
b099d7 |
/* Losing Destination Selection */
|
|
Packit |
b099d7 |
} else if (*selection == MOTIF_DESTINATION) {
|
|
Packit |
b099d7 |
Boolean orig_ibeam_off = tf->text.refresh_ibeam_off;
|
|
Packit |
b099d7 |
tf->text.has_destination = False;
|
|
Packit |
b099d7 |
/* if we have focus, we have a valid putback area. If we don't have
|
|
Packit |
b099d7 |
* focus, don't want to update the putback with the destination cursor
|
|
Packit |
b099d7 |
* image.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
tf->text.refresh_ibeam_off = False;
|
|
Packit |
b099d7 |
_XmTextFieldDrawInsertionPoint(tf, False);
|
|
Packit |
b099d7 |
tf->text.blink_on = True;
|
|
Packit |
b099d7 |
_XmTextFieldDrawInsertionPoint(tf, True);
|
|
Packit |
b099d7 |
/* Restore the state of the refresh_ibeam_off flag. */
|
|
Packit |
b099d7 |
tf->text.refresh_ibeam_off = orig_ibeam_off;
|
|
Packit |
b099d7 |
/* Losing Secondary Selection */
|
|
Packit |
b099d7 |
} else if (*selection == XA_SECONDARY && tf->text.has_secondary){
|
|
Packit |
b099d7 |
_XmTextFieldSetSel2(w, 0, 0, True,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
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 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (_XmTextFDNDContext == 0)
|
|
Packit |
b099d7 |
_XmTextFDNDContext = XUniqueContext();
|
|
Packit |
b099d7 |
loc_context = _XmTextFDNDContext;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XSaveContext(display, (Window)screen,
|
|
Packit |
b099d7 |
loc_context, (XPointer)w);
|
|
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 |
XContext loc_context;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
loc_context = _XmTextFDNDContext;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XDeleteContext(display, (Window)screen, loc_context);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Widget
|
|
Packit |
b099d7 |
_XmTextFieldGetDropReciever(Widget w)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Widget widget;
|
|
Packit |
b099d7 |
XContext loc_context;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
loc_context = _XmTextFDNDContext;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (loc_context == 0) return NULL;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!XFindContext(XtDisplay(w), (Window) XtScreen(w),
|
|
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 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DropDestroyCB(Widget w,
|
|
Packit |
b099d7 |
XtPointer clientData,
|
|
Packit |
b099d7 |
XtPointer callData)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTransferDoneCallbackStruct *ts =
|
|
Packit |
b099d7 |
(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 |
static void
|
|
Packit |
b099d7 |
DropTransferProc(Widget w, 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 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
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 |
int max_length = 0;
|
|
Packit |
b099d7 |
Boolean local = tf->text.has_primary;
|
|
Packit |
b099d7 |
char * total_value = NULL;
|
|
Packit |
b099d7 |
wchar_t * wc_total_value;
|
|
Packit |
b099d7 |
unsigned long total_length = 0;
|
|
Packit |
b099d7 |
int wc_total_length;
|
|
Packit |
b099d7 |
Boolean replace = False;
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
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 |
tf->text.prim_anchor = transfer_rec->insert_pos;
|
|
Packit |
b099d7 |
cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, cursorPos,
|
|
Packit |
b099d7 |
False, True);
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, tf->text.prim_anchor,
|
|
Packit |
b099d7 |
TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(w)));
|
|
Packit |
b099d7 |
tf->text.pending_off = False;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
True, True);
|
|
Packit |
b099d7 |
}
|
|
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 |
if (!(ds->value) ||
|
|
Packit |
b099d7 |
(ds->type != CS_OF_ENCODING &&
|
|
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 != 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
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
|| ds->type == atoms[XmAUTF8_STRING]
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|| ds->type == atoms[XmACOMPOUND_TEXT]) {
|
|
Packit |
b099d7 |
if ((total_value = _XmTextToLocaleText(w, ds->value, ds->type,
|
|
Packit |
b099d7 |
8, ds->length, NULL)) != NULL)
|
|
Packit |
b099d7 |
total_length = strlen(total_value);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
if (ds->value) {
|
|
Packit |
b099d7 |
XtFree((char*) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
total_value = (char*) ds->value;
|
|
Packit |
b099d7 |
total_length = ds->length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (total_value == NULL) return;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (TextF_PendingDelete(tf) && tf->text.has_primary &&
|
|
Packit |
b099d7 |
tf->text.prim_pos_left != tf->text.prim_pos_right) {
|
|
Packit |
b099d7 |
if(insertPosLeft > tf->text.prim_pos_left
|
|
Packit |
b099d7 |
&& insertPosLeft < tf->text.prim_pos_right)
|
|
Packit |
b099d7 |
insertPosLeft = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
if(insertPosRight < tf->text.prim_pos_right
|
|
Packit |
b099d7 |
&& insertPosRight > tf->text.prim_pos_left)
|
|
Packit |
b099d7 |
insertPosRight = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
transfer_rec->num_chars = _XmTextFieldCountCharacters(tf, total_value,
|
|
Packit |
b099d7 |
total_length);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextFieldDrawInsertionPoint(tf, False);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (transfer_rec->move && local) {
|
|
Packit |
b099d7 |
max_length = TextF_MaxLength(tf);
|
|
Packit |
b099d7 |
TextF_MaxLength(tf) = INT_MAX;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tf->text.max_char_size == 1) {
|
|
Packit |
b099d7 |
replace = _XmTextFieldReplaceText(tf, ds->event, insertPosLeft,
|
|
Packit |
b099d7 |
insertPosRight, (char *) total_value,
|
|
Packit |
b099d7 |
(int)total_length, False);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
wc_total_length = _XmTextFieldCountCharacters(tf, total_value,
|
|
Packit |
b099d7 |
total_length);
|
|
Packit |
b099d7 |
wc_total_value = (wchar_t*)XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(wc_total_length+1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
wc_total_length = mbstowcs(wc_total_value, total_value, wc_total_length+1);
|
|
Packit |
b099d7 |
if (wc_total_length > 0)
|
|
Packit |
b099d7 |
replace = _XmTextFieldReplaceText(tf, ds->event, insertPosLeft,
|
|
Packit |
b099d7 |
insertPosRight, (char *)wc_total_value,
|
|
Packit |
b099d7 |
wc_total_length, False);
|
|
Packit |
b099d7 |
XtFree((char*)wc_total_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (replace) {
|
|
Packit |
b099d7 |
tf->text.pending_off = FALSE;
|
|
Packit |
b099d7 |
if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
|
|
Packit |
b099d7 |
cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, cursorPos,
|
|
Packit |
b099d7 |
True, True);
|
|
Packit |
b099d7 |
_XmTextFieldSetDestination((Widget)tf, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
transfer_rec->timestamp);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
if (tf->text.has_primary) {
|
|
Packit |
b099d7 |
if (transfer_rec->move && left < transfer_rec->insert_pos)
|
|
Packit |
b099d7 |
transfer_rec->insert_pos -= transfer_rec->num_chars;
|
|
Packit |
b099d7 |
if (TextF_CursorPosition(tf) < left ||
|
|
Packit |
b099d7 |
TextF_CursorPosition(tf) > right)
|
|
Packit |
b099d7 |
tf->text.pending_off = TRUE;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (!transfer_rec->move && !tf->text.add_mode &&
|
|
Packit |
b099d7 |
transfer_rec->num_chars != 0)
|
|
Packit |
b099d7 |
tf->text.prim_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 |
cb.reason = XmCR_VALUE_CHANGED;
|
|
Packit |
b099d7 |
cb.event = ds->event;
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (transfer_rec->move && local) {
|
|
Packit |
b099d7 |
TextF_MaxLength(tf) = max_length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (total_value && (total_value != (char*)ds->value))
|
|
Packit |
b099d7 |
XtFree(total_value);
|
|
Packit |
b099d7 |
if (ds->value) {
|
|
Packit |
b099d7 |
XtFree((char*) ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextFieldDrawInsertionPoint(tf, True);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define CR1228
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
DoStuff(Widget w,
|
|
Packit |
b099d7 |
#ifdef CR1228
|
|
Packit |
b099d7 |
XtPointer closure,
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
XtPointer closure, /* unused */
|
|
Packit |
b099d7 |
#endif
|
|
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 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
Packit |
b099d7 |
XmTextPosition right=0, left=0, replace_from, replace_to;
|
|
Packit |
b099d7 |
int prim_char_length = 0;
|
|
Packit |
b099d7 |
Boolean replace_res = False;
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
#ifdef CR1228
|
|
Packit |
b099d7 |
_XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
|
|
Packit |
b099d7 |
#endif
|
|
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 (!tf->text.has_focus && _XmGetFocusPolicy(w) == XmEXPLICIT)
|
|
Packit |
b099d7 |
(void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD] &&
|
|
Packit |
b099d7 |
ds->length == 0 &&
|
|
Packit |
b099d7 |
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 ds->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 && tf->text.selection_move) {
|
|
Packit |
b099d7 |
prim_char_length = prim_select->num_chars;
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, prim_select->position,
|
|
Packit |
b099d7 |
prim_select->position + prim_char_length,
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
tf->text.pending_off = False;
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL,
|
|
Packit |
b099d7 |
prim_select->position + prim_char_length,
|
|
Packit |
b099d7 |
True, True);
|
|
Packit |
b099d7 |
tf->text.prim_anchor = prim_select->position;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock(); /* for prim_select */
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
int max_length = 0;
|
|
Packit |
b099d7 |
Boolean local = tf->text.has_primary;
|
|
Packit |
b099d7 |
Boolean dest_disjoint = True;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tf->text.selection_move && local) {
|
|
Packit |
b099d7 |
max_length = TextF_MaxLength(tf);
|
|
Packit |
b099d7 |
TextF_MaxLength(tf) = INT_MAX;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
replace_from = replace_to = prim_select->position;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
if (tf->text.has_primary) {
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
if (tf->text.pending_delete &&
|
|
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 |
}
|
|
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 |
char *total_value;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if ((total_value =
|
|
Packit |
b099d7 |
_XmTextToLocaleText(w, ds->value, ds->type, ds->format, ds->length,
|
|
Packit |
b099d7 |
NULL))
|
|
Packit |
b099d7 |
!= NULL) {
|
|
Packit |
b099d7 |
if (tf->text.max_char_size == 1) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = strlen(total_value);
|
|
Packit |
b099d7 |
replace_res =
|
|
Packit |
b099d7 |
_XmTextFieldReplaceText (tf, ds->event,
|
|
Packit |
b099d7 |
replace_from,
|
|
Packit |
b099d7 |
replace_to,
|
|
Packit |
b099d7 |
total_value,
|
|
Packit |
b099d7 |
prim_select->num_chars,
|
|
Packit |
b099d7 |
ds->selection == atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree(total_value);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
wchar_t * wc_value;
|
|
Packit |
b099d7 |
int tmp_len = strlen(total_value) + 1;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = 0;
|
|
Packit |
b099d7 |
wc_value = (wchar_t*)XtMalloc ((unsigned) tmp_len * sizeof(wchar_t));
|
|
Packit |
b099d7 |
prim_select->num_chars = mbstowcs(wc_value, total_value, tmp_len);
|
|
Packit |
b099d7 |
if (prim_select->num_chars < 0)
|
|
Packit |
b099d7 |
prim_select->num_chars = 0;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
replace_res =
|
|
Packit |
b099d7 |
_XmTextFieldReplaceText(tf, ds->event,
|
|
Packit |
b099d7 |
replace_from,
|
|
Packit |
b099d7 |
replace_to,
|
|
Packit |
b099d7 |
(char*)wc_value,
|
|
Packit |
b099d7 |
prim_select->num_chars,
|
|
Packit |
b099d7 |
ds->selection == atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree((char*)wc_value);
|
|
Packit |
b099d7 |
XtFree(total_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else { /* initialize prim_select values for possible delete oper */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = 0;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (tf->text.max_char_size == 1) {
|
|
Packit |
b099d7 |
/* Note: length may be truncated during cast to int */
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = (int) ds->length;
|
|
Packit |
b099d7 |
replace_res =
|
|
Packit |
b099d7 |
_XmTextFieldReplaceText(tf, ds->event,
|
|
Packit |
b099d7 |
replace_from,
|
|
Packit |
b099d7 |
replace_to,
|
|
Packit |
b099d7 |
(char *) ds->value,
|
|
Packit |
b099d7 |
prim_select->num_chars,
|
|
Packit |
b099d7 |
ds->selection == atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
wchar_t * wc_value;
|
|
Packit |
b099d7 |
char *temp;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
temp = XtMalloc((unsigned) ds->length + 1);
|
|
Packit |
b099d7 |
(void)memcpy((void*)temp, (void*)ds->value, (size_t)ds->length);
|
|
Packit |
b099d7 |
temp[(size_t)ds->length] = '\0';
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wc_value = (wchar_t*)XtMalloc ((unsigned)
|
|
Packit |
b099d7 |
((ds->length + 1) * sizeof(wchar_t)));
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
prim_select->num_chars = mbstowcs(wc_value, (char *) temp,
|
|
Packit |
b099d7 |
(size_t) ds->length+1);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (prim_select->num_chars < 0)
|
|
Packit |
b099d7 |
prim_select->num_chars = 0;
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
wc_value[prim_select->num_chars] = 0;
|
|
Packit |
b099d7 |
replace_res =
|
|
Packit |
b099d7 |
_XmTextFieldReplaceText(tf, ds->event,
|
|
Packit |
b099d7 |
replace_from,
|
|
Packit |
b099d7 |
replace_to,
|
|
Packit |
b099d7 |
(char*)wc_value,
|
|
Packit |
b099d7 |
prim_select->num_chars,
|
|
Packit |
b099d7 |
ds->selection == atoms[XmACLIPBOARD]);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree(temp);
|
|
Packit |
b099d7 |
XtFree((char*)wc_value);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (replace_res) {
|
|
Packit |
b099d7 |
XmTextPosition cursorPos = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
tf->text.pending_off = FALSE;
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
cursorPos = replace_from + prim_select->num_chars;
|
|
Packit |
b099d7 |
if (prim_select->num_chars > 0 && !tf->text.selection_move) {
|
|
Packit |
b099d7 |
_XmTextFieldSetCursorPosition(tf, NULL, cursorPos,
|
|
Packit |
b099d7 |
True, True);
|
|
Packit |
b099d7 |
(void) _XmTextFieldSetDestination(w, cursorPos, prim_select->time);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
(void) _XmTextFieldSetDestination(w, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
if (tf->text.has_primary) {
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
if (left != right && (!dest_disjoint || !tf->text.add_mode))
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
_XmTextFieldStartSelection(tf, TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
TextF_CursorPosition(tf),
|
|
Packit |
b099d7 |
prim_select->time);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (tf->text.selection_move && left < prim_select->position)
|
|
Packit |
b099d7 |
prim_select->position -= prim_select->num_chars;
|
|
Packit |
b099d7 |
if (left <= cursorPos && right >= cursorPos)
|
|
Packit |
b099d7 |
tf->text.pending_off = TRUE;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
if (ds->selection == atoms[XmACLIPBOARD])
|
|
Packit |
b099d7 |
tf->text.prim_anchor = replace_from;
|
|
Packit |
b099d7 |
else if (!tf->text.selection_move && !tf->text.add_mode &&
|
|
Packit |
b099d7 |
prim_select->num_chars != 0)
|
|
Packit |
b099d7 |
tf->text.prim_anchor = prim_select->position;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
cb.reason = XmCR_VALUE_CHANGED;
|
|
Packit |
b099d7 |
cb.event = ds->event;
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget) tf, TextF_ValueChangedCallback(tf),
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
prim_select->num_chars = 0; /* Stop SetPrimarySelection from doing
|
|
Packit |
b099d7 |
anything */
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tf->text.selection_move && local) {
|
|
Packit |
b099d7 |
TextF_MaxLength(tf) = max_length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
HandleTargets(Widget w, 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 |
XmTextFieldWidget tf = (XmTextFieldWidget) w;
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
XmTextPosition left, right;
|
|
Packit |
b099d7 |
Boolean supports_encoding_data = False;
|
|
Packit |
b099d7 |
Boolean supports_CT = False;
|
|
Packit |
b099d7 |
Boolean supports_utf8_string = False;
|
|
Packit |
b099d7 |
Boolean supports_text = False;
|
|
Packit |
b099d7 |
XPoint *point = (XPoint *)closure;
|
|
Packit |
b099d7 |
Atom *atom_ptr;
|
|
Packit |
b099d7 |
Atom targets[2];
|
|
Packit |
b099d7 |
XmTextPosition select_pos;
|
|
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; /* 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 *)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 = XmTextFieldXYToPos((Widget)tf, (Position)point->x, 0);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
select_pos = TextF_CursorPosition(tf);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (ds->selection != atoms[XmACLIPBOARD]) {
|
|
Packit |
b099d7 |
left = tf->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = tf->text.prim_pos_right;
|
|
Packit |
b099d7 |
if (tf->text.has_primary &&
|
|
Packit |
b099d7 |
left != right && select_pos > left && 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 (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 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
XtFree((char *)ds->value);
|
|
Packit |
b099d7 |
ds->value = NULL;
|
|
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 |
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 |
Display *display = XtDisplay(w);
|
|
Packit |
b099d7 |
Boolean doTransfer = False;
|
|
Packit |
b099d7 |
_XmTextDropTransferRec *transfer_rec;
|
|
Packit |
b099d7 |
XtPointer tid = ds->transfer_id;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
drag_cont = cb->dragContext;
|
|
Packit |
b099d7 |
transfer_rec = (_XmTextDropTransferRec *) NULL;
|
|
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 = XmTextFieldXYToPos(w, cb->x, 0);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
left = ((XmTextFieldWidget)w)->text.prim_pos_left;
|
|
Packit |
b099d7 |
right = ((XmTextFieldWidget)w)->text.prim_pos_right;
|
|
Packit |
b099d7 |
if (cb->operation & XmDROP_MOVE && w == initiator &&
|
|
Packit |
b099d7 |
((XmTextFieldWidget)w)->text.has_primary &&
|
|
Packit |
b099d7 |
left != right && insert_pos >= left && insert_pos <= right) {
|
|
Packit |
b099d7 |
/*EMPTY*/
|
|
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 |
|
|
Packit |
b099d7 |
Atom atoms[XtNumber(atom_names)];
|
|
Packit |
b099d7 |
Atom CS_OF_ENCODING = XmeGetEncodingAtom(w);
|
|
Packit |
b099d7 |
Boolean encoding_found = False;
|
|
Packit |
b099d7 |
Boolean utf8_string_found = False;
|
|
Packit |
b099d7 |
Boolean c_text_found = False;
|
|
Packit |
b099d7 |
Boolean string_found = False;
|
|
Packit |
b099d7 |
Boolean text_found = False;
|
|
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 |
/* 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 |
transfer_rec->move = False;
|
|
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 |
if (!encoding_found) {
|
|
Packit |
b099d7 |
#ifdef UTF8_SUPPORTED
|
|
Packit |
b099d7 |
if (utf8_string_found)
|
|
Packit |
b099d7 |
desiredTarget = atoms[XmAUTF8_STRING];
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
if (c_text_found)
|
|
Packit |
b099d7 |
desiredTarget = atoms[XmACOMPOUND_TEXT];
|
|
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 |
|
|
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 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
TextFieldConvertCallback(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, XmA_MOTIF_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmACOMPOUND_TEXT, XmATEXT, XmATARGETS, 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, XmS_MOTIF_CLIPBOARD_TARGETS,
|
|
Packit |
b099d7 |
XmSCOMPOUND_TEXT, XmSTEXT, XmSTARGETS, 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 |
_XmTextFieldLoseSelection(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 |
_XmTextFieldHandleSecondaryFinished(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 (!_XmTextFieldConvert(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 |
TextFieldDestinationCallback(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 |
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 |
} 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) TextFieldSecondaryWrapper,
|
|
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) TextFieldSecondaryWrapper,
|
|
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 |
_XmTextFieldInstallTransferTrait(void)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmeTraitSet((XtPointer)xmTextFieldWidgetClass, XmQTtransfer,
|
|
Packit |
b099d7 |
(XtPointer) &textFieldTT);
|
|
Packit |
b099d7 |
}
|