/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <Xm/XmosP.h>
#include <X11/Xatom.h>
#include <X11/ShellP.h>
#include <X11/VendorP.h>
#include <X11/keysym.h>
#include <X11/Xresource.h>
#include "XmI.h"
#include <Xm/AtomMgr.h>
#include <Xm/CutPaste.h>
#include <Xm/DragC.h>
#include <Xm/DragIcon.h>
#include <Xm/DropSMgr.h>
#include <Xm/DropTrans.h>
#include <Xm/Display.h>
#include <Xm/ManagerP.h>
#include <Xm/ScreenP.h>
#include <Xm/DragIconP.h>
#include <Xm/TransltnsP.h>
#include <Xm/DrawP.h>
#include <Xm/Ext.h>
#include <Xm/DataFSelP.h>
#include <Xm/DataFP.h>
#include <Xm/TraitP.h>
#include <Xm/AccTextT.h>
#include <Xm/TransferT.h>
#include <Xm/SpecRenderT.h>
#include <Xm/VaSimpleP.h>
#include "TextFI.h"
#include "TextFSelI.h"
#include "XmStringI.h"
#include "ImageCachI.h"
#ifdef USE_XFT
#include <X11/Xft/Xft.h>
#include "XmRenderTI.h"
#endif
#include "MessagesI.h"
#define FIX_1531
/*
* Stuff from various internal motif headers that we need to declare
*/
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#define TEXT_MAX_INSERT_SIZE 64 /* Size of buffer for XLookupString. */
/*
* Various DataField messages macro
*/
#define MSG1 _XmMMsgDataF_0000
#define MSG2 _XmMMsgDataF_0001
#define MSG3 _XmMMsgDataF_0002
#define MSG4 _XmMMsgDataF_0003
#define MSG5 _XmMMsgDataF_0004
#define MSG6 _XmMMsgDataF_0005
#define MSG7 _XmMMsgDataF_0006
#define WC_MSG1 _XmMMsgDataFWcs_0000
#define WC_MSG2 _XmMMsgDataFWcs_0001
#define GRABKBDERROR _XmMMsgRowColText_0024
#ifdef _XmConst
#undef _XmConst
#define _XmConst
#else
#define _XmConst
#endif
#ifdef _NO_PROTO
extern Boolean _XmParentProcess();
extern Boolean _XmMgrTraversal();
extern unsigned char _XmGetFocusPolicy();
extern void _XmPrimitiveFocusIn();
extern void _XmPrimitiveEnter();
extern void _XmPrimitiveLeave();
extern Boolean _XmGetImage();
extern Boolean _XmGetIconControlInfo();
extern unsigned char _XmGetAudibleWarning();
extern void _XmSetDestination();
#else
extern Boolean _XmParentProcess(Widget, XmParentProcessData);
extern Boolean _XmMgrTraversal(Widget, XmTraversalDirection);
extern unsigned char _XmGetFocusPolicy(Widget);
extern void _XmPrimitiveFocusIn(Widget, XEvent *, String *, Cardinal *);
extern void _XmPrimitiveEnter(Widget, XEvent *, String *, Cardinal *);
extern void _XmPrimitiveLeave(Widget, XEvent *, String *, Cardinal *);
extern Boolean _XmGetImage(Screen *, char *, XImage **);
extern Boolean _XmGetIconControlInfo(
Screen *screen,
Boolean *useMaskRtn,
Boolean *useMultiColorIconsRtn,
Boolean *useIconFileCacheRtn) ;
extern unsigned char _XmGetAudibleWarning(Widget);
extern void _XmSetDestination(Display *, Widget);
#endif
/*
* Back to the original XmTextField code
*/
#define TEXT_INCREMENT 32
#define PRIM_SCROLL_INTERVAL 100
#define SEC_SCROLL_INTERVAL 200
#define XmDYNAMIC_BOOL 255
#define EventBindings1 _XmDataF_EventBindings1
#define EventBindings2 _XmDataF_EventBindings2
#define EventBindings3 _XmDataF_EventBindings3
#define EventBindings4 _XmDataF_EventBindings4
typedef struct {
Boolean has_destination;
XmTextPosition position;
int replace_length;
Boolean quick_key;
} TextFDestDataRec, *TextFDestData;
typedef struct {
XmDataFieldWidget tf;
} TextFGCDataRec, *TextFGCData;
/******** Static Function Declarations ********/
#ifdef _NO_PROTO
static void df_ValidateAndMove() ;
static int _XmDataFieldCountCharacters() ;
static void df_MakeCopy() ;
static void df_WcsMakeCopy() ;
static void df_FreeContextData() ;
static TextFDestData df_GetTextFDestData() ;
static void df_SetDropContext() ;
static void df_DeleteDropContext() ;
static TextFGCData df_GetTextFGCData() ;
static _XmHighlightRec * df_FindHighlight() ;
static void df_InsertHighlight() ;
static void DataFieldSetHighlight() ;
static Boolean df_GetXYFromPos() ;
static Boolean df_CurrentCursorState() ;
static void df_PaintCursor() ;
static int _XmGetImage();
static void df_BlinkInsertionPoint() ;
static void df_HandleTimer() ;
static void df_ChangeBlinkBehavior() ;
static void df_GetRect() ;
static void df_CheckHasRect() ;
static void df_XmSetFullGC() ;
static void df_XmSetMarginGC() ;
static void df_XmResetSaveGC() ;
static void df_XmSetNormGC() ;
#ifdef FIX_1381
static void df_XmSetShadowGC() ;
#endif
static void df_XmSetInvGC() ;
static void df_DrawText() ;
static int df_FindPixelLength() ;
static void df_DrawTextSegment() ;
static void df_RedisplayText() ;
static void df_ComputeSize() ;
static XtGeometryResult df_TryResize() ;
static Boolean df_AdjustText() ;
static void df_AdjustSize() ;
static Boolean df_ModifyVerify() ;
static void df_ResetClipOrigin() ;
static void df_InvertImageGC() ;
static void df_ResetImageGC() ;
static void df_SetCursorPosition() ;
static void df_VerifyBounds() ;
static XmTextPosition df_GetPosFromX() ;
static XmTextPosition RightAlignedGetPosFromX() ;
static Boolean df_SetDestination() ;
static Boolean df_VerifyLeave() ;
static Boolean _XmDataFieldIsWordBoundary() ;
static int _XmGetImage(Screen *, char *, XImage **);
static Boolean _XmDataFieldIsWSpace() ;
static void df_FindWord() ;
static void df_FindPrevWord() ;
static void df_FindNextWord() ;
static void df_CheckDisjointSelection() ;
static Boolean df_NeedsPendingDelete() ;
static Boolean df_NeedsPendingDeleteDisjoint() ;
static Time df_GetServerTime() ;
static void df_InsertChar() ;
static void df_InsertString() ;
static void df_DeletePrevChar() ;
static void df_DeleteNextChar() ;
static void df_DeletePrevWord() ;
static void df_DeleteNextWord() ;
static void df_DeleteToEndOfLine() ;
static void df_DeleteToStartOfLine() ;
static void df_ProcessCancel() ;
static void df_Activate() ;
static void df_SetAnchorBalancing() ;
static void df_SetNavigationAnchor() ;
static void df_CompleteNavigation() ;
static void df_SimpleMovement() ;
static void df_BackwardChar() ;
static void df_ForwardChar() ;
static void df_BackwardWord() ;
static void df_ForwardWord() ;
static void df_EndOfLine() ;
static void df_BeginningOfLine() ;
static void df_SetSelection() ;
static void df_ProcessHorizontalParams() ;
static void df_ProcessSelectParams() ;
static void df_KeySelection() ;
static void df_TextFocusIn() ;
static void df_TextFocusOut() ;
static void df_SetScanIndex() ;
static void df_ExtendScanSelection() ;
static void df_SetScanSelection() ;
static void df_StartPrimary() ;
static void df_MoveDestination() ;
static void df_ExtendPrimary() ;
static void df_ExtendEnd() ;
static void df_DoExtendedSelection() ;
static void df_DoSecondaryExtend() ;
static void df_BrowseScroll() ;
static Boolean df_CheckTimerScrolling() ;
static void df_RestorePrimaryHighlight() ;
static void df_StartDrag() ;
static void df_StartSecondary() ;
static void df_ProcessBDrag() ;
static void df_ExtendSecondary() ;
static void df_DoStuff() ;
static void df_Stuff() ;
static void df_HandleSelectionReplies() ;
static void df_SecondaryNotify() ;
static void df_HandleTargets() ;
static void df_ProcessBDragRelease() ;
static void df_ProcessCopy() ;
static void df_ProcessMove() ;
static void df_DeleteSelection() ;
static void df_ClearSelection() ;
static void df_PageRight() ;
static void df_PageLeft() ;
static void df_CopyPrimary() ;
static void df_CutPrimary() ;
static void df_SetAnchor() ;
static void df_ToggleOverstrike() ;
static void df_ToggleAddMode() ;
static void df_SelectAll() ;
static void df_DeselectAll() ;
static void df_VoidAction() ;
static void df_CutClipboard() ;
static void df_CopyClipboard() ;
static void df_PasteClipboard() ;
static void df_TraverseDown() ;
static void df_TraverseUp() ;
static void df_TraverseHome() ;
static void df_TraverseNextTabGroup() ;
static void df_TraversePrevTabGroup() ;
static void df_TextEnter() ;
static void df_TextLeave() ;
static void df_ClassPartInitialize() ;
static void df_Validates() ;
static Boolean df_LoadFontMetrics() ;
static void df_ValidateString() ;
static void df_InitializeTextStruct() ;
static Pixmap df_GetClipMask() ;
static void df_LoadGCs() ;
static void df_MakeIBeamOffArea() ;
static void df_MakeIBeamStencil() ;
static void df_MakeAddModeCursor() ;
static void df_MakeCursors() ;
static void df_DropDestroyCB() ;
static void df_DropTransferCallback() ;
static void df_HandleDrop() ;
static void df_DragProcCallback() ;
static void df_DropProcCallback() ;
static void df_RegisterDropSite() ;
static void df_Initialize() ;
static void df_Realize() ;
static void df_Destroy() ;
static void df_Resize() ;
static XtGeometryResult df_QueryGeometry() ;
static void DataFieldExpose() ;
static Boolean df_SetValues() ;
static Boolean DataFieldGetBaselines() ;
static Boolean DataFieldGetDisplayRect() ;
static void DataFieldMarginsProc() ;
static Boolean DataFieldRemove();
static void PictureVerifyCallback();
static void ClassInit();
static void XmDataFieldSetStringWcs();
#else
static void df_ValidateAndMove(
Widget w,
XEvent *ev,
String *args,
Cardinal *nargs) ;
static int _XmDataFieldCountCharacters(
XmDataFieldWidget tf,
char *ptr,
int n_bytes) ;
static void df_MakeCopy(
Widget w,
int n,
XtArgVal *value) ;
static void df_WcsMakeCopy(
Widget w,
int n,
XtArgVal *value) ;
static void df_FreeContextData(
Widget w,
XtPointer clientData,
XtPointer callData) ;
static TextFDestData df_GetTextFDestData(
Widget w) ;
static void df_SetDropContext(
Widget w) ;
static void df_DeleteDropContext(
Widget w) ;
static TextFGCData df_GetTextFGCData(
Widget w) ;
static _XmHighlightRec * df_FindHighlight(
XmDataFieldWidget w,
XmTextPosition position) ;
static void df_InsertHighlight(
XmDataFieldWidget w,
XmTextPosition position,
XmHighlightMode mode) ;
static void DataFieldSetHighlight(
XmDataFieldWidget tf,
XmTextPosition left,
XmTextPosition right,
XmHighlightMode mode) ;
static Boolean df_GetXYFromPos(
XmDataFieldWidget tf,
XmTextPosition position,
Position *x,
Position *y) ;
static Boolean df_CurrentCursorState(
XmDataFieldWidget tf) ;
static void df_PaintCursor(
XmDataFieldWidget tf) ;
static void df_BlinkInsertionPoint(
XmDataFieldWidget tf) ;
static void df_HandleTimer(
XtPointer closure,
XtIntervalId *id) ;
static void df_ChangeBlinkBehavior(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int turn_on) ;
#else
Boolean turn_on) ;
#endif /* NeedWidePrototypes */
static void df_GetRect(
XmDataFieldWidget tf,
XRectangle *rect) ;
static void df_CheckHasRect(
XmDataFieldWidget tf) ;
static void df_XmSetFullGC(
XmDataFieldWidget tf,
GC gc) ;
static void df_XmSetMarginGC(
XmDataFieldWidget tf,
GC gc) ;
static void df_XmResetSaveGC(
XmDataFieldWidget tf,
GC gc) ;
static void df_XmSetNormGC(
XmDataFieldWidget tf,
GC gc,
#if NeedWidePrototypes
int change_stipple,
int stipple) ;
#else
Boolean change_stipple,
Boolean stipple) ;
#endif /* NeedWidePrototypes */
#ifdef FIX_1381
static void df_XmSetShadowGC(
XmDataFieldWidget tf,
GC gc);
#endif
static void df_XmSetInvGC(
XmDataFieldWidget tf,
GC gc) ;
static void df_DrawText(
XmDataFieldWidget tf,
GC gc,
int x,
int y,
char *string,
int length) ;
static int df_FindPixelLength(
XmDataFieldWidget tf,
char *string,
int length) ;
static void df_DrawTextSegment(
XmDataFieldWidget tf,
XmHighlightMode mode,
XmTextPosition prev_seg_start,
XmTextPosition seg_start,
XmTextPosition seg_end,
XmTextPosition next_seg,
#if NeedWidePrototypes
int stipple,
#else
Boolean stipple,
#endif /* NeedWidePrototypes */
int y,
int *x) ;
static void df_RedisplayText(
XmDataFieldWidget tf,
XmTextPosition start,
XmTextPosition end) ;
static void df_ComputeSize(
XmDataFieldWidget tf,
Dimension *width,
Dimension *height) ;
static XtGeometryResult df_TryResize(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int width,
int height) ;
#else
Dimension width,
Dimension height) ;
#endif /* NeedWidePrototypes */
static Boolean df_AdjustText(
XmDataFieldWidget tf,
XmTextPosition position,
#if NeedWidePrototypes
int flag) ;
#else
Boolean flag) ;
#endif /* NeedWidePrototypes */
static void df_AdjustSize(
XmDataFieldWidget tf) ;
static Boolean df_ModifyVerify(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition *replace_prev,
XmTextPosition *replace_next,
char **insert,
int *insert_length,
XmTextPosition *newInsert,
int *free_insert) ;
static void df_ResetClipOrigin(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int clip_mask_reset) ;
#else
Boolean clip_mask_reset) ;
#endif /* NeedWidePrototypes */
static void df_InvertImageGC(
XmDataFieldWidget tf) ;
static void df_ResetImageGC(
XmDataFieldWidget tf) ;
static void df_SetCursorPosition(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition position,
#if NeedWidePrototypes
int adjust_flag,
int call_cb,
int set_dest) ;
#else
Boolean adjust_flag,
Boolean call_cb,
Boolean set_dest) ;
#endif /* NeedWidePrototypes */
static void df_VerifyBounds(
XmDataFieldWidget tf,
XmTextPosition *from,
XmTextPosition *to) ;
static XmTextPosition df_GetPosFromX(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int x) ;
#else
Position x) ;
#endif /* NeedWidePrototypes */
static XmTextPosition RightAlignedGetPosFromX(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int x) ;
#else
Position x) ;
#endif /* NeedWidePrototypes */
static Boolean df_SetDestination(
Widget w,
XmTextPosition position,
#if NeedWidePrototypes
int disown,
#else
Boolean disown,
#endif /* NeedWidePrototypes */
Time set_time) ;
static Boolean df_VerifyLeave(
XmDataFieldWidget tf,
XEvent *event) ;
static Boolean _XmDataFieldIsWordBoundary(
XmDataFieldWidget tf,
XmTextPosition pos1,
XmTextPosition pos2) ;
static Boolean _XmDataFieldIsWSpace(
wchar_t wide_char,
wchar_t *white_space,
int num_entries) ;
static void df_FindWord(
XmDataFieldWidget tf,
XmTextPosition begin,
XmTextPosition *left,
XmTextPosition *right) ;
static void df_FindPrevWord(
XmDataFieldWidget tf,
XmTextPosition *left,
XmTextPosition *right) ;
static void df_FindNextWord(
XmDataFieldWidget tf,
XmTextPosition *left,
XmTextPosition *right) ;
static void df_CheckDisjointSelection(
Widget w,
XmTextPosition position,
Time sel_time) ;
static Boolean df_NeedsPendingDelete(
XmDataFieldWidget tf) ;
static Boolean df_NeedsPendingDeleteDisjoint(
XmDataFieldWidget tf) ;
static Time df_GetServerTime(
Widget w) ;
static void df_InsertChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_InsertString(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeletePrevChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeleteNextChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeletePrevWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeleteNextWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeleteToEndOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeleteToStartOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ProcessCancel(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_Activate(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_SetAnchorBalancing(
XmDataFieldWidget tf,
XmTextPosition position) ;
static void df_SetNavigationAnchor(
XmDataFieldWidget tf,
XmTextPosition position,
#if NeedWidePrototypes
int extend) ;
#else
Boolean extend) ;
#endif /* NeedWidePrototypes */
static void df_CompleteNavigation(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition position,
Time time,
#if NeedWidePrototypes
int extend) ;
#else
Boolean extend) ;
#endif /* NeedWidePrototypes */
static void df_SimpleMovement(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params,
XmTextPosition cursorPos,
XmTextPosition position) ;
static void df_BackwardChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ForwardChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_BackwardWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ForwardWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_EndOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_BeginningOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_SetSelection(
XmDataFieldWidget tf,
XmTextPosition left,
XmTextPosition right,
#if NeedWidePrototypes
int redisplay) ;
#else
Boolean redisplay) ;
#endif /* NeedWidePrototypes */
static void df_ProcessHorizontalParams(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params,
XmTextPosition *left,
XmTextPosition *right,
XmTextPosition *position) ;
static void df_ProcessSelectParams(
Widget w,
XEvent *event,
XmTextPosition *left,
XmTextPosition *right,
XmTextPosition *position) ;
static void df_KeySelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TextFocusIn(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TextFocusOut(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_SetScanIndex(
XmDataFieldWidget tf,
XEvent *event) ;
static void df_ExtendScanSelection(
XmDataFieldWidget tf,
XEvent *event) ;
static void df_SetScanSelection(
XmDataFieldWidget tf,
XEvent *event) ;
static void df_StartPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_MoveDestination(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ExtendPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ExtendEnd(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DoExtendedSelection(
Widget w,
Time time) ;
static void df_DoSecondaryExtend(
Widget w,
Time ev_time) ;
static void df_BrowseScroll(
XtPointer closure,
XtIntervalId *id) ;
static Boolean df_CheckTimerScrolling(
Widget w,
XEvent *event) ;
static void df_RestorePrimaryHighlight(
XmDataFieldWidget tf,
XmTextPosition prim_left,
XmTextPosition prim_right) ;
static void df_StartDrag(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void df_StartSecondary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ProcessBDrag(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ExtendSecondary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DoStuff(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format) ;
static void df_Stuff(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_HandleSelectionReplies(
Widget w,
XtPointer closure,
XEvent *event,
Boolean *cont) ;
static void df_SecondaryNotify(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_HandleTargets(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format) ;
static void df_ProcessBDragRelease(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void df_ProcessCopy(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ProcessMove(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeleteSelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ClearSelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_PageRight(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_PageLeft(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_CopyPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_CutPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_SetAnchor(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ToggleOverstrike(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_ToggleAddMode(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_SelectAll(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_DeselectAll(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_VoidAction(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_CutClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_CopyClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_PasteClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TraverseDown(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TraverseUp(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TraverseHome(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TraverseNextTabGroup(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TraversePrevTabGroup(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params) ;
static void df_TextEnter(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void df_TextLeave(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params) ;
static void df_ClassPartInitialize(
WidgetClass w_class) ;
static void df_Validates(
XmDataFieldWidget tf) ;
static Boolean df_LoadFontMetrics(
XmDataFieldWidget tf) ;
static void df_ValidateString(
XmDataFieldWidget tf,
char *value,
#if NeedWidePrototypes
int is_wchar) ;
#else
Boolean is_wchar) ;
#endif /* NeedWidePrototypes */
static void df_InitializeTextStruct(
XmDataFieldWidget tf) ;
static Pixmap df_GetClipMask(
XmDataFieldWidget tf,
char *pixmap_name) ;
static void df_LoadGCs(
XmDataFieldWidget tf,
Pixel background,
Pixel foreground) ;
static void df_MakeIBeamOffArea(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int width,
int height) ;
#else
Dimension width,
Dimension height) ;
#endif /* NeedWidePrototypes */
static void df_MakeIBeamStencil(
XmDataFieldWidget tf,
int line_width) ;
static void df_MakeAddModeCursor(
XmDataFieldWidget tf,
int line_width) ;
static void df_MakeCursors(
XmDataFieldWidget tf) ;
static void df_DropDestroyCB(
Widget w,
XtPointer clientData,
XtPointer callData) ;
static void df_DropTransferCallback(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format) ;
static void df_HandleDrop(
Widget w,
XmDropProcCallbackStruct *cb) ;
static void df_DragProcCallback(
Widget w,
XtPointer client,
XtPointer call) ;
static void df_DropProcCallback(
Widget w,
XtPointer client,
XtPointer call) ;
static void df_RegisterDropSite(
Widget w) ;
static void df_Initialize(
Widget request,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static void df_Realize(
Widget w,
XtValueMask *valueMask,
XSetWindowAttributes *attributes) ;
static void df_Destroy(
Widget wid) ;
static void df_Resize(
Widget w) ;
static XtGeometryResult df_QueryGeometry(
Widget w,
XtWidgetGeometry *intended,
XtWidgetGeometry *reply) ;
static void DataFieldExpose(
Widget w,
XEvent *event,
Region region) ;
static Boolean df_SetValues(
Widget old,
Widget request,
Widget new_w,
ArgList args,
Cardinal *num_args) ;
static Boolean DataFieldGetBaselines(
Widget w,
Dimension **baselines,
int *line_count) ;
static Boolean DataFieldGetDisplayRect(
Widget w,
XRectangle *display_rect) ;
static void DataFieldMarginsProc(
Widget w,
XmBaselineMargins *margins_rec) ;
static XtPointer DataFieldGetValue(Widget w,
int format);
static void DataFieldSetValue(Widget w,
XtPointer s,
int format);
static int DataFieldPreferredValue(Widget w);
static void CheckSetRenderTable(Widget wid,
int offset,
XrmValue *value);
static Boolean DataFieldRemove(Widget w,
XEvent *event);
static void PictureVerifyCallback(Widget w,
XtPointer call_d, XtPointer client_d);
static void ClassInit(void);
static void XmDataFieldSetStringWcs(Widget w, wchar_t *wc_value);
#endif /* _NO_PROTO */
/***************** End Static Function Declarations ************/
static XmTextScanType df_sarray[] = {
XmSELECT_POSITION, XmSELECT_WORD, XmSELECT_LINE
};
static int df_sarraysize = XtNumber(df_sarray);
static XContext _XmDataFDestContext = 0;
static XContext _XmDataFGCContext = 0;
static XContext _XmDataFDNDContext = 0;
/* default translations and action recs */
static XtActionsRec data_actions[] = {
/* ICS DataField actions */
{"ValidateAndMove", df_ValidateAndMove},
/* Text Replacing Bindings */
{"self-insert", df_InsertChar},
{"insert-string", df_InsertString},
{"delete-previous-character", df_DeletePrevChar},
{"delete-next-character", df_DeleteNextChar},
{"delete-previous-word", df_DeletePrevWord},
{"delete-next-word", df_DeleteNextWord},
{"delete-to-end-of-line", df_DeleteToEndOfLine},
{"delete-to-start-of-line", df_DeleteToStartOfLine},
/* Miscellaneous Bindings */
{"activate", df_Activate},
{"process-cancel", df_ProcessCancel},
{"process-bdrag", df_ProcessBDrag},
/* Motion Bindings */
{"backward-character", df_BackwardChar},
{"forward-character", df_ForwardChar},
{"backward-word", df_BackwardWord},
{"forward-word", df_ForwardWord},
{"end-of-line", df_EndOfLine},
{"beginning-of-line", df_BeginningOfLine},
{"page-left", df_PageLeft},
{"page-right", df_PageRight},
/* Selection Bindings */
{"key-select", df_KeySelection},
{"grab-focus", df_StartPrimary},
{"move-destination", df_MoveDestination},
{"extend-start", df_ExtendPrimary},
{"extend-adjust", df_ExtendPrimary},
{"extend-end", df_ExtendEnd},
{"delete-selection", df_DeleteSelection},
{"clear-selection", df_ClearSelection},
{"cut-primary", df_CutPrimary},
{"copy-primary", df_CopyPrimary},
{"set-anchor", df_SetAnchor},
{"toggle-overstrike", df_ToggleOverstrike},
{"toggle-add-mode", df_ToggleAddMode},
{"select-all", df_SelectAll},
{"deselect-all", df_DeselectAll},
/* Quick Cut and Paste Bindings */
{"secondary-start", df_StartSecondary},
{"secondary-adjust", df_ExtendSecondary},
{"copy-to", df_ProcessCopy},
{"move-to", df_ProcessMove},
{"quick-cut-set", df_VoidAction},
{"quick-copy-set", df_VoidAction},
{"do-quick-action", df_VoidAction},
/* Clipboard Bindings */
{"cut-clipboard", df_CutClipboard},
{"copy-clipboard", df_CopyClipboard},
{"paste-clipboard", df_PasteClipboard},
/* Traversal */
{"traverse-next", df_TraverseDown},
{"traverse-prev", df_TraverseUp},
{"traverse-home", df_TraverseHome},
{"next-tab-group", df_TraverseNextTabGroup},
{"prev-tab-group", df_TraversePrevTabGroup},
/* Focus */
{"focusIn", df_TextFocusIn},
{"focusOut", df_TextFocusOut},
{"enter", df_TextEnter},
{"leave", df_TextLeave},
};
static XtResource resources[] =
{
{
XmNpicture, XmCPicture, XmRString, sizeof(String),
XtOffsetOf(XmDataFieldRec, data.picture_source),
XmRImmediate, (XtPointer) NULL
},
{
XmNautoFill, XmCAutoFill, XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, data.auto_fill),
XmRImmediate, (XtPointer) True
},
{
XmNalignment, XmCAlignment, XmRAlignment, sizeof(unsigned char),
XtOffsetOf(XmDataFieldRec, data.alignment), XmRImmediate,
(XtPointer) XmALIGNMENT_BEGINNING
},
{
XmNpictureErrorCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, data.picture_error_cb), XmRCallback,
(XtPointer) NULL
},
{
XmNvalidateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, data.validate_cb),
XmRCallback, (XtPointer) NULL
},
/* the following are undocumented overrides of XmTextField resources */
{
XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.activate_callback),
XmRCallback, NULL
},
{
XmNlosingFocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.losing_focus_callback),
XmRCallback, NULL
},
{
XmNfocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.focus_callback),
XmRCallback, NULL
},
{
XmNmodifyVerifyCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.modify_verify_callback),
XmRCallback, NULL
},
{
XmNmodifyVerifyCallbackWcs, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.wcs_modify_verify_callback),
XmRCallback, NULL
},
{
XmNmotionVerifyCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.motion_verify_callback),
XmRCallback, NULL
},
{
XmNgainPrimaryCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.gain_primary_callback),
XmRCallback, NULL
},
{
XmNlosePrimaryCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.lose_primary_callback),
XmRCallback, NULL
},
{
XmNvalueChangedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
XtOffsetOf(XmDataFieldRec, text.value_changed_callback),
XmRCallback, NULL
},
{
XmNvalue, XmCValue, XmRString, sizeof(String),
XtOffsetOf(XmDataFieldRec, text.value),
XmRString, ""
},
{
XmNvalueWcs, XmCValueWcs, XmRValueWcs, sizeof(wchar_t*),
XtOffsetOf(XmDataFieldRec, text.wc_value),
XmRString, NULL
},
{
XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension),
XtOffsetOf(XmDataFieldRec, text.margin_height),
XmRImmediate, (XtPointer) 5
},
{
XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension),
XtOffsetOf(XmDataFieldRec, text.margin_width),
XmRImmediate, (XtPointer) 5
},
{
XmNcursorPosition, XmCCursorPosition, XmRTextPosition, sizeof (XmTextPosition),
XtOffsetOf(XmDataFieldRec, text.cursor_position),
XmRImmediate, (XtPointer) 0
},
{
XmNcolumns, XmCColumns, XmRShort, sizeof(short),
XtOffsetOf(XmDataFieldRec, text.columns),
XmRImmediate, (XtPointer) 20
},
{
XmNmaxLength, XmCMaxLength, XmRInt, sizeof(int),
XtOffsetOf(XmDataFieldRec, text.max_length),
XmRImmediate, (XtPointer) INT_MAX
},
{
XmNblinkRate, XmCBlinkRate, XmRInt, sizeof(int),
XtOffsetOf(XmDataFieldRec, text.blink_rate),
XmRImmediate, (XtPointer) 500
},
{
"pri.vate", "Pri.vate", XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.check_set_render_table),
XmRImmediate, (XtPointer) False
},
{
XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList),
XtOffsetOf(XmDataFieldRec, text.font_list),
XmRCallProc, (XtPointer)CheckSetRenderTable
},
{
XmNrenderTable, XmCRenderTable, XmRRenderTable, sizeof(XmRenderTable),
XtOffsetOf(XmDataFieldRec, text.font_list),
XmRCallProc, (XtPointer)CheckSetRenderTable
},
{
XmNselectionArray, XmCSelectionArray, XmRPointer,
sizeof(XtPointer),
XtOffsetOf(XmDataFieldRec, text.selection_array),
XmRImmediate, (XtPointer) df_sarray
},
{
XmNselectionArrayCount, XmCSelectionArrayCount, XmRInt, sizeof(int),
XtOffsetOf(XmDataFieldRec, text.selection_array_count),
XmRInt, (XtPointer) &df_sarraysize
},
{
XmNresizeWidth, XmCResizeWidth, XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.resize_width),
XmRImmediate, (XtPointer) False
},
{
XmNpendingDelete, XmCPendingDelete, XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.pending_delete),
XmRImmediate, (XtPointer) True
},
{
XmNeditable, XmCEditable, XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.editable),
XmRImmediate, (XtPointer) True
},
{
XmNcursorPositionVisible, XmCCursorPositionVisible, XmRBoolean,
sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.cursor_position_visible),
XmRImmediate, (XtPointer) True
},
{
XmNverifyBell, XmCVerifyBell, XmRBoolean, sizeof(Boolean),
XtOffsetOf(XmDataFieldRec, text.verify_bell),
XmRImmediate, (XtPointer) XmDYNAMIC_BOOL
},
{
XmNselectThreshold, XmCSelectThreshold, XmRInt, sizeof(int),
XtOffsetOf(XmDataFieldRec, text.threshold),
XmRImmediate, (XtPointer) 5
},
{
XmNnavigationType, XmCNavigationType, XmRNavigationType,
sizeof (unsigned char),
XtOffsetOf(XmDataFieldRec, primitive.navigation_type),
XmRImmediate, (XtPointer) XmTAB_GROUP
},
};
/* Definition for resources that need special processing in get values */
static XmSyntheticResource syn_resources[] =
{
{
XmNmarginWidth,
sizeof(Dimension),
XtOffsetOf(XmDataFieldRec, text.margin_width),
XmeFromHorizontalPixels,
XmeToHorizontalPixels
},
{
XmNmarginHeight,
sizeof(Dimension),
XtOffsetOf(XmDataFieldRec, text.margin_height),
XmeFromVerticalPixels,
XmeToVerticalPixels
},
{
XmNvalue,
sizeof(char *),
XtOffsetOf(XmDataFieldRec, text.value),
df_MakeCopy,
NULL
},
{
XmNvalueWcs,
sizeof(wchar_t *),
XtOffsetOf(XmDataFieldRec, text.wc_value),
df_WcsMakeCopy,
NULL
},
};
XmPrimitiveClassExtRec _XmDataFPrimClassExtRec = {
NULL,
NULLQUARK,
XmPrimitiveClassExtVersion,
sizeof(XmPrimitiveClassExtRec),
DataFieldGetBaselines, /* widget_baseline */
DataFieldGetDisplayRect, /* widget_display_rect */
DataFieldMarginsProc, /* get/set widget margins */
};
externaldef(xmdatafieldclassrec) XmDataFieldClassRec xmDataFieldClassRec =
{
{
(WidgetClass) &xmPrimitiveClassRec, /* superclass */
"XmDataField", /* class_name */
sizeof(XmDataFieldRec), /* widget_size */
ClassInit, /* class_initialize */
df_ClassPartInitialize, /* class_part_initiali*/
FALSE, /* class_inited */
df_Initialize, /* initialize */
(XtArgsProc)NULL, /* initialize_hook */
df_Realize, /* realize */
data_actions, /* actions */
XtNumber(data_actions), /* num_actions */
resources, /* resources */
XtNumber(resources), /* num_resources */
NULLQUARK, /* xrm_class */
TRUE, /* compress_motion */
XtExposeCompressMaximal, /* compress_exposure */
TRUE, /* compress_enterleave*/
FALSE, /* visible_interest */
df_Destroy, /* destroy */
df_Resize, /* resize */
DataFieldExpose, /* expose */
df_SetValues, /* set_values */
#ifdef sco /* ICS -pwc 7/28/93 */
NULL, /* set_values_hook */
#else
(XtArgsFunc)NULL, /* set_values_hook */
#endif /* sco */
XtInheritSetValuesAlmost, /* set_values_almost */
(XtArgsProc)NULL, /* get_values_hook */
#ifdef sco /* ICS - pwc 7/28/93 */
NULL, /* accept_focus */
#else
(XtAcceptFocusProc)NULL, /* accept_focus */
#endif /* sco */
XtVersion, /* version */
NULL, /* callback_private */
NULL, /* tm_table */
df_QueryGeometry, /* query_geometry */
(XtStringProc)NULL, /* display accel */
NULL, /* extension */
},
{ /* Xmprimitive */
XmInheritBorderHighlight, /* border_highlight */
XmInheritBorderUnhighlight, /* border_unhighlight */
NULL, /* translations */
(XtActionProc)NULL, /* arm_and_activate */
syn_resources, /* syn resources */
XtNumber(syn_resources), /* num syn_resources */
(XtPointer) &_XmDataFPrimClassExtRec, /* extension */
},
{ /* text classs */
NULL, /* extension */
}
};
externaldef(xmdatafieldwidgetclass) WidgetClass xmDataFieldWidgetClass =
(WidgetClass) &xmDataFieldClassRec;
/* AccessXmString Trait record for DataField */
static XmConst XmAccessTextualTraitRec dataFieldCS = {
0, /* version */
DataFieldGetValue,
DataFieldSetValue,
DataFieldPreferredValue,
};
static void
#ifdef _NO_PROTO
ClassInit()
#else
ClassInit(void)
#endif
{
XmDataFieldClassRec* wc = &xmDataFieldClassRec;
XmTransferTrait tt;
/* set TextField's transfer trait */
tt = XmeTraitGet((XtPointer)xmTextFieldWidgetClass, XmQTtransfer);
XmeTraitSet((XtPointer)xmDataFieldWidgetClass,
XmQTtransfer,
(XtPointer) &tt);
XmeTraitSet((XtPointer)xmDataFieldWidgetClass,
XmQTaccessTextual,
(XtPointer) &dataFieldCS);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ValidateAndMove(w, ev, args, nargs)
Widget w;
XEvent *ev;
String *args;
Cardinal *nargs;
#else
df_ValidateAndMove(
Widget w,
XEvent *ev,
String *args,
Cardinal *nargs)
#endif
{
XmDataFieldCallbackStruct cbs;
/*
* We are guaranteed that the picture will have accepted the string, so
* just call the verify callbacks.
*/
cbs.w = w;
cbs.text = XmDataFieldGetString(w);
cbs.accept = True;
XtCallCallbackList(w, XmDataField_validate_cb(w), (XtPointer)&cbs);
XtFree(cbs.text);
/*
* Make sure we accepted it
*/
if(cbs.accept == False)
{
XBell(XtDisplay(w), 0);
return;
}
/*
* Otherwise just give up the focus and process the traversal as
* normal
*/
if(*nargs > 0 && strncasecmp(args[0], "prev", 4) == 0) {
(void) XmProcessTraversal(w, XmTRAVERSE_PREV_TAB_GROUP);
} else {
(void) XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
PictureVerifyCallback(w, client_d, call_d)
Widget w;
XtPointer client_d;
XtPointer call_d;
#else
PictureVerifyCallback(
Widget w,
XtPointer client_d,
XtPointer call_d )
#endif /* _NO_PROTO */
{
XmTextVerifyCallbackStruct *cbs =
(XmTextVerifyCallbackStruct*) call_d;
char *curr, *newptr, *changed = NULL;
int src, dst, i;
XmPictureState ps;
Boolean done = False;
/*
* If we're just backspacing, allow the change irregarless
*/
if(cbs->startPos < cbs->currInsert || cbs->text->length == 0)
return;
/*
* Get the current string, and splice in the intended changes
*/
curr = XmDataFieldGetString(w);
newptr = XtMalloc((cbs->text->length + strlen(curr) + 2) *
sizeof(char *));
dst = 0;
/* Copy in the stuff before the modification */
for(src=0; src<cbs->startPos; src++, dst++)
newptr[dst] = curr[src];
/* Then the modification text */
if(cbs->text->ptr) {
for(src=0; src<cbs->text->length; src++, dst++)
newptr[dst] = cbs->text->ptr[src];
}
/* Then the last bit */
if(cbs->endPos > cbs->startPos) {
for(dst = cbs->endPos + cbs->text->length;
src<cbs->endPos;
src++, dst++)
newptr[dst] = curr[src];
}
/* And stick a null in for good measure and sanity in debugging */
newptr[dst] = '\0';
/*
* Run it through the picture, and bail if it isn't accepted
*/
ps = XmGetNewPictureState(XmDataField_picture(w));
for(i=0; i<strlen(newptr); i++) {
changed = XmPictureProcessCharacter(ps, newptr[i], &done);
if(changed == NULL || done) break;
}
if(changed == NULL) {
cbs->doit = False;
XtCallCallbackList(w, XmDataField_picture_error_cb(w), NULL);
return;
}
/*
* And now try autofilling
*/
if(XmDataField_auto_fill(w)) {
changed = XmPictureDoAutoFill(ps);
} else {
changed = XmPictureGetCurrentString(ps);
}
/*
* Now the hard part: we may have been auto-filled, so we have to
* massage the callback struct to reflect what's happened
*/
cbs->startPos = 0;
/* CR03686 cbs->endPos = strlen(newptr); */
cbs->text->ptr = XtNewString(changed);
cbs->text->length = strlen(changed);
XtFree(newptr);
XmPictureDeleteState(ps);
}
/* USE ITERATIONS OF mblen TO COUNT THE NUMBER OF CHARACTERS REPRESENTED
* BY n_bytes BYTES POINTED TO BY ptr, a pointer to char*.
* n_bytes does not include NULL terminator (if any), nor does return.
*/
/* ARGSUSED */
static int
#ifdef _NO_PROTO
_XmDataFieldCountCharacters( tf, ptr, n_bytes )
XmDataFieldWidget tf ;
char *ptr ;
int n_bytes ;
#else
_XmDataFieldCountCharacters(
XmDataFieldWidget tf,
char *ptr,
int n_bytes )
#endif /* _NO_PROTO */
{
char * bptr;
int count = 0;
int char_size = 0;
if (n_bytes <= 0 || ptr == NULL || *ptr == '\0')
return 0;
if (XmTextF_max_char_size(tf) == 1)
return n_bytes;
bptr = ptr;
for (bptr = ptr; n_bytes > 0; count++, bptr+= char_size){
char_size = mblen(bptr, XmTextF_max_char_size(tf));
if (char_size < 0) break; /* error */
n_bytes -= char_size;
}
return count;
}
/* USE ITERATIONS OF wctomb TO COUNT THE NUMBER OF BYTES REQUIRED FOR THE
* MULTI-BYTE REPRESENTION OF num_chars WIDE CHARACTERS IN wc_value.
* COUNT TERMINATED IF NULL ENCOUNTERED IN THE STRING.
* NUMBER OF BYTES IS RETURNED.
*/
/* ARGSUSED */
int
#ifdef _NO_PROTO
_XmDataFieldCountBytes( tf, wc_value, num_chars )
XmDataFieldWidget tf;
wchar_t * wc_value;
int num_chars;
#else /* _NO_PROTO */
_XmDataFieldCountBytes(
XmDataFieldWidget tf,
wchar_t * wc_value,
int num_chars)
#endif /* _NO_PROTO */
{
wchar_t * wc_ptr;
char tmp[MB_LEN_MAX]; /* defined in limits.h: max in any locale */
int n_bytes = 0;
if (num_chars <= 0 || wc_value == NULL || *wc_value == (wchar_t)0L)
return 0;
if (XmTextF_max_char_size(tf) == 1)
return num_chars;
wc_ptr = wc_value;
while ((num_chars > 0) && (*wc_ptr != (wchar_t)0L)){
n_bytes += wctomb(tmp, *wc_ptr);
num_chars--;
wc_ptr++;
}
return n_bytes;
}
/*ARGSUSED*/
static void
#ifdef _NO_PROTO
df_MakeCopy( w, n, value )
Widget w ;
int n;
XtArgVal *value ;
#else
df_MakeCopy(
Widget w,
int n,
XtArgVal *value )
#endif /* _NO_PROTO */
{
(*value) = (XtArgVal) XmDataFieldGetString (w);
}
/*ARGSUSED*/
static void
#ifdef _NO_PROTO
df_WcsMakeCopy( w, n, value )
Widget w ;
int n;
XtArgVal *value ;
#else
df_WcsMakeCopy(
Widget w,
int n,
XtArgVal *value )
#endif /* _NO_PROTO */
{
(*value) = (XtArgVal) XmDataFieldGetStringWcs (w);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_FreeContextData(w, clientData, callData)
Widget w;
XtPointer clientData;
XtPointer callData;
#else
df_FreeContextData(
Widget w,
XtPointer clientData,
XtPointer callData )
#endif /* _NO_PROTO */
{
XmTextContextData ctx_data = (XmTextContextData) clientData;
Display *display = DisplayOfScreen(ctx_data->screen);
XtPointer data_ptr;
if (XFindContext(display, (Window) ctx_data->screen,
ctx_data->context, (char **) &data_ptr)) {
if (ctx_data->type == _XM_IS_PIXMAP_CTX) {
XFreePixmap(display, (Pixmap) data_ptr);
} else if (ctx_data->type != '\0') {
if (data_ptr)
XtFree((char *) data_ptr);
}
XDeleteContext (display, (Window) ctx_data->screen, ctx_data->context);
}
XtFree ((char *) ctx_data);
}
static TextFDestData
#ifdef _NO_PROTO
df_GetTextFDestData( w )
Widget w ;
#else
df_GetTextFDestData(
Widget w )
#endif /* _NO_PROTO */
{
static TextFDestData dest_data;
Display *display = XtDisplay(w);
Screen *screen = XtScreen(w);
if (_XmDataFDestContext == 0)
_XmDataFDestContext = XUniqueContext();
if (XFindContext(display, (Window) screen,
_XmDataFDestContext, (char **) &dest_data)) {
XmTextContextData ctx_data;
Widget xm_display = (Widget) XmGetXmDisplay(display);
ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
ctx_data->screen = screen;
ctx_data->context = _XmDataFDestContext;
ctx_data->type = _XM_IS_DEST_CTX;
dest_data = (TextFDestData) XtCalloc(1, sizeof(TextFDestDataRec));
XtAddCallback(xm_display, XmNdestroyCallback,
(XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
XSaveContext(XtDisplay(w), (Window) screen,
_XmDataFDestContext, (XPointer)dest_data);
}
return dest_data;
}
static void
#ifdef _NO_PROTO
df_SetDropContext( w )
Widget w ;
#else
df_SetDropContext(
Widget w )
#endif /* _NO_PROTO */
{
Display *display = XtDisplay(w);
Screen *screen = XtScreen(w);
if (_XmDataFDNDContext == 0)
_XmDataFDNDContext = XUniqueContext();
XSaveContext(display, (Window)screen,
_XmDataFDNDContext, (XPointer)w);
}
static void
#ifdef _NO_PROTO
df_DeleteDropContext( w )
Widget w ;
#else
df_DeleteDropContext(
Widget w )
#endif /* _NO_PROTO */
{
Display *display = XtDisplay(w);
Screen *screen = XtScreen(w);
XDeleteContext(display, (Window)screen, _XmDataFDNDContext);
}
Widget
#ifdef _NO_PROTO
_XmDataFieldGetDropReciever( w )
Widget w ;
#else
_XmDataFieldGetDropReciever(
Widget w )
#endif /* _NO_PROTO */
{
Widget widget;
if (_XmDataFDNDContext == 0) return NULL;
if (!XFindContext(XtDisplay(w), (Window) XtScreen(w),
_XmDataFDNDContext, (char **) &widget)) {
return widget;
}
return NULL;
}
static TextFGCData
#ifdef _NO_PROTO
df_GetTextFGCData( w )
Widget w ;
#else
df_GetTextFGCData(
Widget w )
#endif /* _NO_PROTO */
{
static TextFGCData gc_data;
Display *display = XtDisplay(w);
Screen *screen = XtScreen(w);
if (_XmDataFGCContext == 0)
_XmDataFGCContext = XUniqueContext();
if (XFindContext(display, (Window)screen,
_XmDataFGCContext, (char **)&gc_data)) {
XmTextContextData ctx_data;
Widget xm_display = (Widget) XmGetXmDisplay(display);
ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
ctx_data->screen = screen;
ctx_data->context = _XmDataFGCContext;
ctx_data->type = _XM_IS_GC_DATA_CTX;
gc_data = (TextFGCData) XtCalloc(1, sizeof(TextFGCDataRec));
XtAddCallback(xm_display, XmNdestroyCallback,
(XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
XSaveContext(display, (Window)screen, _XmDataFGCContext,
(XPointer)gc_data);
gc_data->tf = (XmDataFieldWidget) w;
}
if (gc_data->tf == NULL) gc_data->tf = (XmDataFieldWidget) w;
return gc_data;
}
void
#ifdef _NO_PROTO
_XmDataFToggleCursorGC( widget )
Widget widget;
#else
_XmDataFToggleCursorGC(
Widget widget )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) widget;
XGCValues values;
unsigned long valuemask = GCFillStyle|GCFunction|GCForeground|GCBackground;
if (!XtIsRealized(widget)) return;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
#ifdef FIX_1501
if (!XtIsSensitive(widget)) {
valuemask = GCForeground|GCBackground|GCFillStyle|GCStipple|GCFunction;
values.foreground = _XmAssignInsensitiveColor((Widget)tf);
values.background = tf->core.background_pixel;
values.fill_style = FillStippled;
if (XmTextF_overstrike(tf)) {
if (XmTextF_stipple_tile(tf) == XmUNSPECIFIED_PIXMAP) return;
values.stipple = XmTextF_stipple_tile(tf);
values.function = GXxor;
} else {
if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
values.stipple = XmTextF_cursor(tf);
values.function = GXcopy;
}
} else {
#endif
if (XmTextF_overstrike(tf)) {
if (!XmTextF_add_mode(tf) && XtIsSensitive(widget) &&
(XmTextF_has_focus(tf) || XmTextF_has_destination(tf))) {
values.fill_style = FillSolid;
} else {
values.fill_style = FillTiled;
}
values.foreground = values.background =
tf->primitive.foreground ^ tf->core.background_pixel;
values.function = GXxor;
} else {
if (XtIsSensitive(widget) && !XmTextF_add_mode(tf) &&
(XmTextF_has_focus(tf) || XmTextF_has_destination(tf))) {
if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
values.stipple = XmTextF_cursor(tf);
} else {
if (XmTextF_add_mode_cursor(tf) == XmUNSPECIFIED_PIXMAP) return;
values.stipple = XmTextF_add_mode_cursor(tf);
}
values.fill_style = FillStippled;
values.function = GXcopy;
if (XmTextF_have_inverted_image_gc(tf)){
values.background = tf->primitive.foreground;
values.foreground = tf->core.background_pixel;
} else {
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
}
valuemask |= GCStipple;
}
#ifdef FIX_1501
}
#endif
XChangeGC(XtDisplay(widget), XmTextF_image_gc(tf), valuemask, &values);
}
/*
* Find the highlight record corresponding to the given position. Returns a
* pointer to the record. The third argument indicates whether we are probing
* the left or right edge of a highlighting range.
*/
static _XmHighlightRec *
#ifdef _NO_PROTO
df_FindHighlight( w, position )
XmDataFieldWidget w ;
XmTextPosition position ;
#else
df_FindHighlight(
XmDataFieldWidget w,
XmTextPosition position )
#endif /* _NO_PROTO */
{
_XmHighlightRec *l = XmTextF_highlight(w).list;
int i;
for (i=XmTextF_highlight(w).number - 1 ; i>=0 ; i--)
if (position >= l[i].position) {
l = l + i;
break;
}
return(l);
}
static void
#ifdef _NO_PROTO
df_InsertHighlight( w, position, mode )
XmDataFieldWidget w ;
XmTextPosition position ;
XmHighlightMode mode ;
#else
df_InsertHighlight(
XmDataFieldWidget w,
XmTextPosition position,
XmHighlightMode mode )
#endif /* _NO_PROTO */
{
_XmHighlightRec *l1;
_XmHighlightRec *l = XmTextF_highlight(w).list;
int i, j;
l1 = df_FindHighlight(w, position);
if (l1->position == position)
l1->mode = mode;
else {
i = (l1 - l) + 1;
XmTextF_highlight(w).number++;
if (XmTextF_highlight(w).number > XmTextF_highlight(w).maximum) {
XmTextF_highlight(w).maximum = XmTextF_highlight(w).number;
l = XmTextF_highlight(w).list = (_XmHighlightRec *)XtRealloc((char *) l,
(unsigned)(XmTextF_highlight(w).maximum * sizeof(_XmHighlightRec)));
}
for (j=XmTextF_highlight(w).number-1 ; j>i ; j--)
l[j] = l[j-1];
l[i].position = position;
l[i].mode = mode;
}
}
static void
#ifdef _NO_PROTO
DataFieldSetHighlight( tf, left, right, mode )
XmDataFieldWidget tf ;
XmTextPosition left ;
XmTextPosition right ;
XmHighlightMode mode ;
#else
DataFieldSetHighlight(
XmDataFieldWidget tf,
XmTextPosition left,
XmTextPosition right,
XmHighlightMode mode )
#endif /* _NO_PROTO */
{
_XmHighlightRec *l;
XmHighlightMode endmode;
int i, j;
if (left >= right || right <= 0) return;
_XmDataFieldDrawInsertionPoint(tf, False);
endmode = df_FindHighlight(tf, right)->mode;
df_InsertHighlight(tf, left, mode);
df_InsertHighlight(tf, right, endmode);
l = XmTextF_highlight(tf).list;
i = 1;
while (i < XmTextF_highlight(tf).number) {
if (l[i].position >= left && l[i].position < right)
l[i].mode = mode;
if (l[i].mode == l[i-1].mode) {
XmTextF_highlight(tf).number--;
for (j=i ; j<XmTextF_highlight(tf).number ; j++)
l[j] = l[j+1];
} else i++;
}
if (XmTextF_cursor_position(tf) > left && XmTextF_cursor_position(tf) < right){
if (mode == XmHIGHLIGHT_SELECTED){
df_InvertImageGC(tf);
} else if (mode != XmHIGHLIGHT_SELECTED){
df_ResetImageGC(tf);
}
}
XmTextF_refresh_ibeam_off(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
}
/*
* Get x and y based on position.
*/
static Boolean
#ifdef _NO_PROTO
df_GetXYFromPos( tf, position, x, y )
XmDataFieldWidget tf ;
XmTextPosition position ;
Position *x ;
Position *y ;
#else
df_GetXYFromPos(
XmDataFieldWidget tf,
XmTextPosition position,
Position *x,
Position *y )
#endif /* _NO_PROTO */
{
int x1, x2;
/* initialize the x and y positions to zero */
if (XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING)
{
*x = 0;
*y = 0;
if (position > XmTextF_string_length(tf)) return False;
if (XmTextF_max_char_size(tf) != 1) {
x1 = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf), (int)position);
} else {
x1 = df_FindPixelLength(tf, XmTextF_value(tf), (int)position);
}
}
else
{
int length;
*x = tf->core.width - (XmTextF_margin_width(tf) +
tf->primitive.highlight_thickness +
tf->primitive.shadow_thickness);
*y = 0;
length = XmTextF_string_length(tf) - position;
if (length < 0) return False;
if (XmTextF_max_char_size(tf) != 1) {
x1 = df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + position),
length);
} else {
x1 = df_FindPixelLength(tf, XmTextF_value(tf) + position, length);
}
}
*y += tf->primitive.highlight_thickness + tf->primitive.shadow_thickness
+ XmTextF_margin_top(tf) + XmTextF_font_ascent(tf);
x2 = (Position) XmTextF_h_offset(tf);
if (XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING)
{
*x += x1 + x2;
}
else
{
*x -= (x1 - x2);
}
return True;
}
static Boolean
#ifdef _NO_PROTO
df_CurrentCursorState( tf )
XmDataFieldWidget tf ;
#else
df_CurrentCursorState(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
if (XmTextF_cursor_on(tf) < 0) return False;
if (XmTextF_blink_on(tf) || !XtIsSensitive((Widget)tf))
return True;
return False;
}
/*
* Paint insert cursor
*/
static void
#ifdef _NO_PROTO
df_PaintCursor( tf )
XmDataFieldWidget tf ;
#else
df_PaintCursor(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
Position x, y;
XmTextPosition position;
if (!XmTextF_cursor_position_visible(tf)) return;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
position = XmTextF_cursor_position(tf);
(void) df_GetXYFromPos(tf, position, &x, &y);
if (!XmTextF_overstrike(tf))
x -=(XmTextF_cursor_width(tf) >> 1) + 1; /* "+1" for 1 pixel left of char */
else {
int pxlen;
if (XmTextF_max_char_size(tf) != 1)
pxlen = df_FindPixelLength(tf, (char*)&(XmTextF_wc_value(tf)[position]), 1);
else
pxlen = df_FindPixelLength(tf, &(XmTextF_value(tf)[position]), 1);
if (pxlen > XmTextF_cursor_width(tf))
x += (pxlen - XmTextF_cursor_width(tf)) >> 1;
}
y = (y + (Position) XmTextF_font_descent(tf)) -
(Position) XmTextF_cursor_height(tf);
/* If time to paint the I Beam... first capture the IBeamOffArea, then draw
* the IBeam */
if (XmTextF_refresh_ibeam_off(tf) == True){ /* get area under IBeam first */
/* Fill is needed to realign clip rectangle with gc */
XFillRectangle(XtDisplay((Widget)tf), XtWindow((Widget)tf),
XmTextF_save_gc(tf), 0, 0, 0, 0);
XCopyArea(XtDisplay(tf), XtWindow(tf), XmTextF_ibeam_off(tf),
XmTextF_save_gc(tf), x, y, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf), 0, 0);
XmTextF_refresh_ibeam_off(tf) = False;
}
if ((XmTextF_cursor_on(tf) >= 0) && XmTextF_blink_on(tf)) {
#ifdef FIX_1501
if (!XtIsSensitive((Widget) tf)) {
df_XmSetShadowGC(tf, XmTextF_image_gc(tf));
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_image_gc(tf), x + 1, y + 1,
XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
}
_XmDataFToggleCursorGC((Widget) tf);
#endif
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_image_gc(tf), x, y,
XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
} else {
XCopyArea(XtDisplay(tf), XmTextF_ibeam_off(tf), XtWindow(tf),
XmTextF_save_gc(tf), 0, 0, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf), x, y);
}
}
void
#ifdef _NO_PROTO
_XmDataFieldDrawInsertionPoint( tf, turn_on )
XmDataFieldWidget tf ;
Boolean turn_on ;
#else
_XmDataFieldDrawInsertionPoint(
XmDataFieldWidget tf,
Boolean turn_on )
#endif /* _NO_PROTO */
{
if (turn_on == True) {
XmTextF_cursor_on(tf) += 1;
if (XmTextF_blink_rate(tf) == 0 || !XmTextF_has_focus(tf))
XmTextF_blink_on(tf) = True;
} else {
if (XmTextF_blink_on(tf) && (XmTextF_cursor_on(tf) == 0))
if (XmTextF_blink_on(tf) == df_CurrentCursorState(tf) &&
XtIsRealized((Widget)tf)){
XmTextF_blink_on(tf) = !XmTextF_blink_on(tf);
df_PaintCursor(tf);
}
XmTextF_cursor_on(tf) -= 1;
}
if (XmTextF_cursor_on(tf) < 0 || !XtIsRealized((Widget) tf))
return;
df_PaintCursor(tf);
}
static void
#ifdef _NO_PROTO
df_BlinkInsertionPoint( tf )
XmDataFieldWidget tf ;
#else
df_BlinkInsertionPoint(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
if ((XmTextF_cursor_on(tf) >= 0) &&
XmTextF_blink_on(tf) == df_CurrentCursorState(tf) &&
XtIsRealized((Widget)tf)) {
XmTextF_blink_on(tf) = !XmTextF_blink_on(tf);
df_PaintCursor(tf);
}
}
/*
* Handle blink on and off
*/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_HandleTimer( closure, id )
XtPointer closure ;
XtIntervalId *id ;
#else
df_HandleTimer(
XtPointer closure,
XtIntervalId *id )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) closure;
if (XmTextF_blink_rate(tf) != 0)
XmTextF_timer_id(tf) =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tf),
(unsigned long)XmTextF_blink_rate(tf),
df_HandleTimer,
(XtPointer) closure);
if (XmTextF_has_focus(tf) && XtIsSensitive((Widget)tf))
df_BlinkInsertionPoint(tf);
}
/*
* Change state of blinking insert cursor on and off
*/
static void
#ifdef _NO_PROTO
df_ChangeBlinkBehavior( tf, turn_on )
XmDataFieldWidget tf ;
Boolean turn_on ;
#else
df_ChangeBlinkBehavior(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int turn_on )
#else
Boolean turn_on )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
if (turn_on) {
if (XmTextF_blink_rate(tf) != 0 && XmTextF_timer_id(tf) == (XtIntervalId)0)
XmTextF_timer_id(tf) =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tf),
(unsigned long)XmTextF_blink_rate(tf),
df_HandleTimer,
(XtPointer) tf);
XmTextF_blink_on(tf) = True;
} else {
if (XmTextF_timer_id(tf))
XtRemoveTimeOut(XmTextF_timer_id(tf));
XmTextF_timer_id(tf) = (XtIntervalId)0;
}
}
static void
#ifdef _NO_PROTO
df_GetRect( tf, rect )
XmDataFieldWidget tf ;
XRectangle *rect ;
#else
df_GetRect(
XmDataFieldWidget tf,
XRectangle *rect )
#endif /* _NO_PROTO */
{
Dimension margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension margin_bottom = XmTextF_margin_bottom(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
if (margin_width < tf->core.width)
rect->x = margin_width;
else
rect->x = tf->core.width;
if (margin_top < tf->core.height)
rect->y = margin_top;
else
rect->y = tf->core.height;
if ((int)(2 * margin_width) < (int)tf->core.width)
rect->width = (int) tf->core.width - (2 * margin_width);
else
rect->width = 0;
if ((int)(margin_top + margin_bottom) < (int)tf->core.height)
rect->height = (int) tf->core.height - (margin_top + margin_bottom);
else
rect->height = 0;
}
static void
#ifdef _NO_PROTO
df_CheckHasRect( tf )
XmDataFieldWidget tf ;
#else
df_CheckHasRect(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
/*
* Make sure the cached GC has the clipping rectangle
* set to the current widget.
*/
if (!XmTextF_has_rect(tf)) {
TextFGCData gc_data = df_GetTextFGCData((Widget)tf);
XmTextF_has_rect(gc_data->tf) = False;
gc_data->tf = tf;
XmTextF_has_rect(tf) = True;
}
}
static void
#ifdef _NO_PROTO
df_XmSetFullGC( tf, gc )
XmDataFieldWidget tf ;
GC gc ;
#else
df_XmSetFullGC(
XmDataFieldWidget tf,
GC gc )
#endif /* _NO_PROTO */
{
XRectangle ClipRect;
/* adjust clip rectangle to allow the cursor to paint into the margins */
ClipRect.x = tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
ClipRect.y = tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
ClipRect.width = tf->core.width - (2 * (tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness));
ClipRect.height = tf->core.height - (2 * (tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness));
XSetClipRectangles(XtDisplay(tf), gc, 0, 0, &ClipRect, 1,
Unsorted);
}
static void
#ifdef _NO_PROTO
df_XmSetMarginGC( tf, gc )
XmDataFieldWidget tf ;
GC gc ;
#else
df_XmSetMarginGC(
XmDataFieldWidget tf,
GC gc )
#endif /* _NO_PROTO */
{
XRectangle ClipRect;
df_GetRect(tf, &ClipRect);
#ifdef USE_XFT
if (XmTextF_use_xft(tf))
_XmXftSetClipRectangles(XtDisplay(tf), XtWindow(tf), 0, 0, &ClipRect, 1);
#endif
XSetClipRectangles(XtDisplay(tf), gc, 0, 0, &ClipRect, 1,
Unsorted);
}
static void
#ifdef _NO_PROTO
df_XmResetSaveGC( tf, gc )
XmDataFieldWidget tf ;
GC gc ;
#else
df_XmResetSaveGC(
XmDataFieldWidget tf,
GC gc )
#endif /* _NO_PROTO */
{
XSetClipMask(XtDisplay(tf), gc, None);
}
/*
* Set new clipping rectangle for text field. This is
* done on each focus in event since the text field widgets
* share the same GC.
*/
void
#ifdef _NO_PROTO
_XmDataFieldSetClipRect( tf )
XmDataFieldWidget tf ;
#else
_XmDataFieldSetClipRect(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
XGCValues values;
unsigned long valuemask = (unsigned long) 0;
/*
* Make sure the cached GC has the clipping rectangle
* set to the current widget.
*/
df_CheckHasRect(tf);
df_XmSetMarginGC(tf, XmTextF_gc(tf));
df_XmSetFullGC(tf, XmTextF_image_gc(tf));
df_ResetClipOrigin(tf, False);
/* Restore cached save gc to state correct for this instantiation */
if (XmTextF_save_gc(tf)){
valuemask = (GCFunction | GCBackground | GCForeground);
values.function = GXcopy;
values.foreground = tf->primitive.foreground ;
values.background = tf->core.background_pixel;
XChangeGC(XtDisplay(tf), XmTextF_save_gc(tf), valuemask, &values);
}
/* Restore cached text gc to state correct for this instantiation */
if (XmTextF_gc(tf)){
#if USE_XFT
if (!XmTextF_have_fontset(tf) && !XmTextF_use_xft(tf)
&& (XmTextF_font(tf) != NULL)) {
#else
if (!XmTextF_have_fontset(tf) && (XmTextF_font(tf) != NULL)){
#endif
valuemask |= GCFont;
values.font = XmTextF_font(tf)->fid;
}
valuemask |= GCGraphicsExposures;
values.graphics_exposures = (Bool) True;
values.foreground = tf->primitive.foreground ^ tf->core.background_pixel;
values.background = 0;
XChangeGC(XtDisplay(tf), XmTextF_gc(tf), valuemask, &values);
}
/* Restore cached image gc to state correct for this instantiation */
if (XmTextF_image_gc(tf)){
valuemask = (GCForeground | GCBackground);
if (XmTextF_overstrike(tf)) {
values.background = values.foreground =
tf->core.background_pixel ^ tf->primitive.foreground;
} else if (XmTextF_have_inverted_image_gc(tf)){
values.background = tf->primitive.foreground;
values.foreground = tf->core.background_pixel;
} else {
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
}
XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
}
_XmDataFToggleCursorGC((Widget)tf);
}
static void
#ifdef _NO_PROTO
df_XmSetNormGC( tf, gc, change_stipple, stipple )
XmDataFieldWidget tf ;
GC gc ;
Boolean change_stipple;
Boolean stipple;
#else
df_XmSetNormGC(
XmDataFieldWidget tf,
GC gc,
#if NeedWidePrototypes
int change_stipple,
int stipple)
#else
Boolean change_stipple,
Boolean stipple)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
unsigned long valueMask = (GCForeground | GCBackground);
XGCValues values;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
if (change_stipple) {
#ifdef FIX_1381
valueMask |= GCFillStyle;
if (stipple) {
/*generally gray insensitive foreground (instead stipple)*/
values.foreground = _XmAssignInsensitiveColor((Widget)tf);
values.fill_style = FillSolid;
} else values.fill_style = FillSolid;
#else
valueMask |= GCTile | GCFillStyle;
values.tile = XmTextF_stipple_tile(tf);
if (stipple) values.fill_style = FillTiled;
else values.fill_style = FillSolid;
#endif
}
XChangeGC(XtDisplay(tf), gc, valueMask, &values);
}
#ifdef FIX_1381
static void
#ifdef _NO_PROTO
df_XmSetShadowGC( tf, gc )
XmDataFieldWidget tf ;
GC gc ;
#else
df_XmSetShadowGC(
XmDataFieldWidget tf,
GC gc )
#endif /* _NO_PROTO */
{
unsigned long valueMask = (GCForeground | GCBackground);
XGCValues values;
values.foreground = tf->primitive.top_shadow_color;
values.background = tf->core.background_pixel;
XChangeGC(XtDisplay(tf), gc, valueMask, &values);
}
#endif
static void
#ifdef _NO_PROTO
df_XmSetInvGC( tf, gc )
XmDataFieldWidget tf ;
GC gc ;
#else
df_XmSetInvGC(
XmDataFieldWidget tf,
GC gc )
#endif /* _NO_PROTO */
{
unsigned long valueMask = (GCForeground | GCBackground);
XGCValues values;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
values.foreground = tf->core.background_pixel;
values.background = tf->primitive.foreground;
XChangeGC(XtDisplay(tf), gc, valueMask, &values);
}
static void
#ifdef _NO_PROTO
df_DrawText( tf, gc, x, y, string, length )
XmDataFieldWidget tf ;
GC gc ;
int x ;
int y ;
char * string ;
int length ;
#else
df_DrawText(
XmDataFieldWidget tf,
GC gc,
int x,
int y,
char * string,
int length )
#endif /* _NO_PROTO */
{
if (XmTextF_have_fontset(tf)){
if (XmTextF_max_char_size(tf) != 1)
XwcDrawString (XtDisplay(tf), XtWindow(tf), (XFontSet)XmTextF_font(tf),
gc, x, y, (wchar_t*) string, length);
else /* one byte chars */
XmbDrawString (XtDisplay(tf), XtWindow(tf), (XFontSet)XmTextF_font(tf),
gc, x, y, string, length);
#ifdef USE_XFT
} else if (XmTextF_use_xft(tf)) {
if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t* */
char stack_cache[400], *tmp;
wchar_t tmp_wc;
wchar_t *wc_string = (wchar_t*)string;
int num_bytes = 0;
/* ptr = tmp = XtMalloc((int)(length + 1)*sizeof(wchar_t)); */
tmp = (char *)XmStackAlloc((Cardinal) ((length + 1)*sizeof(wchar_t)),
stack_cache);
tmp_wc = wc_string[length];
wc_string[length] = 0L;
num_bytes = wcstombs(tmp, wc_string,
(int)((length + 1) * sizeof(wchar_t)));
wc_string[length] = tmp_wc;
if (num_bytes >= 0)
_XmXftDrawString2(XtDisplay(tf), XtWindow(tf), gc, XmTextF_xft_font(tf),
1, x, y, tmp, num_bytes);
XmStackFree(tmp, stack_cache);
} else /* one byte chars */
_XmXftDrawString2(XtDisplay(tf), XtWindow(tf), gc, XmTextF_xft_font(tf),
1, x, y, string, length);
#endif
} else { /* have a font struct, not a font set */
if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t* */
char stack_cache[400], *tmp;
wchar_t tmp_wc;
wchar_t *wc_string = (wchar_t*)string;
int num_bytes = 0;
/* ptr = tmp = XtMalloc((int)(length + 1)*sizeof(wchar_t)); */
tmp = (char *)XmStackAlloc((Cardinal) ((length + 1)*sizeof(wchar_t)),
stack_cache);
tmp_wc = wc_string[length];
wc_string[length] = 0L;
num_bytes = wcstombs(tmp, wc_string,
(int)((length + 1) * sizeof(wchar_t)));
wc_string[length] = tmp_wc;
if (num_bytes >= 0) {
if (_XmIsISO10646(XtDisplay(tf), XmTextF_font(tf))) {
size_t str_len = 0;
XChar2b *str = _XmUtf8ToUcs2(tmp, num_bytes, &str_len);
XDrawString16(XtDisplay(tf), XtWindow(tf), gc, x, y,
str, str_len);
XFree(str);
} else
XDrawString(XtDisplay(tf), XtWindow(tf), gc, x, y,
tmp, num_bytes);
}
XmStackFree((char *)tmp, stack_cache);
} else /* one byte chars */
XDrawString (XtDisplay(tf), XtWindow(tf), gc, x, y, string, length);
}
}
static int
#ifdef _NO_PROTO
df_FindPixelLength( tf, string, length)
XmDataFieldWidget tf ;
char * string ;
int length ;
#else
df_FindPixelLength(
XmDataFieldWidget tf,
char * string,
int length )
#endif /* _NO_PROTO */
{
if (XmTextF_have_fontset(tf)) {
if (XmTextF_max_char_size(tf) != 1)
return (XwcTextEscapement((XFontSet)XmTextF_font(tf),
(wchar_t *) string, length));
else /* one byte chars */
return (XmbTextEscapement((XFontSet)XmTextF_font(tf), string, length));
#ifdef USE_XFT
} else if (XmTextF_use_xft(tf)) {
XGlyphInfo ext;
if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t* */
wchar_t *wc_string = (wchar_t*)string;
wchar_t wc_tmp = wc_string[length];
char stack_cache[400], *tmp;
int num_bytes;
wc_string[length] = 0L;
tmp = (char*)XmStackAlloc((Cardinal)((length + 1) * sizeof(wchar_t)),
stack_cache);
num_bytes = wcstombs(tmp, wc_string,
(int)((length + 1)*sizeof(wchar_t)));
wc_string[length] = wc_tmp;
XftTextExtentsUtf8(XtDisplay(tf), XmTextF_xft_font(tf),
(FcChar8*)tmp, num_bytes, &ext);
XmStackFree(tmp, stack_cache);
} else /* one byte chars */
XftTextExtentsUtf8(XtDisplay(tf), XmTextF_xft_font(tf),
(FcChar8*)string, length, &ext);
return ext.xOff;
#endif
} else { /* have font struct, not a font set */
if (XmTextF_max_char_size(tf) != 1) { /* was passed a wchar_t* */
wchar_t *wc_string = (wchar_t*)string;
wchar_t wc_tmp = wc_string[length];
char stack_cache[400], *tmp;
int num_bytes, ret_len = 0;
wc_string[length] = 0L;
tmp = (char*)XmStackAlloc((Cardinal)((length + 1) * sizeof(wchar_t)),
stack_cache);
num_bytes = wcstombs(tmp, wc_string,
(int)((length + 1)*sizeof(wchar_t)));
wc_string[length] = wc_tmp;
if (num_bytes >= 0) {
if (_XmIsISO10646(XtDisplay(tf), XmTextF_font(tf))) {
size_t str_len = 0;
XChar2b *str = _XmUtf8ToUcs2(tmp, num_bytes, &str_len);
ret_len = XTextWidth16(XmTextF_font(tf), str, str_len);
XFree(str);
} else
ret_len = XTextWidth(XmTextF_font(tf), tmp, num_bytes);
}
XmStackFree((char *)tmp, stack_cache);
return (ret_len);
} else /* one byte chars */
return (XTextWidth(XmTextF_font(tf), string, length));
}
}
static void
#ifdef _NO_PROTO
df_DrawTextSegment( tf, mode, prev_seg_start, seg_start, seg_end, next_seg,
stipple, y, x)
XmDataFieldWidget tf ;
XmHighlightMode mode;
XmTextPosition prev_seg_start;
XmTextPosition seg_start;
XmTextPosition seg_end;
XmTextPosition next_seg;
Boolean stipple;
int y ;
int *x ;
#else
df_DrawTextSegment(
XmDataFieldWidget tf,
XmHighlightMode mode,
XmTextPosition prev_seg_start,
XmTextPosition seg_start,
XmTextPosition seg_end,
XmTextPosition next_seg,
#if NeedWidePrototypes
int stipple,
#else
Boolean stipple,
#endif /* NeedWidePrototypes */
int y,
int *x)
#endif /* _NO_PROTO */
{
int x_seg_len;
#if PWC_DEBUG
{
char seg[256];
memset((char *)seg, 256, 0);
strncpy(seg, (char *)(XmTextF_value(tf) + seg_start),
seg_end - seg_start);
seg[seg_end] = '\0';
printf("df_DrawText(\"%s\" - %s) :: [start(%d), end(%d), x(%d), offset(%d)]\n",
seg, (mode == XmHIGHLIGHT_NORMAL ? "NORMAL" : "HIGHLIGHT"),
seg_start, seg_end, *x, XmTextF_h_offset(tf));
}
#endif
/* update x position up to start position */
if (XmTextF_max_char_size(tf) != 1) {
*x += df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + prev_seg_start),
(int)(seg_start - prev_seg_start));
x_seg_len = df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + seg_start),
(int)seg_end - (int)seg_start);
} else {
*x += df_FindPixelLength(tf, XmTextF_value(tf) + prev_seg_start,
(int)(seg_start - prev_seg_start));
x_seg_len = df_FindPixelLength(tf, XmTextF_value(tf) + seg_start,
(int)seg_end - (int)seg_start);
}
if (mode == XmHIGHLIGHT_SELECTED) {
/* Draw the selected text using an inverse gc */
df_XmSetNormGC(tf, XmTextF_gc(tf), False, False);
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x,
y - XmTextF_font_ascent(tf), x_seg_len,
XmTextF_font_ascent(tf) + XmTextF_font_descent(tf));
df_XmSetInvGC(tf, XmTextF_gc(tf));
} else {
df_XmSetInvGC(tf, XmTextF_gc(tf));
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x,
y - XmTextF_font_ascent(tf), x_seg_len,
XmTextF_font_ascent(tf) + XmTextF_font_descent(tf));
df_XmSetNormGC(tf, XmTextF_gc(tf), True, stipple);
}
#ifdef FIX_1381
if (stipple) {
/*Draw shadow for insensitive text*/
df_XmSetShadowGC(tf, XmTextF_gc(tf));
if (tf->text.max_char_size != 1) {
df_DrawText(tf, XmTextF_gc(tf), *x + 1, y + 1, (char*) (XmTextF_wc_value(tf) + seg_start),
(int)seg_end - (int)seg_start);
} else {
df_DrawText(tf, XmTextF_gc(tf), *x + 1, y + 1, XmTextF_value(tf) + seg_start,
(int)seg_end - (int)seg_start);
}
df_XmSetNormGC(tf, XmTextF_gc(tf), True, stipple);
}
#endif
if (XmTextF_max_char_size(tf) != 1) {
df_DrawText(tf, XmTextF_gc(tf), *x, y, (char*) (XmTextF_wc_value(tf) + seg_start),
(int)seg_end - (int)seg_start);
} else {
df_DrawText(tf, XmTextF_gc(tf), *x, y, XmTextF_value(tf) + seg_start,
(int)seg_end - (int)seg_start);
}
if (stipple) df_XmSetNormGC(tf, XmTextF_gc(tf), True, !stipple);
if (mode == XmHIGHLIGHT_SECONDARY_SELECTED)
XDrawLine(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), *x, y,
*x + x_seg_len - 1, y);
/* update x position up to the next highlight position */
if (XmTextF_max_char_size(tf) != 1)
*x += df_FindPixelLength(tf, (char*) (XmTextF_wc_value(tf) + seg_start),
(int)(next_seg - (int)seg_start));
else
*x += df_FindPixelLength(tf, XmTextF_value(tf) + seg_start,
(int)(next_seg - (int)seg_start));
}
/*
* Redisplay the new adjustments that have been made the the text
* field widget.
*/
static void
#ifdef _NO_PROTO
df_RedisplayText( tf, start, end )
XmDataFieldWidget tf ;
XmTextPosition start ;
XmTextPosition end ;
#else
df_RedisplayText(
XmDataFieldWidget tf,
XmTextPosition start,
XmTextPosition end )
#endif /* _NO_PROTO */
{
_XmHighlightRec *l = XmTextF_highlight(tf).list;
XRectangle rect;
int x, y, i, startx = 0;
Dimension margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension margin_bottom = XmTextF_margin_bottom(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Boolean stipple = False;
if (!XtIsRealized((Widget)tf)) return;
if (XmTextF_in_setvalues(tf)) {
XmTextF_redisplay(tf) = True;
return;
}
if ((int)tf->core.width - (int)(2 * margin_width) <= 0)
return;
if ((int)tf->core.height - (int)(margin_top + margin_bottom) <= 0)
return;
/*
* Make sure the cached GC has the clipping rectangle
* set to the current widget.
*/
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
_XmDataFieldDrawInsertionPoint(tf, False);
/* Get the current rectangle.
*/
df_GetRect(tf, &rect);
y = margin_top + XmTextF_font_ascent(tf);
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
{
x = tf->core.width - margin_width + XmTextF_h_offset(tf);
if (XmTextF_max_char_size(tf) != 1)
x -= df_FindPixelLength(tf, (char*)(XmTextF_wc_value(tf) + l[0].position),
XmTextF_string_length(tf) - l[0].position);
else
x -= df_FindPixelLength(tf, XmTextF_value(tf) + l[0].position,
XmTextF_string_length(tf) - l[0].position);
/* PWC - alignment requires we draw all characters to the left of end */
start = 0;
startx = x;
}
else
x = (int) XmTextF_h_offset(tf);
if (!XtIsSensitive((Widget)tf)) stipple = True;
/* search through the highlight array and draw the text */
for (i = 0; i + 1 < XmTextF_highlight(tf).number; i++) {
#if PWC_DEBUG
printf("XmTextF_value(\"%s\")::Highlight #%d = pos(%d), start(%d), end(%d)\n",
(char *)XmTextF_value(tf), i, l[i].position, start, end);
#endif
/* make sure start is within current highlight */
if (l[i].position <= start && start < l[i+1].position &&
l[i].position < end) {
if (end > l[i+1].position) {
df_DrawTextSegment(tf, l[i].mode, l[i].position, start,
l[i+1].position, l[i+1].position, stipple, y, &x);
/* update start position to the next highlight position */
start = l[i+1].position;
} else {
df_DrawTextSegment(tf, l[i].mode, l[i].position, start,
end, l[i+1].position, stipple, y, &x);
start = end;
}
}
else
{ /* start not within current record */
if (XmTextF_max_char_size(tf) != 1)
{
x += df_FindPixelLength(tf, (char *) (XmTextF_wc_value(tf)
+ l[i].position),
(int)(l[i+1].position - l[i].position));
}
else
{
x += df_FindPixelLength(tf, XmTextF_value(tf) + l[i].position,
(int)(l[i+1].position - l[i].position));
}
}
} /* end for loop */
if (l[i].position < end)
{
/* complete the drawing of the text to the end of the line */
df_DrawTextSegment(tf, l[i].mode, l[i].position, start, end,
XmTextF_string_length(tf), stipple, y, &x);
} else {
if (XmTextF_max_char_size(tf) != 1)
x += df_FindPixelLength(tf, (char*) (XmTextF_wc_value(tf) + l[i].position),
XmTextF_string_length(tf) - (int)l[i].position);
else
x += df_FindPixelLength(tf, XmTextF_value(tf) + l[i].position,
XmTextF_string_length(tf) - (int)l[i].position);
}
if (x < (int)(rect.x + rect.width)
&& XmDataField_alignment(tf) == XmALIGNMENT_BEGINNING) {
df_XmSetInvGC(tf, XmTextF_gc(tf));
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), x, rect.y,
rect.x + rect.width - x, rect.height);
} else if (XmTextF_h_offset(tf) < startx
&& XmDataField_alignment(tf) == XmALIGNMENT_END) {
df_XmSetInvGC(tf, XmTextF_gc(tf));
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf), XmTextF_h_offset(tf), rect.y,
startx - XmTextF_h_offset(tf), rect.height);
}
XmTextF_refresh_ibeam_off(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
}
/*
* Use the font along with the resources that have been set
* to determine the height and width of the text field widget.
*/
static void
#ifdef _NO_PROTO
df_ComputeSize( tf, width, height )
XmDataFieldWidget tf ;
Dimension *width ;
Dimension *height ;
#else
df_ComputeSize(
XmDataFieldWidget tf,
Dimension *width,
Dimension *height )
#endif /* _NO_PROTO */
{
Dimension tmp = 0;
if (XmTextF_resize_width(tf) &&
XmTextF_columns(tf) < XmTextF_string_length(tf)){
if (XmTextF_max_char_size(tf) != 1)
tmp = df_FindPixelLength(tf, (char *)XmTextF_wc_value(tf),
XmTextF_string_length(tf));
else
tmp = df_FindPixelLength(tf, XmTextF_value(tf), XmTextF_string_length(tf));
*width = tmp + (2 * (XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness));
} else {
*width = XmTextF_columns(tf) * XmTextF_average_char_width(tf) +
2 * (XmTextF_margin_width(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness);
}
if (height != NULL)
*height = XmTextF_font_descent(tf) + XmTextF_font_ascent(tf) +
2 * (XmTextF_margin_height(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness);
}
/*
* df_TryResize - Attempts to resize the width of the text field widget.
* If the attempt fails or is ineffective, return GeometryNo.
*/
static XtGeometryResult
#ifdef _NO_PROTO
df_TryResize( tf, width, height )
XmDataFieldWidget tf ;
Dimension width ;
Dimension height ;
#else
df_TryResize(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int width,
int height )
#else
Dimension width,
Dimension height )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
Dimension reswidth, resheight;
Dimension origwidth = tf->core.width;
XtGeometryResult result;
result = XtMakeResizeRequest((Widget)tf, width, height,
&reswidth, &resheight);
if (result == XtGeometryAlmost) {
result = XtMakeResizeRequest((Widget)tf, reswidth, resheight,
&reswidth, &resheight);
if (reswidth == origwidth)
result = XtGeometryNo;
return result;
}
/*
* Caution: Some geometry managers return XtGeometryYes
* and don't change the widget's size.
*/
if (tf->core.width != width && tf->core.height != height)
result = XtGeometryNo;
return result;
}
/*
* Function df_AdjustText
*
* df_AdjustText ensures that the character at the given position is entirely
* visible in the Text Field widget. If the character is not already entirely
* visible, df_AdjustText changes the Widget's h_offsetring appropriately. If
* the text must be redrawn, df_AdjustText calls df_RedisplayText.
*
*/
static Boolean
#ifdef _NO_PROTO
df_AdjustText( tf, position, flag )
XmDataFieldWidget tf ;
XmTextPosition position ;
Boolean flag ;
#else
df_AdjustText(
XmDataFieldWidget tf,
XmTextPosition position,
#if NeedWidePrototypes
int flag )
#else
Boolean flag )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
int left_edge = 0;
int diff;
Dimension margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension thickness = 2 * (tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness);
Dimension temp;
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
{
if (XmTextF_max_char_size(tf) != 1)
{
left_edge = tf->core.width - margin_width + XmTextF_h_offset(tf) -
df_FindPixelLength(tf, (char *)(XmTextF_wc_value(tf) + position),
XmTextF_string_length(tf) - (int) position);
}
else
{
left_edge = tf->core.width - margin_width + XmTextF_h_offset(tf) -
df_FindPixelLength(tf, XmTextF_value(tf) + position,
XmTextF_string_length(tf) - (int) position);
}
}
else
{
if (XmTextF_max_char_size(tf) != 1)
{
left_edge = df_FindPixelLength(tf, (char *) XmTextF_wc_value(tf),
(int)position) + (int) XmTextF_h_offset(tf);
}
else
{
left_edge = df_FindPixelLength(tf, XmTextF_value(tf), (int)position) +
(int) XmTextF_h_offset(tf);
}
}
/*
* Make sure the cached GC has the clipping rectangle
* set to the current widget.
*/
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
if ((diff = left_edge - margin_width) < 0) {
/* We need to scroll the string to the right. */
if (!XtIsRealized((Widget)tf)) {
XmTextF_h_offset(tf) -= diff;
return True;
}
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_h_offset(tf) -= diff;
df_XmSetInvGC(tf, XmTextF_gc(tf));
df_XmSetFullGC(tf, XmTextF_gc(tf));
if (tf->core.height <= thickness)
temp = 0;
else
temp = tf->core.height - thickness;
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness,
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness,
XmTextF_margin_width(tf),
temp);
df_XmSetMarginGC(tf, XmTextF_gc(tf));
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
_XmDataFieldDrawInsertionPoint(tf, True);
return True;
} else if ((diff = ( left_edge -
(int)(tf->core.width - margin_width))) > 0) {
/* We need to scroll the string to the left. */
if (!XtIsRealized((Widget)tf)) {
XmTextF_h_offset(tf) -= diff;
return True;
}
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_h_offset(tf) -= diff;
df_XmSetInvGC(tf, XmTextF_gc(tf));
df_XmSetFullGC(tf, XmTextF_gc(tf));
if (tf->core.width <= thickness)
temp = 0;
else
temp = tf->core.width - thickness;
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
tf->core.width - margin_width,
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness,
XmTextF_margin_width(tf),
temp);
df_XmSetMarginGC(tf, XmTextF_gc(tf));
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
_XmDataFieldDrawInsertionPoint(tf, True);
return True;
}
if (flag) df_RedisplayText(tf, position, XmTextF_string_length(tf));
return False;
}
/*
* df_AdjustSize
*
* Adjust size will resize the text to ensure that all the text is visible.
* It will also adjust text that is shrunk. Shrinkage is limited to the
* size determined by the XmNcolumns resource.
*/
static void
#ifdef _NO_PROTO
df_AdjustSize( tf )
XmDataFieldWidget tf ;
#else
df_AdjustSize(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
XtGeometryResult result = XtGeometryYes;
int left_edge = 0;
int diff;
Boolean redisplay = False;
Dimension margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
if (XmTextF_max_char_size(tf) != 1) {
left_edge = df_FindPixelLength(tf, (char *) XmTextF_wc_value(tf),
XmTextF_string_length(tf)) + margin_width;
} else {
left_edge = df_FindPixelLength(tf, XmTextF_value(tf),
XmTextF_string_length(tf)) + margin_width;
}
if ((diff = (left_edge - (tf->core.width - (margin_width)))) > 0) {
if (XmTextF_in_setvalues(tf)) {
tf->core.width += diff;
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
XmTextF_new_h_offset(tf) = diff;
else
XmTextF_new_h_offset(tf) = margin_width - diff;
return;
}
/* Attempt to resize. If it doesn't succeed, do scrolling. */
result = df_TryResize(tf, tf->core.width + diff, tf->core.height);
if (result == XtGeometryYes)
{
XtWidgetProc resize;
_XmProcessLock();
resize = tf->core.widget_class->core_class.resize;
_XmProcessUnlock();
(*resize)((Widget)tf);
return;
} else
/* We need to scroll the string to the left. */
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
XmTextF_h_offset(tf) = diff;
else
XmTextF_h_offset(tf) = margin_width - diff;
} else {
Dimension width;
/* If the new size is smaller than core size, we need
* to shrink. Note: new size will never be less than the
* width determined by the columns resource.
*/
df_ComputeSize(tf, &width, NULL);
if (width < tf->core.width) {
if (XmTextF_in_setvalues(tf)) {
tf->core.width = width;
return;
}
result = df_TryResize(tf, width, tf->core.height);
if (result == XtGeometryYes)
{
XtWidgetProc resize;
_XmProcessLock();
resize = tf->core.widget_class->core_class.resize;
_XmProcessUnlock();
(*resize)((Widget)tf);
return;
}
}
}
redisplay = df_AdjustText(tf, XmTextF_cursor_position(tf), False);
if (!redisplay)
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
}
/* If MB_CUR_MAX == 1, insert is a char* pointer; else, it is a wchar_t *
* pointer and must be appropriately cast. In all cases, insert_length
* is the number of characters, not the number of bytes pointed to by
* insert
*/
static Boolean
#ifdef _NO_PROTO
df_ModifyVerify( tf, event, replace_prev, replace_next,
insert, insert_length, newInsert, free_insert )
XmDataFieldWidget tf ;
XEvent *event ;
XmTextPosition *replace_prev ;
XmTextPosition *replace_next ;
char **insert ;
int *insert_length ;
XmTextPosition *newInsert ;
int *free_insert ;
#else
df_ModifyVerify(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition *replace_prev,
XmTextPosition *replace_next,
char **insert,
int *insert_length,
XmTextPosition *newInsert,
int *free_insert )
#endif /* _NO_PROTO */
{
XmTextVerifyCallbackStruct vcb;
XmTextVerifyCallbackStructWcs wcs_vcb;
XmTextBlockRec newblock;
XmTextBlockRecWcs wcs_newblock;
Boolean do_free = False;
Boolean wcs_do_free = False;
int count;
wchar_t *wptr;
*newInsert = XmTextF_cursor_position(tf);
*free_insert = (int)False;
/* if there are no callbacks, don't waste any time... just return True */
if (!XmTextF_modify_verify_callback(tf) && !XmTextF_wcs_modify_verify_callback(tf))
return(True);
newblock.format = XmFMT_8_BIT;
newblock.length = *insert_length * XmTextF_max_char_size(tf);
if (*insert_length) {
if (XmTextF_modify_verify_callback(tf)){
newblock.ptr = (char *) XtMalloc((unsigned) newblock.length +
XmTextF_max_char_size(tf));
if (XmTextF_max_char_size(tf) == 1) {
(void)memcpy((void*)newblock.ptr, (void*)*insert,
newblock.length);
newblock.ptr[newblock.length]='\0';
} else {
count = (int) wcstombs(newblock.ptr, (wchar_t*)*insert,
newblock.length);
if (count < 0) { /* bad wchar; don't pass anything */
newblock.ptr[0] = '\0';
newblock.length = 0;
} else if (count == newblock.length) {
newblock.ptr[newblock.length] = '\0';
} else {
newblock.ptr[count] = '\0';
newblock.length = count;
}
}
do_free = True;
} else
newblock.ptr = NULL;
} else
newblock.ptr = NULL;
/* Fill in the appropriate structs */
vcb.reason = XmCR_MODIFYING_TEXT_VALUE;
vcb.event = (XEvent *) event;
vcb.doit = True;
vcb.currInsert = XmTextF_cursor_position(tf);
vcb.newInsert = XmTextF_cursor_position(tf);
vcb.text = &newblock;
vcb.startPos = *replace_prev;
vcb.endPos = *replace_next;
/* Call the modify verify callbacks. */
if (XmTextF_modify_verify_callback(tf))
XtCallCallbackList((Widget) tf, XmTextF_modify_verify_callback(tf),
(XtPointer) &vcb);
if (XmTextF_wcs_modify_verify_callback(tf) && vcb.doit){
if (do_free){ /* there is a char* modify verify callback; the data we
* want is in vcb struct */
wcs_newblock.wcsptr = (wchar_t *) XtMalloc((unsigned)
(vcb.text->length + 1) * sizeof(wchar_t));
wcs_newblock.length = mbstowcs(wcs_newblock.wcsptr, vcb.text->ptr,
vcb.text->length);
if (wcs_newblock.length < 0) { /* bad value; don't pass anything */
wcs_newblock.wcsptr[0] = 0L;
wcs_newblock.length = 0;
} else
wcs_newblock.wcsptr[wcs_newblock.length] = 0L;
} else { /* there was no char* modify verify callback; use data
* passed in from caller instead of that in vcb struct. */
wcs_newblock.wcsptr = (wchar_t *) XtMalloc((unsigned)
(*insert_length + 1) * sizeof(wchar_t));
if (XmTextF_max_char_size(tf) == 1)
wcs_newblock.length = mbstowcs(wcs_newblock.wcsptr, *insert,
*insert_length);
else {
wcs_newblock.length = *insert_length;
(void)memcpy((void*)wcs_newblock.wcsptr, (void*)*insert,
*insert_length * sizeof(wchar_t));
}
if (wcs_newblock.length < 0) { /* bad value; don't pass anything */
wcs_newblock.wcsptr[0] = 0L;
wcs_newblock.length = 0;
} else
wcs_newblock.wcsptr[wcs_newblock.length] = 0L;
}
wcs_do_free = True;
wcs_vcb.reason = XmCR_MODIFYING_TEXT_VALUE;
wcs_vcb.event = (XEvent *) event;
wcs_vcb.doit = True;
wcs_vcb.currInsert = vcb.currInsert;
wcs_vcb.newInsert = vcb.newInsert;
wcs_vcb.text = &wcs_newblock;
wcs_vcb.startPos = vcb.startPos;
wcs_vcb.endPos = vcb.endPos;
XtCallCallbackList((Widget) tf, XmTextF_wcs_modify_verify_callback(tf),
(XtPointer) &wcs_vcb);
}
/*
* copy the newblock.ptr, length, start, and
* end to the pointers passed
*/
if (XmTextF_wcs_modify_verify_callback(tf))
{ /* use wcs_vcb data */
*insert_length = wcs_vcb.text->length; /* length is char count*/
if (wcs_vcb.doit)
{
if (XmTextF_max_char_size(tf) == 1)
{ /* caller expects char */
wcs_vcb.text->wcsptr[wcs_vcb.text->length] = 0L;
if (*insert_length > 0)
{
*insert = XtMalloc((unsigned) (*insert_length + 1) \
* sizeof(wchar_t));
*free_insert = (int)True;
count = wcstombs(*insert, wcs_vcb.text->wcsptr,
*insert_length + 1);
if (count < 0)
{
(*insert)[0] = 0;
*insert_length = 0;
}
}
}
else
{ /* callback struct has wchar*; caller expects wchar* */
if (*insert_length > 0)
{
*insert = XtMalloc((unsigned)(*insert_length + 1) \
* sizeof(wchar_t));
*free_insert = (int)True;
(void)memcpy((void*)*insert, (void*)wcs_vcb.text->wcsptr,
*insert_length * sizeof(wchar_t));
wptr = (wchar_t*) *insert;
wptr[*insert_length] = 0L;
}
}
*replace_prev = wcs_vcb.startPos;
*replace_next = wcs_vcb.endPos;
*newInsert = wcs_vcb.newInsert;
}
}
else
{ /* use vcb data */
if (vcb.doit)
{
if (XmTextF_max_char_size(tf) == 1)
{ /* caller expects char* */
*insert_length = vcb.text->length;
if (*insert_length > 0)
{
*insert = XtMalloc((unsigned) *insert_length + 1);
*free_insert = (int)True;
(void)memcpy((void*)*insert, (void*)vcb.text->ptr,
*insert_length);
(*insert)[*insert_length] = 0;
}
}
else
{ /* caller expects wchar_t* back */
*insert_length =
_XmDataFieldCountCharacters(tf, vcb.text->ptr,
vcb.text->length);
if (*insert_length > 0)
{
*insert =
XtMalloc((unsigned)(*insert_length + 1) *
sizeof(wchar_t));
*free_insert = (int)True;
count = mbstowcs((wchar_t*)*insert, vcb.text->ptr,
*insert_length);
wptr = (wchar_t*) *insert;
if (count < 0) {
wptr[0] = 0L;
*insert_length = 0;
}
else
{
wptr[count] = 0L;
}
}
}
*replace_prev = vcb.startPos;
*replace_next = vcb.endPos;
*newInsert = vcb.newInsert;
}
}
if (do_free) {
XtFree(newblock.ptr);
}
if (wcs_do_free) {
XtFree((char*)wcs_newblock.wcsptr);
}
/* If doit becomes False, then don't allow the change. */
if (XmTextF_wcs_modify_verify_callback(tf))
return wcs_vcb.doit;
else
return vcb.doit;
}
static void
#ifdef _NO_PROTO
df_ResetClipOrigin(tf, clip_mask_reset)
XmDataFieldWidget tf;
Boolean clip_mask_reset;
#else /* _NO_PROTO */
df_ResetClipOrigin(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int clip_mask_reset)
#else
Boolean clip_mask_reset)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
unsigned long valuemask = (GCTileStipXOrigin | GCTileStipYOrigin |
GCClipXOrigin | GCClipYOrigin);
XGCValues values;
int x, y, clip_mask_x, clip_mask_y;
Position x_pos, y_pos;
(void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x_pos, &y_pos);
if (!XtIsRealized((Widget)tf)) return;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
x = (int) x_pos; y = (int) y_pos;
x -=(XmTextF_cursor_width(tf) >> 1) + 1;
clip_mask_y = y = (y + XmTextF_font_descent(tf)) - XmTextF_cursor_height(tf);
if (x < (int)(tf->primitive.highlight_thickness +
tf->primitive.shadow_thickness + XmTextF_margin_width(tf))){
clip_mask_x = tf->primitive.highlight_thickness +
tf->primitive.shadow_thickness + (int)(XmTextF_margin_width(tf));
} else
clip_mask_x = x;
if (clip_mask_reset) {
values.ts_x_origin = x;
values.ts_y_origin = y;
values.clip_x_origin = clip_mask_x;
values.clip_y_origin = clip_mask_y;
XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
}
else
XSetTSOrigin(XtDisplay(tf), XmTextF_image_gc(tf), x, y);
}
static void
#ifdef _NO_PROTO
df_InvertImageGC (tf)
XmDataFieldWidget tf ;
#else
df_InvertImageGC (
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
unsigned long valuemask = (GCForeground | GCBackground);
XGCValues values;
Display *dpy = XtDisplay(tf);
if (XmTextF_have_inverted_image_gc(tf)) return;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
if (!XmTextF_overstrike(tf)) {
values.background = tf->primitive.foreground;
values.foreground = tf->core.background_pixel;
XChangeGC(dpy, XmTextF_image_gc(tf), valuemask, &values);
}
XmTextF_have_inverted_image_gc(tf) = True;
}
static void
#ifdef _NO_PROTO
df_ResetImageGC (tf)
XmDataFieldWidget tf ;
#else
df_ResetImageGC (
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
unsigned long valuemask = (GCForeground | GCBackground);
XGCValues values;
Display *dpy = XtDisplay(tf);
if (!XmTextF_have_inverted_image_gc(tf)) return;
if (!XmTextF_has_rect(tf))
{
_XmDataFieldSetClipRect(tf);
}
if (!XmTextF_overstrike(tf))
{
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
XChangeGC(dpy, XmTextF_image_gc(tf), valuemask, &values);
}
XmTextF_have_inverted_image_gc(tf) = False;
}
/*
* Calls the motion verify callback. If the doit flag is true,
* then reset the cursor_position and call df_AdjustText() to
* move the text if need be.
*/
void
#ifdef _NO_PROTO
_XmDataFielddf_SetCursorPosition( tf, event, position,
adjust_flag, call_cb)
XmDataFieldWidget tf ;
XEvent *event ;
XmTextPosition position ;
Boolean adjust_flag ;
Boolean call_cb ;
#else
_XmDataFielddf_SetCursorPosition(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition position,
#if NeedWidePrototypes
int adjust_flag,
int call_cb)
#else
Boolean adjust_flag,
Boolean call_cb)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
df_SetCursorPosition(tf, event, position, adjust_flag, call_cb, True);
}
static void
#ifdef _NO_PROTO
df_SetCursorPosition( tf, event, position,
adjust_flag, call_cb, set_dest)
XmDataFieldWidget tf ;
XEvent *event ;
XmTextPosition position ;
Boolean adjust_flag ;
Boolean call_cb ;
Boolean set_dest;
#else
df_SetCursorPosition(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition position,
#if NeedWidePrototypes
int adjust_flag,
int call_cb,
int set_dest)
#else
Boolean adjust_flag,
Boolean call_cb,
Boolean set_dest)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextVerifyCallbackStruct cb;
Boolean flag = False;
XPoint xmim_point;
_XmHighlightRec *hl_list = XmTextF_highlight(tf).list;
int i;
if (position < 0) position = 0;
if (position > XmTextF_string_length(tf))
position = XmTextF_string_length(tf);
if (XmTextF_cursor_position(tf) != position && call_cb) {
/* Call Motion Verify Callback before Cursor Changes Positon */
cb.reason = XmCR_MOVING_INSERT_CURSOR;
cb.event = event;
cb.currInsert = XmTextF_cursor_position(tf);
cb.newInsert = position;
cb.doit = True;
XtCallCallbackList((Widget) tf, XmTextF_motion_verify_callback(tf),
(XtPointer) &cb);
if (!cb.doit) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
return;
}
}
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_cursor_position(tf) = position;
if (!XmTextF_add_mode(tf) && XmTextF_pending_off(tf) && XmTextF_has_primary(tf)) {
df_SetSelection(tf, position, position, True);
flag = True;
}
/* Deterimine if we need an inverted image GC or not. Get the highlight
* record for the cursor position. If position is on a boundary of
* a highlight, then we always display cursor in normal mode (i.e. set
* normal image GC). If position is within a selected highlight rec,
* then make sure the image GC is inverted. If we've moved out of a
* selected highlight region, restore the normal image GC. */
for (i = XmTextF_highlight(tf).number - 1; i >= 0; i--){
if (position >= hl_list[i].position || i == 0)
break;
}
if (position == hl_list[i].position)
df_ResetImageGC(tf);
else if (hl_list[i].mode != XmHIGHLIGHT_SELECTED)
df_ResetImageGC(tf);
else
df_InvertImageGC(tf);
if (adjust_flag) (void) df_AdjustText(tf, position, flag);
df_ResetClipOrigin(tf, False);
XmTextF_refresh_ibeam_off(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
(void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf),
&xmim_point.x, &xmim_point.y);
XmImVaSetValues((Widget)tf, XmNspotLocation, &xmim_point, NULL);
if (set_dest)
(void) df_SetDestination((Widget) tf, XmTextF_cursor_position(tf), False,
XtLastTimestampProcessed(XtDisplay((Widget)tf)));
}
/*
* This routine is used to verify that the positions are within the bounds
* of the current DataField widgets value. Also, it ensures that left is
* less than right.
*/
static void
#ifdef _NO_PROTO
df_VerifyBounds( tf, from, to )
XmDataFieldWidget tf ;
XmTextPosition *from ;
XmTextPosition *to ;
#else
df_VerifyBounds(
XmDataFieldWidget tf,
XmTextPosition *from,
XmTextPosition *to )
#endif /* _NO_PROTO */
{
XmTextPosition tmp;
if (*from < 0)
*from = 0;
else if (*from > XmTextF_string_length(tf)) {
*from = XmTextF_string_length(tf);
}
if (*to < 0 )
*to = 0;
else if (*to > XmTextF_string_length(tf)) {
*to = XmTextF_string_length(tf);
}
if (*from > *to) {
tmp = *to;
*to = *from;
*from = tmp;
}
}
/*
* Function _XmDataFieldReplaceText
*
* _XmDataFieldReplaceText is a utility function for the text-modifying
* action procedures below (df_InsertChar, df_DeletePrevChar, and so on).
* _XmDataFieldReplaceText does the real work of editing the string,
* including:
*
* (1) invoking the modify verify callbacks,
* (2) allocating more memory for the string if necessary,
* (3) doing the string manipulation,
* (4) moving the selection (the insertion point), and
* (5) redrawing the text.
*
* Though the procedure claims to take a char* argument, MB_CUR_MAX determines
* what the different routines will actually pass to it. If MB_CUR_MAX is
* greater than 1, then "insert" points to wchar_t data and we must set up
* the appropriate cast. In all cases, insert_length is the number of
* characters (not bytes) to be inserted.
*/
Boolean
#ifdef _NO_PROTO
_XmDataFieldReplaceText( tf, event, replace_prev, replace_next,
insert, insert_length, move_cursor )
XmDataFieldWidget tf ;
XEvent *event ;
XmTextPosition replace_prev ;
XmTextPosition replace_next ;
char *insert ;
int insert_length ;
Boolean move_cursor ;
#else
_XmDataFieldReplaceText(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition replace_prev,
XmTextPosition replace_next,
char *insert,
int insert_length,
Boolean move_cursor )
#endif /* _NO_PROTO */
{
int replace_length, i;
char *src, *dst;
wchar_t *wc_src, *wc_dst;
int delta = 0;
XmTextPosition cursorPos, newInsert;
XmTextPosition old_pos = replace_prev;
int free_insert = (int)False;
Position x1, y1, x2, y2;
df_VerifyBounds(tf, &replace_prev, &replace_next);
if (!XmTextF_editable(tf)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
return False;
}
replace_length = (int) (replace_next - replace_prev);
delta = insert_length - replace_length;
/* Disallow insertions that go beyond max length boundries.
*/
if ((delta >= 0) &&
((XmTextF_string_length(tf) + delta) - (XmTextF_max_length(tf)) > 0)) {
if (XmTextF_verify_bell(tf))
{
XBell(XtDisplay(tf), 0);
}
return False;
}
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
{
df_GetXYFromPos(tf, 0, &x1, &y1);
}
/* If there are modify verify callbacks, verify that we want to continue
* the action.
*/
newInsert = XmTextF_cursor_position(tf);
if (XmTextF_modify_verify_callback(tf) || XmTextF_wcs_modify_verify_callback(tf)) {
/* If the function df_ModifyVerify() returns false then don't
* continue with the action.
*/
if (!df_ModifyVerify(tf, event, &replace_prev, &replace_next,
&insert, &insert_length, &newInsert, &free_insert)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay(tf), 0);
if (free_insert) XtFree(insert);
return False;
} else {
df_VerifyBounds(tf, &replace_prev, &replace_next);
replace_length = (int) (replace_next - replace_prev);
delta = insert_length - replace_length;
/* Disallow insertions that go beyond max length boundries.
*/
if ((delta >= 0) &&
((XmTextF_string_length(tf) + delta) - (XmTextF_max_length(tf)) > 0)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay(tf), 0);
if (free_insert) XtFree(insert);
return False;
}
}
}
/* make sure selections are turned off prior to changeing text */
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
_XmDataFieldDrawInsertionPoint(tf, False);
/* Allocate more space if we need it.
*/
if (XmTextF_max_char_size(tf) == 1){
if (XmTextF_string_length(tf) + insert_length - replace_length >=
XmTextF_size_allocd(tf))
{
XmTextF_size_allocd(tf) += MAX(insert_length + TEXT_INCREMENT,
(XmTextF_size_allocd(tf) * 2));
XmTextF_value(tf) = (char *) XtRealloc((char*)XmTextF_value(tf),
(unsigned) (XmTextF_size_allocd(tf) * sizeof(char)));
}
} else {
if ((XmTextF_string_length(tf) + insert_length - replace_length) *
sizeof(wchar_t) >= XmTextF_size_allocd(tf))
{
XmTextF_size_allocd(tf) +=
MAX((insert_length + TEXT_INCREMENT)*sizeof(wchar_t),
(XmTextF_size_allocd(tf) * 2));
XmTextF_wc_value(tf) = (wchar_t *) XtRealloc((char*)XmTextF_wc_value(tf),
(unsigned) XmTextF_size_allocd(tf));
}
}
if (XmTextF_has_primary(tf) && replace_prev < XmTextF_prim_pos_right(tf) &&
replace_next > XmTextF_prim_pos_left(tf)) {
if (replace_prev <= XmTextF_prim_pos_left(tf)) {
if (replace_next < XmTextF_prim_pos_right(tf)) {
/* delete encompasses left half of the selection
* so move left endpoint
*/
XmTextF_prim_pos_left(tf) = replace_next;
} else {
/* delete encompasses the selection so set selection to NULL */
XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf);
}
} else {
if (replace_next > XmTextF_prim_pos_right(tf)) {
/* delete encompasses the right half of the selection
* so move right endpoint
*/
XmTextF_prim_pos_right(tf) = replace_next;
} else {
/* delete is completely within the selection
* so set selection to NULL
*/
XmTextF_prim_pos_right(tf) = XmTextF_prim_pos_left(tf);
}
}
}
if (XmTextF_max_char_size(tf) == 1) {
if (replace_length > insert_length)
/* We need to shift the text at and after replace_next to the left. */
for (src = XmTextF_value(tf) + replace_next,
dst = src + (insert_length - replace_length),
i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
i > 0;
++src, ++dst, --i)
*dst = *src;
else if (replace_length < insert_length)
/* We need to shift the text at and after replace_next to the right. */
/* Need to add 1 to string_length to handle the NULL terminator on */
/* the string. */
for (src = XmTextF_value(tf) + XmTextF_string_length(tf),
dst = src + (insert_length - replace_length),
i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
i > 0;
--src, --dst, --i)
*dst = *src;
/* Update the string.
*/
if (insert_length != 0) {
for (src = insert,
dst = XmTextF_value(tf) + replace_prev,
i = insert_length;
i > 0;
++src, ++dst, --i)
*dst = *src;
}
} else { /* have wchar_t* data */
if (replace_length > insert_length)
/* We need to shift the text at and after replace_next to the left. */
for (wc_src = XmTextF_wc_value(tf) + replace_next,
wc_dst = wc_src + (insert_length - replace_length),
i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
i > 0;
++wc_src, ++wc_dst, --i)
*wc_dst = *wc_src;
else if (replace_length < insert_length)
/* We need to shift the text at and after replace_next to the right. */
/* Need to add 1 to string_length to handle the NULL terminator on */
/* the string. */
for (wc_src = XmTextF_wc_value(tf) + XmTextF_string_length(tf),
wc_dst = wc_src + (insert_length - replace_length),
i = (int) ((XmTextF_string_length(tf) + 1) - replace_next);
i > 0;
--wc_src, --wc_dst, --i)
*wc_dst = *wc_src;
/* Update the string.
*/
if (insert_length != 0) {
for (wc_src = (wchar_t *)insert,
wc_dst = XmTextF_wc_value(tf) + replace_prev,
i = insert_length;
i > 0;
++wc_src, ++wc_dst, --i)
*wc_dst = *wc_src;
}
}
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
if (replace_prev <= XmTextF_prim_pos_left(tf)) {
XmTextF_prim_pos_left(tf) += delta;
XmTextF_prim_pos_right(tf) += delta;
}
if (XmTextF_prim_pos_left(tf) > XmTextF_prim_pos_right(tf))
XmTextF_prim_pos_right(tf) = XmTextF_prim_pos_left(tf);
}
/* make sure the selection are redisplay, since
* they were turned off earlier
*/
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
{
XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf),
XmHIGHLIGHT_SELECTED);
}
XmTextF_string_length(tf) += insert_length - replace_length;
if (move_cursor) {
if (XmTextF_cursor_position(tf) != newInsert) {
if (newInsert > XmTextF_string_length(tf)) {
cursorPos = XmTextF_string_length(tf);
} else if (newInsert < 0) {
cursorPos = 0;
} else {
cursorPos = newInsert;
}
} else
cursorPos = replace_next + (insert_length - replace_length);
if (event != NULL) {
(void)df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
} else {
(void) df_SetDestination((Widget)tf, cursorPos, False,
XtLastTimestampProcessed(XtDisplay((Widget)tf)));
}
_XmDataFielddf_SetCursorPosition(tf, event, cursorPos, False, True);
}
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
{
df_GetXYFromPos(tf, 0, &x2, &y2);
y2 -= XmTextF_font_ascent(tf);
if ((x2 > 0) && (x1 < x2) && (y2 < y1))
{
if (x1 < 0) x1 = 0;
/* PWC - Erase leading space (delta of old & new first position) */
df_XmSetInvGC(tf, XmTextF_gc(tf));
XFillRectangle(XtDisplay(tf), XtWindow(tf), XmTextF_gc(tf),
x1, y2, x2, y1);
#if PWC_DEBUG
printf("Fill Rectangle :: x1(%d), y1(%d) - x2(%d), y2(%d)\n",
x1, y2, x2, y1);
#endif
}
}
if (XmTextF_resize_width(tf) && XmTextF_do_resize(tf))
{
df_AdjustSize(tf);
} else {
df_AdjustText(tf, XmTextF_cursor_position(tf), False);
df_RedisplayText(tf, old_pos, XmTextF_string_length(tf));
}
_XmDataFieldDrawInsertionPoint(tf, True);
if (free_insert) {
XtFree(insert);
}
return True;
}
/*
* Reset selection flag and selection positions and then display
* the new settings.
*/
void
#ifdef _NO_PROTO
_XmDataFieldDeselectSelection( w, disown, sel_time )
Widget w ;
Boolean disown ;
Time sel_time ;
#else
_XmDataFieldDeselectSelection(
Widget w,
#if NeedWidePrototypes
int disown,
#else
Boolean disown,
#endif /* NeedWidePrototypes */
Time sel_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (disown)
{
/*
* Disown the primary selection (This function is a no-op if
* this widget doesn't own the primary selection)
*/
XtDisownSelection(w, XA_PRIMARY, sel_time);
}
if (tf != NULL) {
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_has_primary(tf) = False;
DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
if (!XmTextF_has_focus(tf))
{
XmDataFieldSetAddMode(w, False);
}
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/*
* Finds the cursor position from the given X value.
*/
static XmTextPosition
#ifdef _NO_PROTO
df_GetPosFromX( tf, x )
XmDataFieldWidget tf ;
Position x ;
#else
df_GetPosFromX(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int x )
#else
Position x )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextPosition position;
int temp_x = 0;
int next_char_width = 0;
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
return RightAlignedGetPosFromX(tf, x);
/* Decompose the x to equal the length of the text string */
temp_x += (int) XmTextF_h_offset(tf);
/* Next width is an offset allowing button presses on the left side
* of a character to select that character, while button presses
* on the rigth side of the character select the NEXT character.
*/
if (XmTextF_string_length(tf) > 0) {
if (XmTextF_max_char_size(tf) != 1) {
next_char_width = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf), 1);
} else {
next_char_width = df_FindPixelLength(tf, XmTextF_value(tf), 1);
}
}
for (position = 0; temp_x + next_char_width/2 < (int) x &&
position < XmTextF_string_length(tf); position++){
temp_x+=next_char_width; /*
* We still haven't reached the x pos.
* Add the width and find the next chars
* width.
*/
/*
* If there is a next position, find its width. Otherwise, use the
* current "next" width.
*/
if (XmTextF_string_length(tf) > position + 1) {
if (XmTextF_max_char_size(tf) != 1) {
next_char_width = df_FindPixelLength(tf,
(char*)(XmTextF_wc_value(tf) + position + 1), 1);
} else {
next_char_width = df_FindPixelLength(tf,
XmTextF_value(tf) + position + 1, 1);
}
}
} /* for */
return position;
}
/*
* Finds the cursor position from the given X value.
*/
static XmTextPosition
#ifdef _NO_PROTO
RightAlignedGetPosFromX( tf, x )
XmDataFieldWidget tf ;
Position x ;
#else
RightAlignedGetPosFromX( XmDataFieldWidget tf,
#if NeedWidePrototypes
int x )
#else
Position x )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextPosition position;
int margin_width = XmTextF_margin_width(tf) +
tf->primitive.highlight_thickness +
tf->primitive.shadow_thickness;
int temp_x;
int next_char_width = 0;
position = XmTextF_string_length(tf);
temp_x = tf->core.width - margin_width + XmTextF_h_offset(tf);
if (XmTextF_string_length(tf) > 0) {
if (XmTextF_max_char_size(tf) != 1) {
next_char_width = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf) +
position - 1, 1);
} else {
next_char_width = df_FindPixelLength(tf, XmTextF_value(tf) +
position - 1, 1);
}
}
for (; x < (temp_x - next_char_width / 2) && (position > 0); position--)
{
temp_x -= next_char_width; /*
* We still haven't reached the x pos.
* Add the width and find the next chars
* width.
*/
/*
* If there is a next position, find its width. Otherwise, use the
* current "next" width.
*/
if (position > 1)
{
if (XmTextF_max_char_size(tf) != 1) {
next_char_width = df_FindPixelLength(tf,
(char*)(XmTextF_wc_value(tf) + position - 2), 1);
} else {
next_char_width = df_FindPixelLength(tf,
XmTextF_value(tf) + position - 2 , 1);
}
}
} /* for */
#if PWC_DEBUG
printf("CursorPos(%d), x(%d)\n", position, x);
#endif
return position;
}
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
df_SetDestination( w, position, disown, set_time )
Widget w ;
XmTextPosition position ;
Boolean disown ;
Time set_time ;
#else
df_SetDestination(
Widget w,
XmTextPosition position,
#if NeedWidePrototypes
int disown,
#else
Boolean disown,
#endif /* NeedWidePrototypes */
Time set_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean result = TRUE;
Atom MOTIF_DESTINATION = XmInternAtom(XtDisplay(w),
"MOTIF_DESTINATION", False);
if (!XtIsRealized(w)) return False;
_XmDataFieldDrawInsertionPoint(tf, False);
if (!disown) {
if (!XmTextF_has_destination(tf)) {
if (!set_time) set_time = df_GetServerTime(w);
result = XtOwnSelection(w, MOTIF_DESTINATION, set_time,
_XmDataFieldConvert,
_XmDataFieldLoseSelection,
(XtSelectionDoneProc) NULL);
XmTextF_dest_time(tf) = set_time;
XmTextF_has_destination(tf) = result;
if (result) _XmSetDestination(XtDisplay(w), w);
_XmDataFToggleCursorGC(w);
}
} else {
if (XmTextF_has_destination(tf))
if (!set_time) set_time = df_GetServerTime(w);
XtDisownSelection(w, MOTIF_DESTINATION, set_time);
/* Call XmGetDestination(dpy) to get widget that last had
destination cursor. */
if (w == XmGetDestination(XtDisplay(w)))
_XmSetDestination(XtDisplay(w), (Widget)NULL);
XmTextF_has_destination(tf) = False;
_XmDataFToggleCursorGC(w);
}
_XmDataFieldDrawInsertionPoint(tf, True);
return result;
}
Boolean
#ifdef _NO_PROTO
_XmDataFielddf_SetDestination( w, position, set_time )
Widget w ;
XmTextPosition position ;
Time set_time ;
#else
_XmDataFielddf_SetDestination(
Widget w,
XmTextPosition position,
Time set_time )
#endif /* _NO_PROTO */
{
Boolean result;
result = df_SetDestination(w, position, False, set_time);
return result;
}
/*
* Calls the losing focus verify callback to verify that the application
* want to traverse out of the text field widget. Returns the result.
*/
static Boolean
#ifdef _NO_PROTO
df_VerifyLeave( tf, event )
XmDataFieldWidget tf ;
XEvent *event ;
#else
df_VerifyLeave(
XmDataFieldWidget tf,
XEvent *event )
#endif /* _NO_PROTO */
{
XmTextVerifyCallbackStruct cbdata;
cbdata.reason = XmCR_LOSING_FOCUS;
cbdata.event = event;
cbdata.doit = True;
cbdata.currInsert = XmTextF_cursor_position(tf);
cbdata.newInsert = XmTextF_cursor_position(tf);
cbdata.startPos = XmTextF_cursor_position(tf);
cbdata.endPos = XmTextF_cursor_position(tf);
cbdata.text = NULL;
XtCallCallbackList((Widget) tf, XmTextF_losing_focus_callback(tf),
(XtPointer) &cbdata);
return(cbdata.doit);
}
/* This routine is used to determine if two adjacent wchar_t characters
* constitute a word boundary */
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
_XmDataFieldIsWordBoundary( tf, pos1, pos2 )
XmDataFieldWidget tf ;
XmTextPosition pos1 ;
XmTextPosition pos2 ;
#else
_XmDataFieldIsWordBoundary(
XmDataFieldWidget tf,
XmTextPosition pos1 ,
XmTextPosition pos2 )
#endif /* _NO_PROTO */
{
int size_pos1 = 0;
int size_pos2 = 0;
char s1[MB_LEN_MAX];
char s2[MB_LEN_MAX];
/* if positions aren't adjacent, return False */
if(pos1 < pos2 && ((pos2 - pos1) != 1))
return False;
else if(pos2 < pos1 && ((pos1 - pos2) != 1))
return False;
if (XmTextF_max_char_size(tf) == 1) { /* data is char* and one-byte per char */
if (isspace((int)(unsigned char)XmTextF_value(tf)[pos1]) ||
isspace((int)(unsigned char)XmTextF_value(tf)[pos2])) return True;
} else {
size_pos1 = wctomb(s1, XmTextF_wc_value(tf)[pos1]);
size_pos2 = wctomb(s2, XmTextF_wc_value(tf)[pos2]);
if (size_pos1 == 1 && (size_pos2 != 1 ||
isspace((int)(unsigned char)*s1)))
return True;
if (size_pos2 == 1 && (size_pos1 != 1 ||
isspace((int)(unsigned char)*s2)))
return True;
}
return False;
}
/* This routine accepts an array of wchar_t's containing wchar encodings
* of whitespace characters (and the number of array elements), comparing
* the wide character passed to each element of the array. If a match
* is found, we got a white space. This routine exists only because
* iswspace(3c) is not yet standard. If a system has isw* available,
* calls to this routine should be changed to iswspace(3c) (and callers
* should delete initialization of the array), and this routine should
* be deleted. Its a stop gap measure to avoid allocating an instance
* variable for the white_space array and/or declaring a widget wide
* global for the data and using a macro. Its ugly, but it works and
* in the long run will be replaced by standard functionality. */
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
_XmDataFieldIsWSpace( wide_char, white_space, num_entries )
wchar_t wide_char ;
wchar_t * white_space ;
int num_entries ;
#else
_XmDataFieldIsWSpace(
wchar_t wide_char,
wchar_t * white_space ,
int num_entries )
#endif /* _NO_PROTO */
{
int i;
for (i=num_entries; i > 0; i--){
if (wide_char == white_space[i]) return True;
}
return False;
}
static void
#ifdef _NO_PROTO
df_FindWord( tf, begin, left, right )
XmDataFieldWidget tf ;
XmTextPosition begin ;
XmTextPosition *left ;
XmTextPosition *right ;
#else
df_FindWord(
XmDataFieldWidget tf,
XmTextPosition begin,
XmTextPosition *left,
XmTextPosition *right )
#endif /* _NO_PROTO */
{
XmTextPosition start, end;
wchar_t white_space[3];
if (XmTextF_max_char_size(tf) == 1) {
for (start = begin; start > 0; start--) {
if (isspace((int)(unsigned char)XmTextF_value(tf)[start - 1])) {
break;
}
}
*left = start;
for (end = begin; end <= XmTextF_string_length(tf); end++) {
if (isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
end++;
break;
}
}
*right = end - 1;
} else { /* check for iswspace and iswordboundary in each direction */
(void)mbtowc(&white_space[0], " ", 1);
(void)mbtowc(&white_space[1], "\n", 1);
(void)mbtowc(&white_space[2], "\t", 1);
for (start = begin; start > 0; start --) {
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start-1],white_space, 3)
|| _XmDataFieldIsWordBoundary(tf, (XmTextPosition) start - 1,
start)) {
break;
}
}
*left = start;
for (end = begin; end <= XmTextF_string_length(tf); end++) {
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)){
end++;
break;
} else if (end < XmTextF_string_length(tf)) {
if (_XmDataFieldIsWordBoundary(tf, end, (XmTextPosition)end + 1)){
end += 2; /* want to return position of next word; end + 1 */
break; /* is that position && *right = end - 1... */
}
}
}
*right = end - 1;
}
}
static void
#ifdef _NO_PROTO
df_FindPrevWord( tf, left, right )
XmDataFieldWidget tf ;
XmTextPosition *left ;
XmTextPosition *right ;
#else
df_FindPrevWord(
XmDataFieldWidget tf,
XmTextPosition *left,
XmTextPosition *right )
#endif /* _NO_PROTO */
{
XmTextPosition start = XmTextF_cursor_position(tf);
wchar_t white_space[3];
if (XmTextF_max_char_size(tf) != 1) {
(void)mbtowc(&white_space[0], " ", 1);
(void)mbtowc(&white_space[1], "\n", 1);
(void)mbtowc(&white_space[2], "\t", 1);
}
if (XmTextF_max_char_size(tf) == 1) {
if ((start > 0) &&
(isspace((int)(unsigned char)XmTextF_value(tf)[start - 1]))) {
for (; start > 0; start--) {
if (!isspace((int)(unsigned char)XmTextF_value(tf)[start - 1])) {
start--;
break;
}
}
}
df_FindWord(tf, start, left, right);
} else {
if ((start > 0) && (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start - 1],
white_space, 3))) {
for (; start > 0; start--) {
if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[start -1],
white_space, 3)){
start--;
break;
}
}
} else if ((start > 0) &&
_XmDataFieldIsWordBoundary(tf, (XmTextPosition) start - 1,
start)){
start--;
}
df_FindWord(tf, start, left, right);
}
}
static void
#ifdef _NO_PROTO
df_FindNextWord( tf, left, right )
XmDataFieldWidget tf ;
XmTextPosition *left ;
XmTextPosition *right ;
#else
df_FindNextWord(
XmDataFieldWidget tf,
XmTextPosition *left,
XmTextPosition *right )
#endif /* _NO_PROTO */
{
XmTextPosition end = XmTextF_cursor_position(tf);
wchar_t white_space[3];
if (XmTextF_max_char_size(tf) != 1) {
(void)mbtowc(&white_space[0], " ", 1);
(void)mbtowc(&white_space[1], "\n", 1);
(void)mbtowc(&white_space[2], "\t", 1);
}
if(XmTextF_max_char_size(tf) == 1) {
if (isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
for (end = XmTextF_cursor_position(tf);
end < XmTextF_string_length(tf); end++) {
if (!isspace((int)(unsigned char)XmTextF_value(tf)[end])) {
break;
}
}
}
df_FindWord(tf, end, left, right);
/*
* Set right to the last whitespace following the end of the
* current word.
*/
while (*right < XmTextF_string_length(tf) &&
isspace((int)(unsigned char)XmTextF_value(tf)[(int)*right]))
*right = *right + 1;
if (*right < XmTextF_string_length(tf))
*right = *right - 1;
} else {
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)) {
for ( ; end < XmTextF_string_length(tf); end ++) {
if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[end], white_space, 3)) {
break;
}
}
} else { /* if for other reasons at word boundry, advance to next word */
if ((end < XmTextF_string_length(tf)) &&
_XmDataFieldIsWordBoundary(tf, end, (XmTextPosition) end + 1))
end++;
}
df_FindWord(tf, end, left, right);
/*
* If word boundary caused by whitespace, set right to the last
* whitespace following the end of the current word.
*/
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[(int)*right], white_space, 3)) {
while (*right < XmTextF_string_length(tf) &&
_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[(int)*right],
white_space, 3)) {
*right = *right + 1;
}
if (*right < XmTextF_string_length(tf))
*right = *right - 1;
}
}
}
static void
#ifdef _NO_PROTO
df_CheckDisjointSelection( w, position, sel_time )
Widget w ;
XmTextPosition position ;
Time sel_time ;
#else
df_CheckDisjointSelection(
Widget w,
XmTextPosition position,
Time sel_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left = 0, right = 0;
if (XmTextF_add_mode(tf) ||
(XmDataFieldGetSelectionPosition(w, &left, &right) && left != right &&
position >= left && position <= right))
XmTextF_pending_off(tf) = FALSE;
else
XmTextF_pending_off(tf) = TRUE;
if (left == right) {
(void) df_SetDestination(w, position, False, sel_time);
XmTextF_prim_anchor(tf) = position;
} else {
(void) df_SetDestination(w, position, False, sel_time);
if (!XmTextF_add_mode(tf)) XmTextF_prim_anchor(tf) = position;
}
}
static Boolean
#ifdef _NO_PROTO
df_NeedsPendingDelete( tf )
XmDataFieldWidget tf ;
#else
df_NeedsPendingDelete(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
return (XmTextF_add_mode(tf) ?
(XmTextF_pending_delete(tf) &&
XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
XmTextF_prim_pos_left(tf) <= XmTextF_cursor_position(tf) &&
XmTextF_prim_pos_right(tf) >= XmTextF_cursor_position(tf)) :
(XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)));
}
static Boolean
#ifdef _NO_PROTO
df_NeedsPendingDeleteDisjoint( tf )
XmDataFieldWidget tf ;
#else
df_NeedsPendingDeleteDisjoint(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
return (XmTextF_pending_delete(tf) &&
XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
XmTextF_prim_pos_left(tf) <= XmTextF_cursor_position(tf) &&
XmTextF_prim_pos_right(tf) >= XmTextF_cursor_position(tf));
}
static Time
#ifdef _NO_PROTO
df_GetServerTime( w )
Widget w ;
#else
df_GetServerTime(
Widget w )
#endif /* _NO_PROTO */
{
XEvent event;
EventMask shellMask;
while(!XtIsShell(w)) w = XtParent(w);
shellMask = XtBuildEventMask(w);
if (!(shellMask & PropertyChangeMask))
XSelectInput(XtDisplay(w), XtWindow(w),
(long)(shellMask | PropertyChangeMask));
XChangeProperty(XtDisplay(w), XtWindow(w), XA_WM_HINTS, XA_WM_HINTS,
32, PropModeAppend, (unsigned char *)NULL, 0);
XWindowEvent(XtDisplay(w), XtWindow(w), PropertyChangeMask, &event);
if (!(shellMask & PropertyChangeMask))
XSelectInput(XtDisplay(w), XtWindow(w), (long)shellMask);
return (event.xproperty.time);
}
static Boolean
PrintableString(XmDataFieldWidget tf,
char* str,
int n,
Boolean use_wchar) /* sometimes unused */
{
#ifdef SUPPORT_ZERO_WIDTH
/* some locales (such as Thai) have characters that are
* printable but non-spacing. These should be inserted,
* even if they have zero width.
*/
if (tf->text.max_char_size == 1) {
int i;
if (!use_wchar) {
for (i = 0; i < n; i++) {
if (!isprint((unsigned char)str[i])) {
return False;
}
}
} else {
char scratch[8];
wchar_t *ws = (wchar_t *) str;
for (i = 0; i < n; i++) {
if (wctomb(scratch, ws[i]) <= 0)
return False;
if (!isprint((unsigned char)scratch[0])) {
return False;
}
}
}
return True;
} else {
/* tf->text.max_char_size > 1 */
#ifdef HAS_WIDECHAR_FUNCTIONS
if (use_wchar) {
int i;
wchar_t *ws = (wchar_t *) str;
for (i = 0; i < n; i++) {
if (!iswprint(ws[i])) {
return False;
}
}
return True;
} else {
int i, csize;
wchar_t wc;
#ifndef NO_MULTIBYTE
for (i = 0, csize = mblen(str, tf->text.max_char_size);
i < n;
i += csize, csize=mblen(&(str[i]), tf->text.max_char_size))
#else
for (i = 0, csize = *str ? 1 : 0; i < n;
i += csize, csize = str[i] ? 1 : 0)
#endif
{
if (csize < 0)
return False;
if (mbtowc(&wc, &(str[i]), tf->text.max_char_size) <= 0)
return False;
if (!iswprint(wc)) {
return False;
}
}
}
#else /* HAS_WIDECHAR_FUNCTIONS */
/*
* This will only check if any single-byte characters are non-
* printable. Better than nothing...
*/
int i, csize;
if (!use_wchar) {
#ifndef NO_MULTIBYTE
for (i = 0, csize = mblen(str, tf->text.max_char_size);
i < n;
i += csize, csize=mblen(&(str[i]), tf->text.max_char_size))
#else
for (i = 0, csize = *str ? 1 : 0; i < n;
i += csize, csize = str[i] ? 1 : 0)
#endif
{
if (csize < 0)
return False;
if (csize == 1 && !isprint((unsigned char)str[i])) {
return False;
}
}
} else {
char scratch[8];
wchar_t *ws = (wchar_t *) str;
for (i = 0; i < n; i++) {
if ((csize = wctomb(scratch, ws[i])) <= 0)
return False;
if (csize == 1 && !isprint((unsigned char)scratch[0])) {
return False;
}
}
}
#endif /* HAS_WIDECHAR_FUNCTIONS */
return True;
}
#else /* SUPPORT_ZERO_WIDTH */
if (TextF_UseFontSet(tf)) {
if(use_wchar)
return (XwcTextEscapement((XFontSet)TextF_Font(tf), (wchar_t *)str, n) != 0);
else
return (XmbTextEscapement((XFontSet)TextF_Font(tf), str, n) != 0);
#ifdef USE_XFT
} else if (TextF_UseXft(tf)) {
XGlyphInfo ext;
XftTextExtentsUtf8(XtDisplay(tf), TextF_XftFont(tf),
(FcChar8*)str, n, &ext);
return ext.xOff != 0;
#endif
}
else {
if (use_wchar) {
char cache[100];
char *tmp, *cache_ptr;
wchar_t *tmp_str;
int ret_val, buf_size, count;
Boolean is_printable;
buf_size = (n * MB_CUR_MAX) + 1;
cache_ptr = tmp = XmStackAlloc(buf_size, cache);
tmp_str = (wchar_t *)str;
// Fixed MZ BZ#1257: by Brad Despres <brad@sd.aonix.com>
count = 0;
do {
ret_val = wctomb(tmp, *tmp_str);
count += 1;
tmp += ret_val;
buf_size -= ret_val;
tmp_str++;
} while ( (ret_val > 0)&& (buf_size >= MB_CUR_MAX) && (count < n) ) ;
if (ret_val == -1) /* bad character */
return (False);
is_printable = XTextWidth(TextF_Font(tf), cache_ptr, tmp - cache_ptr);
XmStackFree(cache_ptr, cache);
return (is_printable);
}
else {
return (XTextWidth(TextF_Font(tf), str, n) != 0);
}
}
#endif /* SUPPORT_ZERO_WIDTH */
}
/****************************************************************
*
* Input functions defined in the action table.
*
****************************************************************/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_InsertChar( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_InsertChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
char insert_string[TEXT_MAX_INSERT_SIZE];
XmTextPosition cursorPos, nextPos;
wchar_t * wc_insert_string;
int insert_length, i;
int num_chars;
Boolean replace_res;
Boolean pending_delete = False;
Status status_return;
XmAnyCallbackStruct cb;
/* Determine what was pressed.
*/
insert_length = XmImMbLookupString(w, (XKeyEvent *) event, insert_string,
TEXT_MAX_INSERT_SIZE, (KeySym *) NULL,
&status_return);
if (insert_length > 0 && !XmTextF_editable(tf)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
return;
}
/* If there is more data than we can handle, bail out */
if (status_return == XBufferOverflow || insert_length > TEXT_MAX_INSERT_SIZE)
{
return;
}
/* *LookupString in some cases can return the NULL as a character, such
* as when the user types <Ctrl><back_quote> or <Ctrl><@>. Text widget
* can't handle the NULL as a character, so we dump it here.
*/
for (i=0; i < insert_length; i++)
if (insert_string[i] == 0) insert_length = 0; /* toss out input string */
if (insert_length > 0) {
/* do not insert non-printing characters */
if (!PrintableString(tf, insert_string, insert_length, False))
return;
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDeleteDisjoint(tf)){
if (!XmDataFieldGetSelectionPosition(w, &cursorPos, &nextPos) ||
cursorPos == nextPos) {
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
}
pending_delete = True;
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
} else {
cursorPos = nextPos = XmTextF_cursor_position(tf);
}
if (XmTextF_max_char_size(tf) == 1) {
if (XmTextF_overstrike(tf)) nextPos += insert_length;
if (nextPos > XmTextF_string_length(tf)) nextPos = XmTextF_string_length(tf);
replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
nextPos, insert_string,
insert_length, True);
} else {
char stack_cache[100];
insert_string[insert_length] = '\0'; /* NULL terminate for mbstowcs */
wc_insert_string = (wchar_t*)XmStackAlloc((Cardinal)(insert_length+1) * sizeof(wchar_t), stack_cache);
num_chars = mbstowcs( wc_insert_string, insert_string, insert_length+1);
if (XmTextF_overstrike(tf)) nextPos += num_chars;
if (nextPos > XmTextF_string_length(tf)) nextPos = XmTextF_string_length(tf);
replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
nextPos, (char*) wc_insert_string,
num_chars, True);
XmStackFree((char *)wc_insert_string, stack_cache);
}
if (replace_res) {
if (pending_delete) {
XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf), event->xkey.time);
}
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_InsertString( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_InsertString(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
char insert_string[TEXT_MAX_INSERT_SIZE];
XmTextPosition cursorPos, nextPos;
wchar_t * wc_insert_string;
int insert_length;
int num_chars;
Boolean replace_res;
Boolean pending_delete = False;
register int i;
if (!XmTextF_editable(tf)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay((Widget)tf), 0);
}
for (i = 0; i < *num_params; i++) {
strcpy(insert_string, params[i]);
insert_length = strlen(insert_string);
if (insert_length > 0) {
/* do not insert non-printing characters */
if (XmTextF_have_fontset(tf)){
if (!XmbTextEscapement((XFontSet)XmTextF_font(tf), insert_string,
insert_length))
return;
} else {
if (!XTextWidth(XmTextF_font(tf), insert_string, insert_length))
return;
}
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDeleteDisjoint(tf)){
if (!XmDataFieldGetSelectionPosition(w, &cursorPos, &nextPos) ||
cursorPos == nextPos) {
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
}
pending_delete = True;
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
} else {
cursorPos = nextPos = XmTextF_cursor_position(tf);
}
if (XmTextF_overstrike(tf)) {
if (nextPos != XmTextF_string_length(tf)) nextPos++;
}
if (XmTextF_max_char_size(tf) == 1) {
replace_res =
_XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
nextPos, insert_string,insert_length,
True);
} else {
insert_string[insert_length] = '\0'; /* NULL terminate for mbstowcs */
wc_insert_string = (wchar_t*)XtMalloc((unsigned)(insert_length+1) * sizeof(wchar_t));
num_chars = mbstowcs( wc_insert_string, insert_string, insert_length+1);
replace_res = _XmDataFieldReplaceText(tf, (XEvent *) event, cursorPos,
nextPos, (char*) wc_insert_string,
num_chars, True);
XtFree((char *)wc_insert_string);
}
if (replace_res) {
if (pending_delete) {
XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf), event->xkey.time);
}
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf), False, True);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeletePrevChar( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeletePrevChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else {
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
if (XmTextF_cursor_position(tf) - 1 >= 0)
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf) - 1,
XmTextF_cursor_position(tf), NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
} else if (XmTextF_cursor_position(tf) - 1 >= 0) {
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf) - 1,
XmTextF_cursor_position(tf), NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeleteNextChar( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeleteNextChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else {
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf) + 1, NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
} else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf) + 1,
NULL, 0, True))
{
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeletePrevWord( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeletePrevWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else {
df_FindPrevWord(tf, &left, &right);
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
{
if (_XmDataFieldReplaceText(tf, event,
left, XmTextF_cursor_position(tf),
NULL, 0, True))
{
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
} else if (XmTextF_cursor_position(tf) - 1 >= 0)
if (_XmDataFieldReplaceText(tf, event, left, XmTextF_cursor_position(tf),
NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeleteNextWord( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeleteNextWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else {
df_FindNextWord(tf, &left, &right);
if (XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf)) {
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
right, NULL, 0, True)){
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
} else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf))
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
right, NULL, 0, True)){
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event,
XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeleteToEndOfLine( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeleteToEndOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else if (XmTextF_cursor_position(tf) < XmTextF_string_length(tf)) {
if (_XmDataFieldReplaceText(tf, event, XmTextF_cursor_position(tf),
XmTextF_string_length(tf), NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeleteToStartOfLine( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeleteToStartOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
/* if pending delete is on and there is a selection */
_XmDataFieldDrawInsertionPoint(tf, False);
if (df_NeedsPendingDelete(tf)) (void) DataFieldRemove(w, event);
else if (XmTextF_cursor_position(tf) - 1 >= 0) {
if (_XmDataFieldReplaceText(tf, event, 0,
XmTextF_cursor_position(tf), NULL, 0, True)) {
df_CheckDisjointSelection(w, XmTextF_cursor_position(tf),
event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
False, True);
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ProcessCancel( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ProcessCancel(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmParentInputActionRec p_event ;
p_event.process_type = XmINPUT_ACTION ;
p_event.action = XmPARENT_CANCEL ;
p_event.event = event ;/* Pointer to XEvent. */
p_event.params = params ; /* Or use what you have if */
p_event.num_params = num_params ;/* input is from translation.*/
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmTextF_has_secondary(tf)) {
XmTextF_cancel(tf) = True;
_XmDataFieldSetSel2(w, 0, 0, False, event->xkey.time);
XmTextF_has_secondary(tf) = False;
XtUngrabKeyboard(w, CurrentTime);
}
if (XmTextF_has_primary(tf) && XmTextF_extending(tf)) {
XmTextF_cancel(tf) = True;
/* reset orig_left and orig_right */
XmDataFieldSetSelection(w, XmTextF_orig_left(tf),
XmTextF_orig_right(tf), event->xkey.time);
}
if (!XmTextF_cancel(tf))
(void) _XmParentProcess(XtParent(tf), (XmParentProcessData) &p_event);
if (XmTextF_select_id(tf)) {
XtRemoveTimeOut(XmTextF_select_id(tf));
XmTextF_select_id(tf) = 0;
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_Activate( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_Activate(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmAnyCallbackStruct cb;
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmParentInputActionRec p_event ;
p_event.process_type = XmINPUT_ACTION ;
p_event.action = XmPARENT_ACTIVATE ;
p_event.event = event ;/* Pointer to XEvent. */
p_event.params = params ; /* Or use what you have if */
p_event.num_params = num_params ;/* input is from translation.*/
cb.reason = XmCR_ACTIVATE;
cb.event = event;
XtCallCallbackList(w, XmTextF_activate_callback(tf), (XtPointer) &cb);
(void) _XmParentProcess(XtParent(w), (XmParentProcessData) &p_event);
}
static void
#ifdef _NO_PROTO
df_SetAnchorBalancing(tf, position)
XmDataFieldWidget tf;
XmTextPosition position;
#else
df_SetAnchorBalancing(
XmDataFieldWidget tf,
XmTextPosition position)
#endif /* _NO_PROTO */
{
XmTextPosition left, right;
float bal_point;
if (!XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) ||
left == right) {
XmTextF_prim_anchor(tf) = position;
} else {
bal_point = (float)(((float)(right - left) / 2.0) + (float)left);
/* shift anchor and direction to opposite end of the selection */
if ((float)position < bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
} else if ((float)position > bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
}
}
}
static void
#ifdef _NO_PROTO
df_SetNavigationAnchor(tf, position, extend)
XmDataFieldWidget tf;
XmTextPosition position;
Boolean extend;
#else
df_SetNavigationAnchor(
XmDataFieldWidget tf,
XmTextPosition position,
#if NeedWidePrototypes
int extend )
#else
Boolean extend )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextPosition left, right;
if (!XmTextF_add_mode(tf)) {
if (extend) {
df_SetAnchorBalancing(tf, position);
} else {
if (XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) &&
left != right) {
df_SetSelection(tf, position, position, True);
XmTextF_prim_anchor(tf) = position;
}
}
} else if (extend) {
df_SetAnchorBalancing(tf, position);
}
}
static void
#ifdef _NO_PROTO
df_CompleteNavigation(tf, event, position, time, extend)
XmDataFieldWidget tf;
XEvent *event;
XmTextPosition position;
Time time;
Boolean extend;
#else
df_CompleteNavigation(
XmDataFieldWidget tf,
XEvent *event,
XmTextPosition position,
Time time,
#if NeedWidePrototypes
int extend )
#else
Boolean extend )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextPosition left, right;
Boolean backward = False;
if ((XmTextF_add_mode(tf) &&
XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) &&
position >= left && position <= right) || extend)
XmTextF_pending_off(tf) = FALSE;
else
XmTextF_pending_off(tf) = TRUE;
_XmDataFielddf_SetCursorPosition(tf, event, position, True, True);
if (extend) {
if (XmTextF_prim_anchor(tf) > position) {
left = position;
right = XmTextF_prim_anchor(tf);
backward = True;
} else {
left = XmTextF_prim_anchor(tf);
right = position;
}
XmDataFieldSetSelection((Widget)tf, left, right, time);
/* Begin fix for CR 5994 */
if ( backward )
_XmDataFielddf_SetCursorPosition(tf, event, position, False, False);
/* End fix for CR 5994 */
XmTextF_orig_left(tf) = left;
XmTextF_orig_right(tf) = right;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_SimpleMovement( w, event, params, num_params, cursorPos, position )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
XmTextPosition cursorPos ;
XmTextPosition position ;
#else
df_SimpleMovement(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params,
XmTextPosition cursorPos,
XmTextPosition position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean extend = False;
if (*num_params > 0 && !strcmp(*params, "extend")) extend = True;
_XmDataFieldDrawInsertionPoint(tf, False);
df_SetNavigationAnchor(tf, cursorPos, extend);
df_CompleteNavigation(tf, event, position, event->xkey.time, extend);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_BackwardChar( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_BackwardChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position;
cursorPos = XmTextF_cursor_position(tf);
if (cursorPos > 0) {
_XmDataFieldDrawInsertionPoint(tf, False);
position = cursorPos - 1;
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ForwardChar( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ForwardChar(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position;
cursorPos = XmTextF_cursor_position(tf);
if (cursorPos < XmTextF_string_length(tf)) {
_XmDataFieldDrawInsertionPoint(tf, False);
position = cursorPos + 1;
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_BackwardWord( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_BackwardWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position, dummy;
cursorPos = XmTextF_cursor_position(tf);
if (cursorPos > 0) {
_XmDataFieldDrawInsertionPoint(tf, False);
df_FindPrevWord(tf, &position, &dummy);
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ForwardWord( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ForwardWord(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position, dummy;
wchar_t white_space[3];
if (XmTextF_max_char_size(tf) != 1) {
(void)mbtowc(&white_space[0], " ", 1);
(void)mbtowc(&white_space[1], "\n", 1);
(void)mbtowc(&white_space[2], "\t", 1);
}
cursorPos = XmTextF_cursor_position(tf);
_XmDataFieldDrawInsertionPoint(tf, False);
if (cursorPos < XmTextF_string_length(tf)) {
if (XmTextF_max_char_size(tf) == 1) {
if (isspace((int)(unsigned char)XmTextF_value(tf)[cursorPos]))
df_FindWord(tf, cursorPos, &dummy, &position);
else
df_FindNextWord(tf, &dummy, &position);
if(isspace((int)(unsigned char)XmTextF_value(tf)[position])){
for (;position < XmTextF_string_length(tf); position++){
if (!isspace((int)(unsigned char)XmTextF_value(tf)[position]))
break;
}
}
} else {
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[cursorPos],
white_space, 3))
df_FindWord(tf, cursorPos, &dummy, &position);
else
df_FindNextWord(tf, &dummy, &position);
if (_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[position],
white_space, 3)){
for (; position < XmTextF_string_length(tf); position++) {
if (!_XmDataFieldIsWSpace(XmTextF_wc_value(tf)[position],
white_space, 3))
break;
}
}
}
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_EndOfLine( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_EndOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position;
cursorPos = XmTextF_cursor_position(tf);
if (cursorPos < XmTextF_string_length(tf)) {
_XmDataFieldDrawInsertionPoint(tf, False);
position = XmTextF_string_length(tf);
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_BeginningOfLine( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_BeginningOfLine(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos, position;
cursorPos = XmTextF_cursor_position(tf);
if (cursorPos > 0) {
position = 0;
_XmDataFieldDrawInsertionPoint(tf, False);
df_SimpleMovement((Widget) tf, event, params, num_params,
cursorPos, position);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
static void
#ifdef _NO_PROTO
df_SetSelection( tf, left, right, redisplay )
XmDataFieldWidget tf ;
XmTextPosition left ;
XmTextPosition right ;
Boolean redisplay ;
#else
df_SetSelection(
XmDataFieldWidget tf,
XmTextPosition left,
XmTextPosition right,
#if NeedWidePrototypes
int redisplay )
#else
Boolean redisplay )
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
XmTextPosition display_left, display_right;
XmTextPosition old_prim_left, old_prim_right;
if (left < 0) left = 0;
if (right < 0) right = 0;
if (left > XmTextF_string_length(tf))
left = XmTextF_string_length(tf);
if (right > XmTextF_string_length(tf))
right = XmTextF_string_length(tf);
if (left == right && XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf))
XmDataFieldSetAddMode((Widget)tf, False);
if (left == XmTextF_prim_pos_left(tf) && right == XmTextF_prim_pos_right(tf))
return;
DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
old_prim_left = XmTextF_prim_pos_left(tf);
old_prim_right = XmTextF_prim_pos_right(tf);
if (left > right) {
XmTextF_prim_pos_left(tf) = right;
XmTextF_prim_pos_right(tf) = left;
} else {
XmTextF_prim_pos_left(tf) = left;
XmTextF_prim_pos_right(tf) = right;
}
DataFieldSetHighlight(tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf), XmHIGHLIGHT_SELECTED);
if (redisplay) {
if (old_prim_left > XmTextF_prim_pos_left(tf)) {
display_left = XmTextF_prim_pos_left(tf);
} else if (old_prim_left < XmTextF_prim_pos_left(tf)) {
display_left = old_prim_left;
} else
display_left = (old_prim_right > XmTextF_prim_pos_right(tf)) ?
XmTextF_prim_pos_right(tf) : old_prim_right;
if (old_prim_right < XmTextF_prim_pos_right(tf)) {
display_right = XmTextF_prim_pos_right(tf);
} else if (old_prim_right > XmTextF_prim_pos_right(tf)) {
display_right = old_prim_right;
} else
display_right = (old_prim_left < XmTextF_prim_pos_left(tf)) ?
XmTextF_prim_pos_left(tf) : old_prim_left;
df_RedisplayText(tf, display_left, display_right);
}
XmTextF_refresh_ibeam_off(tf) = True;
}
/*
* Begin the selection by gaining ownership of the selection
* and setting the selection parameters.
*/
void
#ifdef _NO_PROTO
_XmDataFieldStartSelection( tf, left, right, sel_time )
XmDataFieldWidget tf ;
XmTextPosition left ;
XmTextPosition right ;
Time sel_time ;
#else
_XmDataFieldStartSelection(
XmDataFieldWidget tf,
XmTextPosition left,
XmTextPosition right,
Time sel_time )
#endif /* _NO_PROTO */
{
if (!XtIsRealized((Widget)tf)) return;
/* if we don't already own the selection */
if (!XmTextF_has_primary(tf)) {
/*
* Try to gain ownership. This function identifies the
* XtConvertSelectionProc and the XtLoseSelectionProc.
*/
if (XtOwnSelection((Widget)tf, XA_PRIMARY, sel_time, _XmDataFieldConvert,
_XmDataFieldLoseSelection, (XtSelectionDoneProc) NULL)) {
XmAnyCallbackStruct cb;
XmTextF_prim_time(tf) = sel_time;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_has_primary(tf) = True;
XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
/*
* Set the selection boundries for highlighting the text,
* and marking the selection.
*/
df_SetSelection(tf, left, right, True);
_XmDataFieldDrawInsertionPoint(tf, True);
/* Call the gain selection callback */
cb.reason = XmCR_GAIN_PRIMARY;
cb.event = NULL;
XtCallCallbackList((Widget) tf, XmTextF_gain_primary_callback(tf),
(XtPointer) &cb);
} else
/*
* Failed to gain ownership of the selection so make sure
* the text does not think it owns the selection.
* (this might be overkill)
*/
_XmDataFieldDeselectSelection((Widget)tf, True, sel_time);
} else {
_XmDataFieldDrawInsertionPoint(tf, False);
XmDataFieldSetHighlight((Widget)tf, XmTextF_prim_pos_left(tf),
XmTextF_prim_pos_right(tf), XmHIGHLIGHT_NORMAL);
XmTextF_prim_pos_left(tf) = XmTextF_prim_pos_right(tf) =
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
/*
* Set the new selection boundries for highlighting the text,
* and marking the selection.
*/
df_SetSelection(tf, left, right, True);
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ProcessHorizontalParams( w, event, params, num_params, left, right, position )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params;
XmTextPosition *left ;
XmTextPosition *right ;
XmTextPosition *position ;
#else
df_ProcessHorizontalParams(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params,
XmTextPosition *left,
XmTextPosition *right,
XmTextPosition *position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition old_cursorPos = XmTextF_cursor_position(tf);
*position = XmTextF_cursor_position(tf);
if (!XmDataFieldGetSelectionPosition(w, left, right) || *left == *right) {
XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_anchor(tf);
*left = *right = old_cursorPos;
}
if (*num_params > 0 && !strcmp(*params, "right")) {
if (*position >= XmTextF_string_length(tf)) return;
(*position)++;
} else if (*num_params > 0 && !strcmp(*params, "left")) {
if (*position <= 0) return;
(*position)--;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ProcessSelectParams( w, event, left, right, position )
Widget w ;
XEvent *event ;
XmTextPosition *left ;
XmTextPosition *right ;
XmTextPosition *position ;
#else
df_ProcessSelectParams(
Widget w,
XEvent *event,
XmTextPosition *left,
XmTextPosition *right,
XmTextPosition *position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
*position = XmTextF_cursor_position(tf);
if (!XmDataFieldGetSelectionPosition(w, left, right) || *left == *right) {
if (*position > XmTextF_prim_anchor(tf)) {
*left = XmTextF_prim_anchor(tf);
*right = *position;
} else {
*left = *position;
*right = XmTextF_prim_anchor(tf);
}
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_KeySelection( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_KeySelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmTextPosition position = 0, left, right;
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition cursorPos;
_XmDataFieldDrawInsertionPoint(tf,False); /* Turn off I beam blink
during selection */
XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
cursorPos = XmTextF_cursor_position(tf);
if (*num_params > 0 && (!strcmp(*params,"right") || !strcmp(*params, "left")))
df_SetAnchorBalancing(tf, cursorPos);
XmTextF_extending(tf) = True;
if (*num_params == 0) {
position = cursorPos;
df_ProcessSelectParams(w, event, &left, &right, &position);
} else if (*num_params > 0 && (!strcmp(*params, "right") ||
!strcmp(*params, "left"))) {
df_ProcessHorizontalParams(w, event, params, num_params, &left,
&right, &position);
}
cursorPos = position;
if (position < 0 || position > XmTextF_string_length(tf)) {
_XmDataFieldDrawInsertionPoint(tf,True); /* Turn on I beam now
that we are done */
return;
}
/* shift anchor and direction to opposite end of the selection */
if (position > XmTextF_prim_anchor(tf)) {
right = cursorPos = position;
left = XmTextF_prim_anchor(tf);
} else {
left = cursorPos = position;
right = XmTextF_prim_anchor(tf);
}
if (left > right) {
XmTextPosition tempIndex = left;
left = right;
right = tempIndex;
}
if (XmTextF_has_primary(tf))
df_SetSelection(tf, left, right, True);
else
_XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
XmTextF_pending_off(tf) = False;
_XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
(void) df_SetDestination(w, cursorPos, False, event->xkey.time);
XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
_XmDataFieldDrawInsertionPoint(tf,True); /* Turn on I beam now
that we are done */
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TextFocusIn( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TextFocusIn(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
XPoint xmim_point;
XtWidgetProc bhl;
if (event->xfocus.send_event && !(XmTextF_has_focus(tf))) {
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
XmTextF_has_focus(tf) = True;
if (XtIsSensitive(w)) _XmDataFToggleCursorGC(w);
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_blink_on(tf) = False;
XmTextF_refresh_ibeam_off(tf) = True;
if (_XmGetFocusPolicy(w) == XmEXPLICIT)
{
_XmProcessLock();
bhl = ((XmDataFieldWidgetClass)XtClass(w))->primitive_class.border_highlight;
_XmProcessUnlock();
if (bhl)
{
(*bhl)(w);
}
if (!XmTextF_has_destination(tf))
{
(void) df_SetDestination(w, XmTextF_cursor_position(tf), False, XtLastTimestampProcessed(XtDisplay(w)));
}
}
if (tf->core.sensitive) df_ChangeBlinkBehavior(tf, True);
_XmDataFieldDrawInsertionPoint(tf, True);
(void) df_GetXYFromPos(tf, XmTextF_cursor_position(tf),
&xmim_point.x, &xmim_point.y);
XmImVaSetFocusValues(w, XmNspotLocation, &xmim_point, NULL);
cb.reason = XmCR_FOCUS;
cb.event = event;
XtCallCallbackList (w, XmTextF_focus_callback(tf), (XtPointer) &cb);
}
_XmPrimitiveFocusIn(w, event, params, num_params);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TextFocusOut( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TextFocusOut(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XtWidgetProc buhl;
if (event->xfocus.send_event && XmTextF_has_focus(tf)) {
XmTextF_has_focus(tf) = False;
df_ChangeBlinkBehavior(tf, False);
_XmDataFieldDrawInsertionPoint(tf, False);
_XmDataFToggleCursorGC(w);
XmTextF_blink_on(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
_XmProcessLock();
buhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_unhighlight;
_XmProcessUnlock();
if(buhl)
{
(*buhl)( (Widget) tf) ;
}
XmImUnsetFocus(w);
}
/* If traversal is on, then the leave verification callback is called in
the traversal event handler */
if (event->xfocus.send_event && !XmTextF_traversed(tf) &&
_XmGetFocusPolicy(w) == XmEXPLICIT) {
if (!df_VerifyLeave(tf, event)) {
if (XmTextF_verify_bell(tf)) XBell(XtDisplay(w), 0);
return;
}
} else
if (XmTextF_traversed(tf)) {
XmTextF_traversed(tf) = False;
}
}
static void
#ifdef _NO_PROTO
df_SetScanIndex( tf, event )
XmDataFieldWidget tf ;
XEvent *event ;
#else
df_SetScanIndex(
XmDataFieldWidget tf,
XEvent *event )
#endif /* _NO_PROTO */
{
Time sel_time;
if (event->type == ButtonPress) sel_time = event->xbutton.time;
else sel_time = event->xkey.time;
if (sel_time > XmTextF_last_time(tf) &&
sel_time - XmTextF_last_time(tf) < XtGetMultiClickTime(XtDisplay(tf))) {
/*
* Fix for HaL DTS 9841 - Increment the sarray_index first, then check to
* see if it is greater that the count. Otherwise,
* an error will occur.
*/
XmTextF_sarray_index(tf)++;
if (XmTextF_sarray_index(tf) >= XmTextF_selection_array_count(tf)) {
XmTextF_sarray_index(tf) = 0;
}
/*
* End fix for HaL DTS 9841
*/
} else
XmTextF_sarray_index(tf) = 0;
XmTextF_last_time(tf) = sel_time;
}
static void
#ifdef _NO_PROTO
df_ExtendScanSelection( tf, event )
XmDataFieldWidget tf ;
XEvent *event ;
#else
df_ExtendScanSelection(
XmDataFieldWidget tf,
XEvent *event )
#endif /* _NO_PROTO */
{
XmTextPosition pivot_left, pivot_right;
XmTextPosition left, right;
XmTextPosition new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
XmTextPosition cursorPos = XmTextF_cursor_position(tf);
Boolean pivot_modify = False;
float bal_point;
if (!XmDataFieldGetSelectionPosition((Widget)tf, &left, &right) ||
left == right) {
XmTextF_orig_left(tf) = XmTextF_orig_right(tf) =
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
bal_point = (float)XmTextF_orig_left(tf);
} else
bal_point = (float)(((float)(right - left) / 2.0) + (float)left);
if (!XmTextF_extending(tf))
{
if ((float)new_position < bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
} else if ((float)new_position > bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
}
}
XmTextF_extending(tf) = True;
switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
case XmSELECT_POSITION:
if (XmTextF_has_primary(tf))
df_SetSelection(tf, XmTextF_prim_anchor(tf), new_position, True);
else if (new_position != XmTextF_prim_anchor(tf))
_XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
new_position, event->xbutton.time);
XmTextF_pending_off(tf) = False;
cursorPos = new_position;
break;
case XmSELECT_WHITESPACE:
case XmSELECT_WORD:
df_FindWord(tf, new_position, &left, &right);
df_FindWord(tf, XmTextF_prim_anchor(tf),
&pivot_left, &pivot_right);
XmTextF_pending_off(tf) = False;
if (left != pivot_left || right != pivot_right) {
if (left > pivot_left)
left = pivot_left;
if (right < pivot_right)
right = pivot_right;
pivot_modify = True;
}
if (XmTextF_has_primary(tf))
df_SetSelection(tf, left, right, True);
else
_XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
if (pivot_modify) {
if ((((right - left) / 2) + left) <= new_position) {
cursorPos = right;
} else
cursorPos = left;
} else {
if (left >= XmTextF_cursor_position(tf))
cursorPos = left;
else
cursorPos = right;
}
break;
default:
break;
}
if (cursorPos != XmTextF_cursor_position(tf)) {
(void) df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
_XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
}
}
static void
#ifdef _NO_PROTO
df_SetScanSelection( tf, event )
XmDataFieldWidget tf ;
XEvent *event ;
#else
df_SetScanSelection(
XmDataFieldWidget tf,
XEvent *event )
#endif /* _NO_PROTO */
{
XmTextPosition left, right;
XmTextPosition new_position = 0;
XmTextPosition cursorPos = XmTextF_cursor_position(tf);
Position dummy = 0;
Boolean update_position = False;
df_SetScanIndex(tf, event);
if (event->type == ButtonPress)
new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
else
new_position = XmTextF_cursor_position(tf);
_XmDataFieldDrawInsertionPoint(tf,False); /* Turn off I beam
blink during selection */
switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
case XmSELECT_POSITION:
XmTextF_prim_anchor(tf) = new_position;
if (XmTextF_has_primary(tf)) {
df_SetSelection(tf, new_position, new_position, True);
XmTextF_pending_off(tf) = False;
}
cursorPos = new_position;
update_position = True;
break;
case XmSELECT_WHITESPACE:
case XmSELECT_WORD:
df_FindWord(tf, XmTextF_cursor_position(tf), &left, &right);
if (XmTextF_has_primary(tf))
df_SetSelection(tf, left, right, True);
else
_XmDataFieldStartSelection(tf, left, right, event->xbutton.time);
XmTextF_pending_off(tf) = False;
if ((((right - left) / 2) + left) <= new_position)
cursorPos = right;
else
cursorPos = left;
break;
case XmSELECT_LINE:
case XmSELECT_OUT_LINE:
case XmSELECT_PARAGRAPH:
case XmSELECT_ALL:
if (XmTextF_has_primary(tf))
df_SetSelection(tf, 0, XmTextF_string_length(tf), True);
else
_XmDataFieldStartSelection(tf, 0, XmTextF_string_length(tf),
event->xbutton.time);
XmTextF_pending_off(tf) = False;
if (event->type == ButtonPress)
{
if ((XmTextF_string_length(tf)) / 2 <= new_position)
cursorPos = XmTextF_string_length(tf);
else
cursorPos = 0;
}
break;
}
(void) df_SetDestination((Widget)tf, cursorPos, False, event->xkey.time);
if (cursorPos != XmTextF_cursor_position(tf) || update_position) {
_XmDataFielddf_SetCursorPosition(tf, event, cursorPos, True, True);
}
df_GetXYFromPos(tf, cursorPos, &(XmTextF_select_pos_x(tf)),
&dummy);
_XmDataFieldDrawInsertionPoint(tf,True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_StartPrimary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_StartPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
(void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
_XmDataFieldDrawInsertionPoint(tf,False);
df_SetScanSelection(tf, event); /* use scan type to set the selection */
_XmDataFieldDrawInsertionPoint(tf,True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_MoveDestination( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_MoveDestination(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
XmTextPosition new_position;
Boolean old_has_focus = XmTextF_has_focus(tf);
Boolean reset_cursor = False;
new_position = df_GetPosFromX(tf, (Position) event->xbutton.x);
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmDataFieldGetSelectionPosition(w, &left, &right) && (right != left))
(void) df_SetDestination(w, new_position, False, event->xbutton.time);
XmTextF_pending_off(tf) = False;
if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
(void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
/* Doing the the df_MoveDestination caused a traversal into my, causing
* me to gain focus... Cursor is now on when it shouldn't be. */
if ((reset_cursor = !old_has_focus && XmTextF_has_focus(tf)) != False)
_XmDataFieldDrawInsertionPoint(tf, False);
_XmDataFielddf_SetCursorPosition(tf, event, new_position,
True, True);
if (new_position < left && new_position > right)
XmTextF_pending_off(tf) = True;
/*
* if cursor was turned off as a result of the focus state changing
* then we need to undo the decrement to the cursor_on variable
* by redrawing the insertion point.
*/
if (reset_cursor)
_XmDataFieldDrawInsertionPoint(tf, True);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ExtendPrimary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ExtendPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (XmTextF_cancel(tf)) return;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_do_drop(tf) = False;
if (!df_CheckTimerScrolling(w, event)){
if (event->type == ButtonPress)
df_DoExtendedSelection(w, event->xbutton.time);
else
df_DoExtendedSelection(w, event->xkey.time);
} else
df_ExtendScanSelection(tf, event); /* use scan type to set the selection */
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ExtendEnd( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ExtendEnd(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (XmTextF_prim_pos_left(tf) == 0 && XmTextF_prim_pos_right(tf) == 0)
XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_cursor_position(tf);
else {
XmTextF_orig_left(tf) = XmTextF_prim_pos_left(tf);
XmTextF_orig_right(tf) = XmTextF_prim_pos_right(tf);
XmTextF_cancel(tf) = False;
}
if (XmTextF_select_id(tf)) {
XtRemoveTimeOut(XmTextF_select_id(tf));
XmTextF_select_id(tf) = 0;
}
XmTextF_select_pos_x(tf) = 0;
XmTextF_extending(tf) = False;
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DoExtendedSelection(w, time)
Widget w;
Time time;
#else
df_DoExtendedSelection(
Widget w,
Time time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition position, left, right, cursorPos;
XmTextPosition pivot_left, pivot_right;
Boolean pivot_modify = False;
float bal_point;
if (XmTextF_cancel(tf)) {
if (XmTextF_select_id(tf)) XtRemoveTimeOut(XmTextF_select_id(tf));
XmTextF_select_id(tf) = 0;
return;
}
cursorPos = XmTextF_cursor_position(tf);
_XmDataFieldDrawInsertionPoint(tf, False);
if (!(XmDataFieldGetSelectionPosition(w, &left, &right)) || left == right) {
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
left = right = XmTextF_cursor_position(tf);
XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_anchor(tf);
bal_point = (float)XmTextF_prim_anchor(tf);
} else
bal_point = (float)(((float)(XmTextF_orig_right(tf) - XmTextF_orig_left(tf))
/ 2.0) + (float)XmTextF_orig_left(tf));
position = XmDataFieldXYToPos(w, XmTextF_select_pos_x(tf), 0);
if (!XmTextF_extending(tf))
{
if ((float)position < bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_right(tf);
} else if ((float)position > bal_point) {
XmTextF_prim_anchor(tf) = XmTextF_orig_left(tf);
}
}
XmTextF_extending(tf) = True;
/* Extend selection in same way as ExtendScan would do */
switch (XmTextF_selection_array(tf)[XmTextF_sarray_index(tf)]) {
case XmSELECT_POSITION:
if (XmTextF_has_primary(tf))
df_SetSelection(tf, XmTextF_prim_anchor(tf), position, True);
else if (position != XmTextF_prim_anchor(tf))
_XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
position, time);
XmTextF_pending_off(tf) = False;
cursorPos = position;
break;
case XmSELECT_WHITESPACE:
case XmSELECT_WORD:
df_FindWord(tf, position, &left, &right);
df_FindWord(tf, XmTextF_prim_anchor(tf),
&pivot_left, &pivot_right);
XmTextF_pending_off(tf) = False;
if (left != pivot_left || right != pivot_right) {
if (left > pivot_left)
left = pivot_left;
if (right < pivot_right)
right = pivot_right;
pivot_modify = True;
}
if (XmTextF_has_primary(tf))
df_SetSelection(tf, left, right, True);
else
_XmDataFieldStartSelection(tf, left, right, time);
if (pivot_modify) {
if ((((right - left) / 2) + left) <= position) {
cursorPos = right;
} else
cursorPos = left;
} else {
if (left >= XmTextF_cursor_position(tf))
cursorPos = left;
else
cursorPos = right;
}
break;
default:
break;
}
if (cursorPos != XmTextF_cursor_position(tf)) {
(void) df_SetDestination((Widget)tf, cursorPos, False, time);
_XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos, True, True);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DoSecondaryExtend(w, ev_time)
Widget w;
Time ev_time;
#else
df_DoSecondaryExtend(
Widget w,
Time ev_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition position = XmDataFieldXYToPos(w, XmTextF_select_pos_x(tf), 0);
if (XmTextF_cancel(tf)) return;
if (position < XmTextF_sec_anchor(tf)) {
if (XmTextF_sec_pos_left(tf) > 0)
_XmDataFieldSetSel2(w, position, XmTextF_sec_anchor(tf), False, ev_time);
XmDataFieldShowPosition(w, XmTextF_sec_pos_left(tf));
} else if (position > XmTextF_sec_anchor(tf)) {
if (XmTextF_sec_pos_right(tf) < XmTextF_string_length(tf))
_XmDataFieldSetSel2(w, XmTextF_sec_anchor(tf), position, False, ev_time);
XmDataFieldShowPosition(w, XmTextF_sec_pos_right(tf));
} else {
_XmDataFieldSetSel2(w, position, position, False, ev_time);
XmDataFieldShowPosition(w, position);
}
df_ResetClipOrigin(tf, False);
XmTextF_sec_extending(tf) = True;
}
/************************************************************************
* *
* df_BrowseScroll - timer proc that scrolls the list if the user has left *
* the window with the button down. If the button has been *
* released, call the standard click stuff. *
* *
************************************************************************/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_BrowseScroll( closure, id )
XtPointer closure ;
XtIntervalId *id ;
#else
df_BrowseScroll(
XtPointer closure,
XtIntervalId *id )
#endif /* _NO_PROTO */
{
Widget w = (Widget) closure ;
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (XmTextF_cancel(tf)) {
XmTextF_select_id(tf) = 0;
return;
}
if (!XmTextF_select_id(tf)) return;
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmTextF_sec_extending(tf))
df_DoSecondaryExtend(w, XtLastTimestampProcessed(XtDisplay(w)));
else if (XmTextF_extending(tf))
df_DoExtendedSelection(w, XtLastTimestampProcessed(XtDisplay(w)));
XSync (XtDisplay(w), False);
_XmDataFieldDrawInsertionPoint(tf, True);
XmTextF_select_id(tf) = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
(unsigned long) PRIM_SCROLL_INTERVAL,
df_BrowseScroll, (XtPointer) w);
}
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
df_CheckTimerScrolling( w, event )
Widget w ;
XEvent *event ;
#else
df_CheckTimerScrolling(
Widget w,
XEvent *event )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Dimension margin_size = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Dimension top_margin = XmTextF_margin_height(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
XmTextF_select_pos_x(tf) = event->xmotion.x;
if ((event->xmotion.x > (int) margin_size) &&
(event->xmotion.x < (int) (tf->core.width - margin_size)) &&
(event->xmotion.y > (int) top_margin) &&
(event->xmotion.y < (int) (top_margin + XmTextF_font_ascent(tf) +
XmTextF_font_descent(tf)))) {
if (XmTextF_select_id(tf)) {
XtRemoveTimeOut(XmTextF_select_id(tf));
XmTextF_select_id(tf) = 0;
}
} else {
/* to the left of the text */
if (event->xmotion.x <= (int) margin_size)
XmTextF_select_pos_x(tf) = (Position) (margin_size -
(XmTextF_average_char_width(tf) + 1));
/* to the right of the text */
else if (event->xmotion.x >= (int) (tf->core.width - margin_size))
XmTextF_select_pos_x(tf) = (Position) ((tf->core.width - margin_size) +
XmTextF_average_char_width(tf) + 1);
if (!XmTextF_select_id(tf))
XmTextF_select_id(tf) = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
(unsigned long) SEC_SCROLL_INTERVAL,
df_BrowseScroll, (XtPointer) w);
return True;
}
return False;
}
static void
#ifdef _NO_PROTO
df_RestorePrimaryHighlight( tf, prim_left, prim_right )
XmDataFieldWidget tf ;
XmTextPosition prim_left ;
XmTextPosition prim_right ;
#else
df_RestorePrimaryHighlight(
XmDataFieldWidget tf,
XmTextPosition prim_left,
XmTextPosition prim_right )
#endif /* _NO_PROTO */
{
if (XmTextF_sec_pos_right(tf) >= prim_left &&
XmTextF_sec_pos_right(tf) <= prim_right) {
/* secondary selection is totally inside primary selection */
if (XmTextF_sec_pos_left(tf) >= prim_left) {
DataFieldSetHighlight(tf, prim_left, XmTextF_sec_pos_left(tf),
XmHIGHLIGHT_SELECTED);
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
XmTextF_sec_pos_right(tf),
XmHIGHLIGHT_NORMAL);
DataFieldSetHighlight(tf, XmTextF_sec_pos_right(tf), prim_right,
XmHIGHLIGHT_SELECTED);
/* right side of secondary selection is inside primary selection */
} else {
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_left,
XmHIGHLIGHT_NORMAL);
DataFieldSetHighlight(tf, prim_left, XmTextF_sec_pos_right(tf),
XmHIGHLIGHT_SELECTED);
}
} else {
/* left side of secondary selection is inside primary selection */
if (XmTextF_sec_pos_left(tf) <= prim_right &&
XmTextF_sec_pos_left(tf) >= prim_left) {
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_right,
XmHIGHLIGHT_SELECTED);
DataFieldSetHighlight(tf, prim_right, XmTextF_sec_pos_right(tf),
XmHIGHLIGHT_NORMAL);
} else {
/* secondary selection encompasses the primary selection */
if (XmTextF_sec_pos_left(tf) <= prim_left &&
XmTextF_sec_pos_right(tf) >= prim_right){
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf), prim_left,
XmHIGHLIGHT_NORMAL);
DataFieldSetHighlight(tf, prim_left, prim_right,
XmHIGHLIGHT_SELECTED);
DataFieldSetHighlight(tf, prim_right, XmTextF_sec_pos_right(tf),
XmHIGHLIGHT_NORMAL);
/* secondary selection is outside primary selection */
} else {
DataFieldSetHighlight(tf, prim_left, prim_right,
XmHIGHLIGHT_SELECTED);
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
XmTextF_sec_pos_right(tf),
XmHIGHLIGHT_NORMAL);
}
}
}
}
void
#ifdef _NO_PROTO
_XmDataFieldSetSel2( w, left, right, disown, sel_time )
Widget w ;
XmTextPosition left ;
XmTextPosition right ;
Boolean disown ;
Time sel_time ;
#else
_XmDataFieldSetSel2(
Widget w,
XmTextPosition left,
XmTextPosition right,
Boolean disown,
Time sel_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean result;
if (XmTextF_has_secondary(tf)) {
XmTextPosition prim_left, prim_right;
if (left == XmTextF_sec_pos_left(tf) && right == XmTextF_sec_pos_right(tf))
return;
/* If the widget has the primary selection, make sure the selection
* highlight is restored appropriately.
*/
if (XmDataFieldGetSelectionPosition(w, &prim_left, &prim_right))
df_RestorePrimaryHighlight(tf, prim_left, prim_right);
else
DataFieldSetHighlight(tf, XmTextF_sec_pos_left(tf),
XmTextF_sec_pos_right(tf), XmHIGHLIGHT_NORMAL);
}
if (left < right) {
if (!XmTextF_has_secondary(tf)) {
result = XtOwnSelection(w, XA_SECONDARY, sel_time,
_XmDataFieldConvert,
_XmDataFieldLoseSelection,
(XtSelectionDoneProc) NULL);
XmTextF_sec_time(tf) = sel_time;
XmTextF_has_secondary(tf) = result;
if (result) {
XmTextF_sec_pos_left(tf) = left;
XmTextF_sec_pos_right(tf) = right;
}
} else {
XmTextF_sec_pos_left(tf) = left;
XmTextF_sec_pos_right(tf) = right;
}
XmTextF_sec_drag(tf) = True;
} else {
XmTextF_sec_pos_left(tf) = XmTextF_sec_pos_right(tf) = left;
if (disown) {
XtDisownSelection(w, XA_SECONDARY, sel_time);
XmTextF_has_secondary(tf) = False;
}
}
DataFieldSetHighlight((XmDataFieldWidget) w, XmTextF_sec_pos_left(tf),
XmTextF_sec_pos_right(tf), XmHIGHLIGHT_SECONDARY_SELECTED);
/* This can be optimized for performance enhancement */
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_StartDrag( w, event, params, num_params )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
df_StartDrag(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Atom targets[5];
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
int status = 0;
Cardinal num_targets = 0;
Widget drag_icon;
Arg args[10];
int n;
tmp_prop.value = NULL;
status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
targets[num_targets++] = tmp_prop.encoding;
else
targets[num_targets++] = 99999; /* XmbTextList... should never fail
* for XPCS characters. But just in
* case someones Xlib is broken,
* this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
#ifdef UTF8_SUPPORTED
targets[num_targets++] = XmInternAtom(XtDisplay(w), "UTF8_STRING", False);
#endif
targets[num_targets++] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
targets[num_targets++] = XA_STRING;
targets[num_targets++] = XmInternAtom(XtDisplay(w), "TEXT", False);
drag_icon = XmeGetTextualDragIcon(w);
n = 0;
XtSetArg(args[n], XmNcursorBackground, tf->core.background_pixel); n++;
XtSetArg(args[n], XmNcursorForeground, tf->primitive.foreground); n++;
XtSetArg(args[n], XmNsourceCursorIcon, drag_icon); n++;
XtSetArg(args[n], XmNexportTargets, targets); n++;
XtSetArg(args[n], XmNnumExportTargets, num_targets); n++;
XtSetArg(args[n], XmNconvertProc, _XmDataFieldConvert); n++;
XtSetArg(args[n], XmNclientData, w); n++;
if (XmTextF_editable(tf)) {
XtSetArg(args[n], XmNdragOperations, (XmDROP_MOVE | XmDROP_COPY)); n++;
} else {
XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
}
(void) XmDragStart(w, event, args, n);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_StartSecondary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_StartSecondary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition position = df_GetPosFromX(tf, (Position) event->xbutton.x);
int status;
XmTextF_sec_anchor(tf) = position;
XmTextF_selection_move(tf) = FALSE;
status = XtGrabKeyboard(w, False, GrabModeAsync, GrabModeAsync,
event->xbutton.time);
if (status != GrabSuccess)
XmeWarning(w, GRABKBDERROR);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ProcessBDrag( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ProcessBDrag(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition position, left, right;
Position left_x, right_x, dummy;
position = df_GetPosFromX(tf, (Position) event->xbutton.x);
XmTextF_sec_pos_left(tf) = position;
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmDataFieldGetSelectionPosition(w, &left, &right) &&
left != right) {
if ((position > left && position < right) ||
/* Take care of border conditions */
(position == left &&
df_GetXYFromPos(tf, left, &left_x, &dummy) &&
event->xbutton.x > left_x) ||
(position == right &&
df_GetXYFromPos(tf, right, &right_x, &dummy) &&
event->xbutton.x < right_x)) {
XmTextF_sel_start(tf) = False;
df_StartDrag(w, event, params, num_params);
} else {
XmTextF_sel_start(tf) = True;
XAllowEvents(XtDisplay(w), AsyncBoth, event->xbutton.time);
df_StartSecondary(w, event, params, num_params);
}
} else {
XmTextF_sel_start(tf) = True;
XAllowEvents(XtDisplay(w), AsyncBoth, event->xbutton.time);
df_StartSecondary(w, event, params, num_params);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ExtendSecondary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ExtendSecondary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition position = df_GetPosFromX(tf, (Position) event->xbutton.x);
if (XmTextF_cancel(tf)) return;
_XmDataFieldDrawInsertionPoint(tf, False);
if (position < XmTextF_sec_anchor(tf)) {
_XmDataFieldSetSel2(w, position, XmTextF_sec_anchor(tf),
False, event->xbutton.time);
} else if (position > XmTextF_sec_anchor(tf)) {
_XmDataFieldSetSel2(w, XmTextF_sec_anchor(tf), position,
False, event->xbutton.time);
} else {
_XmDataFieldSetSel2(w, position, position, False, event->xbutton.time);
}
XmTextF_sec_extending(tf) = True;
if (!df_CheckTimerScrolling(w, event))
df_DoSecondaryExtend(w, event->xmotion.time);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DoStuff( w, closure, seltype, type, value, length, format )
Widget w ;
XtPointer closure ;
Atom *seltype ;
Atom *type ;
XtPointer value ;
unsigned long *length ;
int *format ;
#else
df_DoStuff(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmTextPrimSelect *prim_select = (_XmTextPrimSelect *) closure;
Atom NULL_ATOM = XmInternAtom(XtDisplay(w), "NULL", False);
XmTextPosition right, left;
int prim_char_length = 0;
Boolean replace_res = False;
XTextProperty tmp_prop;
int i, status;
int malloc_size;
int num_vals;
char **tmp_value;
XmAnyCallbackStruct cb;
if (!XmTextF_has_focus(tf) && _XmGetFocusPolicy(w) == XmEXPLICIT)
(void) XmProcessTraversal(w, XmTRAVERSE_CURRENT);
if (!(*length) && *type != NULL_ATOM ) {
/* Backwards compatibility for 1.0 Selections */
if (prim_select->target == XmInternAtom(XtDisplay(w), "TEXT", False)) {
prim_select->target = XA_STRING;
XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, df_DoStuff,
(XtPointer)prim_select, prim_select->time);
}
XtFree((char *)value);
value = NULL;
return;
}
/* if length == 0 and *type is the NULL atom we are assuming
* that a DELETE target is requested.
*/
if (*type == NULL_ATOM ) {
if (prim_select->num_chars > 0 && XmTextF_selection_move(tf)) {
prim_char_length = prim_select->num_chars;
XmDataFieldSetSelection(w, prim_select->position,
prim_select->position + prim_char_length,
prim_select->time);
XmTextF_prim_anchor(tf) = prim_select->position;
(void) df_SetDestination(w, XmTextF_cursor_position(tf),
False, prim_select->time);
}
} else {
int max_length = 0;
Boolean local = XmTextF_has_primary(tf);
if (XmTextF_selection_move(tf) && local) {
max_length = XmTextF_max_length(tf);
XmTextF_max_length(tf) = INT_MAX;
}
if (*type == XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False) ||
#ifdef UTF8_SUPPORTED
*type == XmInternAtom(XtDisplay(w), "UTF8_STRING", False) ||
#endif
*type == XA_STRING) {
tmp_prop.value = (unsigned char *) value;
tmp_prop.encoding = *type;
tmp_prop.format = *format;
tmp_prop.nitems = *length;
num_vals = 0;
status = XmbTextPropertyToTextList(XtDisplay(w), &tmp_prop,
&tmp_value, &num_vals);
/* if no conversion, num_vals is not changed */
/* status will be >0 if some characters could not be converted */
if (num_vals && (status == Success || status > 0)) {
if (XmTextF_max_char_size(tf) == 1){
char * total_tmp_value;
for (i = 0, malloc_size = 1; i < num_vals ; i++)
malloc_size += strlen(tmp_value[i]);
prim_select->num_chars = malloc_size - 1;
total_tmp_value = XtMalloc ((unsigned) malloc_size);
total_tmp_value[0] = '\0';
for (i = 0; i < num_vals ; i++)
strcat(total_tmp_value, tmp_value[i]);
replace_res = _XmDataFieldReplaceText(tf, NULL,
prim_select->position,
prim_select->position,
total_tmp_value,
strlen(total_tmp_value),
False);
XFreeStringList(tmp_value);
XtFree(total_tmp_value);
} else {
wchar_t * wc_value;
prim_select->num_chars = 0;
for (i = 0, malloc_size = sizeof(wchar_t); i < num_vals ; i++)
malloc_size += strlen(tmp_value[i]) * sizeof(wchar_t);
wc_value = (wchar_t*)XtMalloc ((unsigned) malloc_size);
for (i = 0; i < num_vals ; i++)
prim_select->num_chars +=
mbstowcs(wc_value + prim_select->num_chars,
tmp_value[i],
(size_t)malloc_size -
prim_select->num_chars);
replace_res = _XmDataFieldReplaceText(tf, NULL,
prim_select->position,
prim_select->position,
(char*)wc_value,
prim_select->num_chars,
False);
XtFree((char*)wc_value);
}
} else { /* initialize prim_select values for possible delete oper */
prim_select->num_chars = 0;
}
} else {
if (XmTextF_max_char_size(tf) == 1){
/* Note: *length may be truncated during cast to int */
prim_select->num_chars = (int) *length;
replace_res = _XmDataFieldReplaceText(tf, NULL,
prim_select->position,
prim_select->position,
(char *) value,
prim_select->num_chars,
False);
} else {
wchar_t * wc_value;
wc_value = (wchar_t*)XtMalloc ((unsigned)
(*length * sizeof(wchar_t)));
prim_select->num_chars = mbstowcs(wc_value, (char *) value,
(size_t) *length);
replace_res = _XmDataFieldReplaceText(tf, NULL,
prim_select->position,
prim_select->position,
(char*)wc_value,
prim_select->num_chars,
False);
XtFree((char*)wc_value);
}
}
if (replace_res) {
XmTextPosition cursorPos;
XmTextF_pending_off(tf) = FALSE;
cursorPos = prim_select->position + prim_select->num_chars;
if (prim_select->num_chars > 0 && !XmTextF_selection_move(tf)){
(void) df_SetDestination(w, cursorPos, False, prim_select->time);
_XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
True, True);
}
if (XmDataFieldGetSelectionPosition(w, &left, &right)) {
if (XmTextF_selection_move(tf) && left < prim_select->position)
prim_select->position -= prim_select->num_chars;
if (left <= cursorPos && right >= cursorPos)
XmTextF_pending_off(tf) = TRUE;
} else {
if (!XmTextF_selection_move(tf) && !XmTextF_add_mode(tf) &&
prim_select->num_chars != 0)
XmTextF_prim_anchor(tf) = prim_select->position;
}
if (XmTextF_selection_move(tf)) {
prim_select->ref_count++;
XtGetSelectionValue(w, XA_PRIMARY,
XmInternAtom(XtDisplay(w), "DELETE", False),
df_DoStuff, (XtPointer)prim_select,
prim_select->time);
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = (XEvent *)NULL;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
if (XmTextF_selection_move(tf) && local) {
XmTextF_max_length(tf) = max_length;
}
}
XtFree((char *)value);
value = NULL;
if (--prim_select->ref_count == 0)
XtFree((char*)prim_select);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_Stuff( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_Stuff(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
_XmTextActionRec *tmp = (_XmTextActionRec*)XtMalloc(sizeof(_XmTextActionRec));
/* Request targets from the selection owner so you can decide what to
* request. The decision process and request for the selection is
* taken care of in df_HandleTargets().
*/
tmp->event = (XEvent *) XtMalloc(sizeof(XEvent));
memcpy((void *)tmp->event, (void *)event, sizeof(XEvent));
tmp->params = params;
tmp->num_params = num_params;
XtGetSelectionValue(w, XA_PRIMARY,
XmInternAtom(XtDisplay(w), "TARGETS", False),
df_HandleTargets,
(XtPointer)tmp, event->xbutton.time);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_HandleSelectionReplies( w, closure, event, cont )
Widget w ;
XtPointer closure ;
XEvent *event ;
Boolean *cont ;
#else
df_HandleSelectionReplies(
Widget w,
XtPointer closure,
XEvent *event,
Boolean *cont )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Atom property = (Atom) closure;
TextFDestData dest_data;
XmTextPosition left, right;
int adjustment = 0;
XmAnyCallbackStruct cb;
if (event->type != SelectionNotify) return;
XtRemoveEventHandler(w, (EventMask) NULL, TRUE,
df_HandleSelectionReplies,
(XtPointer) XmInternAtom(XtDisplay(w),
"_XM_TEXT_I_S_PROP", False));
dest_data = df_GetTextFDestData(w);
if (event->xselection.property == None) {
(void) _XmDataFieldSetSel2(w, 0, 0, False, event->xselection.time);
XmTextF_selection_move(tf) = False;
} else {
if (dest_data->has_destination) {
adjustment = (int) (XmTextF_sec_pos_right(tf) - XmTextF_sec_pos_left(tf));
XmDataFieldSetHighlight(w, XmTextF_sec_pos_left(tf),
XmTextF_sec_pos_right(tf), XmHIGHLIGHT_NORMAL);
if (dest_data->position <= XmTextF_sec_pos_left(tf)) {
XmTextF_sec_pos_left(tf) += adjustment - dest_data->replace_length;
XmTextF_sec_pos_right(tf) += adjustment - dest_data->replace_length;
} else if (dest_data->position > XmTextF_sec_pos_left(tf) &&
dest_data->position < XmTextF_sec_pos_right(tf)) {
XmTextF_sec_pos_left(tf) -= dest_data->replace_length;
XmTextF_sec_pos_right(tf) += adjustment - dest_data->replace_length;
}
}
left = XmTextF_sec_pos_left(tf);
right = XmTextF_sec_pos_right(tf);
(void) _XmDataFieldSetSel2(w, 0, 0, False, event->xselection.time);
XmTextF_has_secondary(tf) = False;
if (XmTextF_selection_move(tf)) {
if (_XmDataFieldReplaceText(tf, event, left, right, NULL, 0, False)) {
if (dest_data->has_destination && XmTextF_cursor_position(tf) > right){
XmTextPosition cursorPos;
cursorPos = XmTextF_cursor_position(tf) - (right - left);
if (!dest_data->quick_key)
_XmDataFielddf_SetCursorPosition(tf, event, cursorPos,
True, True);
(void) df_SetDestination((Widget) tf, cursorPos, False,
event->xselection.time);
}
if (!dest_data->has_destination) {
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
XmDataFieldSetAddMode(w, False);
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
XmTextF_selection_move(tf) = False;
}
}
XDeleteProperty(XtDisplay(w), event->xselection.requestor, property);
}
/*
* Notify the primary selection that the secondary selection
* wants to insert it's selection data into the primary selection.
*/
/* REQUEST TARGETS FROM SELECTION RECEIVER; THEN CALL HANDLETARGETS
* WHICH LOOKS AT THE TARGET LIST AND DETERMINE WHAT TARGET TO PLACE
* IN THE PAIR. IT WILL THEN DO ANY NECESSARY CONVERSIONS BEFORE
* TELLING THE RECEIVER WHAT TO REQUEST AS THE SELECTION VALUE.
* THIS WILL GUARANTEE THE BEST CHANCE AT A SUCCESSFUL EXCHANGE.
*/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_SecondaryNotify( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_SecondaryNotify(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Atom XM_TEXT_PROP = XmInternAtom(XtDisplay(w), "_XM_TEXT_I_S_PROP", False);
Atom CS_OF_LOCALE; /* to be initialized by XmbTextListToTextProperty */
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
TextFDestData dest_data;
XTextProperty tmp_prop;
_XmTextInsertPair tmp_pair[1];
_XmTextInsertPair *pair = tmp_pair;
XmTextPosition left, right;
int status = 0;
if (XmTextF_selection_move(tf) == TRUE && XmTextF_has_destination(tf) &&
XmTextF_cursor_position(tf) >= XmTextF_sec_pos_left(tf) &&
XmTextF_cursor_position(tf) <= XmTextF_sec_pos_right(tf)) {
(void) _XmDataFieldSetSel2(w, 0, 0, False, event->xbutton.time);
return;
}
status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
CS_OF_LOCALE = tmp_prop.encoding;
else
CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
/*
* Determine what the reciever supports so you can tell 'em what to
* request.
*/
/* fill in atom pair */
pair->selection = XA_SECONDARY;
pair->target = CS_OF_LOCALE;
/* add the insert selection property on the text field widget's window */
XChangeProperty(XtDisplay(w), XtWindow(w), XM_TEXT_PROP,
XmInternAtom(XtDisplay(w), "ATOM_PAIR", False),
32, PropModeReplace, (unsigned char *)pair, 2);
dest_data = df_GetTextFDestData(w);
dest_data->has_destination = XmTextF_has_destination(tf);
dest_data->position = XmTextF_cursor_position(tf);
dest_data->replace_length = 0;
if (*(num_params) == 1) dest_data->quick_key = True;
else dest_data->quick_key = False;
if (XmDataFieldGetSelectionPosition(w, &left, &right) && left != right) {
if (dest_data->position >= left && dest_data->position <= right)
dest_data->replace_length = (int) (right - left);
}
/* add an event handler to handle selection notify events */
XtAddEventHandler(w, (EventMask) NULL, TRUE,
df_HandleSelectionReplies, (XtPointer)XM_TEXT_PROP);
/*
* Make a request for the primary selection to convert to
* type INSERT_SELECTION as per ICCCM.
*/
XConvertSelection(XtDisplay(w),
XmInternAtom(XtDisplay(w), "MOTIF_DESTINATION", False),
XmInternAtom(XtDisplay(w), "INSERT_SELECTION", False),
XM_TEXT_PROP, XtWindow(w), event->xbutton.time);
}
/*
* LOOKS AT THE TARGET LIST AND DETERMINE WHAT TARGET TO PLACE
* IN THE PAIR. IT WILL THEN DO ANY NECESSARY CONVERSIONS BEFORE
* TELLING THE RECEIVER WHAT TO REQUEST AS THE SELECTION VALUE.
* THIS WILL GUARANTEE THE BEST CHANCE AT A SUCCESSFUL EXCHANGE.
*/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_HandleTargets( w, closure, seltype, type, value, length, format )
Widget w ;
XtPointer closure ;
Atom *seltype ;
Atom *type ;
XtPointer value ;
unsigned long *length ;
int *format ;
#else
df_HandleTargets(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Atom CS_OF_LOCALE; /* to be initialized by XmbTextListToTextProperty */
Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w),"COMPOUND_TEXT", False);
#ifdef UTF8_SUPPORTED
Atom UTF8_STRING = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
#endif
XmTextPosition left, right;
Boolean supports_locale_data = False;
Boolean supports_CT = False;
Boolean supports_utf8_string = False;
Atom *atom_ptr;
_XmTextActionRec *tmp_action = (_XmTextActionRec *) closure;
_XmTextPrimSelect *prim_select;
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
int status = 0;
Atom targets[2];
XmTextPosition select_pos;
int i;
if (!length) {
XtFree((char *)value);
value = NULL;
XtFree((char *)tmp_action->event);
XtFree((char *)tmp_action);
return; /* Supports no targets, so don't bother sending anything */
}
atom_ptr = (Atom *)value;
status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
CS_OF_LOCALE = tmp_prop.encoding;
else
CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
for (i = 0; i < *length; i++, atom_ptr++) {
if (*atom_ptr == CS_OF_LOCALE) {
supports_locale_data = True;
break;
}
if (*atom_ptr == COMPOUND_TEXT)
supports_CT = True;
#ifdef UTF8_SUPPORTED
if (*atom_ptr == UTF8_STRING)
supports_utf8_string = True;
#endif
}
/*
* Set stuff position to the x and y position of
* the button pressed event for primary pastes.
*/
if (tmp_action->event->type == ButtonRelease) {
select_pos = df_GetPosFromX(tf, (Position)tmp_action->event->xbutton.x);
} else {
select_pos = XmTextF_cursor_position(tf);
}
if (XmDataFieldGetSelectionPosition(w, &left, &right) &&
left != right && select_pos > left && select_pos < right) {
XtFree((char *)value);
value = NULL;
XtFree((char *)tmp_action->event);
XtFree((char *)tmp_action);
return;
}
prim_select = (_XmTextPrimSelect *)
XtMalloc((unsigned) sizeof(_XmTextPrimSelect));
prim_select->position = select_pos;
if (tmp_action->event->type == ButtonRelease) {
prim_select->time = tmp_action->event->xbutton.time;
} else {
prim_select->time = tmp_action->event->xkey.time;
}
prim_select->num_chars = 0;
if (supports_locale_data)
prim_select->target = targets[0] = XmInternAtom(XtDisplay(w), "TEXT",
False);
#ifdef UTF8_SUPPORTED
else if (supports_utf8_string)
prim_select->target = targets[0] = UTF8_STRING;
#endif
else if (supports_CT)
prim_select->target = targets[0] = COMPOUND_TEXT;
else
prim_select->target = targets[0] = XA_STRING;
prim_select->ref_count = 1;
/* Make request to call df_DoStuff() with the primary selection. */
XtGetSelectionValue(w, XA_PRIMARY, targets[0], df_DoStuff,
(XtPointer)prim_select,
tmp_action->event->xbutton.time);
XtFree((char *)value);
value = NULL;
XtFree((char *)tmp_action->event);
XtFree((char *)tmp_action);
}
static void
#ifdef _NO_PROTO
df_ProcessBDragRelease( w, event, params, num_params )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
df_ProcessBDragRelease(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XButtonEvent *ev = (XButtonEvent *) event;
XmTextPosition position;
/* Work around for intrinsic bug. Remove once bug is fixed. */
XtUngrabPointer(w, ev->time);
_XmDataFieldDrawInsertionPoint(tf, False);
if (!XmTextF_cancel(tf)) XtUngrabKeyboard(w, CurrentTime);
position = df_GetPosFromX(tf, (Position) event->xbutton.x);
if (XmTextF_sel_start(tf)) {
if (XmTextF_has_secondary(tf) &&
XmTextF_sec_pos_left(tf) != XmTextF_sec_pos_right(tf)) {
if (ev->x > (int)tf->core.width || ev->x < 0 ||
ev->y > (int)tf->core.height || ev->x < 0) {
_XmDataFieldSetSel2(w, 0, 0, False, event->xkey.time);
XmTextF_has_secondary(tf) = False;
} else {
df_SecondaryNotify(w, event, params, num_params);
}
} else if (!XmTextF_sec_drag(tf) && !XmTextF_cancel(tf) &&
XmTextF_sec_pos_left(tf) == position) {
XmTextF_stuff_pos(tf) = df_GetPosFromX(tf, (Position) event->xbutton.x);
/*
* Copy contents of primary selection to the stuff position found above.
*/
df_Stuff(w, event, params, num_params);
}
}
if (XmTextF_select_id(tf)) {
XtRemoveTimeOut(XmTextF_select_id(tf));
XmTextF_select_id(tf) = 0;
}
XmTextF_sec_extending(tf) = False;
XmTextF_sec_drag(tf) = False;
XmTextF_sel_start(tf) = False;
XmTextF_cancel(tf) = False;
_XmDataFieldDrawInsertionPoint(tf, True);
}
static void
#ifdef _NO_PROTO
df_ProcessCopy( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ProcessCopy(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_selection_move(tf) = FALSE;
df_ProcessBDragRelease(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
static void
#ifdef _NO_PROTO
df_ProcessMove( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ProcessMove(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_selection_move(tf) = TRUE;
df_ProcessBDragRelease(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeleteSelection( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeleteSelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
(void) DataFieldRemove(w, event);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ClearSelection( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ClearSelection(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left = XmTextF_prim_pos_left(tf);
XmTextPosition right = XmTextF_prim_pos_right(tf);
int num_spaces = 0;
XmAnyCallbackStruct cb;
Boolean rep_result = False;
if (left < right)
num_spaces = (int)(right - left);
else
num_spaces = (int)(left - right);
if (num_spaces) {
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmTextF_max_char_size(tf) == 1){
char spaces_cache[100];
Cardinal spaces_size;
char *spaces;
int i;
spaces_size = num_spaces + 1;
spaces = (char *)XmStackAlloc(spaces_size, spaces_cache);
for (i = 0; i < num_spaces; i++) spaces[i] = ' ';
spaces[num_spaces] = 0;
rep_result = _XmDataFieldReplaceText(tf, (XEvent *)event, left, right,
spaces, num_spaces, False);
if (XmTextF_cursor_position(tf) > left)
df_ResetClipOrigin(tf, False);
XmStackFree((char *)spaces, spaces_cache);
} else {
wchar_t *wc_spaces;
int i;
wc_spaces = (wchar_t *)XtMalloc((unsigned)
(num_spaces + 1) * sizeof(wchar_t));
for (i = 0; i < num_spaces; i++){
(void)mbtowc(&wc_spaces[i], " ", 1);
}
rep_result = _XmDataFieldReplaceText(tf, (XEvent *)event, left, right,
(char*)wc_spaces, num_spaces,
False);
if (XmTextF_cursor_position(tf) > left)
df_ResetClipOrigin(tf, False);
XtFree((char*)wc_spaces);
}
if (rep_result) {
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
_XmDataFieldDrawInsertionPoint(tf, True);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_PageRight( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_PageRight(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
Position x, y;
int length = 0;
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Dimension margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
if (XmTextF_max_char_size(tf) != 1){
length = df_FindPixelLength(tf, (char*)XmTextF_wc_value(tf),
XmTextF_string_length(tf));
} else {
length = df_FindPixelLength(tf, XmTextF_value(tf), XmTextF_string_length(tf));
}
_XmDataFieldDrawInsertionPoint(tf, False);
if (*num_params > 0 && !strcmp(*params, "extend"))
df_SetAnchorBalancing(tf, XmTextF_cursor_position(tf));
df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x, &y);
if (length - ((int)(tf->core.width - (2 * margin_width)) -
XmTextF_h_offset(tf)) > (int)(tf->core.width - (2 * margin_width)))
XmTextF_h_offset(tf) -= tf->core.width - (2 * margin_width);
else
XmTextF_h_offset(tf) = -(length - (tf->core.width - (2 * margin_width)));
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
_XmDataFielddf_SetCursorPosition(tf, event, df_GetPosFromX(tf, x),
True, True);
if (*num_params > 0 && !strcmp(*params, "extend"))
df_KeySelection(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_PageLeft( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_PageLeft(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
Position x, y;
XmDataFieldWidget tf = (XmDataFieldWidget) w;
int margin_width = (int)XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
_XmDataFieldDrawInsertionPoint(tf, False);
if (*num_params > 0 && !strcmp(*params, "extend"))
df_SetAnchorBalancing(tf, XmTextF_cursor_position(tf));
df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &x, &y);
if (margin_width <= XmTextF_h_offset(tf) +
((int)tf->core.width - (2 * margin_width)))
XmTextF_h_offset(tf) = margin_width;
else
XmTextF_h_offset(tf) += tf->core.width - (2 * margin_width);
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
_XmDataFielddf_SetCursorPosition(tf, event, df_GetPosFromX(tf, x),
True, True);
if (*num_params > 0 && !strcmp(*params, "extend"))
df_KeySelection(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
static void
#ifdef _NO_PROTO
df_CopyPrimary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_CopyPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_selection_move(tf) = False;
/* perform the primary paste action */
df_Stuff(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
static void
#ifdef _NO_PROTO
df_CutPrimary( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_CutPrimary(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_selection_move(tf) = True;
df_Stuff(w, event, params, num_params);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_SetAnchor( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_SetAnchor(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
(void) df_SetDestination(w, XmTextF_prim_anchor(tf), False, event->xkey.time);
if (XmDataFieldGetSelectionPosition(w, &left, &right)) {
_XmDataFieldStartSelection(tf, XmTextF_prim_anchor(tf),
XmTextF_prim_anchor(tf), event->xkey.time);
XmDataFieldSetAddMode(w, False);
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ToggleOverstrike( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ToggleOverstrike(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_overstrike(tf) = !XmTextF_overstrike(tf);
XmTextF_refresh_ibeam_off(tf) = True;
if (XmTextF_overstrike(tf))
XmTextF_cursor_width(tf) = XmTextF_cursor_height(tf) >> 1;
else {
XmTextF_cursor_width(tf) = 5;
if (XmTextF_cursor_height(tf) > 19)
XmTextF_cursor_width(tf)++;
df_ResetClipOrigin(tf, False);
}
_XmDataFToggleCursorGC(w);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_ToggleAddMode( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_ToggleAddMode(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
_XmDataFieldDrawInsertionPoint(tf, False);
XmDataFieldSetAddMode(w, !XmTextF_add_mode(tf));
if (XmTextF_add_mode(tf) &&
(!(XmDataFieldGetSelectionPosition(w, &left, &right)) ||
left == right))
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_SelectAll( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_SelectAll(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmTextF_has_primary(tf))
df_SetSelection(tf, 0, XmTextF_string_length(tf), True);
else
_XmDataFieldStartSelection(tf, 0, XmTextF_string_length(tf),
event->xbutton.time);
/* Call _XmDataFielddf_SetCursorPosition to force image gc to be updated
* in case the i-beam is contained within the selection */
XmTextF_pending_off(tf) = False;
_XmDataFielddf_SetCursorPosition(tf, NULL, XmTextF_cursor_position(tf),
False, False);
XmTextF_prim_anchor(tf) = 0;
(void) df_SetDestination(w, XmTextF_cursor_position(tf),
False, event->xkey.time);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DeselectAll( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_DeselectAll(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
df_SetSelection(tf, XmTextF_cursor_position(tf), XmTextF_cursor_position(tf), True);
XmTextF_pending_off(tf) = True;
_XmDataFielddf_SetCursorPosition(tf, event, XmTextF_cursor_position(tf),
True, True);
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
(void) df_SetDestination(w, XmTextF_cursor_position(tf),
False, event->xkey.time);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_VoidAction( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_VoidAction(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
/* Do Nothing */
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_CutClipboard( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_CutClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
_XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, False);
(void) XmDataFieldCut(w, event->xkey.time);
_XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_CopyClipboard( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_CopyClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmDataFieldDrawInsertionPoint(tf, False);
(void) XmDataFieldCopy(w, event->xkey.time);
(void) df_SetDestination(w, XmTextF_cursor_position(tf), False, event->xkey.time);
_XmDataFieldDrawInsertionPoint(tf, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_PasteClipboard( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_PasteClipboard(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
_XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, False);
(void) XmDataFieldPaste(w);
_XmDataFieldDrawInsertionPoint((XmDataFieldWidget)w, True);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TraverseDown( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TraverseDown(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
XmTextF_traversed(tf) = True;
if (!_XmMgrTraversal(w, XmTRAVERSE_DOWN))
XmTextF_traversed(tf) = False;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TraverseUp( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TraverseUp(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
XmTextF_traversed(tf) = True;
if (!_XmMgrTraversal(w, XmTRAVERSE_UP))
XmTextF_traversed(tf) = False;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TraverseHome( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TraverseHome(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
/* Allow the verification routine to control the traversal */
if (tf->primitive.navigation_type == XmNONE && df_VerifyLeave(tf, event)) {
XmTextF_traversed(tf) = True;
if (!_XmMgrTraversal(w, XmTRAVERSE_HOME))
XmTextF_traversed(tf) = False;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TraverseNextTabGroup( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TraverseNextTabGroup(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
/* Allow the verification routine to control the traversal */
if (df_VerifyLeave(tf, event)) {
XmTextF_traversed(tf) = True;
if (!_XmMgrTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP))
XmTextF_traversed(tf) = False;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TraversePrevTabGroup( w, event, params, num_params )
Widget w ;
XEvent *event ;
char **params ;
Cardinal *num_params ;
#else
df_TraversePrevTabGroup(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
/* Allow the verification routine to control the traversal */
if (df_VerifyLeave(tf, event)) {
XmTextF_traversed(tf) = True;
if (!_XmMgrTraversal(w, XmTRAVERSE_PREV_TAB_GROUP))
XmTextF_traversed(tf) = False;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TextEnter( w, event, params, num_params )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
df_TextEnter(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
XPoint xmim_point;
/* Use != NotifyInferior along with event->xcrossing.focus to avoid
* sending input method info if reason for the event is pointer moving
* from TextF widget to over-the-spot window (case when over-the-spot
* is child of TextF widget). */
if (_XmGetFocusPolicy(w) != XmEXPLICIT && !(XmTextF_has_focus(tf)) &&
event->xcrossing.focus &&
(event->xcrossing.detail != NotifyInferior)) {
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_blink_on(tf) = False;
XmTextF_has_focus(tf) = True;
_XmDataFToggleCursorGC(w);
if (XtIsSensitive(w)) df_ChangeBlinkBehavior(tf, True);
_XmDataFieldDrawInsertionPoint(tf, True);
df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x,
&xmim_point.y);
XmImVaSetFocusValues(w, XmNspotLocation, &xmim_point, NULL);
cb.reason = XmCR_FOCUS;
cb.event = event;
XtCallCallbackList (w, XmTextF_focus_callback(tf), (XtPointer) &cb);
}
_XmPrimitiveEnter(w, event, params, num_params);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_TextLeave( w, event, params, num_params )
Widget w ;
XEvent *event ;
String *params ;
Cardinal *num_params ;
#else
df_TextLeave(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
/* use detail!= NotifyInferior to handle focus change due to pointer
* wandering into over-the-spot input window - we don't want to change
* IM's focus state in this case. */
if (_XmGetFocusPolicy(w) != XmEXPLICIT && XmTextF_has_focus(tf) &&
event->xcrossing.focus &&
(event->xcrossing.detail != NotifyInferior)) {
if (tf->core.sensitive) df_ChangeBlinkBehavior(tf, False);
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_has_focus(tf) = False;
_XmDataFToggleCursorGC(w);
XmTextF_blink_on(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
(void) df_VerifyLeave(tf, event);
XmImUnsetFocus(w);
}
_XmPrimitiveLeave(w, event, params, num_params);
}
/****************************************************************
*
* Private definitions.
*
****************************************************************/
/*
* df_ClassPartInitialize sets up the fast subclassing for the widget.i
* It also merges translation tables.
*/
static void
#ifdef _NO_PROTO
df_ClassPartInitialize( w_class )
WidgetClass w_class ;
#else
df_ClassPartInitialize(
WidgetClass w_class )
#endif /* _NO_PROTO */
{
char *event_bindings;
_XmFastSubclassInit (w_class, XmDATAFIELD_BIT);
/* Install traits */
XmeTraitSet((XtPointer) w_class, XmQTaccessTextual, (XtPointer) &dataFieldCS);
event_bindings = (char *)XtMalloc((unsigned) (strlen(EventBindings1) +
strlen(EventBindings2) +
strlen(EventBindings3) + strlen("\n") +
strlen(EventBindings4) + 1));
strcpy(event_bindings, EventBindings4);
strcat(event_bindings, "\n");
strcat(event_bindings, EventBindings1);
strcat(event_bindings, EventBindings2);
strcat(event_bindings, EventBindings3);
_XmProcessLock();
w_class->core_class.tm_table = (String) XtParseTranslationTable(event_bindings);
_XmProcessUnlock();
XtFree(event_bindings);
}
/****************************************************************
*
* Private functions used in df_Initialize.
*
****************************************************************/
/*
* Verify that the resource settings are valid. Print a warning
* message and reset the s if the are invalid.
*/
static void
#ifdef _NO_PROTO
df_Validates( tf )
XmDataFieldWidget tf ;
#else
df_Validates(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
XtPointer temp_ptr;
if (XmTextF_cursor_position(tf) < 0) {
XmeWarning ((Widget)tf, MSG1);
XmTextF_cursor_position(tf) = 0;
}
if (XmTextF_columns(tf) <= 0) {
XmeWarning ((Widget)tf, MSG2);
XmTextF_columns(tf) = 20;
}
if (XmTextF_selection_array(tf) == NULL)
XmTextF_selection_array(tf) = (XmTextScanType *) df_sarray;
if (XmTextF_selection_array_count(tf) <= 0)
XmTextF_selection_array_count(tf) = XtNumber(df_sarray);
/*
* Fix for HaL DTS 9841 - copy the selectionArray into dedicated memory.
*/
temp_ptr = (XtPointer)XmTextF_selection_array(tf);
XmTextF_selection_array(tf) = NULL;
XmTextF_selection_array(tf) = (XmTextScanType *)XtMalloc (
XmTextF_selection_array_count(tf) * sizeof(XmTextScanType));
memcpy((void *)XmTextF_selection_array(tf), (void *)temp_ptr,
(XmTextF_selection_array_count(tf) * sizeof(XmTextScanType)));
/*
* End fix for HaL DTS 9841
*/
}
static Boolean
#ifdef _NO_PROTO
df_LoadFontMetrics( tf )
XmDataFieldWidget tf ;
#else
df_LoadFontMetrics(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
XmFontContext context;
XmFontListEntry next_entry;
XmFontType type_return = XmFONT_IS_FONT;
XtPointer tmp_font;
Boolean have_font_struct = False;
Boolean have_font_set = False;
#ifdef USE_XFT
Boolean have_xft_font = False;
#endif
XFontSetExtents *fs_extents;
XFontStruct *font;
unsigned long charwidth = 0;
char* font_tag = NULL;
Boolean return_val = 1; /* non-zero == success */
if (!XmFontListInitFontContext(&context, XmTextF_font_list(tf)))
XmeWarning ((Widget)tf, MSG3);
do {
next_entry = XmFontListNextEntry(context);
if (next_entry) {
tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
if (type_return == XmFONT_IS_FONTSET) {
font_tag = XmFontListEntryGetTag(next_entry);
if (!have_font_set){ /* this saves the first fontset found, just in
* case we don't find a default tag set.
*/
XmTextF_have_fontset(tf) = True;
#ifdef USE_XFT
XmTextF_use_xft(tf) = False;
#endif
tf->text.font = (XFontStruct *)tmp_font;
have_font_struct = True; /* we have a font set, so no need to
* consider future font structs */
have_font_set = True; /* we have a font set. */
if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
break; /* Break out! We've found the one we want. */
} else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)){
tf->text.font = (XFontStruct *)tmp_font;
have_font_set = True; /* we have a font set. */
break; /* Break out! We've found the one we want. */
}
} else if (type_return == XmFONT_IS_FONT && !have_font_struct) {
/* return_type must be XmFONT_IS_FONT */
XmTextF_have_fontset(tf) = False;
#ifdef USE_XFT
XmTextF_use_xft(tf) = False;
#endif
tf->text.font=(XFontStruct*)tmp_font; /* save the first font
* struct in case no font
* set is found */
have_font_struct = True;
#ifdef USE_XFT
} else if (type_return == XmFONT_IS_XFT && !have_xft_font) {
XmTextF_have_fontset(tf) = False;
XmTextF_use_xft(tf) = True;
have_xft_font = True;
tf->text.font = tmp_font;
#endif
}
}
} while(next_entry != NULL);
#if USE_XFT
if (!have_font_struct && !have_font_set && !have_xft_font) {
#else
if (!have_font_struct && !have_font_set) {
#endif
XmeWarning ((Widget)tf, MSG4);
}
if (XmTextF_max_char_size(tf) > 1 && !have_font_set){
/*XmeWarning((Widget)tf, MSGnnn); */
/* printf ("You've got the wrong font baby, Uh-Huh!\n"); */
/* Must have a font set, as text will be rendered only with new R5 calls
* If df_LoadFontMetrics is called from df_SetValues and set
* values will retain use of old fontlist (which is presumed correct
* for the current locale). */
return_val = 0; /* tell caller that this font won't work for MB_CUR_MAX*/
}
XmFontListFreeFontContext(context);
if(XmTextF_have_fontset(tf)){
fs_extents = XExtentsOfFontSet((XFontSet)XmTextF_font(tf));
charwidth = (unsigned long)fs_extents->max_ink_extent.width;
/* max_ink_extent.y is number of pixels from origin to top of
* rectangle (i.e. y is negative) */
XmTextF_font_ascent(tf) = -fs_extents->max_ink_extent.y;
XmTextF_font_descent(tf) = fs_extents->max_ink_extent.height +
fs_extents->max_ink_extent.y;
#ifdef USE_XFT
} else if (XmTextF_use_xft(tf)) {
#ifdef FIX_1415
_XmXftFontAverageWidth((Widget) tf, TextF_XftFont(tf), &charwidth);
#else
charwidth = XmTextF_xft_font(tf)->max_advance_width;
#endif
#ifdef FIX_1531
XmTextF_font_ascent(tf) = TextF_XftFont(tf)->ascent;
XmTextF_font_descent(tf) = TextF_XftFont(tf)->descent;
#endif /* FIX_1531 */
#endif
} else {
font = XmTextF_font(tf);
if ((!XGetFontProperty(font, XA_QUAD_WIDTH, &charwidth)) ||
charwidth == 0) {
if (font->per_char && font->min_char_or_byte2 <= '0' &&
font->max_char_or_byte2 >= '0')
charwidth = font->per_char['0' - font->min_char_or_byte2].width;
else
charwidth = font->max_bounds.width;
}
XmTextF_font_ascent(tf) = font->max_bounds.ascent;
XmTextF_font_descent(tf) = font->max_bounds.descent;
}
XmTextF_average_char_width(tf) = (Dimension) charwidth;
return (return_val);
}
/* df_ValidateString makes the following assumption: if MB_CUR_MAX == 1, value
* is a char*, otherwise value is a wchar_t*. The Boolean "is_wchar" indicates
* if value points to char* or wchar_t* data.
*
* It is df_ValidateString's task to verify that "value" contains only printing
* characters; all others are discarded. df_ValidateString then mallocs data
* to store the value and assignes it to XmTextF_value(tf) (if MB_CUR_MAX == 1)
* or to XmTextF_wc_value(tf) (if MB_CUR_MAX != 1), setting the opposite
* pointer to NULL. It is the callers responsibility to free data before
* calling df_ValidateString.
*/
static void
#ifdef _NO_PROTO
df_ValidateString( tf, value, is_wchar )
XmDataFieldWidget tf ;
char *value ;
Boolean is_wchar;
#else
df_ValidateString(
XmDataFieldWidget tf,
char *value,
#if NeedWidePrototypes
int is_wchar)
#else
Boolean is_wchar)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
/* if value is wchar_t *, must count the characters; else use strlen */
int str_len = 0;
int i, j;
char stack_cache[400];
if (!is_wchar) {
char *temp_str, *curr_str, *start_temp;
str_len = strlen(value);
temp_str = (char*)XmStackAlloc((Cardinal)str_len + 1, stack_cache);
start_temp = temp_str;
curr_str = value;
for (i = 0; i < str_len;) {
if (XmTextF_max_char_size(tf) == 1){
if (df_FindPixelLength(tf, curr_str, 1)) {
*temp_str = *curr_str;
temp_str++;
} else {
char warn_str[52];
sprintf(warn_str, MSG5, *curr_str);
XmeWarning ((Widget)tf, warn_str);
}
curr_str++;
i++;
} else {
wchar_t tmp[XmTextF_max_char_size(tf)+1];
int num_conv;
num_conv = mbtowc(tmp, curr_str, XmTextF_max_char_size(tf));
if (num_conv >= 0 && df_FindPixelLength(tf, (char*) &tmp, 1)) {
for (j = 0; j < num_conv; j++) {
*temp_str = *curr_str;
temp_str++;
curr_str++;
i++;
}
} else {
char warn_str[52];
sprintf(warn_str, MSG5, *curr_str);
XmeWarning ((Widget)tf, warn_str);
curr_str++;
i++;
}
}
}
*temp_str = '\0';
/* value contains validated string; now stuff it into the proper
* instance pointer. */
if (XmTextF_max_char_size(tf) == 1) {
XmTextF_string_length(tf) = strlen(start_temp);
/* malloc the space for the text value */
XmTextF_value(tf) = (char *) memcpy(
XtMalloc((unsigned)(XmTextF_string_length(tf) + 30)),
(void *)start_temp, XmTextF_string_length(tf) + 1);
XmTextF_size_allocd(tf) = XmTextF_string_length(tf) + 30;
XmTextF_wc_value(tf) = NULL;
} else { /* Need wchar_t* data to set as the widget's value */
/* count number of wchar's */
str_len = strlen(start_temp);
XmTextF_string_length(tf) = str_len;
XmTextF_size_allocd(tf) = (XmTextF_string_length(tf) + 30)*sizeof(wchar_t);
XmTextF_wc_value(tf) = (wchar_t*)XtMalloc((unsigned)XmTextF_size_allocd(tf));
XmTextF_string_length(tf) = mbstowcs(XmTextF_wc_value(tf), start_temp,
XmTextF_string_length(tf) + 30);
XmTextF_value(tf) = NULL;
}
XmStackFree((char *)start_temp, stack_cache);
} else { /* pointer passed points to wchar_t* data */
wchar_t *wc_value, *wcs_temp_str, *wcs_start_temp, *wcs_curr_str;
char scratch[8];
int new_len = 0;
int csize = 1;
wc_value = (wchar_t *) value;
for (str_len = 0, i = 0; *wc_value != (wchar_t)0L; str_len++)
wc_value++; /* count number of wchars */
wcs_temp_str=(wchar_t *)XmStackAlloc((Cardinal)
((str_len+1) * sizeof(wchar_t)),
stack_cache);
wcs_start_temp = wcs_temp_str;
wcs_curr_str = (wchar_t *) value;
for (i = 0; i < str_len; i++, wcs_curr_str++) {
if (XmTextF_max_char_size(tf) == 1){
csize = wctomb(scratch, *wcs_curr_str);
if (csize >= 0 && df_FindPixelLength(tf, scratch, csize)) {
*wcs_temp_str = *wcs_curr_str;
wcs_temp_str++;
new_len++;
} else {
char warn_str[52];
scratch[csize]= '\0';
sprintf(warn_str, WC_MSG1, scratch);
XmeWarning ((Widget)tf, warn_str);
}
} else {
if (df_FindPixelLength(tf, (char*)wcs_curr_str, 1)) {
*wcs_temp_str = *wcs_curr_str;
wcs_temp_str++;
new_len++;
} else {
char warn_str[52];
csize = wctomb(scratch, *wcs_curr_str);
if (csize >= 0)
scratch[csize]= '\0';
else
scratch[0] = '\0';
sprintf(warn_str, WC_MSG1, scratch);
XmeWarning ((Widget)tf, warn_str);
}
}
}
str_len = new_len;
*wcs_temp_str = (wchar_t)0L; /* terminate with a wchar_t NULL */
XmTextF_string_length(tf) = str_len; /* This is *wrong* if MB_CUR_MAX > 2
* with no font set... but what can
* ya do? Spec says let it dump core. */
XmTextF_size_allocd(tf) = (str_len + 30) * sizeof(wchar_t);
if (XmTextF_max_char_size(tf) == 1) { /* Need to store data as char* */
XmTextF_value(tf) = XtMalloc((unsigned)XmTextF_size_allocd(tf));
(void)wcstombs(XmTextF_value(tf), wcs_start_temp, XmTextF_size_allocd(tf));
XmTextF_wc_value(tf) = NULL;
} else { /* Need to store data as wchar_t* */
XmTextF_wc_value(tf) = (wchar_t*)memcpy(XtMalloc((unsigned)
XmTextF_size_allocd(tf)),
(void*)wcs_start_temp,
(1 + str_len) *
sizeof(wchar_t));
XmTextF_value(tf) = NULL;
}
XmStackFree((char *)wcs_start_temp, stack_cache);
}
}
/* The following is a hack to overcome the buggy Motif from SGI on IM */
#if defined(__sgi)
static void /* CR03685 */
#ifdef _NO_PROTO
SGI_hack_XmImRegister(w)
Widget w;
#else
SGI_hack_XmImRegister(
Widget w )
#endif /* _NO_PROTO */
{
_XmProcessLock();
w->core.widget_class = xmTextFieldWidgetClass;
_XmProcessUnlock();
XmImRegister(w, NULL);
_XmProcessLock();
w->core.widget_class = xmDataFieldWidgetClass;
_XmProcessUnlock();
}
#endif
/*
* df_Initialize the s in the text fields instance record.
*/
static void
#ifdef _NO_PROTO
df_InitializeTextStruct( tf )
XmDataFieldWidget tf ;
#else
df_InitializeTextStruct(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
/* Flag used in losing focus verification to indicate that a traversal
* key was pressed. Must be initialized to False.
*/
Arg args[6]; /* To set initial values to input method */
Cardinal n = 0;
XPoint xmim_point;
XmTextF_traversed(tf) = False;
XmTextF_add_mode(tf) = False;
XmTextF_has_focus(tf) = False;
XmTextF_blink_on(tf) = True;
XmTextF_cursor_on(tf) = 0;
XmTextF_has_rect(tf) = False;
XmTextF_has_primary(tf) = False;
XmTextF_has_secondary(tf) = False;
XmTextF_has_destination(tf) = False;
XmTextF_overstrike(tf) = False;
XmTextF_selection_move(tf) = False;
XmTextF_sel_start(tf) = False;
XmTextF_pending_off(tf) = True;
XmTextF_fontlist_created(tf) = False;
XmTextF_cancel(tf) = False;
XmTextF_extending(tf) = False;
XmTextF_prim_time(tf) = 0;
XmTextF_dest_time(tf) = 0;
XmTextF_select_id(tf) = 0;
XmTextF_select_pos_x(tf) = 0;
XmTextF_sec_extending(tf) = False;
XmTextF_sec_drag(tf) = False;
XmTextF_changed_visible(tf) = False;
XmTextF_refresh_ibeam_off(tf) = True;
XmTextF_in_setvalues(tf) = False;
XmTextF_do_resize(tf) = True;
XmTextF_have_inverted_image_gc(tf) = False;
XmTextF_margin_top(tf) = XmTextF_margin_height(tf);
XmTextF_margin_bottom(tf) = XmTextF_margin_height(tf);
/* copy over the font list */
if (XmTextF_font_list(tf) == NULL) {
XmTextF_font_list(tf) = XmeGetDefaultRenderTable((Widget)tf,
(unsigned char) XmTEXT_FONTLIST);
XmTextF_fontlist_created(tf) = True;
}
XmTextF_font_list(tf) = (XmFontList)XmFontListCopy(XmTextF_font_list(tf));
XmTextF_max_char_size(tf) = MB_CUR_MAX;
(void)df_LoadFontMetrics(tf);
XmTextF_gc(tf) = NULL;
XmTextF_image_gc(tf) = NULL;
XmTextF_save_gc(tf) = NULL;
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
XmTextF_new_h_offset(tf) = XmTextF_h_offset(tf) = 0;
else
XmTextF_new_h_offset(tf) = XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness + tf->primitive.highlight_thickness;
/* df_ValidateString will verify value contents, convert to appropriate
* storage form (i.e. char* or wchar_t*), place in the appropriate
* location (text.value or text.wc_value), and null out opposite
* pointer. */
if (XmTextF_wc_value(tf) != NULL) { /* XmNvalueWcs was set - it rules */
XmTextF_value(tf) = NULL;
df_ValidateString(tf, (char*)XmTextF_wc_value(tf), True);
} else if (XmTextF_value(tf) != NULL)
df_ValidateString(tf, XmTextF_value(tf), False);
else /* XmTextF_value(tf) is null pointer */
df_ValidateString(tf, "", False);
if (XmTextF_cursor_position(tf) > XmTextF_string_length(tf))
XmTextF_cursor_position(tf) = XmTextF_string_length(tf);
XmTextF_orig_left(tf) = XmTextF_orig_right(tf) = XmTextF_prim_pos_left(tf) =
XmTextF_prim_pos_right(tf) = XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
XmTextF_sec_pos_left(tf) = XmTextF_sec_pos_right(tf) =
XmTextF_sec_anchor(tf) = XmTextF_cursor_position(tf);
XmTextF_stuff_pos(tf) = XmTextF_cursor_position(tf);
XmTextF_cursor_height(tf) = XmTextF_cursor_width(tf) = 0;
XmTextF_stipple_tile(tf) = None;
XmTextF_add_mode_cursor(tf) = XmUNSPECIFIED_PIXMAP;
XmTextF_cursor(tf) = XmUNSPECIFIED_PIXMAP;
XmTextF_ibeam_off(tf) = XmUNSPECIFIED_PIXMAP;
XmTextF_image_clip(tf) = XmUNSPECIFIED_PIXMAP;
XmTextF_last_time(tf) = 0;
XmTextF_sarray_index(tf) = 0;
/* df_Initialize highlight elements */
XmTextF_highlight(tf).number = XmTextF_highlight(tf).maximum = 1;
XmTextF_highlight(tf).list = (_XmHighlightRec *)XtMalloc((unsigned)
sizeof(_XmHighlightRec));
XmTextF_highlight(tf).list[0].position = 0;
XmTextF_highlight(tf).list[0].mode = XmHIGHLIGHT_NORMAL;
XmTextF_timer_id(tf) = (XtIntervalId)0;
if(XmDataField_picture_source(tf)) {
XmDataField_picture_source(tf) = XtNewString(XmDataField_picture_source(tf));
XmDataField_picture(tf) = XmParsePicture(XmDataField_picture_source(tf));
XtAddCallback((Widget)tf, XmNmodifyVerifyCallback,
PictureVerifyCallback, NULL);
} else {
/* No picture specified */
XmDataField_picture(tf) = NULL;
}
XmDataFieldSetEditable((Widget)tf, XmTextF_editable(tf));
if (XmTextF_editable(tf)){
#if defined(__sgi)
/* CR03685 */
SGI_hack_XmImRegister((Widget)tf);
#else
XmImRegister((Widget)tf, (unsigned int) NULL);
#endif
df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x, &xmim_point.y);
n = 0;
XtSetArg(args[n], XmNfontList, XmTextF_font_list(tf)); n++;
XtSetArg(args[n], XmNbackground, tf->core.background_pixel); n++;
XtSetArg(args[n], XmNforeground, tf->primitive.foreground); n++;
XtSetArg(args[n], XmNbackgroundPixmap,tf->core.background_pixmap);n++;
XtSetArg(args[n], XmNspotLocation, &xmim_point); n++;
XtSetArg(args[n], XmNlineSpace,
XmTextF_font_ascent(tf)+ XmTextF_font_descent(tf)); n++;
XmImSetValues((Widget)tf, args, n);
}
}
static Pixmap
#ifdef _NO_PROTO
df_GetClipMask( tf, pixmap_name)
XmDataFieldWidget tf ;
char *pixmap_name ;
#else
df_GetClipMask(
XmDataFieldWidget tf,
char *pixmap_name)
#endif /* _NO_PROTO */
{
Display *dpy = XtDisplay(tf);
Screen *screen = XtScreen(tf);
XGCValues values;
GC fillGC;
Pixmap clip_mask;
clip_mask = XCreatePixmap(dpy, RootWindowOfScreen(screen),
XmTextF_cursor_width(tf), XmTextF_cursor_height(tf), 1);
values.foreground = 1;
values.background = 0;
fillGC = XCreateGC(dpy, clip_mask, GCForeground | GCBackground, &values);
XFillRectangle(dpy, clip_mask, fillGC, 0, 0, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf));
/* Install the clipmask for pixmap caching */
(void) _XmCachePixmap(clip_mask, screen, pixmap_name, 1, 0, 0, 0, 0);
XFreeGC(XtDisplay(tf), fillGC);
return(clip_mask);
}
/*
* Get the graphics context for filling the background, and for drawing
* and inverting text. Used a unique pixmap so all text field widgets
* share common GCs.
*/
static void
#ifdef _NO_PROTO
df_LoadGCs( tf, background, foreground )
XmDataFieldWidget tf ;
Pixel background ;
Pixel foreground ;
#else
df_LoadGCs(
XmDataFieldWidget tf,
Pixel background,
Pixel foreground )
#endif /* _NO_PROTO */
{
Display *display = XtDisplay((Widget)tf);
Screen *screen = XtScreen((Widget)tf);
XGCValues values;
static XContext context = 0;
static Pixmap tf_cache_pixmap;
unsigned long value_mask = (GCFunction | GCForeground | GCBackground |
GCClipMask | GCArcMode);
unsigned long dynamic_mask;
if (XmTextF_stipple_tile(tf) != None)
XmDestroyPixmap(XtScreen(tf), XmTextF_stipple_tile(tf));
XmTextF_stipple_tile(tf) = (Pixmap)
XmGetPixmapByDepth(XtScreen(tf),"50_foreground",
tf->primitive.foreground, tf->core.background_pixel,
tf->core.depth);
if (context == 0)
context = XUniqueContext();
if (XFindContext(display, (Window)screen,
context, (char **) &tf_cache_pixmap)){
XmTextContextData ctx_data;
Widget xm_display = (Widget) XmGetXmDisplay(display);
ctx_data = (XmTextContextData) XtMalloc(sizeof(XmTextContextDataRec));
ctx_data->screen = screen;
ctx_data->context = context;
ctx_data->type = _XM_IS_PIXMAP_CTX;
/* Get the Pixmap identifier that the X Toolkit uses to cache our */
/* GC's. We never actually use this Pixmap; just so long as it's */
/* a unique identifier. */
tf_cache_pixmap = XCreatePixmap(display,
(Drawable) RootWindowOfScreen(screen),
(unsigned int) 1, (unsigned int) 1,
(unsigned int) 1);
XtAddCallback(xm_display, XmNdestroyCallback,
(XtCallbackProc) df_FreeContextData, (XtPointer) ctx_data);
XSaveContext(display, (Window)screen, context, (XPointer) tf_cache_pixmap);
}
/* Used to be: values.clip_mask = tf_cache_pixmap; */
values.clip_mask = 0; /* use in caching Text Field gc's */
values.arc_mode = ArcPieSlice; /* Used in differentiating from Text
widget GC caching */
if (XmTextF_has_rect(tf)) {
TextFGCData gc_data = df_GetTextFGCData((Widget)tf);
XmTextF_has_rect(gc_data->tf) = False;
gc_data->tf = NULL;
}
/*
* Get GC for saving area under the cursor.
*/
values.function = GXcopy;
values.foreground = tf->primitive.foreground ;
values.background = tf->core.background_pixel;
if (XmTextF_save_gc(tf) != NULL)
XtReleaseGC((Widget)tf, XmTextF_save_gc(tf));
dynamic_mask = (GCClipMask);
XmTextF_save_gc(tf) = XtAllocateGC((Widget) tf,
tf->core.depth, value_mask,
&values, dynamic_mask, 0);
df_XmResetSaveGC(tf, XmTextF_save_gc(tf));
/*
* Get GC for drawing text.
*/
#if USE_XFT
if (!XmTextF_have_fontset(tf) && !XmTextF_use_xft(tf)) {
#else
if (!XmTextF_have_fontset(tf)) {
#endif
value_mask |= GCFont | GCGraphicsExposures;
values.font = XmTextF_font(tf)->fid;
} else {
value_mask |= GCGraphicsExposures;
}
values.graphics_exposures = (Bool) TRUE;
values.foreground = foreground ^ background;
values.background = 0;
if (XmTextF_gc(tf) != NULL)
XtReleaseGC((Widget)tf, XmTextF_gc(tf));
dynamic_mask |= GCForeground | GCBackground | GCFillStyle | GCTile;
XmTextF_gc(tf) = XtAllocateGC((Widget) tf,
tf->core.depth, value_mask,
&values, dynamic_mask, 0);
/* Create a temporary GC - change it later in make IBEAM */
value_mask |= GCTile;
values.tile = XmTextF_stipple_tile(tf);
if (XmTextF_image_gc(tf) != NULL)
XtReleaseGC((Widget)tf, XmTextF_image_gc(tf));
dynamic_mask = (GCForeground | GCBackground | GCStipple | GCFillStyle |
GCTileStipXOrigin | GCTileStipYOrigin | GCFunction |
GCClipMask | GCClipXOrigin | GCClipYOrigin);
XmTextF_image_gc(tf) = XtAllocateGC((Widget) tf,
tf->core.depth, value_mask,
&values, dynamic_mask, 0);
}
static void
#ifdef _NO_PROTO
df_MakeIBeamOffArea( tf, width, height )
XmDataFieldWidget tf ;
Dimension width ;
Dimension height ;
#else
df_MakeIBeamOffArea(
XmDataFieldWidget tf,
#if NeedWidePrototypes
int width,
int height)
#else
Dimension width,
Dimension height)
#endif /* NeedWidePrototypes */
#endif /* _NO_PROTO */
{
Display *dpy = XtDisplay(tf);
Screen *screen = XtScreen(tf);
GC fillGC;
/* Create a pixmap for storing the screen data where the I-Beam will
* be painted */
XmTextF_ibeam_off(tf) = XCreatePixmap(dpy, RootWindowOfScreen(screen), width,
height, tf->core.depth);
/* Create a GC for drawing 0's into the pixmap */
fillGC = XCreateGC(dpy, XmTextF_ibeam_off(tf), 0, (XGCValues *) NULL);
/* df_Initialize the pixmap to 0's */
XFillRectangle(dpy, XmTextF_ibeam_off(tf), fillGC, 0, 0, width, height);
/* Free the GC */
XFreeGC(XtDisplay(tf), fillGC);
}
static void
#ifdef _NO_PROTO
df_MakeIBeamStencil( tf, line_width )
XmDataFieldWidget tf ;
int line_width ;
#else
df_MakeIBeamStencil(
XmDataFieldWidget tf,
int line_width )
#endif /* _NO_PROTO */
{
Screen *screen = XtScreen(tf);
char pixmap_name[17];
XGCValues values;
unsigned long valuemask;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
sprintf(pixmap_name, "_XmDataF_%d_%d", XmTextF_cursor_height(tf), line_width);
XmTextF_cursor(tf) = (Pixmap) XmGetPixmapByDepth(screen, pixmap_name, 1, 0, 1);
if (XmTextF_cursor(tf) == XmUNSPECIFIED_PIXMAP) {
Display *dpy = XtDisplay(tf);
GC fillGC;
XSegment segments[3];
XRectangle ClipRect;
/* Create a pixmap for the I-Beam stencil */
XmTextF_cursor(tf) = XCreatePixmap(dpy, XtWindow(tf), XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf), 1);
/* Create a GC for "cutting out" the I-Beam shape from the pixmap in
* order to create the stencil.
*/
fillGC = XCreateGC(dpy, XmTextF_cursor(tf), 0, (XGCValues *)NULL);
/* Fill in the stencil with a solid in preparation
* to "cut out" the I-Beam
*/
XFillRectangle(dpy, XmTextF_cursor(tf), fillGC, 0, 0, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf));
/* Change the GC for use in "cutting out" the I-Beam shape */
values.foreground = 1;
values.line_width = line_width;
XChangeGC(dpy, fillGC, GCForeground | GCLineWidth, &values);
/* Draw the segments of the I-Beam */
/* 1st segment is the top horizontal line of the 'I' */
segments[0].x1 = 0;
segments[0].y1 = line_width - 1;
segments[0].x2 = XmTextF_cursor_width(tf);
segments[0].y2 = line_width - 1;
/* 2nd segment is the bottom horizontal line of the 'I' */
segments[1].x1 = 0;
segments[1].y1 = XmTextF_cursor_height(tf) - 1;
segments[1].x2 = XmTextF_cursor_width(tf);
segments[1].y2 = XmTextF_cursor_height(tf) - 1;
/* 3rd segment is the vertical line of the 'I' */
segments[2].x1 = XmTextF_cursor_width(tf) >> 1;
segments[2].y1 = line_width;
segments[2].x2 = XmTextF_cursor_width(tf) >> 1;
segments[2].y2 = XmTextF_cursor_height(tf) - 1;
/* Set the clipping rectangle of the image GC from drawing */
ClipRect.width = XmTextF_cursor_width(tf);
ClipRect.height = XmTextF_cursor_height(tf);
ClipRect.x = 0;
ClipRect.y = 0;
XSetClipRectangles(XtDisplay(tf), fillGC, 0, 0, &ClipRect, 1, Unsorted);
/* Draw the segments onto the cursor */
XDrawSegments(dpy, XmTextF_cursor(tf), fillGC, segments, 3);
/* Install the cursor for pixmap caching */
(void) _XmCachePixmap(XmTextF_cursor(tf), XtScreen(tf), pixmap_name, 1, 0, 0, 0, 0);
/* Free the fill GC */
XFreeGC(XtDisplay(tf), fillGC);
}
/* Get/create the image_gc used to paint the I-Beam */
sprintf(pixmap_name, "_XmText_CM_%d", XmTextF_cursor_height(tf));
XmTextF_image_clip(tf) = XmGetPixmapByDepth(XtScreen(tf), pixmap_name,
1, 0, 1);
if (XmTextF_image_clip(tf) == XmUNSPECIFIED_PIXMAP)
XmTextF_image_clip(tf) = df_GetClipMask(tf, pixmap_name);
valuemask = (GCClipMask | GCStipple | GCForeground | GCBackground |
GCFillStyle);
if (!XmTextF_overstrike(tf)) {
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
} else
values.background = values.foreground =
tf->core.background_pixel ^ tf->primitive.foreground;
values.clip_mask = XmTextF_image_clip(tf);
values.stipple = XmTextF_cursor(tf);
values.fill_style = FillStippled;
XChangeGC(XtDisplay(tf), XmTextF_image_gc(tf), valuemask, &values);
}
/* The IBeam Stencil must have already been created before this routine
* is called.
*/
static void
#ifdef _NO_PROTO
df_MakeAddModeCursor( tf, line_width )
XmDataFieldWidget tf ;
int line_width ;
#else
df_MakeAddModeCursor(
XmDataFieldWidget tf,
int line_width )
#endif /* _NO_PROTO */
{
Screen *screen = XtScreen(tf);
char pixmap_name[25];
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
sprintf(pixmap_name, "_XmDataF_AddMode_%d_%d",
XmTextF_cursor_height(tf), line_width);
XmTextF_add_mode_cursor(tf) = (Pixmap) XmGetPixmapByDepth(screen, pixmap_name,
1, 0, 1);
if (XmTextF_add_mode_cursor(tf) == XmUNSPECIFIED_PIXMAP) {
GC fillGC;
XtGCMask valueMask;
XGCValues values;
unsigned int pix_width, pix_height, unused;
Display *dpy = XtDisplay(tf);
Pixmap stipple;
XImage *image;
Pixmap pixmap;
int unused_origin;
Window root;
pixmap = XmGetPixmapByDepth(screen, "50_foreground",
1, 0, 1);
if (pixmap != XmUNSPECIFIED_PIXMAP) {
XGetGeometry(XtDisplay(tf), pixmap, &root, &unused_origin,
&unused_origin, &pix_width, &pix_height,
&unused, &unused);
image = XGetImage(XtDisplay(tf), (Drawable)pixmap, 0, 0,
pix_width, pix_height, AllPlanes,
XYPixmap);
stipple = XCreatePixmap(dpy, XtWindow(tf),
image->width, image->height,1);
XmTextF_add_mode_cursor(tf) = XCreatePixmap(dpy, XtWindow(tf),
XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf),
1);
fillGC = XCreateGC(dpy, XmTextF_add_mode_cursor(tf), 0,
(XGCValues *)NULL);
XPutImage(dpy, stipple, fillGC, image, 0, 0, 0, 0, image->width,
image->height);
XCopyArea(dpy, XmTextF_cursor(tf), XmTextF_add_mode_cursor(tf),
fillGC, 0, 0, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf), 0, 0);
valueMask = (GCTile | GCFillStyle | GCForeground |
GCBackground | GCFunction);
values.function = GXand;
values.tile = stipple;
values.fill_style = FillTiled;
values.foreground = tf->primitive.foreground;
values.background = tf->core.background_pixel;
XChangeGC(XtDisplay(tf), fillGC, valueMask, &values);
XFillRectangle(dpy, XmTextF_add_mode_cursor(tf), fillGC,
0, 0, XmTextF_cursor_width(tf),
XmTextF_cursor_height(tf));
/* Install the pixmap for pixmap caching */
_XmCachePixmap(XmTextF_add_mode_cursor(tf),
XtScreen(tf), pixmap_name, 1, 0, 0, 0, 0);
XFreePixmap(dpy, stipple);
XFreeGC(dpy, fillGC);
}
}
}
static void
#ifdef _NO_PROTO
df_MakeCursors( tf )
XmDataFieldWidget tf ;
#else
df_MakeCursors(
XmDataFieldWidget tf )
#endif /* _NO_PROTO */
{
Screen *screen = XtScreen(tf);
int line_width = 1;
if (!XtIsRealized((Widget) tf)) return;
XmTextF_cursor_width(tf) = 5;
XmTextF_cursor_height(tf) = XmTextF_font_ascent(tf) + XmTextF_font_descent(tf);
/* setup parameters to make a thicker I-Beam */
if (XmTextF_cursor_height(tf) > 19) {
XmTextF_cursor_width(tf)++;
line_width = 2;
}
/* Remove old ibeam off area */
if (XmTextF_ibeam_off(tf) != XmUNSPECIFIED_PIXMAP)
XFreePixmap(XtDisplay((Widget)tf), XmTextF_ibeam_off(tf));
/* Remove old insert cursor */
if (XmTextF_cursor(tf) != XmUNSPECIFIED_PIXMAP) {
(void) XmDestroyPixmap(screen, XmTextF_cursor(tf));
XmTextF_cursor(tf) = XmUNSPECIFIED_PIXMAP;
}
/* Remove old add mode cursor */
if (XmTextF_add_mode_cursor(tf) != XmUNSPECIFIED_PIXMAP) {
(void) XmDestroyPixmap(screen, XmTextF_add_mode_cursor(tf));
XmTextF_add_mode_cursor(tf) = XmUNSPECIFIED_PIXMAP;
}
/* Remove old image_clip pixmap */
if (XmTextF_image_clip(tf) != XmUNSPECIFIED_PIXMAP) {
(void) XmDestroyPixmap(screen, XmTextF_image_clip(tf));
XmTextF_image_clip(tf) = XmUNSPECIFIED_PIXMAP;
}
/* Create area in which to save text located underneath I beam */
df_MakeIBeamOffArea(tf, MAX(XmTextF_cursor_height(tf)>>1, XmTextF_cursor_height(tf)),
XmTextF_cursor_height(tf));
/* Create a new i-beam cursor */
df_MakeIBeamStencil(tf, line_width);
/* Create a new add_mode cursor */
df_MakeAddModeCursor(tf, line_width);
df_ResetClipOrigin(tf, False);
if (XmTextF_overstrike(tf))
XmTextF_cursor_width(tf) = XmTextF_cursor_height(tf) >> 1;
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DropDestroyCB(w, clientData, callData)
Widget w;
XtPointer clientData;
XtPointer callData;
#else
df_DropDestroyCB(
Widget w,
XtPointer clientData,
XtPointer callData )
#endif /* NO_PROTO */
{
df_DeleteDropContext(w);
XtFree((char *)clientData);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DropTransferCallback( w, closure, seltype, type, value, length, format )
Widget w ;
XtPointer closure ;
Atom *seltype ;
Atom *type ;
XtPointer value ;
unsigned long *length ;
int *format ;
#else
df_DropTransferCallback(
Widget w,
XtPointer closure,
Atom *seltype,
Atom *type,
XtPointer value,
unsigned long *length,
int *format )
#endif /* _NO_PROTO */
{
_XmTextDropTransferRec *transfer_rec = (_XmTextDropTransferRec *) closure;
XmDataFieldWidget tf = (XmDataFieldWidget) transfer_rec->widget;
Atom COMPOUND_TEXT = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
#ifdef UTF8_SUPPORTED
Atom UTF8_STRING = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
#endif
Atom CS_OF_LOCALE;
XmTextPosition insertPosLeft, insertPosRight, left, right, cursorPos;
int max_length = 0;
Boolean local = XmTextF_has_primary(tf);
char * total_tmp_value;
wchar_t * wc_total_tmp_value;
char ** tmp_value;
int malloc_size = 0;
int num_vals, status;
Arg args[8];
Cardinal n, i;
unsigned long total_length = 0;
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
Boolean replace = False;
XmAnyCallbackStruct cb;
/* When type = NULL, we are assuming a DELETE request has been requested */
if (*type == XmInternAtom(XtDisplay(transfer_rec->widget), "NULL", False)) {
if (transfer_rec->num_chars > 0 && transfer_rec->move) {
XmTextF_prim_anchor(tf) = transfer_rec->insert_pos;
cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
_XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
False, True);
(void) df_SetDestination((Widget)tf, XmTextF_cursor_position(tf),
False, transfer_rec->timestamp);
XmDataFieldSetSelection((Widget)tf, XmTextF_prim_anchor(tf),
XmTextF_cursor_position(tf),
transfer_rec->timestamp);
}
if (value) {
XtFree((char *)value);
value = NULL;
}
return;
}
status = XmbTextListToTextProperty(XtDisplay(transfer_rec->widget),
&tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
CS_OF_LOCALE = tmp_prop.encoding;
else
CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
if (!value || (*type != CS_OF_LOCALE && *type != COMPOUND_TEXT
#ifdef UTF8_SUPPORTED
&& *type != XA_STRING && *type != UTF8_STRING
#endif
)) {
n = 0;
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
XtSetValues(w, args, n);
if (value) {
XtFree((char *)value);
value = NULL;
}
return;
}
insertPosLeft = insertPosRight = transfer_rec->insert_pos;
if (*type == XA_STRING || *type == COMPOUND_TEXT
#ifdef UTF8_SUPPORTED
|| *type == UTF8_STRING
#endif
) {
/* value NEEDS TO BE FREED */
tmp_prop.value = (unsigned char *) value;
tmp_prop.encoding = *type;
tmp_prop.format = 8;
tmp_prop.nitems = *length;
status = 0;
status = XmbTextPropertyToTextList(XtDisplay(transfer_rec->widget),
&tmp_prop, &tmp_value, &num_vals);
/* if no conversion, num_vals is not changed */
if (num_vals && (status == Success || status > 0)) {
for (i = 0; i < num_vals ; i++)
malloc_size += strlen(tmp_value[i]);
total_tmp_value = XtMalloc ((unsigned) malloc_size + 1);
total_tmp_value[0] = '\0';
for (i = 0; i < num_vals ; i++)
strcat(total_tmp_value, tmp_value[i]);
total_length = strlen(total_tmp_value);
XFreeStringList(tmp_value);
} else {
if (value) {
XtFree((char *)value);
value = NULL;
}
return;
}
} else {
total_tmp_value = (char *)value;
total_length = *length;
}
if (XmTextF_pending_delete(tf) && XmTextF_has_primary(tf) &&
XmTextF_prim_pos_left(tf) != XmTextF_prim_pos_right(tf) &&
insertPosLeft > XmTextF_prim_pos_left(tf) &&
insertPosRight < XmTextF_prim_pos_right(tf)) {
insertPosLeft = XmTextF_prim_pos_left(tf);
insertPosRight = XmTextF_prim_pos_right(tf);
}
transfer_rec->num_chars = _XmDataFieldCountCharacters(tf, total_tmp_value,
(int)total_length);
_XmDataFieldDrawInsertionPoint(tf, False);
if (transfer_rec->move && local) {
max_length = XmTextF_max_length(tf);
XmTextF_max_length(tf) = INT_MAX;
}
if (XmTextF_max_char_size(tf) == 1) {
if (_XmDataFieldReplaceText(tf, NULL, insertPosLeft, insertPosRight,
(char *) total_tmp_value,
(int)total_length, False))
replace = True;
} else {
wc_total_tmp_value = (wchar_t*)XtMalloc((unsigned)
total_length * sizeof(wchar_t));
/* Note: casting total_length to an int may result in a truncation. */
total_length = mbstowcs(wc_total_tmp_value, total_tmp_value,
(int)total_length);
if (_XmDataFieldReplaceText(tf, NULL, insertPosLeft, insertPosRight,
(char *) wc_total_tmp_value,
(int)total_length, False))
replace = True;
XtFree((char*)wc_total_tmp_value);
}
if (replace) {
XmTextF_pending_off(tf) = FALSE;
if (transfer_rec->num_chars > 0 && !transfer_rec->move) {
cursorPos = transfer_rec->insert_pos + transfer_rec->num_chars;
_XmDataFielddf_SetCursorPosition(tf, NULL, cursorPos,
False, True);
df_SetDestination((Widget)tf, XmTextF_cursor_position(tf), False,
transfer_rec->timestamp);
}
if (XmDataFieldGetSelectionPosition((Widget)tf, &left, &right)) {
if (transfer_rec->move && left < transfer_rec->insert_pos)
transfer_rec->insert_pos -= transfer_rec->num_chars;
if (XmTextF_cursor_position(tf) < left ||
XmTextF_cursor_position(tf) > right)
XmTextF_pending_off(tf) = TRUE;
} else {
if (!transfer_rec->move && !XmTextF_add_mode(tf) &&
transfer_rec->num_chars != 0)
XmTextF_prim_anchor(tf) = insertPosLeft;
}
if (transfer_rec->move) {
XmDropTransferEntryRec transferEntries[1];
transferEntries[0].client_data = (XtPointer) transfer_rec;
transferEntries[0].target = XmInternAtom(XtDisplay(w),"DELETE",False);
XmDropTransferAdd(w, transferEntries, 1);
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = (XEvent *)NULL;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
if (transfer_rec->move && local) {
XmTextF_max_length(tf) = max_length;
}
XtFree(total_tmp_value);
_XmDataFieldDrawInsertionPoint(tf, True);
}
static void
#ifdef _NO_PROTO
df_HandleDrop(w, cb)
Widget w;
XmDropProcCallbackStruct *cb;
#else
df_HandleDrop(
Widget w,
XmDropProcCallbackStruct *cb )
#endif /* _NO_PROTO */
{
static XtCallbackRec dropdf_DestroyCB[] = { {df_DropDestroyCB, NULL},
{(XtCallbackProc)NULL, NULL} };
Widget drag_cont, initiator;
Cardinal numExportTargets, n;
Atom *exportTargets;
Arg args[10];
XmTextPosition insert_pos, left, right;
Display *display = XtDisplay(w);
drag_cont = cb->dragContext;
n = 0;
XtSetArg(args[n], XmNsourceWidget, &initiator); n++;
XtSetArg(args[n], XmNexportTargets, &exportTargets); n++;
XtSetArg(args[n], XmNnumExportTargets, &numExportTargets); n++;
XtGetValues((Widget) drag_cont, args, n);
insert_pos = df_GetPosFromX((XmDataFieldWidget) w, cb->x);
if (cb->operation & XmDROP_MOVE && w == initiator &&
XmDataFieldGetSelectionPosition(w, &left, &right) &&
left != right && insert_pos >= left && insert_pos <= right) {
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
} else {
XmDropTransferEntryRec transferEntries[2];
XmDropTransferEntryRec *transferList = NULL;
Atom TEXT = XmInternAtom(display, "TEXT", False);
Atom COMPOUND_TEXT = XmInternAtom(display, "COMPOUND_TEXT", False);
#ifdef UTF8_SUPPORTED
Atom UTF8_STRING = XmInternAtom(display, "UTF8_STRING", False);
#endif
Atom CS_OF_LOCALE;
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
_XmTextDropTransferRec *transfer_rec;
Cardinal numTransfers = 0;
Boolean locale_found = False;
Boolean c_text_found = False;
Boolean utf8_string_found = False;
Boolean string_found = False;
Boolean text_found = False;
int status;
status = XmbTextListToTextProperty(display, &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
CS_OF_LOCALE = tmp_prop.encoding;
else
CS_OF_LOCALE = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
/* intialize data to send to drop transfer callback */
transfer_rec = (_XmTextDropTransferRec *)
XtMalloc(sizeof(_XmTextDropTransferRec));
transfer_rec->widget = w;
transfer_rec->insert_pos = insert_pos;
transfer_rec->num_chars = 0;
transfer_rec->timestamp = cb->timeStamp;
transfer_rec->move = False;
if (cb->operation & XmDROP_MOVE) {
transfer_rec->move = True;
} else {
transfer_rec->move = False;
}
transferEntries[0].client_data = (XtPointer) transfer_rec;
transferList = transferEntries;
numTransfers = 1;
for (n = 0; n < numExportTargets; n++) {
if (exportTargets[n] == CS_OF_LOCALE) {
transferEntries[0].target = CS_OF_LOCALE;
locale_found = True;
break;
}
if (exportTargets[n] == COMPOUND_TEXT) c_text_found = True;
#ifdef UTF8_SUPPORTED
if (exportTargets[n] == UTF8_STRING) utf8_string_found = True;
#endif
if (exportTargets[n] == XA_STRING) string_found = True;
if (exportTargets[n] == TEXT) text_found = True;
}
n = 0;
if (locale_found || c_text_found || string_found || text_found) {
if (!locale_found) {
#ifdef UTF8_SUPPORTED
if (utf8_string_found)
transferEntries[0].target = UTF8_STRING;
else
#endif
if (c_text_found)
transferEntries[0].target = COMPOUND_TEXT;
else if (string_found)
transferEntries[0].target = XA_STRING;
else
transferEntries[0].target = TEXT;
}
if (cb->operation & XmDROP_MOVE || cb->operation & XmDROP_COPY) {
XtSetArg(args[n], XmNdropTransfers, transferList); n++;
XtSetArg(args[n], XmNnumDropTransfers, numTransfers); n++;
} else {
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
}
} else {
XtSetArg(args[n], XmNtransferStatus, XmTRANSFER_FAILURE); n++;
XtSetArg(args[n], XmNnumDropTransfers, 0); n++;
}
dropdf_DestroyCB[0].closure = (XtPointer) transfer_rec;
XtSetArg(args[n], XmNdestroyCallback, dropdf_DestroyCB); n++;
XtSetArg(args[n], XmNtransferProc, df_DropTransferCallback); n++;
}
df_SetDropContext(w);
XmDropTransferStart(drag_cont, args, n);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DragProcCallback(w, client, call)
Widget w;
XtPointer client;
XtPointer call;
#else
df_DragProcCallback(
Widget w,
XtPointer client,
XtPointer call )
#endif /* _NO_PROTO */
{
XmDragProcCallbackStruct *cb = (XmDragProcCallbackStruct *)call;
Widget drag_cont;
Atom targets[5];
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
Arg args[10];
Atom *exp_targets;
Cardinal num_exp_targets, n;
int status = 0;
status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
targets[0] = tmp_prop.encoding;
else
targets[0] = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
targets[2] = XA_STRING;
targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
#ifdef UTF8_SUPPORTED
targets[4] = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
#endif
drag_cont = cb->dragContext;
n = 0;
XtSetArg(args[n], XmNexportTargets, &exp_targets); n++;
XtSetArg(args[n], XmNnumExportTargets, &num_exp_targets); n++;
XtGetValues(drag_cont, args, n);
switch(cb->reason) {
case XmCR_DROP_SITE_ENTER_MESSAGE:
if (XmTargetsAreCompatible(XtDisplay(drag_cont), exp_targets,
#ifdef UTF8_SUPPORTED
num_exp_targets, targets, 4))
#else
num_exp_targets, targets, 3))
#endif
cb->dropSiteStatus = XmVALID_DROP_SITE;
else
cb->dropSiteStatus = XmINVALID_DROP_SITE;
break;
case XmCR_DROP_SITE_LEAVE_MESSAGE:
case XmCR_DROP_SITE_MOTION_MESSAGE:
case XmCR_OPERATION_CHANGED:
/* we currently don't care about these messages */
break;
default:
/* other messages we consider invalid */
cb->dropSiteStatus = XmINVALID_DROP_SITE;
break;
}
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_DropProcCallback(w, client, call)
Widget w;
XtPointer client;
XtPointer call;
#else
df_DropProcCallback(
Widget w,
XtPointer client,
XtPointer call )
#endif /* _NO_PROTO */
{
XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *) call;
if (cb->dropAction != XmDROP_HELP) {
df_HandleDrop(w, cb);
} else {
Arg args[2];
XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
XtSetArg(args[1], XmNnumDropTransfers, 0);
XmDropTransferStart(cb->dragContext, args, 2);
}
}
static void
#ifdef _NO_PROTO
df_RegisterDropSite(w)
Widget w ;
#else
df_RegisterDropSite(
Widget w )
#endif /* _NO_PROTO */
{
Atom targets[5];
Arg args[10];
int n;
char * tmp_string = "ABC"; /* these are characters in XPCS, so... safe */
XTextProperty tmp_prop;
int status = 0;
status = XmbTextListToTextProperty(XtDisplay(w), &tmp_string, 1,
(XICCEncodingStyle)XTextStyle, &tmp_prop);
if (status == Success)
targets[0] = tmp_prop.encoding;
else
targets[0] = 99999; /* XmbTextList... should never fail for XPCS
* characters. But just in case someones
* Xlib is broken, this prevents a core dump.
*/
if (tmp_prop.value != NULL) XFree((char *)tmp_prop.value);
targets[1] = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
targets[2] = XA_STRING;
targets[3] = XmInternAtom(XtDisplay(w), "TEXT", False);
#ifdef UTF8_SUPPORTED
targets[4] = XmInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
#endif
n = 0;
XtSetArg(args[n], XmNimportTargets, targets); n++;
#ifdef UTF8_SUPPORTED
XtSetArg(args[n], XmNnumImportTargets, 4); n++;
#else
XtSetArg(args[n], XmNnumImportTargets, 3); n++;
#endif
XtSetArg(args[n], XmNdropProc, df_DragProcCallback); n++;
XtSetArg(args[n], XmNdropProc, df_DropProcCallback); n++;
XmDropSiteRegister(w, args, n);
}
/*
* df_Initialize
* Intializes the text data and ensures that the data in new
* is valid.
*/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
df_Initialize( request, new_w, args, num_args )
Widget request ;
Widget new_w ;
ArgList args ;
Cardinal *num_args ;
#else
df_Initialize(
Widget request,
Widget new_w,
ArgList args,
Cardinal *num_args )
#endif /* _NO_PROTO */
{
XmDataFieldWidget req_tf = (XmDataFieldWidget) request;
XmDataFieldWidget new_tf = (XmDataFieldWidget) new_w;
Dimension width, height;
df_Validates(new_tf);
df_InitializeTextStruct(new_tf);
df_LoadGCs(new_tf, new_tf->core.background_pixel,
new_tf->primitive.foreground );
df_ComputeSize(new_tf, &width, &height);
if (req_tf->core.width == 0)
new_tf->core.width = width;
if (req_tf->core.height == 0)
new_tf->core.height = height;
df_RegisterDropSite(new_w);
if (XmTextF_verify_bell(new_tf) == (Boolean) XmDYNAMIC_BOOL)
{
if (_XmGetAudibleWarning(new_w) == XmBELL)
XmTextF_verify_bell(new_tf) = True;
else
XmTextF_verify_bell(new_tf) = False;
}
}
static void
#ifdef _NO_PROTO
df_Realize( w, valueMask, attributes )
Widget w ;
XtValueMask *valueMask ;
XSetWindowAttributes *attributes ;
#else
df_Realize(
Widget w,
XtValueMask *valueMask,
XSetWindowAttributes *attributes )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XtCreateWindow(w, (unsigned int) InputOutput,
(Visual *) CopyFromParent, *valueMask, attributes);
df_MakeCursors(tf);
_XmDataFieldSetClipRect(tf);
}
static void
#ifdef _NO_PROTO
df_Destroy( wid )
Widget wid ;
#else
df_Destroy(
Widget wid )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) wid ;
Widget dest = XmGetDestination(XtDisplay(wid));
if (dest == wid)
_XmSetDestination(XtDisplay(wid), NULL);
if (XmTextF_timer_id(tf))
XtRemoveTimeOut(XmTextF_timer_id(tf));
if (XmTextF_has_rect(tf)) {
TextFGCData gc_data = df_GetTextFGCData(wid);
gc_data->tf = NULL;
}
if (XmTextF_max_char_size(tf) == 1)
XtFree(XmTextF_value(tf));
else
XtFree((char *)XmTextF_wc_value(tf));
XmDestroyPixmap(XtScreen(tf), XmTextF_stipple_tile(tf));
XtReleaseGC(wid, XmTextF_gc(tf));
XtReleaseGC(wid, XmTextF_image_gc(tf));
XtReleaseGC(wid, XmTextF_save_gc(tf));
XtFree((char *)XmTextF_highlight(tf).list);
if (XmTextF_fontlist_created(tf))
XmFontListFree((XmFontList)XmTextF_font_list(tf));
if (XmTextF_add_mode_cursor(tf) != XmUNSPECIFIED_PIXMAP)
(void) XmDestroyPixmap(XtScreen(tf), XmTextF_add_mode_cursor(tf));
if (XmTextF_cursor(tf) != XmUNSPECIFIED_PIXMAP)
(void) XmDestroyPixmap(XtScreen(tf), XmTextF_cursor(tf));
if (XmTextF_ibeam_off(tf) != XmUNSPECIFIED_PIXMAP)
XFreePixmap(XtDisplay((Widget)tf), XmTextF_ibeam_off(tf));
if (XmTextF_image_clip(tf) != XmUNSPECIFIED_PIXMAP)
XmDestroyPixmap(XtScreen(tf), XmTextF_image_clip(tf));
/*
* Fix for HaL DTS 9841 - release the data for the selectionArray.
*/
XtFree((char *)XmTextF_selection_array(tf));
XtRemoveAllCallbacks(wid, XmNactivateCallback);
XtRemoveAllCallbacks(wid, XmNlosingFocusCallback);
XtRemoveAllCallbacks(wid, XmNfocusCallback);
XtRemoveAllCallbacks(wid, XmNmodifyVerifyCallback);
XtRemoveAllCallbacks(wid, XmNmotionVerifyCallback);
XtRemoveAllCallbacks(wid, XmNvalueChangedCallback);
XtRemoveAllCallbacks(wid, XmNgainPrimaryCallback);
XtRemoveAllCallbacks(wid, XmNlosePrimaryCallback);
XmImUnregister(wid);
XtFree((char*)XmDataField_picture_source(tf));
if(XmDataField_picture(tf))
XmPictureDelete(XmDataField_picture(tf));
}
static void
#ifdef _NO_PROTO
df_Resize( w )
Widget w ;
#else
df_Resize(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextF_do_resize(tf) = False;
_XmDataFieldSetClipRect(tf);
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
XmTextF_h_offset(tf) = 0;
else
XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness + tf->primitive.highlight_thickness;
XmTextF_refresh_ibeam_off(tf) = True;
(void) df_AdjustText(tf, XmTextF_cursor_position(tf), True);
XmTextF_do_resize(tf) = True;
}
/************************************************************************
*
* df_QueryGeometry
*
************************************************************************/
static XtGeometryResult
#ifdef _NO_PROTO
df_QueryGeometry( widget, intended, desired )
Widget widget ;
XtWidgetGeometry *intended ;
XtWidgetGeometry *desired ;
#else
df_QueryGeometry(
Widget widget,
XtWidgetGeometry *intended,
XtWidgetGeometry *desired )
#endif /* _NO_PROTO */
{
/* this function deals with resizeWidth False */
df_ComputeSize((XmDataFieldWidget) widget,
&desired->width, &desired->height);
return XmeReplyToQueryGeometry(widget, intended, desired) ;
}
/*
* Redisplay will redraw shadows, borders, and text.
*/
/* ARGSUSED */
static void
#ifdef _NO_PROTO
DataFieldExpose( w, event, region )
Widget w ;
XEvent *event ;
Region region ;
#else
DataFieldExpose(
Widget w,
XEvent *event,
Region region )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XGCValues values;
if (event->xany.type != Expose) return;
XmTextF_do_resize(tf) = False;
if (!XmTextF_has_rect(tf)) _XmDataFieldSetClipRect(tf);
/* I can get here even though the widget isn't visible (i.e. my parent is
* sized so that I have nothing visible. In this case, capturing the putback
* area yields garbage... And if this area is not in an area where text
* will be drawn (i.e. forcing something new/valid to be there next time I
* go to capture it) the garbage persists. To prevent this, initialize the
* putback area and then update it to a solid background color.
*/
XmTextF_refresh_ibeam_off(tf) = False;
values.foreground = tf->core.background_pixel;
XChangeGC(XtDisplay(w), XmTextF_save_gc(tf), GCForeground, &values);
XFillRectangle(XtDisplay(w), XmTextF_ibeam_off(tf), XmTextF_save_gc(tf), 0, 0,
XmTextF_cursor_width(tf), XmTextF_cursor_height(tf));
values.foreground = tf->primitive.foreground;
XChangeGC(XtDisplay(w), XmTextF_save_gc(tf), GCForeground, &values);
_XmDataFieldDrawInsertionPoint(tf, False);
if (XtIsRealized((Widget)tf)) {
if (tf->primitive.shadow_thickness > 0)
XmeDrawShadows(XtDisplay(tf), XtWindow(tf),
tf->primitive.bottom_shadow_GC,
tf->primitive.top_shadow_GC,
(int) tf->primitive.highlight_thickness,
(int) tf->primitive.highlight_thickness,
(int) (tf->core.width - (2 * tf->primitive.highlight_thickness)),
(int) (tf->core.height - (2 * tf->primitive.highlight_thickness)),
(int) tf->primitive.shadow_thickness,
XmSHADOW_OUT);
if (tf->primitive.highlighted)
{
XtWidgetProc bhl;
_XmProcessLock();
bhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_highlight;
_XmProcessUnlock();
if(bhl)
{
(*bhl)( (Widget) tf) ;
}
}
else
{
XtWidgetProc buhl;
_XmProcessLock();
buhl = ((XmDataFieldWidgetClass) XtClass(tf))->primitive_class.border_unhighlight;
_XmProcessUnlock();
if(buhl)
{
(*buhl)( (Widget) tf) ;
}
}
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
}
XmTextF_refresh_ibeam_off(tf) = True;
_XmDataFieldDrawInsertionPoint(tf, True);
XmTextF_do_resize(tf) = True;
}
/*
*
* df_SetValues
*
* Checks the new text data and ensures that the data is valid.
* Invalid values will be rejected and changed back to the old
* values.
*
*/
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
df_SetValues( old, request, new_w, args, num_args )
Widget old ;
Widget request ;
Widget new_w ;
ArgList args ;
Cardinal *num_args ;
#else
df_SetValues(
Widget old,
Widget request,
Widget new_w,
ArgList args,
Cardinal *num_args )
#endif /* _NO_PROTO */
{
XmDataFieldWidget new_tf = (XmDataFieldWidget) new_w;
XmDataFieldWidget old_tf = (XmDataFieldWidget) old;
Boolean cursor_pos_set = False;
Boolean new_size = False;
Boolean redisplay = False;
Boolean redisplay_text = False;
Boolean new_font = False;
Boolean mod_ver_ret = False;
Boolean diff_values = False;
Dimension new_width = new_tf->core.width;
Dimension new_height = new_tf->core.height;
Arg im_args[6];
XPoint xmim_point;
XmTextPosition new_position = 0;
XmTextPosition newInsert;
int n = 0;
if (new_w->core.being_destroyed) return False;
XmTextF_in_setvalues(new_tf) = True;
XmTextF_redisplay(new_tf) = False;
/************************************
* ICS DataField specific stuff here *
************************************/
/*
* This is a patch-around to a bug we seem to have exposed.
* The special redisplay handling has been broken somehow with the
* end result that the DataField doesn't redisplay itself
* correctly when its XmNvalue is set. This just hacks around the
* problem.
*/
if(XmTextF_value(old_tf) != XmTextF_value(new_tf)) {
redisplay = True;
}
if (XmDataField_picture_source(old_tf) != XmDataField_picture_source(new_tf))
{
/*
* Delete what's there
*/
XtFree((char*)XmDataField_picture_source(old_tf));
XmDataField_picture_source(new_tf) = XtNewString(XmDataField_picture_source(new_tf));
if(XmDataField_picture(new_tf)) {
XmPictureDelete(XmDataField_picture(new_tf));
XmDataField_picture(new_tf) = NULL;
}
/*
* And make a new one if we have to
*/
if(XmDataField_picture_source(new_tf)) {
XmDataField_picture(new_tf) = XmParsePicture(XmDataField_picture_source(new_tf));
}
/*
* Finally register (or remove) the callback
*/
if(XmDataField_picture(new_tf)) {
XtAddCallback((Widget)new_tf, XmNmodifyVerifyCallback,
PictureVerifyCallback, NULL);
} else {
XtRemoveCallback((Widget)new_tf, XmNmodifyVerifyCallback,
PictureVerifyCallback, NULL);
}
}
if (XmDataField_alignment(old_tf) != XmDataField_alignment(new_tf))
{
if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
XmTextF_h_offset(new_tf) = XmTextF_new_h_offset(new_tf) = 0;
else
XmTextF_h_offset(new_tf) = XmTextF_new_h_offset(new_tf) =
XmTextF_margin_width(new_tf) +
new_tf->primitive.shadow_thickness +
new_tf->primitive.highlight_thickness;
redisplay = True;
}
/* If new cursor position, copy the old cursor pos to the new widget
* so that when we turn off the i-beam, the current location (old
* widget) is used, but the new i-beam parameters (on/off, state, ...)
* are utilized. Then move the cursor. Otherwise, just turn off
* the i-beam. */
if (XmTextF_cursor_position(new_tf) != XmTextF_cursor_position(old_tf)) {
new_position = XmTextF_cursor_position(new_tf) ;
XmTextF_cursor_position(new_tf) = XmTextF_cursor_position(old_tf);
_XmDataFieldDrawInsertionPoint(old_tf, False);
XmTextF_blink_on(new_tf) = XmTextF_blink_on(old_tf);
XmTextF_cursor_on(new_tf) = XmTextF_cursor_on(old_tf);
_XmDataFielddf_SetCursorPosition(new_tf, NULL, new_position,
True, True);
(void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf), False,
XtLastTimestampProcessed(XtDisplay(new_w)));
cursor_pos_set = True;
} else {
int ix;
for (ix = 0; ix < *num_args; ix++)
if (strcmp(args[ix].name, XmNcursorPosition) == 0) {
cursor_pos_set = True;
new_position = XmTextF_cursor_position(new_tf);
break;
}
_XmDataFieldDrawInsertionPoint(old_tf, False);
XmTextF_blink_on(new_tf) = XmTextF_blink_on(old_tf);
XmTextF_cursor_on(new_tf) = XmTextF_cursor_on(old_tf);
}
if (new_w->core.sensitive == False &&
XmTextF_has_destination(new_tf)) {
(void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf),
True, XtLastTimestampProcessed(XtDisplay(new_w)));
}
if (XmTextF_selection_array(new_tf) == NULL)
XmTextF_selection_array(new_tf) = XmTextF_selection_array(old_tf);
if (XmTextF_selection_array_count(new_tf) <= 0)
XmTextF_selection_array_count(new_tf) = XmTextF_selection_array_count(old_tf);
/*
* Fix for HaL DTS 9841 - If the new and old selectionArrays do not match,
* free the old array and then copy the new array.
*/
if (XmTextF_selection_array(new_tf) != XmTextF_selection_array(old_tf))
{
XtPointer temp_ptr;
XtFree((char *)XmTextF_selection_array(old_tf));
temp_ptr = (XtPointer)XmTextF_selection_array(new_tf);
XmTextF_selection_array(new_tf) = (XmTextScanType *)XtMalloc (
XmTextF_selection_array_count(new_tf) * sizeof(XmTextScanType));
memcpy((void *)XmTextF_selection_array(new_tf), (void *)temp_ptr,
(XmTextF_selection_array_count(new_tf) * sizeof(XmTextScanType)));
}
/*
* End fix for HaL DTS 9841
*/
/* Make sure the new_tf cursor position is a valid value.
*/
if (XmTextF_cursor_position(new_tf) < 0) {
XmeWarning (new_w, MSG1);
XmTextF_cursor_position(new_tf) = XmTextF_cursor_position(old_tf);
cursor_pos_set = False;
}
if (XmTextF_font_list(new_tf)!= XmTextF_font_list(old_tf)) {
new_font = True;
if (XmTextF_font_list(new_tf) == NULL)
XmTextF_font_list(new_tf) = XmeGetDefaultRenderTable(new_w, XmTEXT_FONTLIST);
XmTextF_font_list(new_tf) =
(XmFontList)XmFontListCopy(XmTextF_font_list(new_tf));
if (!df_LoadFontMetrics(new_tf)){ /* Fails if font set required but not
* available. */
XmFontListFree((XmFontList)XmTextF_font_list(new_tf));
XmTextF_font_list(new_tf) = XmTextF_font_list(old_tf);
(void)df_LoadFontMetrics(new_tf); /* it *was* correct, so re-use it */
new_font = False;
} else {
XtSetArg(im_args[n], XmNfontList, XmTextF_font_list(new_tf)); n++;
redisplay = True;
}
}
/* Four cases to handle for value:
* 1. user set both XmNvalue and XmNwcValue.
* 2. user set the opposite resource (i.e. value is a char*
* and user set XmNwcValue, or vice versa).
* 3. user set the corresponding resource (i.e. value is a char*
* and user set XmNValue, or vice versa).
* 4. user set neither XmNValue nor XmNwcValue
*/
/* OSF says: if XmNvalueWcs set, it overrides all else */
if (XmTextF_max_char_size(new_tf) == 1) {
/* wc_value on new will be NULL unless XmNvalueWcs was set. */
if (XmTextF_wc_value(new_tf) != NULL){ /* must be new if MB_CUR... == 1 */
df_ValidateString(new_tf, (char*) XmTextF_wc_value(new_tf), True);
diff_values = True;
} else if (XmTextF_value(new_tf) != XmTextF_value(old_tf)) {
diff_values = True;
if (XmTextF_value(new_tf) == NULL) {
df_ValidateString(new_tf, "", False);
} else
df_ValidateString(new_tf, XmTextF_value(new_tf), False);
} /* else, no change so don't do anything */
} else {
if (XmTextF_wc_value(new_tf) != XmTextF_wc_value(old_tf)) {
diff_values = True;
if (XmTextF_wc_value(new_tf) == NULL) {
XmTextF_wc_value(new_tf) = (wchar_t*) XtMalloc(sizeof(wchar_t));
*XmTextF_wc_value(new_tf) = (wchar_t)NULL;
}
df_ValidateString(new_tf, (char*)XmTextF_wc_value(new_tf), True);
} else if (XmTextF_value(new_tf) != XmTextF_value(old_tf)) {
/* Someone set XmNvalue */
diff_values = True;
if (XmTextF_value(new_tf) == NULL)
df_ValidateString(new_tf, "", True);
else
df_ValidateString(new_tf, XmTextF_value(new_tf), False);
} /* else, no change so don't do anything */
}
if (diff_values) { /* old value != new value */
Boolean do_it = True;
/* If there are modify verify callbacks, verify that we want to continue
* the action.
*/
if (XmTextF_modify_verify_callback(new_tf) ||
XmTextF_wcs_modify_verify_callback(new_tf)) {
/* If the function df_ModifyVerify() returns false then don't
* continue with the action.
*/
char *temp, *old;
int free_insert;
XmTextPosition fromPos = 0, toPos;
toPos = XmTextF_string_length(old_tf);
if (XmTextF_max_char_size(new_tf) == 1) {
temp = XmTextF_value(new_tf);
mod_ver_ret = df_ModifyVerify(new_tf, NULL, &fromPos, &toPos,
&temp, &XmTextF_string_length(new_tf),
&newInsert, &free_insert);
} else {
old = temp = XtMalloc((unsigned)((XmTextF_string_length(new_tf) + 1) *
XmTextF_max_char_size(new_tf)));
(void)wcstombs(temp, XmTextF_wc_value(new_tf),
(XmTextF_string_length(new_tf) + 1) * XmTextF_max_char_size(new_tf));
mod_ver_ret = df_ModifyVerify(new_tf, NULL, &fromPos, &toPos, &temp,
&XmTextF_string_length(new_tf), &newInsert,
&free_insert);
if (old != temp) XtFree (old);
}
if (free_insert) XtFree(temp);
if (!mod_ver_ret) {
if (XmTextF_verify_bell(new_tf)) XBell(XtDisplay(new_w), 0);
if (XmTextF_max_char_size(new_tf) == 1) {
XmTextF_value(new_tf) = (char *) memcpy(
XtRealloc(XmTextF_value(new_tf),
(unsigned)XmTextF_size_allocd(old_tf)),
(void*)XmTextF_value(old_tf),
XmTextF_string_length(old_tf) + 1);
XmTextF_string_length(new_tf) = XmTextF_string_length(old_tf);
XmTextF_size_allocd(new_tf) = XmTextF_size_allocd(old_tf);
XtFree(XmTextF_value(old_tf));
} else {
/* realloc to old size, cast to wchar_t*, and copy the data */
XmTextF_wc_value(new_tf) = (wchar_t*)memcpy(
XtRealloc((char *)XmTextF_wc_value(new_tf),
(unsigned)XmTextF_size_allocd(old_tf)),
(void*)XmTextF_wc_value(old_tf),
(unsigned) XmTextF_size_allocd(old_tf));
XmTextF_string_length(new_tf) = XmTextF_string_length(old_tf);
XmTextF_size_allocd(new_tf) = XmTextF_size_allocd(old_tf);
XtFree((char *)XmTextF_wc_value(old_tf));
}
do_it = False;
}
}
if (do_it) {
XmAnyCallbackStruct cb;
if (XmTextF_max_char_size(new_tf) == 1)
XtFree(XmTextF_value(old_tf));
else
XtFree((char *)XmTextF_wc_value(old_tf));
XmDataFieldSetHighlight(new_w, XmTextF_prim_pos_left(new_tf),
XmTextF_prim_pos_right(new_tf),
XmHIGHLIGHT_NORMAL);
XmTextF_pending_off(new_tf) = True;
/* if new_position was > XmTextF_string_length(old_tf), last time
* the df_SetCursorPosition didn't take.
*/
if (!cursor_pos_set || new_position > XmTextF_string_length(old_tf)){
_XmDataFielddf_SetCursorPosition(new_tf, NULL, new_position,
True, False);
if (XmTextF_has_destination(new_tf))
(void) df_SetDestination(new_w, XmTextF_cursor_position(new_tf),
False, XtLastTimestampProcessed(XtDisplay(new_w)));
}
if (XmTextF_resize_width(new_tf) && XmTextF_do_resize(new_tf))
df_AdjustSize(new_tf);
else {
if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
XmTextF_h_offset(new_tf) = 0;
else
XmTextF_h_offset(new_tf) = XmTextF_margin_width(new_tf) +
new_tf->primitive.shadow_thickness +
new_tf->primitive.highlight_thickness;
if (!df_AdjustText(new_tf, XmTextF_cursor_position(new_tf), False))
redisplay_text = True;
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = NULL;
XtCallCallbackList(new_w, XmTextF_value_changed_callback(new_tf),
(XtPointer) &cb);
}
}
if (new_tf->primitive.foreground != old_tf->primitive.foreground ||
XmTextF_font_list(new_tf)!= XmTextF_font_list(old_tf) ||
new_tf->core.background_pixel != old_tf->core.background_pixel) {
df_LoadGCs(new_tf, new_tf->primitive.foreground,
new_tf->core.background_pixel);
df_MakeCursors(new_tf);
_XmDataFieldSetClipRect(new_tf);
if (XmTextF_have_inverted_image_gc(new_tf)){
XmTextF_have_inverted_image_gc(new_tf) = False;
df_InvertImageGC(new_tf);
}
redisplay = True;
XtSetArg(im_args[n], XmNbackground, new_tf->core.background_pixel); n++;
XtSetArg(im_args[n], XmNforeground, new_tf->primitive.foreground); n++;
}
if (XmTextF_has_focus(new_tf) && XtIsSensitive((Widget)new_tf) &&
XmTextF_blink_rate(new_tf) != XmTextF_blink_rate(old_tf)) {
if (XmTextF_blink_rate(new_tf) == 0) {
XmTextF_blink_on(new_tf) = True;
if (XmTextF_timer_id(new_tf)) {
XtRemoveTimeOut(XmTextF_timer_id(new_tf));
XmTextF_timer_id(new_tf) = (XtIntervalId)0;
}
} else if (XmTextF_timer_id(new_tf) == (XtIntervalId)0) {
XmTextF_timer_id(new_tf) =
XtAppAddTimeOut(XtWidgetToApplicationContext(new_w),
(unsigned long)XmTextF_blink_rate(new_tf),
df_HandleTimer,
(XtPointer) new_tf);
}
df_BlinkInsertionPoint(new_tf);
}
if (XmTextF_margin_height(new_tf) != XmTextF_margin_height(old_tf)) {
XmTextF_margin_top(new_tf) = XmTextF_margin_height(new_tf);
XmTextF_margin_bottom(new_tf) = XmTextF_margin_height(new_tf);
}
new_size = XmTextF_margin_width(new_tf) != XmTextF_margin_width(old_tf) ||
XmTextF_margin_height(new_tf) != XmTextF_margin_height(old_tf) ||
XmTextF_font_list(new_tf) != XmTextF_font_list(old_tf) ||
new_tf->primitive.highlight_thickness !=
old_tf->primitive.highlight_thickness ||
new_tf->primitive.shadow_thickness !=
old_tf->primitive.shadow_thickness;
if (XmTextF_columns(new_tf) < 0) {
XmeWarning (new_w, MSG7);
XmTextF_columns(new_tf) = XmTextF_columns(old_tf);
}
if (!(new_width != old_tf->core.width &&
new_height != old_tf->core.height)) {
if (XmTextF_columns(new_tf) != XmTextF_columns(old_tf) || new_size) {
Dimension width, height;
df_ComputeSize(new_tf, &width, &height);
df_AdjustText(new_tf, 0, False);
if (new_width == old_tf->core.width)
new_w->core.width = width;
if (new_height == old_tf->core.height)
new_w->core.height = height;
if (XmDataField_alignment(new_tf) == XmALIGNMENT_END)
XmTextF_h_offset(new_tf) = 0;
else
XmTextF_h_offset(new_tf) = XmTextF_margin_width(new_tf) +
new_tf->primitive.shadow_thickness +
new_tf->primitive.highlight_thickness;
redisplay = True;
}
} else {
if (new_width != new_tf->core.width)
new_tf->core.width = new_width;
if (new_height != new_tf->core.height)
new_tf->core.height = new_height;
}
XmTextF_refresh_ibeam_off(new_tf) = 1; /* force update of putback area */
_XmDataFieldDrawInsertionPoint(new_tf, True);
if (XtIsSensitive((Widget)new_tf) != XtIsSensitive((Widget)old_tf)) {
if (XtIsSensitive(new_w)) {
_XmDataFieldDrawInsertionPoint(new_tf, False);
XmTextF_blink_on(new_tf) = False;
_XmDataFToggleCursorGC(new_w);
_XmDataFieldDrawInsertionPoint(new_tf, True);
} else {
if (XmTextF_has_focus(new_tf)) {
XmTextF_has_focus(new_tf) = False;
df_ChangeBlinkBehavior(new_tf, False);
_XmDataFieldDrawInsertionPoint(new_tf, False);
_XmDataFToggleCursorGC(new_w);
XmTextF_blink_on(new_tf) = True;
_XmDataFieldDrawInsertionPoint(new_tf, True);
}
}
if (XmTextF_string_length(new_tf) > 0) redisplay = True;
}
df_GetXYFromPos(new_tf, XmTextF_cursor_position(new_tf), &xmim_point.x,
&xmim_point.y);
if (XmTextF_editable(old_tf) != XmTextF_editable(new_tf)) {
Boolean editable = XmTextF_editable(new_tf);
XmTextF_editable(new_tf) = XmTextF_editable(old_tf);
XmDataFieldSetEditable(new_w, editable);
}
XtSetArg(im_args[n], XmNbackgroundPixmap,
new_tf->core.background_pixmap); n++;
XtSetArg(im_args[n], XmNspotLocation, &xmim_point); n++;
XtSetArg(im_args[n], XmNlineSpace,
XmTextF_font_ascent(new_tf) + XmTextF_font_descent(new_tf)); n++;
XmImSetValues((Widget)new_tf, im_args, n);
if (new_font) XmFontListFree((XmFontList)XmTextF_font_list(old_tf));
if (!redisplay) redisplay = XmTextF_redisplay(new_tf);
/* If I'm forced to redisplay, then actual widget won't be updated
* until the expose proc. Force the ibeam putback to be refreshed
* at expose time so that it reflects true visual state of the
* widget. */
if (redisplay) XmTextF_refresh_ibeam_off(new_tf) = True;
XmTextF_in_setvalues(new_tf) = False;
/*
* Force new clip rectangles to be computed during redisplay,
* *after* XtSetValues decides on final geometry.
*/
if (redisplay) XmTextF_has_rect(new_tf) = False;
if ((!XmTextF_editable(new_tf) || !XtIsSensitive(new_w)) &&
XmTextF_has_destination(new_tf))
(void) df_SetDestination(new_w, 0, False, (Time)0);
/* don't shrink to nothing */
if (new_tf->core.width == 0) new_tf->core.width = old_tf->core.width;
if (new_tf->core.height == 0) new_tf->core.height = old_tf->core.height;
if (!redisplay && redisplay_text)
df_RedisplayText(new_tf, 0, XmTextF_string_length(new_tf));
return redisplay;
}
static Boolean
#ifdef _NO_PROTO
DataFieldRemove( w, event)
Widget w ;
XEvent *event ;
#else
DataFieldRemove(
Widget w,
XEvent *event)
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition left, right;
XmAnyCallbackStruct cb;
if (XmTextF_editable(tf) == False)
return False;
if (!XmDataFieldGetSelectionPosition(w, &left, &right) || left == right) {
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
return False;
}
if (_XmDataFieldReplaceText(tf, event, left, right, NULL, 0, True)){
XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf),
XtLastTimestampProcessed(XtDisplay(w)));
cb.reason = XmCR_VALUE_CHANGED;
cb.event = event;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
XmTextF_prim_anchor(tf) = XmTextF_cursor_position(tf);
return True;
}
/********************************************
* AccessTextual trait method implementation
********************************************/
static XtPointer
DataFieldGetValue(Widget w, int format)
{
char *str;
XmString tmp;
switch(format) {
case XmFORMAT_XmSTRING:
str = XmDataFieldGetString(w);
tmp = XmStringCreateLocalized(str);
if (str != NULL) XtFree(str);
return((XtPointer) tmp);
case XmFORMAT_MBYTE:
return((XtPointer) XmDataFieldGetString(w));
case XmFORMAT_WCS:
return((XtPointer) XmDataFieldGetStringWcs(w));
}
return(NULL);
}
static void
DataFieldSetValue(Widget w, XtPointer s, int format)
{
char *str;
switch(format)
{
case XmFORMAT_XmSTRING:
str = _XmStringGetTextConcat((XmString) s);
XmDataFieldSetString(w, str);
if (str != NULL) XtFree(str);
break;
case XmFORMAT_MBYTE:
XmDataFieldSetString(w, (char*) s);
break;
case XmFORMAT_WCS:
XmDataFieldSetStringWcs(w, (wchar_t *) s);
}
}
/*ARGSUSED*/
static int
DataFieldPreferredValue(Widget w) /* unused */
{
return(XmFORMAT_MBYTE);
}
/*
* XmRCallProc routine for checking data.font_list before setting it to NULL
* if no value is specified for both XmNrenderTable and XmNfontList.
* If "check_set_render_table" == True, then function has been called twice
* on same widget, thus resource needs to be set NULL, otherwise leave it
* alone.
*/
/* ARGSUSED */
static void
CheckSetRenderTable(Widget wid, int offset, XrmValue *value)
{
XmDataFieldWidget df = (XmDataFieldWidget)wid;
if (XmTextF_check_set_render_table(df))
value->addr = NULL;
else {
XmTextF_check_set_render_table(df) = True;
value->addr = (char*)&(XmTextF_font_list(df));
}
}
/***********************************<->***************************************
* Public Functions *
***********************************<->***************************************/
char *
#ifdef _NO_PROTO
XmDataFieldGetString( w )
Widget w ;
#else
XmDataFieldGetString(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
char *temp_str;
int ret_val = 0;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_string_length(tf) > 0)
{
if (XmTextF_max_char_size(tf) == 1)
{
temp_str = XtNewString(XmTextF_value(tf));
_XmAppUnlock(app);
return(temp_str);
}
else
{
temp_str = (char *) XtMalloc((unsigned) XmTextF_max_char_size(tf) *
(XmTextF_string_length(tf) + 1));
ret_val = wcstombs(temp_str, XmTextF_wc_value(tf),
(XmTextF_string_length(tf) + 1) *
XmTextF_max_char_size(tf));
if (ret_val < 0)
{
temp_str[0] = '\0';
}
_XmAppUnlock(app);
return temp_str;
}
} else
{
_XmAppUnlock(app);
return(XtNewString(""));
}
}
int
#ifdef _NO_PROTO
XmDataFieldGetSubstring( widget, start, num_chars, buf_size, buffer )
Widget widget;
XmTextPosition start;
int num_chars;
int buf_size;
char *buffer;
#else
XmDataFieldGetSubstring(
Widget widget,
XmTextPosition start,
int num_chars,
int buf_size,
char *buffer )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) widget;
int ret_value = XmCOPY_SUCCEEDED;
int n_bytes = 0;
int wcs_ret = 0;
_XmWidgetToAppContext(widget);
_XmAppLock(app);
if (XmTextF_max_char_size(tf) != 1)
{
n_bytes = _XmDataFieldCountBytes(tf, XmTextF_wc_value(tf)+start, num_chars);
}
else
{
n_bytes = num_chars;
}
if (buf_size < n_bytes + 1 )
{
_XmAppUnlock(app);
return XmCOPY_FAILED;
}
if (start + num_chars > XmTextF_string_length(tf))
{
num_chars = (int) (XmTextF_string_length(tf) - start);
if (XmTextF_max_char_size(tf) != 1)
{
n_bytes = _XmDataFieldCountBytes(tf, XmTextF_wc_value(tf)+start,
num_chars);
}
else
{
n_bytes = num_chars;
}
ret_value = XmCOPY_TRUNCATED;
}
if (num_chars > 0) {
if (XmTextF_max_char_size(tf) == 1)
{
(void)memcpy((void*)buffer, (void*)&XmTextF_value(tf)[start], num_chars);
}
else
{
wcs_ret = wcstombs(buffer, &XmTextF_wc_value(tf)[start],
n_bytes);
if (wcs_ret < 0) n_bytes = 0;
}
buffer[n_bytes] = '\0';
}
else
{
ret_value = XmCOPY_FAILED;
}
_XmAppUnlock(app);
return (ret_value);
}
wchar_t *
#ifdef _NO_PROTO
XmDataFieldGetStringWcs( w )
Widget w ;
#else
XmDataFieldGetStringWcs(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
wchar_t *temp_wcs;
int num_wcs = 0;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_string_length(tf) > 0)
{
temp_wcs = (wchar_t*) XtMalloc((unsigned) sizeof(wchar_t) *
(XmTextF_string_length(tf) + 1));
if (XmTextF_max_char_size(tf) != 1)
{
(void)memcpy((void*)temp_wcs, (void*)XmTextF_wc_value(tf),
sizeof(wchar_t) * (XmTextF_string_length(tf) + 1));
}
else
{
num_wcs = mbstowcs(temp_wcs, XmTextF_value(tf),
XmTextF_string_length(tf) + 1);
}
_XmAppUnlock(app);
return temp_wcs;
}
else
{
temp_wcs = (wchar_t*) XtMalloc((unsigned) sizeof(wchar_t));
temp_wcs[0] = (wchar_t)0L; /* put a wchar_t NULL in position 0 */
_XmAppUnlock(app);
return temp_wcs;
}
}
int
#ifdef _NO_PROTO
XmDataFieldGetSubstringWcs( widget, start, num_chars, buf_size, buffer )
Widget widget;
XmTextPosition start;
int num_chars;
int buf_size;
wchar_t *buffer;
#else
XmDataFieldGetSubstringWcs(
Widget widget,
XmTextPosition start,
int num_chars,
int buf_size,
wchar_t *buffer )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) widget;
int ret_value = XmCOPY_SUCCEEDED;
int num_wcs = 0;
_XmWidgetToAppContext(widget);
_XmAppLock(app);
if (start + num_chars > XmTextF_string_length(tf))
{
num_chars = (int) (XmTextF_string_length(tf) - start);
ret_value = XmCOPY_TRUNCATED;
}
if (buf_size < num_chars + 1 )
{
_XmAppUnlock(app);
return XmCOPY_FAILED;
}
if (num_chars > 0)
{
if (XmTextF_max_char_size(tf) == 1)
{
num_wcs = mbstowcs(buffer, &XmTextF_value(tf)[start], num_chars);
if (num_wcs < 0) num_chars = 0;
}
else
{
(void)memcpy((void*)buffer, (void*)&XmTextF_wc_value(tf)[start],
(size_t) num_chars * sizeof(wchar_t));
}
buffer[num_chars] = '\0';
} else if (num_chars == 0) {
buffer[num_chars] = '\0';
}
else
{
ret_value = XmCOPY_FAILED;
}
_XmAppUnlock(app);
return (ret_value);
}
XmTextPosition
#ifdef _NO_PROTO
XmDataFieldGetLastPosition( w )
Widget w ;
#else
XmDataFieldGetLastPosition(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmTextF_string_length(tf);
_XmAppUnlock(app);
return(ret_val);
}
void
#ifdef _NO_PROTO
XmDataFieldSetString( w, value )
Widget w ;
char *value ;
#else
XmDataFieldSetString(
Widget w,
char *value )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmAnyCallbackStruct cb;
XmTextPosition fromPos, toPos, newInsert;
int length;
int free_insert = False;
int ret_val = 0;
char * tmp_ptr;
char * mod_value = NULL;
_XmWidgetToAppContext(w);
_XmAppLock(app);
fromPos = 0;
if (value == NULL) value = "";
toPos = XmTextF_string_length(tf);
if (XmTextF_max_char_size(tf) == 1)
{
length = strlen(value);
}
else
{
length = mbstowcs(NULL, value, 0);
}
if (tf->core.sensitive && XmTextF_has_focus(tf))
{
df_ChangeBlinkBehavior(tf, False);
}
_XmDataFieldDrawInsertionPoint(tf, False);
if (XmTextF_modify_verify_callback(tf) ||
XmTextF_wcs_modify_verify_callback(tf))
{
/*
* If the function df_ModifyVerify() returns
* false then don't continue with the action.
*/
if (!df_ModifyVerify(tf, NULL, &fromPos, &toPos,
&value, &length, &newInsert, &free_insert))
{
if (XmTextF_verify_bell(tf)) XBell(XtDisplay(w), 0);
if (free_insert) XtFree(value);
_XmAppUnlock(app);
return;
}
}
XmDataFieldSetHighlight(w, 0, XmTextF_string_length(tf),
XmHIGHLIGHT_NORMAL);
if (XmTextF_max_char_size(tf) == 1)
{
XtFree(XmTextF_value(tf));
}
else /* convert to wchar_t before calling df_ValidateString */
{
XtFree((char *)XmTextF_wc_value(tf));
}
df_ValidateString(tf, value, False);
XmTextF_pending_off(tf) = True;
df_SetCursorPosition(tf, NULL, 0, True, True, False);
if (XmTextF_resize_width(tf) && XmTextF_do_resize(tf))
{
df_AdjustSize(tf);
}
else
{
if (XmDataField_alignment(tf) == XmALIGNMENT_END)
{
XmTextF_h_offset(tf) = 0;
}
else
{
XmTextF_h_offset(tf) = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
}
if (!df_AdjustText(tf, XmTextF_cursor_position(tf), False))
{
df_RedisplayText(tf, 0, XmTextF_string_length(tf));
}
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = NULL;
XtCallCallbackList(w, XmTextF_value_changed_callback(tf), (XtPointer) &cb);
XmTextF_refresh_ibeam_off(tf) = True;
if (tf->core.sensitive && XmTextF_has_focus(tf))
{
df_ChangeBlinkBehavior(tf, True);
}
_XmDataFieldDrawInsertionPoint(tf, True);
if (free_insert) XtFree(value);
_XmAppUnlock(app);
}
static void
#ifdef _NO_PROTO
XmDataFieldSetStringWcs( w, wc_value )
Widget w;
wchar_t *wc_value;
#else
XmDataFieldSetStringWcs(
Widget w,
wchar_t *wc_value )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
char * tmp;
wchar_t *tmp_wc;
int num_chars = 0;
int result;
_XmWidgetToAppContext(w);
_XmAppLock(app);
for (num_chars = 0, tmp_wc = wc_value; *tmp_wc != (wchar_t)0L; num_chars++)
tmp_wc++; /* count number of wchar_t's */
tmp = XtMalloc((unsigned) (num_chars + 1) * XmTextF_max_char_size(tf));
result = wcstombs(tmp, wc_value, (num_chars + 1) * XmTextF_max_char_size(tf));
if (result == (size_t) -1) /* if wcstombs fails, it returns (size_t) -1 */
tmp = ""; /* if invalid data, pass in the empty string */
XmDataFieldSetString(w, tmp);
XtFree(tmp);
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldReplace( w, from_pos, to_pos, value )
Widget w ;
XmTextPosition from_pos ;
XmTextPosition to_pos ;
char *value ;
#else
XmDataFieldReplace(
Widget w,
XmTextPosition from_pos,
XmTextPosition to_pos,
char *value )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
int save_maxlength = XmTextF_max_length(tf);
Boolean save_editable = XmTextF_editable(tf);
Boolean deselected = False;
Boolean rep_result = False;
wchar_t *wc_value;
int length = 0;
XmAnyCallbackStruct cb;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (value == NULL) value = "";
df_VerifyBounds(tf, &from_pos, &to_pos);
if (XmTextF_has_primary(tf)) {
if ((XmTextF_prim_pos_left(tf) > from_pos &&
XmTextF_prim_pos_left(tf) < to_pos) ||
(XmTextF_prim_pos_right(tf) >from_pos &&
XmTextF_prim_pos_right(tf) < to_pos) ||
(XmTextF_prim_pos_left(tf) <= from_pos &&
XmTextF_prim_pos_right(tf) >= to_pos)) {
_XmDataFieldDeselectSelection(w, False,
XtLastTimestampProcessed(XtDisplay(w)));
deselected = True;
}
}
XmTextF_editable(tf) = True;
XmTextF_max_length(tf) = INT_MAX;
if (XmTextF_max_char_size(tf) == 1) {
length = strlen(value);
rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos,
to_pos, value, length, False);
} else { /* need to convert to wchar_t* before calling Replace */
wc_value = (wchar_t *) XtMalloc((unsigned) sizeof(wchar_t) *
(1 + strlen(value)));
length = mbstowcs(wc_value, value, (unsigned) (strlen(value) + 1));
rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
(char*)wc_value, length, False);
XtFree((char *)wc_value);
}
if (from_pos <= XmTextF_cursor_position(tf)) {
XmTextPosition cursorPos;
/* Replace will not move us, we still want this to happen */
if (XmTextF_cursor_position(tf) < to_pos) {
if (XmTextF_cursor_position(tf) - from_pos <= length)
cursorPos = XmTextF_cursor_position(tf);
else
cursorPos = from_pos + length;
} else {
cursorPos = XmTextF_cursor_position(tf) - (to_pos - from_pos) + length;
}
XmDataFieldSetInsertionPosition((Widget)tf, cursorPos);
}
XmTextF_editable(tf) = save_editable;
XmTextF_max_length(tf) = save_maxlength;
/*
* Replace Text utilizes an optimization in deciding which text to redraw;
* in the case that the selection has been changed (as above), this can
* cause part/all of the replaced text to NOT be redrawn. The following
* df_AdjustText call ensures that it IS drawn in this case.
*/
if (deselected)
df_AdjustText(tf, from_pos, True);
(void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
XtLastTimestampProcessed(XtDisplay(w)));
if (rep_result) {
cb.reason = XmCR_VALUE_CHANGED;
cb.event = (XEvent *)NULL;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
_XmAppUnlock(app);
}
/* TOM - XmDataFieldReplaceWcs not converted */
void
#ifdef _NO_PROTO
XmDataFieldReplaceWcs( w, from_pos, to_pos, wc_value )
Widget w ;
XmTextPosition from_pos ;
XmTextPosition to_pos ;
wchar_t *wc_value ;
#else
XmDataFieldReplaceWcs(
Widget w,
XmTextPosition from_pos,
XmTextPosition to_pos,
wchar_t *wc_value )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
int save_maxlength = XmTextF_max_length(tf);
Boolean save_editable = XmTextF_editable(tf);
Boolean deselected = False;
Boolean rep_result = False;
wchar_t *tmp_wc;
char *tmp;
int wc_length = 0;
XmAnyCallbackStruct cb;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (wc_value == NULL) wc_value = (wchar_t*)"";
df_VerifyBounds(tf, &from_pos, &to_pos);
if (XmTextF_has_primary(tf)) {
if ((XmTextF_prim_pos_left(tf) > from_pos &&
XmTextF_prim_pos_left(tf) < to_pos) ||
(XmTextF_prim_pos_right(tf) >from_pos &&
XmTextF_prim_pos_right(tf) < to_pos) ||
(XmTextF_prim_pos_left(tf) <= from_pos &&
XmTextF_prim_pos_right(tf) >= to_pos)) {
_XmDataFieldDeselectSelection(w, False,
XtLastTimestampProcessed(XtDisplay(w)));
deselected = True;
}
}
/* Count the number of wide chars in the array */
for (wc_length = 0, tmp_wc = wc_value; *tmp_wc != (wchar_t)0L; wc_length++)
tmp_wc++; /* count number of wchar_t's */
XmTextF_editable(tf) = True;
XmTextF_max_length(tf) = INT_MAX;
if (XmTextF_max_char_size(tf) != 1)
{
rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
(char*)wc_value, wc_length, False);
}
else
{ /* need to convert to char* before calling Replace */
tmp = XtMalloc((unsigned) (wc_length + 1) * XmTextF_max_char_size(tf));
wc_length = wcstombs(tmp, wc_value,
(wc_length + 1) * XmTextF_max_char_size(tf));
if (wc_length == (size_t) -1){ /* if wcstombs fails, it returns -1 */
tmp = ""; /* if invalid data, pass in the empty
* string */
wc_length = 0;
}
rep_result = _XmDataFieldReplaceText(tf, NULL, from_pos, to_pos,
(char*)tmp, wc_length, False);
XtFree(tmp);
}
if (from_pos <= XmTextF_cursor_position(tf)) {
XmTextPosition cursorPos;
/* Replace will not move us, we still want this to happen */
if (XmTextF_cursor_position(tf) < to_pos) {
if (XmTextF_cursor_position(tf) - from_pos <= wc_length)
cursorPos = XmTextF_cursor_position(tf);
else
cursorPos = from_pos + wc_length;
} else {
cursorPos = XmTextF_cursor_position(tf) - (to_pos - from_pos) + wc_length;
}
XmDataFieldSetInsertionPosition((Widget)tf, cursorPos);
}
XmTextF_editable(tf) = save_editable;
XmTextF_max_length(tf) = save_maxlength;
/*
* Replace Text utilizes an optimization in deciding which text to redraw;
* in the case that the selection has been changed (as above), this can
* cause part/all of the replaced text to NOT be redrawn. The following
* df_AdjustText call ensures that it IS drawn in this case.
*/
if (deselected)
df_AdjustText(tf, from_pos, True);
(void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
XtLastTimestampProcessed(XtDisplay(w)));
if (rep_result) {
cb.reason = XmCR_VALUE_CHANGED;
cb.event = (XEvent *)NULL;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldInsert( w, position, value )
Widget w ;
XmTextPosition position ;
char *value ;
#else
XmDataFieldInsert(
Widget w,
XmTextPosition position,
char *value )
#endif /* _NO_PROTO */
{
_XmWidgetToAppContext(w);
_XmAppLock(app);
/* XmDataFieldReplace takes care of converting to wchar_t* if needed */
XmDataFieldReplace(w, position, position, value);
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldInsertWcs( w, position, wcstring )
Widget w ;
XmTextPosition position ;
wchar_t *wcstring ;
#else
XmDataFieldInsertWcs(
Widget w,
XmTextPosition position,
wchar_t *wcstring )
#endif /* _NO_PROTO */
{
_XmWidgetToAppContext(w);
_XmAppLock(app);
/* XmDataFieldReplaceWcs takes care of converting to wchar_t* if needed */
XmDataFieldReplaceWcs(w, position, position, wcstring);
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldSetAddMode( w, state )
Widget w ;
Boolean state ;
#else
XmDataFieldSetAddMode(
Widget w,
Boolean state )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_add_mode(tf) == state)
{
_XmAppUnlock(app);
return;
}
_XmDataFieldDrawInsertionPoint(tf, False);
XmTextF_add_mode(tf) = state;
_XmDataFToggleCursorGC(w);
_XmDataFieldDrawInsertionPoint(tf, True);
_XmAppUnlock(app);
}
Boolean
#ifdef _NO_PROTO
XmDataFieldGetAddMode( w )
Widget w ;
#else
XmDataFieldGetAddMode(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmTextF_add_mode(tf);
_XmAppUnlock(app);
return (ret_val);
}
Boolean
#ifdef _NO_PROTO
XmDataFieldGetEditable( w )
Widget w ;
#else
XmDataFieldGetEditable(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmTextF_editable(tf);
_XmAppUnlock(app);
return ret_val;
}
void
#ifdef _NO_PROTO
XmDataFieldSetEditable( w, editable )
Widget w ;
Boolean editable ;
#else
XmDataFieldSetEditable(
Widget w,
Boolean editable )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XPoint xmim_point;
Arg args[6]; /* To set initial values to input method */
Cardinal n = 0;
_XmWidgetToAppContext(w);
_XmAppLock(app);
/* if widget previously wasn't editable, no input method has yet been */
/* registered. So, if we're making it editable now, register the IM */
/* give the IM the relevent values. */
if (!XmTextF_editable(tf) && editable)
{
#if defined(__sgi)
/* CR03685 */
SGI_hack_XmImRegister((Widget)tf);
#else
XmImRegister((Widget)tf, (unsigned int) NULL);
#endif
df_GetXYFromPos(tf, XmTextF_cursor_position(tf), &xmim_point.x,
&xmim_point.y);
n = 0;
XtSetArg(args[n], XmNfontList, XmTextF_font_list(tf)); n++;
XtSetArg(args[n], XmNbackground, tf->core.background_pixel); n++;
XtSetArg(args[n], XmNforeground, tf->primitive.foreground); n++;
XtSetArg(args[n], XmNbackgroundPixmap,tf->core.background_pixmap);n++;
XtSetArg(args[n], XmNspotLocation, &xmim_point); n++;
XtSetArg(args[n], XmNlineSpace,
XmTextF_font_ascent(tf)+ XmTextF_font_descent(tf)); n++;
XmImSetValues((Widget)tf, args, n);
} else if (XmTextF_editable(tf) && !editable){
XmImUnregister(w);
}
XmTextF_editable(tf) = editable;
n = 0;
if (editable) {
XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_ACTIVE); n++;
} else {
XtSetArg(args[n], XmNdropSiteActivity, XmDROP_SITE_INACTIVE); n++;
}
XmDropSiteUpdate((Widget)tf, args, n);
_XmAppUnlock(app);
}
int
#ifdef _NO_PROTO
XmDataFieldGetMaxLength( w )
Widget w ;
#else
XmDataFieldGetMaxLength(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
int ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmTextF_max_length(tf);
_XmAppUnlock(app);
return ret_val;
}
void
#ifdef _NO_PROTO
XmDataFieldSetMaxLength( w, max_length )
Widget w ;
int max_length ;
#else
XmDataFieldSetMaxLength(
Widget w,
int max_length )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
XmTextF_max_length(tf) = max_length;
_XmAppUnlock(app);
}
XmTextPosition
#ifdef _NO_PROTO
XmDataFieldGetCursorPosition( w )
Widget w ;
#else
XmDataFieldGetCursorPosition(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmTextF_cursor_position(tf);
_XmAppUnlock(app);
return ret_val;
}
XmTextPosition
#ifdef _NO_PROTO
XmDataFieldGetInsertionPosition( w )
Widget w ;
#else
XmDataFieldGetInsertionPosition(
Widget w )
#endif /* _NO_PROTO */
{
XmTextPosition ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = XmDataFieldGetCursorPosition(w);
_XmAppUnlock(app);
return ret_val;
}
/* Obsolete - shouldn't be here ! */
void
#ifdef _NO_PROTO
XmDataFielddf_SetCursorPosition( w, position )
Widget w ;
XmTextPosition position ;
#else
XmDataFielddf_SetCursorPosition(
Widget w,
XmTextPosition position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
df_SetCursorPosition(tf, NULL, position, True, False, False);
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldSetInsertionPosition( w, position )
Widget w ;
XmTextPosition position ;
#else
XmDataFieldSetInsertionPosition(
Widget w,
XmTextPosition position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
df_SetCursorPosition(tf, NULL, position, True, True, False);
_XmAppUnlock(app);
}
Boolean
#ifdef _NO_PROTO
XmDataFieldGetSelectionPosition( w, left, right )
Widget w ;
XmTextPosition *left ;
XmTextPosition *right ;
#else
XmDataFieldGetSelectionPosition(
Widget w,
XmTextPosition *left,
XmTextPosition *right )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (!XmTextF_has_primary(tf)) {
_XmAppUnlock(app);
return False;
}
*left = XmTextF_prim_pos_left(tf);
*right = XmTextF_prim_pos_right(tf);
_XmAppUnlock(app);
return True;
}
char *
#ifdef _NO_PROTO
XmDataFieldGetSelection( w )
Widget w ;
#else
XmDataFieldGetSelection(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
size_t length, num_chars;
char *value;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_prim_pos_left(tf) == XmTextF_prim_pos_right(tf))
{
_XmAppUnlock(app);
return NULL;
}
num_chars = (size_t) (XmTextF_prim_pos_right(tf) \
- XmTextF_prim_pos_left(tf));
length = num_chars;
if (XmTextF_max_char_size(tf) == 1)
{
value = XtMalloc((unsigned) num_chars + 1);
(void) memcpy((void*)value,
(void*)(XmTextF_value(tf) +
XmTextF_prim_pos_left(tf)), num_chars);
}
else
{
value = XtMalloc((unsigned) ((num_chars + 1) * XmTextF_max_char_size(tf)));
length = wcstombs(value, XmTextF_wc_value(tf) + XmTextF_prim_pos_left(tf),
(num_chars + 1) * XmTextF_max_char_size(tf));
if (length == (size_t) -1)
{
length = 0;
}
else
{
for (length = 0;num_chars > 0; num_chars--)
{
length += mblen(&value[length], XmTextF_max_char_size(tf));
}
}
}
value[length] = (char)'\0';
_XmAppUnlock(app);
return value;
}
wchar_t *
#ifdef _NO_PROTO
XmDataFieldGetSelectionWcs( w )
Widget w ;
#else
XmDataFieldGetSelectionWcs(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
size_t length;
wchar_t *wc_value;
int return_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_prim_pos_left(tf) == XmTextF_prim_pos_right(tf))
{
_XmAppUnlock(app);
return NULL;
}
length = (size_t)(XmTextF_prim_pos_right(tf) -
XmTextF_prim_pos_left(tf));
wc_value = (wchar_t*)XtMalloc((unsigned) (length + 1) * sizeof(wchar_t));
if (XmTextF_max_char_size(tf) == 1)
{
return_val = mbstowcs(wc_value, XmTextF_value(tf) +
XmTextF_prim_pos_left(tf), length);
if (return_val < 0) length = 0;
}
else
{
(void)memcpy((void*)wc_value,
(void*)(XmTextF_wc_value(tf) + XmTextF_prim_pos_left(tf)),
length * sizeof(wchar_t));
}
wc_value[length] = (wchar_t)0L;
_XmAppUnlock(app);
return (wc_value);
}
Boolean
#ifdef _NO_PROTO
XmDataFieldRemove( w )
Widget w ;
#else
XmDataFieldRemove(
Widget w )
#endif /* _NO_PROTO */
{
Boolean ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = DataFieldRemove(w, NULL);
_XmAppUnlock(app);
return ret_val;
}
Boolean
#ifdef _NO_PROTO
XmDataFieldCopy( w, clip_time )
Widget w ;
Time clip_time ;
#else
XmDataFieldCopy(
Widget w,
Time clip_time )
#endif /* _NO_PROTO */
{
/* XmDataFieldGetSelection gets char* rep of data, so no special handling
* needed
*/
char * selected_string = XmDataFieldGetSelection(w); /* text selection */
long item_id = 0L; /* clipboard item id */
long data_id = 0; /* clipboard data id */
int status = 0; /* clipboard status */
XmString clip_label;
XTextProperty tmp_prop;
Display *display = XtDisplay(w);
Window window = XtWindow(w);
char *atom_name;
_XmWidgetToAppContext(w);
_XmAppLock(app);
/* using the clipboard facilities, copy the selected text to the clipboard */
if (selected_string != NULL)
{
clip_label = XmStringCreateLtoR ("XM_TEXT_FIELD",
XmFONTLIST_DEFAULT_TAG);
/* start copy to clipboard */
status = XmClipboardStartCopy(display, window, clip_label, clip_time,
w, (XmCutPasteProc)NULL, &item_id);
if (status != ClipboardSuccess)
{
XtFree(selected_string);
XmStringFree(clip_label);
_XmAppUnlock(app);
return False;
}
status = XmbTextListToTextProperty(display, &selected_string, 1,
(XICCEncodingStyle)XStdICCTextStyle,
&tmp_prop);
if (status != Success && status <= 0)
{
XmClipboardCancelCopy(display, window, item_id);
XtFree(selected_string);
XmStringFree(clip_label);
_XmAppUnlock(app);
return False;
}
atom_name = XGetAtomName(display, tmp_prop.encoding);
/* move the data to the clipboard */
status = XmClipboardCopy(display, window, item_id, atom_name,
(XtPointer)tmp_prop.value, tmp_prop.nitems,
0, &data_id);
XtFree(atom_name);
if (status != ClipboardSuccess)
{
XmClipboardCancelCopy(XtDisplay(w), XtWindow(w), item_id);
XtFree(selected_string);
XmStringFree(clip_label);
_XmAppUnlock(app);
return False;
}
/* end the copy to the clipboard */
status = XmClipboardEndCopy(display, window, item_id);
XtFree((char*)tmp_prop.value);
XmStringFree(clip_label);
if (status != ClipboardSuccess)
{
XtFree (selected_string);
_XmAppUnlock(app);
return False;
}
}
else
{
_XmAppUnlock(app);
return False;
}
if (selected_string != NULL)
{
XtFree (selected_string);
}
_XmAppUnlock(app);
return True;
}
Boolean
#ifdef _NO_PROTO
XmDataFieldCut( w, clip_time )
Widget w ;
Time clip_time ;
#else
XmDataFieldCut(
Widget w,
Time clip_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean success = False;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_editable(tf) == False)
{
_XmAppUnlock(app);
return False;
}
if (XmDataFieldCopy(w, clip_time))
{
if (XmDataFieldRemove(w))
{
success = True;
}
}
_XmAppUnlock(app);
return success;
}
/*
* Retrieves the current data from the clipboard
* and paste it at the current cursor position
*/
Boolean
#ifdef _NO_PROTO
XmDataFieldPaste( w )
Widget w ;
#else
XmDataFieldPaste(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition sel_left = 0;
XmTextPosition sel_right = 0;
XmTextPosition paste_pos_left, paste_pos_right;
int status = 0; /* clipboard status */
char* buffer; /* temporary text buffer */
unsigned long length; /* length of buffer */
unsigned long outlength = 0L; /* length of bytes copied */
long private_id = 0; /* id of item on clipboard */
Boolean dest_disjoint = True;
Boolean rep_status = False; /* did Replace succeed? */
Display *display = XtDisplay(w);
Window window = XtWindow(w);
Boolean get_ct = False;
Boolean get_us = False;
XTextProperty tmp_prop;
int malloc_size = 0;
int num_vals;
char **tmp_value;
int i;
XmAnyCallbackStruct cb;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (XmTextF_editable(tf) == False)
{
_XmAppUnlock(app);
return False;
}
paste_pos_left = paste_pos_right = XmTextF_cursor_position(tf);
status = XmClipboardInquireLength(display, window, "STRING", &length);
if (status == ClipboardNoData || length == 0)
{
status = XmClipboardInquireLength(display,
window, "COMPOUND_TEXT",
&length);
if (status == ClipboardNoData || length == 0)
{
#ifdef UTF8_SUPPORTED
status = XmClipboardInquireLength(display, window,
XmSUTF8_STRING, &length);
#endif
if (status == ClipboardNoData || length == 0)
{
_XmAppUnlock(app);
return False;
}
get_us = True;
} else {
get_ct = True;
}
}
/* malloc length of clipboard data */
buffer = XtMalloc((unsigned) length);
if (!get_ct && !get_us)
{
status = XmClipboardRetrieve(display, window, "STRING", buffer,
length, &outlength, &private_id);
}
#ifdef UTF8_SUPPORTED
else if (!get_ct && get_us) {
status = XmClipboardRetrieve(display, window, XmSUTF8_STRING, buffer,
length, &outlength, &private_id);
}
#endif
else
{
status = XmClipboardRetrieve(display, window, "COMPOUND_TEXT", buffer,
length, &outlength, &private_id);
}
if (status != ClipboardSuccess)
{
XmClipboardEndRetrieve(display, window);
XtFree(buffer);
_XmAppUnlock(app);
return False;
}
if (XmDataFieldGetSelectionPosition(w, &sel_left, &sel_right))
{
if (XmTextF_pending_delete(tf) &&
paste_pos_left >= sel_left && paste_pos_right <= sel_right)
{
paste_pos_left = sel_left;
paste_pos_right = sel_right;
dest_disjoint = False;
}
}
tmp_prop.value = (unsigned char *) buffer;
if (!get_ct)
{
tmp_prop.encoding = XA_STRING;
}
else
{
tmp_prop.encoding = XmInternAtom(display, "COMPOUND_TEXT", False);
}
tmp_prop.format = 8;
tmp_prop.nitems = outlength;
num_vals = 0;
status = XmbTextPropertyToTextList(display, &tmp_prop, &tmp_value,
&num_vals);
/* add new text */
if (num_vals && (status == Success || status > 0))
{
if (XmTextF_max_char_size(tf) == 1)
{
char * total_tmp_value;
for (i = 0, malloc_size = 1; i < num_vals ; i++)
{
malloc_size += strlen(tmp_value[i]);
}
total_tmp_value = XtMalloc ((unsigned) malloc_size);
total_tmp_value[0] = '\0';
for (i = 0; i < num_vals ; i++)
{
strcat(total_tmp_value, tmp_value[i]);
}
rep_status = _XmDataFieldReplaceText(tf, NULL, paste_pos_left,
paste_pos_right,
total_tmp_value,
strlen(total_tmp_value), True);
XFreeStringList(tmp_value);
if (malloc_size) XtFree(total_tmp_value);
} else {
wchar_t * wc_value;
int num_chars = 0;
for (i = 0, malloc_size = sizeof(wchar_t); i < num_vals ; i++)
{
malloc_size += strlen(tmp_value[i]);
}
wc_value = (wchar_t*)XtMalloc((unsigned)malloc_size * sizeof(wchar_t));
/* change malloc_size to the number of wchars available in wc_value */
for (i = 0; i < num_vals ; i++)
num_chars +=
mbstowcs(wc_value + num_chars, tmp_value[i],
(size_t)malloc_size - num_chars);
rep_status = _XmDataFieldReplaceText(tf, NULL, paste_pos_left,
paste_pos_right,
(char*)wc_value,
num_chars, True);
if (malloc_size) XtFree((char*)wc_value);
}
}
if (rep_status) {
XmTextF_prim_anchor(tf) = sel_left;
(void) df_SetDestination(w, XmTextF_cursor_position(tf), False,
XtLastTimestampProcessed(display));
if (sel_left != sel_right)
{
if (!dest_disjoint || !XmTextF_add_mode(tf))
{
XmDataFieldSetSelection(w, XmTextF_cursor_position(tf),
XmTextF_cursor_position(tf),
XtLastTimestampProcessed(display));
}
}
cb.reason = XmCR_VALUE_CHANGED;
cb.event = (XEvent *)NULL;
XtCallCallbackList((Widget) tf, XmTextF_value_changed_callback(tf),
(XtPointer) &cb);
}
XtFree(buffer);
_XmAppUnlock(app);
return True;
}
void
#ifdef _NO_PROTO
XmDataFielddf_ClearSelection( w, sel_time )
Widget w ;
Time sel_time ;
#else
XmDataFielddf_ClearSelection(
Widget w,
Time sel_time )
#endif /* _NO_PROTO */
{
_XmWidgetToAppContext(w);
_XmAppLock(app);
_XmDataFieldDeselectSelection(w, False, sel_time);
_XmAppUnlock(app);
}
void
#ifdef _NO_PROTO
XmDataFieldSetSelection( w, first, last, sel_time )
Widget w ;
XmTextPosition first ;
XmTextPosition last ;
Time sel_time ;
#else
XmDataFieldSetSelection(
Widget w,
XmTextPosition first,
XmTextPosition last,
Time sel_time )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
_XmDataFieldStartSelection(tf, first, last, sel_time);
XmTextF_pending_off(tf) = False;
df_SetCursorPosition(tf, NULL, last, True, True, False);
_XmAppUnlock(app);
}
/* ARGSUSED */
XmTextPosition
#ifdef _NO_PROTO
XmDataFieldXYToPos( w, x, y )
Widget w ;
Position x ;
Position y ;
#else
XmDataFieldXYToPos(
Widget w,
Position x,
Position y )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
XmTextPosition ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = df_GetPosFromX(tf, x);
_XmAppUnlock(app);
return(ret_val);
}
Boolean
#ifdef _NO_PROTO
XmDataFieldPosToXY( w, position, x, y )
Widget w ;
XmTextPosition position ;
Position *x ;
Position *y ;
#else
XmDataFieldPosToXY(
Widget w,
XmTextPosition position,
Position *x,
Position *y )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Boolean ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
ret_val = df_GetXYFromPos(tf, position, x, y);
_XmAppUnlock(app);
return(ret_val);
}
/*
* Force the given position to be displayed. If position < 0, then don't force
* any position to be displayed.
*/
void
#ifdef _NO_PROTO
XmDataFieldShowPosition( w, position )
Widget w ;
XmTextPosition position ;
#else
XmDataFieldShowPosition(
Widget w,
XmTextPosition position )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (position < 0) {
_XmAppUnlock(app);
return;
}
df_AdjustText(tf, position, True);
_XmAppUnlock(app);
}
/* ARGSUSED */
void
#ifdef _NO_PROTO
XmDataFieldSetHighlight( w, left, right, mode )
Widget w ;
XmTextPosition left ;
XmTextPosition right ;
XmHighlightMode mode ;
#else
XmDataFieldSetHighlight(
Widget w,
XmTextPosition left,
XmTextPosition right,
XmHighlightMode mode )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
_XmWidgetToAppContext(w);
_XmAppLock(app);
if (left >= right || right <= 0) {
_XmAppUnlock(app);
return;
}
if (left < 0) left = 0;
if (right > XmTextF_string_length(tf))
{
right = XmTextF_string_length(tf);
}
DataFieldSetHighlight(tf, left, right, mode);
df_RedisplayText(tf, left, right);
_XmAppUnlock(app);
}
/* ARGSUSED */
static Boolean
#ifdef _NO_PROTO
DataFieldGetBaselines( w, baselines, line_count )
Widget w ;
Dimension ** baselines;
int *line_count;
#else
DataFieldGetBaselines(
Widget w,
Dimension ** baselines,
int *line_count )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Dimension *base_array;
_XmWidgetToAppContext(w);
_XmAppLock(app);
*line_count = 1;
base_array = (Dimension *) XtMalloc(sizeof(Dimension));
base_array[0] = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness + XmTextF_font_ascent(tf);
*baselines = base_array;
_XmAppUnlock(app);
return (TRUE);
}
int
#ifdef _NO_PROTO
XmDataFieldGetBaseline( w )
Widget w ;
#else
XmDataFieldGetBaseline(
Widget w )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Dimension margin_top;
int ret_val;
_XmWidgetToAppContext(w);
_XmAppLock(app);
margin_top = XmTextF_margin_top(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
ret_val = (int) margin_top + (int) XmTextF_font_ascent(tf);
_XmAppUnlock(app);
return(ret_val);
}
static Boolean
#ifdef _NO_PROTO
DataFieldGetDisplayRect( w, display_rect )
Widget w;
XRectangle * display_rect;
#else
DataFieldGetDisplayRect(
Widget w,
XRectangle * display_rect )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
Position margin_width = XmTextF_margin_width(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Position margin_top = XmTextF_margin_top(tf) + tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
Position margin_bottom = XmTextF_margin_bottom(tf) +
tf->primitive.shadow_thickness +
tf->primitive.highlight_thickness;
(*display_rect).x = margin_width;
(*display_rect).y = margin_top;
(*display_rect).width = tf->core.width - (2 * margin_width);
(*display_rect).height = tf->core.height - (margin_top + margin_bottom);
return(TRUE);
}
/* ARGSUSED */
static void
#ifdef _NO_PROTO
DataFieldMarginsProc( w, margins_rec )
Widget w ;
XmBaselineMargins *margins_rec;
#else
DataFieldMarginsProc(
Widget w,
XmBaselineMargins *margins_rec )
#endif /* _NO_PROTO */
{
XmDataFieldWidget tf = (XmDataFieldWidget) w;
if (margins_rec->get_or_set == XmBASELINE_SET) {
XmTextF_margin_top(tf) = margins_rec->margin_top;
XmTextF_margin_bottom(tf) = margins_rec->margin_bottom;
} else {
margins_rec->margin_top = XmTextF_margin_top(tf);
margins_rec->margin_bottom = XmTextF_margin_bottom(tf);
margins_rec->text_height = XmTextF_font_ascent(tf) + XmTextF_font_descent(tf);
margins_rec->shadow = tf->primitive.shadow_thickness;
margins_rec->highlight = tf->primitive.highlight_thickness;
}
}
/*
* Text Field w creation convienence routine.
*/
Widget
#ifdef _NO_PROTO
XmCreateDataField( parent, name, arglist, argcount )
Widget parent ;
char *name ;
ArgList arglist ;
Cardinal argcount ;
#else
XmCreateDataField(
Widget parent,
char *name,
ArgList arglist,
Cardinal argcount )
#endif /* _NO_PROTO */
{
return (XtCreateWidget(name, xmDataFieldWidgetClass,
parent, arglist, argcount));
}
Widget
XmVaCreateDataField(
Widget parent,
char *name,
...)
{
register Widget w;
va_list var;
int count;
Va_start(var,name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmDataFieldWidgetClass,
parent, False,
var, count);
va_end(var);
return w;
}
Widget
XmVaCreateManagedDataField(
Widget parent,
char *name,
...)
{
Widget w = NULL;
va_list var;
int count;
Va_start(var, name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmDataFieldWidgetClass,
parent, True,
var, count);
va_end(var);
return w;
}