/*
* 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
*/
/*
* HISTORY
*/
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$TOG: Display.c /main/23 1997/06/18 17:36:59 samborn $"
#endif
#endif
/* (c) Copyright 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/extensions/shape.h>
#include <X11/Xatom.h>
#include <Xm/AtomMgr.h>
#include <Xm/DisplayP.h>
#include <Xm/DropTransP.h>
#include <Xm/ScreenP.h>
#include <Xm/TransltnsP.h>
#include "XmI.h"
#include "DisplayI.h"
#include "DragBSI.h"
#include "DragCI.h"
#include "DragICCI.h"
#include "MessagesI.h"
#include "VirtKeysI.h"
#include "ColorObjI.h"
#define MESSAGE1 _XmMMsgDisplay_0001
#define MESSAGE2 _XmMMsgDisplay_0002
#define MESSAGE3 _XmMMsgDisplay_0003
#define TheDisplay(dd) (XtDisplayOfObject((Widget)dd))
#define TheScreen(dd) (XtScreen((Widget)dd))
#define Offset(x) (XtOffsetOf( struct _XmDisplayRec, x))
#define CHECK_TIME(dc, time) \
((dc->drag.dragStartTime <= time) && \
((dc->drag.dragFinishTime == 0) || (time <= dc->drag.dragFinishTime)))
#define INVALID_PROTOCOL_VALUE 255
/******** Static Function Declarations ********/
static void DisplayClassPartInitialize(
WidgetClass wc) ;
static void DisplayClassInitialize( void ) ;
static void SetDragReceiverInfo(
Widget w,
XtPointer client_data,
XEvent *event,
Boolean *dontSwallow) ;
static void TreeUpdateHandler(
Widget w,
XtPointer client,
XtPointer call) ;
static void DisplayInitialize(
Widget requested_widget,
Widget new_widget,
ArgList args,
Cardinal *num_args) ;
static void DisplayInsertChild(
Widget w) ;
static void DisplayDeleteChild(
Widget w) ;
static void DisplayDestroy(
Widget w) ;
static XmDragContext FindDC(
XmDisplay xmDisplay,
Time time,
#if NeedWidePrototypes
int sourceIsExternal) ;
#else
Boolean sourceIsExternal) ;
#endif /* NeedWidePrototypes */
static int isMine(
Display *dpy,
register XEvent *event,
char *arg) ;
static void ReceiverShellExternalSourceHandler(
Widget w,
XtPointer client_data,
XEvent *event,
Boolean *dontSwallow) ;
static Widget GetDisplay(
Display *display) ;
/******** End Static Function Declarations ********/
externaldef(displaymsg) String _Xm_MOTIF_DRAG_AND_DROP_MESSAGE = NULL;
static XContext displayContext = 0;
static WidgetClass curDisplayClass = NULL;
static XtResource resources[] = {
{
XmNdropSiteManagerClass, XmCDropSiteManagerClass, XmRWidgetClass,
sizeof(WidgetClass), Offset(display.dropSiteManagerClass),
XmRImmediate, (XtPointer)&xmDropSiteManagerClassRec,
},
{
XmNdropTransferClass, XmCDropTransferClass, XmRWidgetClass,
sizeof(WidgetClass), Offset(display.dropTransferClass),
XmRImmediate, (XtPointer)&xmDropTransferClassRec,
},
{
XmNdragContextClass, XmCDragContextClass, XmRWidgetClass,
sizeof(WidgetClass), Offset(display.dragContextClass),
XmRImmediate, (XtPointer)&xmDragContextClassRec,
},
{
XmNdragInitiatorProtocolStyle, XmCDragInitiatorProtocolStyle,
XmRDragInitiatorProtocolStyle, sizeof(unsigned char),
Offset(display.dragInitiatorProtocolStyle),
XmRImmediate, (XtPointer)XmDRAG_PREFER_RECEIVER,
},
{
XmNdragReceiverProtocolStyle, XmCDragReceiverProtocolStyle,
XmRDragReceiverProtocolStyle, sizeof(unsigned char),
Offset(display.dragReceiverProtocolStyle),
XmRImmediate, (XtPointer) XmDRAG_PREFER_PREREGISTER,
},
{
XmNdefaultVirtualBindings, XmCDefaultVirtualBindings,
XmRString, sizeof(String),
Offset(display.bindingsString),
XmRImmediate, (XtPointer)NULL,
},
{
XmNuserData, XmCUserData, XmRPointer,
sizeof(XtPointer), Offset(display.user_data),
XmRImmediate, (XtPointer) NULL
},
{
XmNmotifVersion, XmCMotifVersion, XmRInt,
sizeof(int), Offset(display.motif_version),
XmRImmediate, (XtPointer) XmVersion
},
{
XmNenableWarp, XmCEnableWarp, XmREnableWarp,
sizeof(XtEnum), Offset(display.enable_warp),
XmRImmediate, (XtPointer) True
},
{
XmNdragStartCallback, XmCCallback,
XmRCallback, sizeof(XtCallbackList),
Offset(display.dragStartCallback),
XmRImmediate, (XtPointer)NULL,
},
{
XmNnoFontCallback, XmCCallback,
XmRCallback, sizeof(XtCallbackList),
Offset(display.noFontCallback),
XmRImmediate, (XtPointer)NULL,
},
{
XmNnoRenditionCallback, XmCCallback,
XmRCallback, sizeof(XtCallbackList),
Offset(display.noRenditionCallback),
XmRImmediate, (XtPointer)NULL,
},
{
XmNenableBtn1Transfer, XmCEnableBtn1Transfer,
XmREnableBtn1Transfer, sizeof(XtEnum),
Offset(display.enable_btn1_transfer),
XmRImmediate, (XtPointer) XmOFF
},
{
XmNenableButtonTab, XmCEnableButtonTab,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_button_tab),
XmRImmediate, (XtPointer) False
},
{
XmNenableEtchedInMenu, XmCEnableEtchedInMenu,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_etched_in_menu),
XmRImmediate, (XtPointer) False
},
{
XmNdefaultButtonEmphasis, XmCDefaultButtonEmphasis,
XmRDefaultButtonEmphasis, sizeof(XtEnum),
Offset(display.default_button_emphasis),
XmRImmediate, (XtPointer) XmEXTERNAL_HIGHLIGHT
},
{
XmNenableToggleColor, XmCEnableToggleColor,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_toggle_color),
XmRImmediate, (XtPointer) False
},
{
XmNenableToggleVisual, XmCEnableToggleVisual,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_toggle_visual),
XmRImmediate, (XtPointer) False
},
{
XmNenableDragIcon, XmCEnableDragIcon,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_drag_icon),
XmRImmediate, (XtPointer) False
},
{
XmNenableUnselectableDrag, XmCEnableUnselectableDrag,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_unselectable_drag),
XmRImmediate, (XtPointer) True
},
{
XmNenableThinThickness, XmCEnableThinThickness,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_thin_thickness),
XmRImmediate, (XtPointer) False
},
{
XmNenableMultiKeyBindings, XmCEnableMultiKeyBindings,
XmRBoolean, sizeof(Boolean),
Offset(display.enable_multi_key_bindings),
XmRImmediate, (XtPointer) False
},
/* Force this resource to avoid loop in the pixmap conversion.
XmDisplay is a VendorShell, so when iconPixmap is set in
a resource file, the VendorShell converter is called, but
since it needs an XmDisplay (via an XmScreen resource), it
goes and create the XmDisplay, for which the iconPixmap is
also converted: loop. By forcing it to Bitmap, the screen
bitmapConversionModel is not needed and it works. This is a
small limitation in XmDisplay */
{ XmNiconPixmap, XmCIconPixmap, XmRBitmap,
sizeof(Pixmap),
XtOffsetOf(WMShellRec, wm.wm_hints.icon_pixmap),
XmRImmediate, NULL
},
};
#undef Offset
static XmBaseClassExtRec baseClassExtRec = {
NULL,
NULLQUARK,
XmBaseClassExtVersion,
sizeof(XmBaseClassExtRec),
(XtInitProc)NULL, /* InitializePrehook */
(XtSetValuesFunc)NULL, /* SetValuesPrehook */
(XtInitProc)NULL, /* InitializePosthook */
(XtSetValuesFunc)NULL, /* SetValuesPosthook */
NULL, /* secondaryObjectClass */
(XtInitProc)NULL, /* secondaryCreate */
(XmGetSecResDataFunc)NULL, /* getSecRes data */
{ 0 }, /* fastSubclass flags */
(XtArgsProc)NULL, /* getValuesPrehook */
(XtArgsProc)NULL, /* getValuesPosthook */
(XtWidgetClassProc)NULL, /* classPartInitPrehook */
(XtWidgetClassProc)NULL, /* classPartInitPosthook*/
NULL, /* ext_resources */
NULL, /* compiled_ext_resources*/
0, /* num_ext_resources */
FALSE, /* use_sub_resources */
(XmWidgetNavigableProc)NULL, /* widgetNavigable */
(XmFocusChangeProc)NULL, /* focusChange */
(XmWrapperData)NULL /* wrapperData */
};
externaldef(xmdisplayclassrec)
XmDisplayClassRec xmDisplayClassRec = {
{
(WidgetClass) &applicationShellClassRec, /* superclass */
"XmDisplay", /* class_name */
sizeof(XmDisplayRec), /* size */
DisplayClassInitialize, /* Class Initializer */
DisplayClassPartInitialize, /* class_part_init */
FALSE, /* Class init'ed ? */
DisplayInitialize, /* initialize */
_XmColorObjCreate, /* initialize_notify */
XtInheritRealize, /* realize */
NULL, /* actions */
0, /* num_actions */
resources, /* resources */
XtNumber(resources), /* resource_count */
NULLQUARK, /* xrm_class */
FALSE, /* compress_motion */
FALSE, /* compress_exposure */
FALSE, /* compress_enterleave */
FALSE, /* visible_interest */
DisplayDestroy, /* destroy */
(XtWidgetProc)NULL, /* resize */
(XtExposeProc)NULL, /* expose */
(XtSetValuesFunc)NULL, /* set_values */
(XtArgsFunc)NULL, /* set_values_hook */
(XtAlmostProc)NULL, /* set_values_almost */
(XtArgsProc)NULL, /* get_values_hook */
(XtAcceptFocusProc)NULL, /* accept_focus */
XtVersion, /* intrinsics version */
NULL, /* callback offsets */
NULL, /* tm_table */
(XtGeometryHandler)NULL, /* query_geometry */
(XtStringProc)NULL, /* display_accelerator */
(XtPointer)&baseClassExtRec, /* extension */
},
{ /* composite class record */
(XtGeometryHandler)NULL, /* geometry_manager */
(XtWidgetProc)NULL, /* change_managed */
DisplayInsertChild, /* insert_child */
DisplayDeleteChild, /* from the shell */
NULL, /* extension record */
},
{ /* shell class record */
NULL, /* extension record */
},
{ /* wm shell class record */
NULL, /* extension record */
},
{ /* vendor shell class record */
NULL, /* extension record */
},
{ /* toplevelclass record */
NULL, /* extension record */
},
{ /* appShell record */
NULL, /* extension record */
},
{ /* Display class */
GetDisplay, /* GetDisplay */
NULL, /* extension */
},
};
externaldef(xmdisplayclass) WidgetClass
xmDisplayClass = (WidgetClass) (&xmDisplayClassRec);
static void
DisplayClassPartInitialize(
WidgetClass wc )
{
_XmFastSubclassInit(wc, XmDISPLAY_BIT);
}
static void
DisplayClassInitialize( void )
{
baseClassExtRec.record_type = XmQmotif;
_Xm_MOTIF_DRAG_AND_DROP_MESSAGE =
XmMakeCanonicalString("_MOTIF_DRAG_AND_DROP_MESSAGE");
}
/*ARGSUSED*/
static void
SetDragReceiverInfo(
Widget w,
XtPointer client_data,
XEvent *event,
Boolean *dontSwallow )
{
XmDisplay dd = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
if (XtIsRealized(w)) {
_XmSetDragReceiverInfo(dd, (Widget)client_data);
XtRemoveEventHandler(w, StructureNotifyMask, False,
SetDragReceiverInfo,
client_data);
}
}
/*
* this routine is registered on the XmNtreeUpdateProc resource of the
* dropSiteManager. It is called whenever the tree is changed.
*/
/*ARGSUSED*/
static void
TreeUpdateHandler(
Widget w,
XtPointer client,
XtPointer call )
{
XmAnyCallbackStruct *anyCB = (XmAnyCallbackStruct *)call;
XmDisplay dd = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
if (dd->display.dragReceiverProtocolStyle == XmDRAG_NONE)
return;
switch(anyCB->reason) {
case XmCR_DROP_SITE_TREE_ADD:
{
XmDropSiteTreeAddCallback cb =
(XmDropSiteTreeAddCallback)anyCB;
if (XtIsRealized(cb->rootShell)) {
_XmSetDragReceiverInfo(dd, cb->rootShell);
}
else {
XtAddEventHandler(cb->rootShell,
StructureNotifyMask, False,
SetDragReceiverInfo,
(XtPointer)cb->rootShell);
}
/*
* ClientMessages are not maskable so all we have to
* do is indicate interest in non-maskable events.
*/
XtAddEventHandler(cb->rootShell, NoEventMask, True,
ReceiverShellExternalSourceHandler,
(XtPointer)dd);
}
break;
case XmCR_DROP_SITE_TREE_REMOVE:
{
XmDropSiteTreeRemoveCallback cb =
(XmDropSiteTreeRemoveCallback)anyCB;
XtRemoveEventHandler(cb->rootShell, NoEventMask, True,
ReceiverShellExternalSourceHandler,
(XtPointer)dd);
if (XtIsRealized(cb->rootShell))
_XmClearDragReceiverInfo(cb->rootShell);
}
break;
default:
break;
}
}
/************************************************************************
*
* DisplayInitialize
*
************************************************************************/
/* ARGSUSED */
static void
DisplayInitialize(
Widget requested_widget,
Widget new_widget,
ArgList args,
Cardinal *num_args )
{
static char *atom_names[] = {
"Customize Data:0", /* XmSCUSTOMIZE_DATA + "0" */
XmIATOM_PAIR, XmIAVERAGE_WIDTH, XmIPIXEL_SIZE, XmIRESOLUTION_Y,
XmIWM_DELETE_WINDOW, XmI_MOTIF_DRAG_ATOMS,
XmI_MOTIF_DRAG_INITIATOR_INFO, XmI_MOTIF_DRAG_PROXY_WINDOW,
XmI_MOTIF_DRAG_RECEIVER_INFO, XmI_MOTIF_DRAG_TARGETS,
XmI_MOTIF_DRAG_WINDOW,
XmSCLIPBOARD, XmSCLIP_TEMPORARY, XmSCOMPOUND_TEXT, XmSDELETE,
XmSINCR, XmSINSERT_SELECTION, XmSLENGTH, XmSLINK_SELECTION,
XmSMULTIPLE, XmSNULL, XmSTARGETS, XmSTEXT, XmSTIMESTAMP,
XmSTRANSFER_FAILURE, XmSTRANSFER_SUCCESS, XmSWM_STATE,
XmS_MOTIF_ATOM_0, XmS_MOTIF_CLIP_DATA_DELETE,
XmS_MOTIF_CLIP_DATA_REQUEST, XmS_MOTIF_CLIP_HEADER,
XmS_MOTIF_CLIP_LOCK_ACCESS_VALID, XmS_MOTIF_CLIP_MESSAGE,
XmS_MOTIF_CLIP_NEXT_ID, XmS_MOTIF_CLIP_TIME,
XmS_MOTIF_CLIPBOARD_TARGETS, XmS_MOTIF_DESTINATION,
XmS_MOTIF_DRAG_OFFSET, XmS_MOTIF_DEFERRED_CLIPBOARD_TARGETS,
XmS_MOTIF_DROP, XmS_MOTIF_EXPORT_TARGETS, XmS_MOTIF_LOSE_SELECTION,
_XA_MOTIF_BINDINGS, _XA_MOTIF_WM_HINTS, _XA_MOTIF_WM_INFO,
_XA_MOTIF_WM_MENU, _XA_MOTIF_WM_MESSAGES, _XA_MOTIF_WM_OFFSET,
"WM_PROTOCOLS"
};
Atom atoms[XtNumber(atom_names)];
XmDisplay xmDisplay = (XmDisplay)new_widget;
int dummy1, dummy2;
XContext context;
/*
* Pre-load the Xlib atom cache with atoms we are likely to use,
* similar to the way _XmInitAtomPairs() did in Motif 1.2.x.
*/
XInternAtoms(XtDisplay(xmDisplay), atom_names, XtNumber(atom_names),
False, atoms);
xmDisplay->display.shellCount = 0;
xmDisplay->display.numModals = 0;
xmDisplay->display.modals = NULL;
xmDisplay->display.maxModals = 0;
xmDisplay->display.userGrabbed = False;
xmDisplay->display.activeDC = NULL;
xmDisplay->display.dsm = (XmDropSiteManagerObject) NULL;
xmDisplay->display.proxyWindow =
_XmGetDragProxyWindow(XtDisplay(xmDisplay));
_XmInitByteOrderChar();
xmDisplay->display.xmim_info = NULL;
xmDisplay->display.displayInfo = (XtPointer) XtNew(XmDisplayInfo);
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->SashCursor = 0L;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->TearOffCursor = 0L;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->UniqueStamp = 0L;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->destinationWidget=
(Widget)NULL;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->excParentPane.pane =
(Widget *)NULL;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->excParentPane.pane_list_size = 0;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->excParentPane.num_panes= 0;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->resetFocusFlag = 0;
((XmDisplayInfo *)(xmDisplay->display.displayInfo))->traversal_in_progress=
FALSE;
xmDisplay->display.displayHasShapeExtension =
XShapeQueryExtension(XtDisplay(xmDisplay), &dummy1, &dummy2);
/* Handle dynamic default of receiver protocol style */
if (xmDisplay->display.dragReceiverProtocolStyle ==
INVALID_PROTOCOL_VALUE) {
if (xmDisplay->display.displayHasShapeExtension)
xmDisplay->display.dragReceiverProtocolStyle = XmDRAG_PREFER_DYNAMIC;
else
xmDisplay->display.dragReceiverProtocolStyle =
XmDRAG_PREFER_PREREGISTER;
}
_XmVirtKeysInitialize (new_widget);
_XmProcessLock();
if (displayContext == 0)
displayContext = XUniqueContext();
context = displayContext;
_XmProcessUnlock();
if (! XFindContext(XtDisplay(xmDisplay), None, context,
(char **) &xmDisplay))
{
/*
* There's one already created for this display.
* What should we do? If we destroy the previous one, we may
* wreak havoc with shell modality and screen objects. BUT,
* Xt doesn't really give us a way to abort a create. We'll
* just let the new one dangle.
*/
XmeWarning((Widget) xmDisplay, MESSAGE1);
}
else
{
XSaveContext(XtDisplayOfObject((Widget)xmDisplay),
None,
context,
(char *)xmDisplay);
}
if (xmDisplay->display.enable_multi_key_bindings) {
Display * display = XtDisplay(new_widget);
int i, num_screens = ScreenCount(display);
XrmDatabase new_db;
for (i = 0; i < num_screens; i++) {
Screen * screen = ScreenOfDisplay(display, i);
XrmDatabase db = XtScreenDatabase(screen);
new_db = XrmGetStringDatabase(_XmDisplay_baseTranslations);
XrmCombineDatabase(new_db, &db, False);
}
}
}
/************************************************************************
*
* DisplayInsertChild
*
************************************************************************/
static void
DisplayInsertChild(
Widget w )
{
if (XtIsRectObj(w)) {
XtWidgetProc insert_child;
_XmProcessLock();
insert_child = ((CompositeWidgetClass)compositeWidgetClass)
->composite_class.insert_child;
_XmProcessUnlock();
(*insert_child)(w);
}
}
/************************************************************************
*
* DisplayDeleteChild
*
************************************************************************/
static void
DisplayDeleteChild(
Widget w )
{
if (XtIsRectObj(w)) {
XtWidgetProc delete_child;
_XmProcessLock();
delete_child = ((CompositeWidgetClass)compositeWidgetClass)
->composite_class.delete_child;
_XmProcessUnlock();
(*delete_child)(w);
}
}
/************************************************************************
*
* DisplayDestroy
*
************************************************************************/
/* ARGSUSED */
static void
DisplayDestroy(
Widget w )
{
XmDisplay dd = (XmDisplay) w ;
XContext context;
_XmProcessLock();
context = displayContext;
_XmProcessUnlock();
XtFree((char *) dd->display.modals);
if (((XmDisplayInfo *)(dd->display.displayInfo))
->excParentPane.pane != (Widget *)NULL)
XtFree((char *) ((XmDisplayInfo *)(dd->display.displayInfo))
->excParentPane.pane);
XtFree((char *) dd->display.displayInfo);
/* Destroy the DropSiteManager object. */
if (dd->display.dsm != NULL)
XtDestroyWidget((Widget) dd->display.dsm);
_XmClearDisplayTables(XtDisplay(w));
_XmVirtKeysDestroy (w);
XDeleteContext( XtDisplay( w), None, context) ;
}
/*ARGSUSED*/
XmDropSiteManagerObject
_XmGetDropSiteManagerObject(
XmDisplay xmDisplay )
{
/* Defer the creation of the XmDisplayObject's DropSiteManager until
* it is referenced, since the converters of some DSM resources
* (animationPixmap, for instance) depend on the presence of the
* Display/Screen objects, and a circular recursive creation loop
* results if the DSM is created during DisplayInitialize.
*/
if( xmDisplay->display.dsm == NULL )
{
Arg lclArgs[1] ;
XtSetArg( lclArgs[0], XmNtreeUpdateProc, TreeUpdateHandler) ;
xmDisplay->display.dsm = (XmDropSiteManagerObject) XtCreateWidget( "dsm",
xmDisplay->display.dropSiteManagerClass,
(Widget) xmDisplay, lclArgs, 1) ;
}
return( xmDisplay->display.dsm);
}
unsigned char
_XmGetDragProtocolStyle(
Widget w )
{
XmDisplay xmDisplay;
unsigned char style;
xmDisplay = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
switch(xmDisplay->display.dragReceiverProtocolStyle) {
case XmDRAG_NONE:
case XmDRAG_DROP_ONLY:
style = XmDRAG_NONE;
break;
case XmDRAG_DYNAMIC:
style = XmDRAG_DYNAMIC;
break;
case XmDRAG_PREFER_DYNAMIC:
case XmDRAG_PREFER_PREREGISTER:
case XmDRAG_PREREGISTER:
style = XmDRAG_PREREGISTER;
break;
default:
style = XmDRAG_NONE;
break;
}
return style;
}
Widget
XmGetDragContext(
Widget w,
Time time )
{
XmDisplay xmDisplay;
XmDragContext matchedDC = NULL, dc = NULL;
Cardinal i;
_XmWidgetToAppContext(w);
_XmAppLock(app);
xmDisplay = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
for(i = 0; i < xmDisplay->composite.num_children; i++)
{
dc = (XmDragContext)(xmDisplay->composite.children[i]);
if ((XmIsDragContext((Widget) dc)) && (CHECK_TIME(dc, time)) &&
((!matchedDC) ||
(matchedDC->drag.dragStartTime
< dc->drag.dragStartTime)) &&
!dc->core.being_destroyed)
matchedDC = dc;
}
_XmAppUnlock(app);
return((Widget)matchedDC);
}
Widget
_XmGetDragContextFromHandle(
Widget w,
Atom iccHandle )
{
XmDisplay xmDisplay;
XmDragContext dc;
Cardinal i;
xmDisplay = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
for(i = 0; i < xmDisplay->composite.num_children; i++)
{
dc = (XmDragContext)(xmDisplay->composite.children[i]);
if ((XmIsDragContext((Widget) dc)) &&
(dc->drag.iccHandle == iccHandle) &&
!dc->core.being_destroyed)
return((Widget)dc);
}
return(NULL);
}
static XmDragContext
FindDC(
XmDisplay xmDisplay,
Time time,
#if NeedWidePrototypes
int sourceIsExternal )
#else
Boolean sourceIsExternal )
#endif /* NeedWidePrototypes */
{
XmDragContext dc = NULL;
Cardinal i;
for(i = 0; i < xmDisplay->composite.num_children; i++)
{
dc = (XmDragContext)(xmDisplay->composite.children[i]);
if ((XmIsDragContext((Widget) dc)) &&
(CHECK_TIME(dc, time)) &&
(dc->drag.sourceIsExternal == sourceIsExternal) &&
!dc->core.being_destroyed)
return(dc);
}
return(NULL);
}
/*ARGSUSED*/
static int
isMine(
Display *dpy,
register XEvent *event,
char *arg )
{
XmDisplayEventQueryStruct *q = (XmDisplayEventQueryStruct *) arg;
XmICCCallbackStruct callback, *cb = &callback;
/* Once we have a drop start we must stop looking at the queue */
if (q->hasDropStart)
return(False);
if (!_XmICCEventToICCCallback((XClientMessageEvent *)event,
cb, XmICC_INITIATOR_EVENT))
return(False);
if ((cb->any.reason == XmCR_DROP_SITE_ENTER) ||
(cb->any.reason == XmCR_DROP_SITE_LEAVE))
{
/*
* We must assume this to be a dangling set of messages, so
* we will quietly consume it in the interest of hygene.
*/
return(True);
}
if (!q->dc)
q->dc = FindDC(q->dd, cb->any.timeStamp, True);
/*
* if we can find a dc then we have already processed
* an enter for this shell.
*/
switch(cb->any.reason)
{
case XmCR_TOP_LEVEL_ENTER:
q->hasLeave = False;
if (q->dc == NULL)
{
*(q->enterCB) = *(XmTopLevelEnterCallbackStruct *)cb;
q->hasEnter = True;
}
break;
case XmCR_TOP_LEVEL_LEAVE:
if (q->dc != NULL)
{
*(q->leaveCB) = *(XmTopLevelLeaveCallbackStruct *)cb;
q->hasLeave = True;
q->hasMotion = False;
}
else
{
/*
* hasEnter is true if we are missing a
* drag context because an enter got compressed.
* In that case, all is OK, and no warning is
* needed. ??? Is a warning ever needed ???
*/
if (!q->hasEnter)
XmeWarning((Widget) q->dd, MESSAGE2);
}
q->hasEnter = False;
break;
case XmCR_DRAG_MOTION:
*(q->motionCB) = *(XmDragMotionCallbackStruct *)cb;
q->hasMotion = True;
break;
case XmCR_DROP_START:
*(q->dropStartCB) = *(XmDropStartCallbackStruct *)cb;
q->hasDropStart = True;
break;
default:
break;
}
return True;
}
/*
* this handler is used to catch messages from external drag
* contexts that want to map motion or drop events
*/
/*ARGSUSED*/
static void
ReceiverShellExternalSourceHandler(
Widget w,
XtPointer client_data,
XEvent *event,
Boolean *dontSwallow )
{
XmDragTopLevelClientDataStruct topClientData;
XmTopLevelEnterCallbackStruct enterCB;
XmTopLevelLeaveCallbackStruct leaveCB;
XmDropStartCallbackStruct dropStartCB;
XmDragMotionCallbackStruct motionCB;
XmDisplayEventQueryStruct q;
Widget shell = w;
XmDisplay dd = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
XmDragContext dc;
XmDropSiteManagerObject dsm = _XmGetDropSiteManagerObject( dd);
/*
* If dd has an active dc then we are the initiator. We shouldn't
* do receiver processing as the initiator, so bail out.
*/
if (dd->display.activeDC != NULL)
return;
q.dd = dd;
q.dc = (XmDragContext)NULL;
q.enterCB = &enterCB;
q.leaveCB = &leaveCB;
q.motionCB = &motionCB;
q.dropStartCB = &dropStartCB;
q.hasEnter =
q.hasDropStart =
q.hasLeave =
q.hasMotion = False;
/*
* Since this event handler gets called for all non-maskable events,
* we want to bail out now with don't swallow if we don't want this
* event. Otherwise we'll swallow it.
*/
/*
* process the event that fired this event handler.
* If it's not a Receiver DND event, bail out.
*/
if (!isMine(XtDisplayOfObject(w), event, (char*)&q))
return;
/*
* swallow all the pending messages inline except the last motion
*/
while (XCheckIfEvent( XtDisplayOfObject(w), event, isMine, (char*)&q))
/*EMPTY*/;
dc = q.dc;
if (q.hasEnter || q.hasMotion || q.hasDropStart || q.hasLeave) {
/*
* handle a dangling leave first
*/
if (q.hasLeave)
{
XmTopLevelLeaveCallback callback = &leaveCB;
topClientData.destShell = shell;
topClientData.xOrigin = shell->core.x;
topClientData.yOrigin = shell->core.y;
topClientData.sourceIsExternal = True;
topClientData.iccInfo = NULL;
topClientData.window = XtWindow(w);
topClientData.dragOver = NULL;
_XmDSMUpdate(dsm,
(XtPointer)&topClientData,
(XtPointer)callback);
/* destroy it if no drop. otherwise done in dropTransfer */
if (!q.hasDropStart)
{
XtDestroyWidget((Widget)dc);
q.dc = dc = NULL;
}
}
/*
* check for a dropStart from a preregister client or an enter
* either of which require a dc to be alloced
*/
if (q.hasEnter || q.hasDropStart) {
if (!q.dc) {
Arg args[4];
Cardinal i = 0;
Time timeStamp;
Window window;
Atom iccHandle;
if (q.hasDropStart) {
XmDropStartCallback dsCallback = &dropStartCB;
timeStamp = dsCallback->timeStamp;
window = dsCallback->window;
iccHandle = dsCallback->iccHandle;
}
else {
XmTopLevelEnterCallback teCallback = &enterCB;
timeStamp = teCallback->timeStamp;
window = teCallback->window;
iccHandle = teCallback->iccHandle;
}
XtSetArg(args[i], XmNsourceWindow, window);i++;
XtSetArg(args[i], XmNsourceIsExternal,True);i++;
XtSetArg(args[i], XmNstartTime, timeStamp);i++;
XtSetArg(args[i], XmNiccHandle, iccHandle);i++;
dc = (XmDragContext) XtCreateWidget("dragContext",
dd->display.dragContextClass, (Widget)dd, args, i);
_XmReadInitiatorInfo((Widget)dc);
/*
* force in value for dropTransfer to use in selection
* calls.
*/
dc->drag.currReceiverInfo =
_XmAllocReceiverInfo(dc);
dc->drag.currReceiverInfo->shell = shell;
dc->drag.currReceiverInfo->dragProtocolStyle =
dd->display.dragReceiverProtocolStyle;
}
topClientData.destShell = shell;
topClientData.xOrigin = XtX(shell);
topClientData.yOrigin = XtY(shell);
topClientData.width = XtWidth(shell);
topClientData.height = XtHeight(shell);
topClientData.sourceIsExternal = True;
topClientData.iccInfo = NULL;
}
if (!dc) return;
if (q.hasDropStart) {
dc->drag.dragFinishTime = dropStartCB.timeStamp;
_XmDSMUpdate(dsm,
(XtPointer)&topClientData,
(XtPointer)&dropStartCB);
}
/*
* we only see enters if they're not matched with a leave
*/
if (q.hasEnter) {
_XmDSMUpdate(dsm,
(XtPointer)&topClientData,
(XtPointer)&enterCB);
}
if (q.hasMotion) {
XmDragMotionCallback callback = &motionCB;
XmDragMotionClientDataStruct motionData;
motionData.window = XtWindow(w);
motionData.dragOver = NULL;
_XmDSMUpdate(dsm, (XtPointer)&motionData, (XtPointer)callback);
}
}
}
static Widget
GetDisplay(
Display *display )
{
XmDisplay xmDisplay = NULL;
XContext context;
Arg args[3];
int n;
_XmProcessLock();
context = displayContext;
_XmProcessUnlock();
if ((context == 0) ||
(XFindContext(display, None, context,
(char **) &xmDisplay)))
{
String name, w_class;
XtGetApplicationNameAndClass(display, &name, &w_class);
n = 0;
XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
XtSetArg(args[n], XmNwidth, 1); n++;
XtSetArg(args[n], XmNheight, 1); n++;
xmDisplay = (XmDisplay) XtAppCreateShell(name, w_class,
xmDisplayClass, display, args, n);
}
/* We need a window to be useful */
if (!XtIsRealized((Widget)xmDisplay))
{
XtRealizeWidget((Widget)xmDisplay);
/*
* Got the resources - get rid of name-type properties.
* Otherwise, clients (ie: xwd) may get the wrong window
* using the -name option.
*/
XDeleteProperty(display, XtWindow(xmDisplay), XA_WM_NAME);
XDeleteProperty(display, XtWindow(xmDisplay), XA_WM_ICON_NAME);
XDeleteProperty(display, XtWindow(xmDisplay), XA_WM_CLASS);
}
return ((Widget)xmDisplay);
}
Widget
XmGetXmDisplay(
Display *display )
{
XmDisplayClass dC;
Widget w;
_XmDisplayToAppContext(display);
/*
* We have a chicken and egg problem here; we'd like to get
* the display via a class function, but we don't know which
* class to use. Hence the magic functions _XmGetXmDisplayClass
* and _XmSetXmDisplayClass.
*/
_XmAppLock(app);
_XmProcessLock();
dC = (XmDisplayClass) _XmGetXmDisplayClass();
w = (*(dC->display_class.GetDisplay))(display);
_XmProcessUnlock();
_XmAppUnlock(app);
return w;
}
/*
* It would be nice if the next two functions were methods, but
* for obvious reasons they're not.
*/
WidgetClass
_XmGetXmDisplayClass( void )
{
WidgetClass class;
_XmProcessLock();
if (curDisplayClass == NULL)
curDisplayClass = xmDisplayClass;
class = curDisplayClass;
_XmProcessUnlock();
return class;
}
WidgetClass
_XmSetXmDisplayClass(
WidgetClass wc )
{
WidgetClass oldDisplayClass;
WidgetClass sc = wc;
_XmProcessLock();
oldDisplayClass = curDisplayClass;
/*
* We aren't going to let folks just set any old class in as the
* display class. They will have to use subclasses of xmDisplay.
*/
while ((sc != NULL) && (sc != xmDisplayClass))
sc = sc->core_class.superclass;
if (sc != NULL)
curDisplayClass = wc;
else
XmeWarning(NULL, MESSAGE3);
_XmProcessUnlock();
return(oldDisplayClass);
}
/**********************************************************************
*
* _XmSetThickness
* This procedure is called as the resource default XtRCallProc
* to default the shadow and highlight thickness resources. If
* enablethinThickness is true (CDE apps), the value is "1 pixel",
* else defaults to "2".
**********************************************************************/
void
_XmSetThickness(
Widget widget,
int offset,
XrmValue *value )
{
XmDisplay xmDisplay;
static Dimension thickness;
xmDisplay = (XmDisplay)XmGetXmDisplay(XtDisplay(widget));
if (xmDisplay->display.enable_thin_thickness) {
thickness = 1;
}
else {
thickness = 2;
}
value->addr = (XPointer)&thickness;
}
/**********************************************************************
*
* _XmSetThicknessDefault0
* This procedure is called as the resource default XtRCallProc
* to default the shadow and highlight thickness resources. If
* enablethinThickness is true (CDE apps), the value is "1 pixel",
* else defaults to "0".
**********************************************************************/
void
_XmSetThicknessDefault0(
Widget widget,
int offset,
XrmValue *value )
{
XmDisplay xmDisplay;
static Dimension thickness;
xmDisplay = (XmDisplay)XmGetXmDisplay(XtDisplay(widget));
if (xmDisplay->display.enable_thin_thickness) {
thickness = 1;
}
else {
thickness = 0;
}
value->addr = (XPointer)&thickness;
}