Blame lib/Xm/DragBS.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
*/ 
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: DragBS.c /main/29 1998/03/18 15:10:28 csn $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
*  (c) Copyright 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  The purpose of the routines in this module is to cache frequently needed
Packit b099d7
 *  data on window properties to reduce roundtrip server requests.
Packit b099d7
 *
Packit b099d7
 *  The data is stored on window properties of motifWindow, a persistent,
Packit b099d7
 *  override-redirect, InputOnly child window of the display's default root
Packit b099d7
 *  window.  A client looks for the motifWindow id on the "_MOTIF_DRAG_WINDOW"
Packit b099d7
 *  property of the display's default root window.  If it finds the id, the
Packit b099d7
 *  client saves it in its displayToMotifWindowContext.  Otherwise, the 
Packit b099d7
 *  client creates the motifWindow and stores its id on that root property
Packit b099d7
 *  and saves the id in its displayToMotifWindowContext.  MotifWindow is
Packit b099d7
 *  mapped but is not visible on the screen.
Packit b099d7
 *
Packit b099d7
 *  Two sets of data are stored on motifWindow properties:
Packit b099d7
 *
Packit b099d7
 *    1. an atom table, and
Packit b099d7
 *    2. a targets list table.
Packit b099d7
 *
Packit b099d7
 *  The "_MOTIF_DRAG_ATOMS" property on motifWindow contains an atoms table,
Packit b099d7
 *  consisting of pairs of atoms and timestamps.  The atoms are interned
Packit b099d7
 *  once and are available for clients to use without repeated roundtrip
Packit b099d7
 *  server requests to intern them.  A timestamp of 0 indicates that the 
Packit b099d7
 *  atom is available.  A nonzero timestamp indicates when the atom was last
Packit b099d7
 *  allocated to a client.  The atoms table initially contains only atom
Packit b099d7
 *  "_MOTIF_ATOM_0" with timestamp 0.  A client requests an atom by calling
Packit b099d7
 *  _XmAllocMotifAtom() with a timestamp.  _XmAllocMotifAtom() tries to find
Packit b099d7
 *  an available atom in the table.  If it succeeds it sets the atom's
Packit b099d7
 *  timestamp to the value specified and returns the atom.  If no atom is
Packit b099d7
 *  available, _XmAllocMotifAtom() adds an atom to the table with the
Packit b099d7
 *  specified timestamp, updates the "_MOTIF_DRAG_ATOMS" property on
Packit b099d7
 *  motifWindow, and returns the new atom.  These new atoms are named
Packit b099d7
 *  "_MOTIF_ATOM_n" where n is 1, 2, 3, ... .  The routine _XmGetMotifAtom()
Packit b099d7
 *  returns the atom from the atoms table with nonzero timestamp less than
Packit b099d7
 *  but closest to a specified value.  It does not change the atoms table.
Packit b099d7
 *  A client frees an atom by calling _XmFreeMotifAtom(), which sets the 
Packit b099d7
 *  atom's timestamp to 0 and updates the "_MOTIF_DRAG_ATOMS" property on
Packit b099d7
 *  motifWindow.  To minimize property access, the client saves the address
Packit b099d7
 *  of its current atoms table on the displayToAtomsContext context.
Packit b099d7
 *
Packit b099d7
 *  The "_MOTIF_DRAG_TARGETS" property on motifWindow contains a targets
Packit b099d7
 *  table, consisting of a sequence of target lists to be shared among
Packit b099d7
 *  clients.  These target lists are sorted into ascending order to avoid
Packit b099d7
 *  permutations.  By sharing the targets table, clients may pass target
Packit b099d7
 *  lists between themselves by passing instead the corresponding target
Packit b099d7
 *  list indexes.  The routine _XmInitTargetsTable() initializes the atoms
Packit b099d7
 *  table on the "_MOTIF_DRAG_ATOMS" property, then initializes the targets
Packit b099d7
 *  table on the "_MOTIF_DRAG_TARGETS" property to contain only two lists:
Packit b099d7
 *
Packit b099d7
 *		{ 0,		}, and
Packit b099d7
 *		{ XA_STRING,	} 
Packit b099d7
 *
Packit b099d7
 *  A client adds a target list to the targets table by passing the target
Packit b099d7
 *  list to _XmTargetsToIndex().  _XmTargetsToIndex() first sorts the target
Packit b099d7
 *  list into ascending order, then searches the targets table for a match.
Packit b099d7
 *  If it finds a match, it returns the index of the matching targets table
Packit b099d7
 *  entry.  Otherwise, it adds the sorted target list to the table, updates
Packit b099d7
 *  the "_MOTIF_DRAG_TARGETS" property on motifWindow, and returns the index
Packit b099d7
 *  of the new targets table entry.  A client uses _XmIndexToTargets() to
Packit b099d7
 *  map a targets table index to a target list.  To minimize property access,
Packit b099d7
 *  the client saves the address of its current targets table on the
Packit b099d7
 *  displayToTargetsContext context.
Packit b099d7
 *
Packit b099d7
 *  The "_MOTIF_DRAG_PROXY_WINDOW" property on motifWindow contains the
Packit b099d7
 *  window id of the DragNDrop proxy window.  The routine
Packit b099d7
 *  _XmGetDragProxyWindow() returns the window id stored there.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
#include <Xm/XmP.h>
Packit b099d7
#include "XmI.h"
Packit b099d7
#include "DragICCI.h"
Packit b099d7
#include "DragBSI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include <Xm/MwmUtil.h>
Packit b099d7
Packit b099d7
#include <X11/Xatom.h>
Packit b099d7
#include <X11/Xresource.h>
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#ifndef X_NOT_STDC_ENV
Packit b099d7
#include <stdlib.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#undef _XmIndexToTargets
Packit b099d7
#undef _XmTargetsToIndex
Packit b099d7
Packit b099d7
#define MAXSTACK	1200
Packit b099d7
#define MAXPROPLEN	100000L
Packit b099d7
Packit b099d7
/* structures to improve portability of WriteTargets */
Packit b099d7
typedef struct {
Packit b099d7
    CARD32 value B32;
Packit b099d7
} CARD32Item;
Packit b099d7
Packit b099d7
typedef struct {
Packit b099d7
    CARD16 value B16;
Packit b099d7
    CARD16 pad B16;
Packit b099d7
} CARD16Item;
Packit b099d7
Packit b099d7
#define MESSAGE1	_XmMMsgDragBS_0000
Packit b099d7
#define MESSAGE2	_XmMMsgDragBS_0001
Packit b099d7
#define MESSAGE3	_XmMMsgDragBS_0002
Packit b099d7
#define MESSAGE4	_XmMMsgDragBS_0003
Packit b099d7
#define MESSAGE5	_XmMMsgDragBS_0004
Packit b099d7
#define MESSAGE6	_XmMMsgDragBS_0005
Packit b099d7
#define MESSAGE7	_XmMMsgDragBS_0006
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static int LocalErrorHandler( 
Packit b099d7
                        Display *display,
Packit b099d7
                        XErrorEvent *error) ;
Packit b099d7
static void StartProtectedSection( 
Packit b099d7
                        Display *display,
Packit b099d7
                        Window window) ;
Packit b099d7
static void EndProtectedSection( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static Window GetMotifWindow( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static void SetMotifWindow( 
Packit b099d7
                        Display *display,
Packit b099d7
                        Window motifWindow) ;
Packit b099d7
static xmTargetsTable GetTargetsTable( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static void SetTargetsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmTargetsTable targetsTable) ;
Packit b099d7
static xmAtomsTable GetAtomsTable( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static void SetAtomsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmAtomsTable atomsTable) ;
Packit b099d7
static Window ReadMotifWindow( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static Window CreateMotifWindow( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static void WriteMotifWindow( 
Packit b099d7
                        Display *display,
Packit b099d7
                        Window *motifWindow) ;
Packit b099d7
static void WriteAtomsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmAtomsTable atomsTable) ;
Packit b099d7
static Boolean ReadAtomsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmAtomsTable atomsTable) ;
Packit b099d7
static void WriteTargetsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmTargetsTable targetsTable) ;
Packit b099d7
static Boolean ReadTargetsTable( 
Packit b099d7
                        Display *display,
Packit b099d7
                        xmTargetsTable targetsTable) ;
Packit b099d7
static xmTargetsTable CreateDefaultTargetsTable( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static xmAtomsTable CreateDefaultAtomsTable( 
Packit b099d7
                        Display *display) ;
Packit b099d7
static int AtomCompare( 
Packit b099d7
                        XmConst void *atom1,
Packit b099d7
                        XmConst void *atom2) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static Boolean		bad_window;
Packit b099d7
static XErrorHandler	oldErrorHandler = NULL;
Packit b099d7
static unsigned long	firstProtectRequest;
Packit b099d7
static Window		errorWindow;
Packit b099d7
Packit b099d7
static XContext 	displayToMotifWindowContext = (XContext) NULL;
Packit b099d7
static XContext 	displayToTargetsContext = (XContext) NULL;
Packit b099d7
static XContext		displayToAtomsContext = (XContext) NULL;
Packit b099d7
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  LocalErrorHandler ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static int 
Packit b099d7
LocalErrorHandler(
Packit b099d7
        Display *display,
Packit b099d7
        XErrorEvent *error )
Packit b099d7
{
Packit b099d7
    int ret_val;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (error->error_code == BadWindow &&
Packit b099d7
	error->resourceid == errorWindow &&
Packit b099d7
	error->serial >= firstProtectRequest) {
Packit b099d7
        bad_window = True;
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	return 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (oldErrorHandler == NULL) {
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
        return 0;  /* should never happen */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    ret_val = (*oldErrorHandler)(display, error);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return ret_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  StartProtectedSection ()
Packit b099d7
 *
Packit b099d7
 *  To protect against reading or writing to a property on a window that has
Packit b099d7
 *  been destroyed.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
StartProtectedSection(
Packit b099d7
        Display *display,
Packit b099d7
        Window window )
Packit b099d7
{
Packit b099d7
    bad_window = False;
Packit b099d7
    oldErrorHandler = XSetErrorHandler (LocalErrorHandler);
Packit b099d7
    firstProtectRequest = NextRequest (display);
Packit b099d7
    errorWindow = window;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  EndProtectedSection ()
Packit b099d7
 *
Packit b099d7
 *  Flushes any generated errors on and restores the original error handler.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
EndProtectedSection(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    XSync (display, False);
Packit b099d7
    XSetErrorHandler (oldErrorHandler);
Packit b099d7
    oldErrorHandler = NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetMotifWindow ()
Packit b099d7
 *
Packit b099d7
 *  Get the motifWindow id from the displayToMotifWindowContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Window 
Packit b099d7
GetMotifWindow(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    Window	motifWindow;
Packit b099d7
    XContext	loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToMotifWindowContext == (XContext) NULL) {
Packit b099d7
        displayToMotifWindowContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToMotifWindowContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    
Packit b099d7
    if (XFindContext(display, 
Packit b099d7
                     DefaultRootWindow (display),
Packit b099d7
		     loc_context, 
Packit b099d7
		     (char **)&motifWindow)) {
Packit b099d7
        motifWindow = None;
Packit b099d7
    }
Packit b099d7
    return (motifWindow);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetMotifWindow ()
Packit b099d7
 *
Packit b099d7
 *  Set the motifWindow id into the displayToMotifWindowContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
SetMotifWindow(
Packit b099d7
        Display *display,
Packit b099d7
        Window motifWindow )
Packit b099d7
{
Packit b099d7
    Window oldMotifWindow;
Packit b099d7
    XContext loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToMotifWindowContext == (XContext) NULL) {
Packit b099d7
        displayToMotifWindowContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToMotifWindowContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Save window data.
Packit b099d7
     * Delete old context if one exists.
Packit b099d7
     */
Packit b099d7
    if (XFindContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context,
Packit b099d7
			(char **) &oldMotifWindow)) {
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
			loc_context, 
Packit b099d7
			(char *) motifWindow);
Packit b099d7
    }
Packit b099d7
    else if (oldMotifWindow != motifWindow) {
Packit b099d7
	XDeleteContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context);
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
			loc_context, 
Packit b099d7
			(char *) motifWindow);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetTargetsTable ()
Packit b099d7
 *
Packit b099d7
 *  Get the targets table address from the displayToTargetsContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static xmTargetsTable 
Packit b099d7
GetTargetsTable(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    xmTargetsTable	targetsTable;
Packit b099d7
    XContext		loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToTargetsContext == (XContext) NULL) {
Packit b099d7
        displayToTargetsContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToTargetsContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    
Packit b099d7
    if (XFindContext(display, 
Packit b099d7
                     DefaultRootWindow (display),
Packit b099d7
		     loc_context, 
Packit b099d7
		     (char **)&targetsTable)) {
Packit b099d7
        targetsTable = NULL;
Packit b099d7
    }
Packit b099d7
    return (targetsTable);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetTargetsTable ()
Packit b099d7
 *
Packit b099d7
 *  Set the targets table address into the displayToTargetsContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
SetTargetsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmTargetsTable targetsTable )
Packit b099d7
{
Packit b099d7
    xmTargetsTable oldTargetsTable;
Packit b099d7
    XContext	loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToTargetsContext == (XContext) NULL) {
Packit b099d7
        displayToTargetsContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToTargetsContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Save targets data.
Packit b099d7
     * Delete old context if one exists.
Packit b099d7
     */
Packit b099d7
    if (XFindContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context,
Packit b099d7
			(char **) &oldTargetsTable)) {
Packit b099d7
	if (targetsTable)
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
			loc_context, 
Packit b099d7
			(char *) targetsTable);
Packit b099d7
    }
Packit b099d7
    else if (oldTargetsTable != targetsTable) {
Packit b099d7
	XDeleteContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context);
Packit b099d7
        {
Packit b099d7
          unsigned i = 0 ;
Packit b099d7
          while(    i < oldTargetsTable->numEntries    )
Packit b099d7
            {
Packit b099d7
              XtFree( (char *) oldTargetsTable->entries[i++].targets) ;
Packit b099d7
            }
Packit b099d7
          XtFree( (char *) oldTargetsTable->entries) ;
Packit b099d7
          XtFree( (char *) oldTargetsTable) ;
Packit b099d7
        }
Packit b099d7
Packit b099d7
	if (targetsTable)
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
			loc_context, 
Packit b099d7
			(char *) targetsTable);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GetAtomsTable ()
Packit b099d7
 *
Packit b099d7
 *  Get the atomsTable address from the displayToAtomsContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static xmAtomsTable 
Packit b099d7
GetAtomsTable(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    xmAtomsTable	atomsTable;
Packit b099d7
    XContext		loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToAtomsContext == (XContext) NULL) {
Packit b099d7
	displayToAtomsContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToAtomsContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    
Packit b099d7
    if (XFindContext (display, 
Packit b099d7
                      DefaultRootWindow (display),
Packit b099d7
		      loc_context,
Packit b099d7
		      (XPointer *)&atomsTable)) {
Packit b099d7
        atomsTable = NULL;
Packit b099d7
    }
Packit b099d7
    return (atomsTable);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetAtomsTable ()
Packit b099d7
 *
Packit b099d7
 *  Set the atoms table address into the displayToAtomsContext.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
SetAtomsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmAtomsTable atomsTable )
Packit b099d7
{
Packit b099d7
    xmAtomsTable oldAtomsTable;
Packit b099d7
    XContext loc_context;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (displayToAtomsContext == (XContext) NULL) {
Packit b099d7
        displayToAtomsContext = XUniqueContext();
Packit b099d7
    }
Packit b099d7
    loc_context = displayToAtomsContext;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Save atom data.
Packit b099d7
     * Delete old context if one exists.
Packit b099d7
     */
Packit b099d7
    if (XFindContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context,
Packit b099d7
			(char **) &oldAtomsTable)) {
Packit b099d7
	if (atomsTable)
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
	                loc_context,
Packit b099d7
			(char *) atomsTable);
Packit b099d7
    }
Packit b099d7
    else if (oldAtomsTable != atomsTable) {
Packit b099d7
	XDeleteContext (display, DefaultRootWindow (display),
Packit b099d7
			loc_context);
Packit b099d7
        XtFree( (char *) (oldAtomsTable->entries)) ;
Packit b099d7
        XtFree( (char *) oldAtomsTable) ;
Packit b099d7
	if (atomsTable)
Packit b099d7
	XSaveContext(display, 
Packit b099d7
                        DefaultRootWindow (display),
Packit b099d7
	                loc_context,
Packit b099d7
			(char *) atomsTable);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ReadMotifWindow ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Boolean RMW_ErrorFlag;
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static int
Packit b099d7
RMW_ErrorHandler(Display *display, /* unused */
Packit b099d7
		 XErrorEvent* event) /* unused */
Packit b099d7
{
Packit b099d7
    _XmProcessLock();
Packit b099d7
    RMW_ErrorFlag = True;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return 0 ; /* unused */
Packit b099d7
}
Packit b099d7
Packit b099d7
static Window 
Packit b099d7
ReadMotifWindow(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    Atom            motifWindowAtom;
Packit b099d7
    Atom            type;
Packit b099d7
    int             format;
Packit b099d7
    unsigned long   lengthRtn;
Packit b099d7
    unsigned long   bytesafter;
Packit b099d7
    Window         *property = NULL;
Packit b099d7
    Window	    motifWindow = None;
Packit b099d7
    XErrorHandler old_Handler;
Packit b099d7
Packit b099d7
    /* Setup error proc and reset error flag */
Packit b099d7
    old_Handler = XSetErrorHandler((XErrorHandler) RMW_ErrorHandler);
Packit b099d7
    _XmProcessLock();
Packit b099d7
    RMW_ErrorFlag = False;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    motifWindowAtom = XInternAtom (display, XmI_MOTIF_DRAG_WINDOW, False);
Packit b099d7
Packit b099d7
    if ((XGetWindowProperty (display,
Packit b099d7
                             RootWindow (display, 0),
Packit b099d7
                             motifWindowAtom,
Packit b099d7
                             0L, MAXPROPLEN,
Packit b099d7
			     False,
Packit b099d7
                             AnyPropertyType,
Packit b099d7
                             &type,
Packit b099d7
			     &format,
Packit b099d7
			     &lengthRtn,
Packit b099d7
			     &bytesafter, 
Packit b099d7
			     (unsigned char **) &property) == Success) &&
Packit b099d7
         (type == XA_WINDOW) &&
Packit b099d7
	 (format == 32) &&
Packit b099d7
	 (lengthRtn == 1)) {
Packit b099d7
	motifWindow = *property;
Packit b099d7
    }
Packit b099d7
    if (property) {
Packit b099d7
	XFree ((char *)property);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XSetErrorHandler(old_Handler);
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    if (RMW_ErrorFlag) motifWindow = None;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    return (motifWindow);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CreateMotifWindow ()
Packit b099d7
 *
Packit b099d7
 *  Creates a persistent window to hold the target list and atom pair
Packit b099d7
 *  properties.  This window is not visible on the screen.
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Window 
Packit b099d7
CreateMotifWindow(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    Display	         *ndisplay;
Packit b099d7
    XSetWindowAttributes sAttributes;
Packit b099d7
    Window	         motifWindow;
Packit b099d7
Packit b099d7
    if ((ndisplay = XOpenDisplay(XDisplayString(display))) == NULL) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE3);
Packit b099d7
	return None;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XGrabServer(ndisplay);
Packit b099d7
Packit b099d7
    XSetCloseDownMode (ndisplay, RetainPermanent);
Packit b099d7
Packit b099d7
    sAttributes.override_redirect = True;
Packit b099d7
    sAttributes.event_mask = PropertyChangeMask;
Packit b099d7
    motifWindow = XCreateWindow (ndisplay,
Packit b099d7
                                 DefaultRootWindow (ndisplay),
Packit b099d7
			         -100, -100, 10, 10, 0, 0,
Packit b099d7
			         InputOnly,
Packit b099d7
			         CopyFromParent,
Packit b099d7
			         (CWOverrideRedirect |CWEventMask),
Packit b099d7
			         &sAttributes);
Packit b099d7
    XMapWindow (ndisplay, motifWindow);
Packit b099d7
Packit b099d7
    WriteMotifWindow (ndisplay, &motifWindow);
Packit b099d7
Packit b099d7
    XCloseDisplay(ndisplay);
Packit b099d7
Packit b099d7
    return (motifWindow);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  WriteMotifWindow ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
WriteMotifWindow(
Packit b099d7
        Display *display,
Packit b099d7
        Window *motifWindow )
Packit b099d7
{
Packit b099d7
    Atom	motifWindowAtom;
Packit b099d7
Packit b099d7
    motifWindowAtom = XInternAtom (display, XmI_MOTIF_DRAG_WINDOW, False);
Packit b099d7
Packit b099d7
    XChangeProperty (display,
Packit b099d7
                     RootWindow (display, 0),
Packit b099d7
                     motifWindowAtom,
Packit b099d7
		     XA_WINDOW,
Packit b099d7
		     32,
Packit b099d7
		     PropModeReplace,
Packit b099d7
		     (unsigned char *) motifWindow,
Packit b099d7
		     1);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  WriteAtomsTable ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
WriteAtomsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmAtomsTable atomsTable )
Packit b099d7
{
Packit b099d7
    BYTE			stackData[MAXSTACK];
Packit b099d7
    struct _propertyRec {
Packit b099d7
	xmMotifAtomsPropertyRec	info;
Packit b099d7
	xmMotifAtomsTableRec	entry[1];
Packit b099d7
    } *propertyRecPtr;
Packit b099d7
Packit b099d7
    Atom                	atomsTableAtom;
Packit b099d7
    int	       			i;
Packit b099d7
    Window			motifWindow;
Packit b099d7
    size_t			dataSize;
Packit b099d7
Packit b099d7
    if (!atomsTable) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE4);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* If the data is bigger than the default stack allocation, then 
Packit b099d7
     * allocate heap storage, else use automatic storage.
Packit b099d7
     */
Packit b099d7
    dataSize = sizeof(xmMotifAtomsPropertyRec) + 
Packit b099d7
      atomsTable->numEntries * sizeof(xmMotifAtomsTableRec) ;
Packit b099d7
Packit b099d7
    if ( dataSize > MAXSTACK ) {
Packit b099d7
	propertyRecPtr = (struct _propertyRec *)XtMalloc( dataSize );
Packit b099d7
    } else {
Packit b099d7
	propertyRecPtr = (struct _propertyRec *)stackData;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    propertyRecPtr->info.byte_order = (BYTE) _XmByteOrderChar;
Packit b099d7
    propertyRecPtr->info.protocol_version = (BYTE) _MOTIF_DRAG_PROTOCOL_VERSION;
Packit b099d7
    propertyRecPtr->info.num_atoms = atomsTable->numEntries;
Packit b099d7
    propertyRecPtr->info.heap_offset = dataSize;
Packit b099d7
Packit b099d7
    /* write each entry's atom and time */
Packit b099d7
Packit b099d7
    for (i = 0; i < atomsTable->numEntries; i++) {
Packit b099d7
        propertyRecPtr->entry[i].atom = atomsTable->entries[i].atom;
Packit b099d7
        propertyRecPtr->entry[i].time = atomsTable->entries[i].time;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Write the buffer to the property within a protected section.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    atomsTableAtom = XInternAtom (display, XmI_MOTIF_DRAG_ATOMS, False);
Packit b099d7
    motifWindow = GetMotifWindow (display);
Packit b099d7
    _XmProcessLock();
Packit b099d7
    StartProtectedSection (display, motifWindow);
Packit b099d7
    XChangeProperty (display, 
Packit b099d7
                     motifWindow,
Packit b099d7
		     atomsTableAtom,
Packit b099d7
		     atomsTableAtom,
Packit b099d7
		     8,
Packit b099d7
		     PropModeReplace, 
Packit b099d7
		     (unsigned char *)propertyRecPtr,
Packit b099d7
		     dataSize );
Packit b099d7
Packit b099d7
    /* If we had to use a heap buffer, free it. */
Packit b099d7
    if (propertyRecPtr != (struct _propertyRec *)stackData) {
Packit b099d7
        XtFree((char *)propertyRecPtr);
Packit b099d7
    }
Packit b099d7
    EndProtectedSection (display);
Packit b099d7
    if (bad_window) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE1);
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ReadAtomsTable ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Boolean 
Packit b099d7
ReadAtomsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmAtomsTable atomsTable )
Packit b099d7
{
Packit b099d7
    struct { 
Packit b099d7
	xmMotifAtomsPropertyRec info;
Packit b099d7
	xmMotifAtomsTableRec	entry[1];
Packit b099d7
    } *propertyRecPtr = NULL;
Packit b099d7
    Atom                        atomsTableAtom;
Packit b099d7
    int				format;
Packit b099d7
    unsigned long 		bytesafter, lengthRtn; 
Packit b099d7
    Atom			type;
Packit b099d7
    int				i;
Packit b099d7
    Boolean			ret;
Packit b099d7
    Window			motifWindow;
Packit b099d7
Packit b099d7
    atomsTableAtom = XInternAtom (display, XmI_MOTIF_DRAG_ATOMS, False);
Packit b099d7
    motifWindow = GetMotifWindow (display);
Packit b099d7
    _XmProcessLock();
Packit b099d7
    StartProtectedSection (display, motifWindow);
Packit b099d7
    ret = ((XGetWindowProperty (display, 	/* display* */
Packit b099d7
    				motifWindow,	/* window */
Packit b099d7
			        atomsTableAtom,	/* property atom */
Packit b099d7
			        0L, MAXPROPLEN,	/* long_offset, long_length */
Packit b099d7
			        False,		/* delete flag */
Packit b099d7
			        atomsTableAtom,	/* property type */
Packit b099d7
			        &type,		/* returned actual type */
Packit b099d7
			        &format,	/* returned actual format */
Packit b099d7
			        &lengthRtn,	/* returned item count */
Packit b099d7
			        &bytesafter,	/* returned bytes remaining */
Packit b099d7
			        (unsigned char **) &propertyRecPtr)
Packit b099d7
						/* returned data */
Packit b099d7
	    == Success) &&
Packit b099d7
           (lengthRtn >= sizeof(xmMotifAtomsPropertyRec)));
Packit b099d7
    EndProtectedSection (display);
Packit b099d7
Packit b099d7
    if (bad_window) {
Packit b099d7
	static Boolean first_time = True;
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Try to recreate the motifWindow. We could have gotten an invalid
Packit b099d7
	 * window id from the _MOTIF_DRAG_WINDOW property.
Packit b099d7
	 */
Packit b099d7
	if (first_time) {
Packit b099d7
	    motifWindow = CreateMotifWindow (display);
Packit b099d7
	    SetMotifWindow (display, motifWindow);
Packit b099d7
	    first_time = False;
Packit b099d7
	} else
Packit b099d7
	    XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE1);
Packit b099d7
Packit b099d7
	ret = False;
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    if (ret) {
Packit b099d7
	if (propertyRecPtr->info.protocol_version != 
Packit b099d7
	    _MOTIF_DRAG_PROTOCOL_VERSION) {
Packit b099d7
	    XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE2);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
	    swap2bytes(propertyRecPtr->info.num_atoms);
Packit b099d7
	    swap4bytes(propertyRecPtr->info.heap_offset);
Packit b099d7
	}
Packit b099d7
Packit b099d7
        if (atomsTable == NULL)
Packit b099d7
        {
Packit b099d7
            atomsTable = (xmAtomsTable) XtMalloc(sizeof(xmAtomsTableRec));
Packit b099d7
            atomsTable->numEntries = 0;
Packit b099d7
            atomsTable->entries = NULL;
Packit b099d7
Packit b099d7
            SetAtomsTable (display, atomsTable);
Packit b099d7
        }
Packit b099d7
Packit b099d7
	if (propertyRecPtr->info.num_atoms > atomsTable->numEntries) {
Packit b099d7
Packit b099d7
            /*
Packit b099d7
	     *  expand the atoms table
Packit b099d7
	     */
Packit b099d7
Packit b099d7
            atomsTable->entries = (xmAtomsTableEntry) XtRealloc(
Packit b099d7
	        (char *)atomsTable->entries,	/* NULL ok */
Packit b099d7
		sizeof(xmAtomsTableEntryRec) * propertyRecPtr->info.num_atoms);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 *  Read the atom table entries.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	for (i = 0; i < (int)propertyRecPtr->info.num_atoms; i++) {
Packit b099d7
	    if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
		swap4bytes(propertyRecPtr->entry[i].atom);
Packit b099d7
		swap4bytes(propertyRecPtr->entry[i].time);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
            atomsTable->entries[i].atom = (Atom) propertyRecPtr->entry[i].atom;
Packit b099d7
            atomsTable->entries[i].time = (Time) propertyRecPtr->entry[i].time;
Packit b099d7
	}
Packit b099d7
        atomsTable->numEntries = propertyRecPtr->info.num_atoms;
Packit b099d7
    }      
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Free any memory that Xlib passed us.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (propertyRecPtr) {
Packit b099d7
        XFree((char *)propertyRecPtr);
Packit b099d7
    }
Packit b099d7
    return (ret);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  WriteTargetsTable ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static void 
Packit b099d7
WriteTargetsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmTargetsTable targetsTable )
Packit b099d7
{
Packit b099d7
    BYTE		stackData[MAXSTACK], *fill;
Packit b099d7
    struct _propertyRec {
Packit b099d7
	xmMotifTargetsPropertyRec	info;
Packit b099d7
    } *propertyRecPtr;
Packit b099d7
Packit b099d7
    Atom                targetsTableAtom;
Packit b099d7
    int			i, j;
Packit b099d7
    Window		motifWindow;
Packit b099d7
    size_t		dataSize;
Packit b099d7
    CARD16Item		shortItem;
Packit b099d7
    CARD32Item		longItem;
Packit b099d7
Packit b099d7
    if (!targetsTable) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE5);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Calculate the total size of the property. */
Packit b099d7
    dataSize = sizeof(xmMotifTargetsPropertyRec);
Packit b099d7
Packit b099d7
    for (i = 0; i < targetsTable->numEntries; i++) {
Packit b099d7
	dataSize += targetsTable->entries[i].numTargets * 4 + 2;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* If size needed is bigger than the pre-allocated space, allocate a
Packit b099d7
     * bigger buffer. 
Packit b099d7
     */
Packit b099d7
    if ( dataSize > MAXSTACK ){
Packit b099d7
	propertyRecPtr = (struct _propertyRec *)XtMalloc( dataSize );
Packit b099d7
    } else {
Packit b099d7
	propertyRecPtr = (struct _propertyRec *)stackData ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    propertyRecPtr->info.byte_order = (BYTE) _XmByteOrderChar;
Packit b099d7
    propertyRecPtr->info.protocol_version = (BYTE) _MOTIF_DRAG_PROTOCOL_VERSION;
Packit b099d7
    propertyRecPtr->info.num_target_lists = targetsTable->numEntries;
Packit b099d7
    propertyRecPtr->info.heap_offset = dataSize;
Packit b099d7
Packit b099d7
    /* write each target list's count and atoms */
Packit b099d7
Packit b099d7
    fill = (BYTE *)propertyRecPtr + sizeof(xmMotifTargetsPropertyRec);
Packit b099d7
Packit b099d7
    for (i = 0; i < targetsTable->numEntries; i++) {
Packit b099d7
        shortItem.value = targetsTable->entries[i].numTargets;
Packit b099d7
	memcpy( fill, &shortItem, 2 );
Packit b099d7
	fill += 2;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 *  Write each Atom out one at a time as a CARD32.
Packit b099d7
	 */
Packit b099d7
	for (j = 0; j < targetsTable->entries[i].numTargets; j++) {
Packit b099d7
	    longItem.value = targetsTable->entries[i].targets[j];
Packit b099d7
	    memcpy( fill, &longItem, 4 );
Packit b099d7
	    fill += 4;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Write the buffer to the property within a protected section.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    targetsTableAtom = XInternAtom (display, XmI_MOTIF_DRAG_TARGETS, False);
Packit b099d7
    motifWindow = GetMotifWindow (display);
Packit b099d7
    _XmProcessLock();
Packit b099d7
    StartProtectedSection (display, motifWindow);
Packit b099d7
    XChangeProperty (display, 
Packit b099d7
                     motifWindow,
Packit b099d7
		     targetsTableAtom,
Packit b099d7
		     targetsTableAtom,
Packit b099d7
		     8,
Packit b099d7
		     PropModeReplace, 
Packit b099d7
		     (unsigned char *)propertyRecPtr,
Packit b099d7
		     dataSize);
Packit b099d7
Packit b099d7
    /* If a buffer was allocated, free it. */
Packit b099d7
    if (propertyRecPtr != (struct _propertyRec *)stackData) {
Packit b099d7
        XtFree((char *)propertyRecPtr);
Packit b099d7
    }
Packit b099d7
    EndProtectedSection (display);
Packit b099d7
    if (bad_window) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE1);
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ReadTargetsTable ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Boolean 
Packit b099d7
ReadTargetsTable(
Packit b099d7
        Display *display,
Packit b099d7
        xmTargetsTable targetsTable )
Packit b099d7
{
Packit b099d7
    struct _propertyRec {
Packit b099d7
	xmMotifTargetsPropertyRec	info;
Packit b099d7
    } *propertyRecPtr = NULL;
Packit b099d7
Packit b099d7
    char			*bufptr;
Packit b099d7
    short			num_targets;
Packit b099d7
    Atom                        targetsTableAtom;
Packit b099d7
    int				format;
Packit b099d7
    unsigned long 		bytesafter, lengthRtn; 
Packit b099d7
    Atom			type;
Packit b099d7
    int				i, j;
Packit b099d7
    Atom		        *targets;
Packit b099d7
    Boolean			ret;
Packit b099d7
    Window			motifWindow;
Packit b099d7
    CARD16Item			shortItem;
Packit b099d7
    CARD32Item			longItem;
Packit b099d7
Packit b099d7
    targetsTableAtom = XInternAtom (display, XmI_MOTIF_DRAG_TARGETS, False);
Packit b099d7
    motifWindow = GetMotifWindow (display);
Packit b099d7
    _XmProcessLock();
Packit b099d7
    StartProtectedSection (display, motifWindow);
Packit b099d7
    ret = ((XGetWindowProperty (display, 
Packit b099d7
    				motifWindow,
Packit b099d7
			        targetsTableAtom,
Packit b099d7
			        0L, MAXPROPLEN,
Packit b099d7
			        False,
Packit b099d7
			        targetsTableAtom,
Packit b099d7
			        &type,
Packit b099d7
			        &format,
Packit b099d7
			        &lengthRtn,
Packit b099d7
			        &bytesafter,
Packit b099d7
			        (unsigned char **) &propertyRecPtr) == Success) &&
Packit b099d7
           (lengthRtn >= sizeof(xmMotifTargetsPropertyRec)));
Packit b099d7
    EndProtectedSection (display);
Packit b099d7
    if (bad_window) {
Packit b099d7
	XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE1);
Packit b099d7
	ret = False;
Packit b099d7
    }
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    if (ret) {
Packit b099d7
	if (propertyRecPtr->info.protocol_version != 
Packit b099d7
	    _MOTIF_DRAG_PROTOCOL_VERSION) {
Packit b099d7
	    XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE2);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
	    swap2bytes(propertyRecPtr->info.num_target_lists);
Packit b099d7
	    swap4bytes(propertyRecPtr->info.heap_offset);
Packit b099d7
	}
Packit b099d7
Packit b099d7
        if (targetsTable == NULL)
Packit b099d7
        {
Packit b099d7
            targetsTable = (xmTargetsTable)XtMalloc(sizeof(xmTargetsTableRec));
Packit b099d7
            targetsTable->numEntries = 0;
Packit b099d7
            targetsTable->entries = NULL;
Packit b099d7
Packit b099d7
            SetTargetsTable (display, targetsTable);
Packit b099d7
        }
Packit b099d7
Packit b099d7
	if (propertyRecPtr->info.num_target_lists > targetsTable->numEntries) {
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     *  expand the target table
Packit b099d7
	     */
Packit b099d7
Packit b099d7
            targetsTable->entries = (xmTargetsTableEntry) 
Packit b099d7
	      XtRealloc(
Packit b099d7
			(char *)targetsTable->entries,	/* NULL ok */
Packit b099d7
			sizeof(xmTargetsTableEntryRec) * 
Packit b099d7
			propertyRecPtr->info.num_target_lists);
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     *  read the new entries
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    bufptr = (char *)propertyRecPtr + sizeof(xmMotifTargetsPropertyRec);
Packit b099d7
	    for (i = 0; i < targetsTable->numEntries; i++) {
Packit b099d7
		memcpy( &shortItem, bufptr, 2 );
Packit b099d7
	        if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
		    swap2bytes(shortItem.value);
Packit b099d7
		}
Packit b099d7
		num_targets = shortItem.value;
Packit b099d7
Packit b099d7
		bufptr += 2 + 4 * num_targets;
Packit b099d7
Packit b099d7
		if (num_targets != targetsTable->entries[i].numTargets) {
Packit b099d7
		    XmeWarning( (Widget) XmGetXmDisplay (display), MESSAGE6);
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    for (; i < (int)propertyRecPtr->info.num_target_lists; i++) {
Packit b099d7
		memcpy( &shortItem, bufptr, 2 );
Packit b099d7
		bufptr += 2;
Packit b099d7
	        if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
	            swap2bytes(shortItem.value);
Packit b099d7
		}
Packit b099d7
		num_targets = shortItem.value;
Packit b099d7
Packit b099d7
                if(!num_targets)
Packit b099d7
		  targets = NULL;
Packit b099d7
                else
Packit b099d7
	          targets = (Atom *) XtMalloc(sizeof(Atom) * num_targets);
Packit b099d7
		/*
Packit b099d7
	 	 *  Read each Atom in one at a time.
Packit b099d7
	 	 */
Packit b099d7
		for (j = 0; j < num_targets; j++) {
Packit b099d7
		    memcpy( &longItem, bufptr, 4 );
Packit b099d7
		    bufptr += 4;
Packit b099d7
	            if (propertyRecPtr->info.byte_order != _XmByteOrderChar) {
Packit b099d7
			swap4bytes(longItem.value);
Packit b099d7
		    }
Packit b099d7
		    targets[j] = (Atom) longItem.value ;
Packit b099d7
		}
Packit b099d7
Packit b099d7
                targetsTable->numEntries++;
Packit b099d7
                targetsTable->entries[i].numTargets = num_targets;
Packit b099d7
                targetsTable->entries[i].targets = targets;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }      
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Free any memory that Xlib passed us.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (propertyRecPtr) {
Packit b099d7
        XFree((char *)propertyRecPtr);
Packit b099d7
    }
Packit b099d7
    return (ret);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CreateDefaultTargetsTable ()
Packit b099d7
 *
Packit b099d7
 *  Create the default targets table.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static Atom nullTargets[] = 	{ 0,		};
Packit b099d7
static Atom stringTargets[] = 	{ XA_STRING,	};
Packit b099d7
Packit b099d7
static xmTargetsTable 
Packit b099d7
CreateDefaultTargetsTable(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    xmTargetsTable	targetsTable;
Packit b099d7
    Cardinal		size;
Packit b099d7
Packit b099d7
    targetsTable = (xmTargetsTable) XtMalloc(sizeof(xmTargetsTableRec));
Packit b099d7
Packit b099d7
    targetsTable->numEntries = 2;
Packit b099d7
    targetsTable->entries =
Packit b099d7
	(xmTargetsTableEntry) XtMalloc(sizeof(xmTargetsTableEntryRec) * 2);
Packit b099d7
Packit b099d7
/* According to specs and man pages, default values of XmNimportTargets 
Packit b099d7
 * and XmNnumImportTargets should be NULL and zero respectively. The 
Packit b099d7
 * corresponding record in default targets table is entries[0]. The original 
Packit b099d7
 * setting of entries[0] (commented out below) was resulting in to default
Packit b099d7
 * values of non NULL pointer pointing to target list with NULL entry and 
Packit b099d7
 * 1 for XmNimportTargets and XmNnumImportTargets respectively. 
Packit b099d7
 *
Packit b099d7
 * The changed code set the XmNnumImportTargets to 0 and XmNimportTargets to
Packit b099d7
 * NULL. This change may cause problem in code where importTarget 
Packit b099d7
 * is dereferanced twice without checking for possible NULL value. It that 
Packit b099d7
 * happens, and there is no easy way to fix it, change entries[0].targets to 
Packit b099d7
 * nullTargets, but leave entries[0].numTargets to 0.
Packit b099d7
 */
Packit b099d7
Packit b099d7
#if 0
Packit b099d7
    targetsTable->entries[0].numTargets = XtNumber(nullTargets);
Packit b099d7
    size = sizeof(Atom) * targetsTable->entries[0].numTargets;
Packit b099d7
    targetsTable->entries[0].targets = (Atom*) XtMalloc(size);
Packit b099d7
    memcpy(targetsTable->entries[0].targets, nullTargets, size);
Packit b099d7
#endif
Packit b099d7
    targetsTable->entries[0].numTargets = _XmDefaultNumImportTargets;
Packit b099d7
    targetsTable->entries[0].targets = (Atom*) _XmDefaultImportTargets;
Packit b099d7
Packit b099d7
    targetsTable->entries[1].numTargets = XtNumber(stringTargets);
Packit b099d7
    size = sizeof(Atom) * targetsTable->entries[1].numTargets;
Packit b099d7
    targetsTable->entries[1].targets = (Atom*) XtMalloc(size);
Packit b099d7
    memcpy(targetsTable->entries[1].targets, stringTargets, size);
Packit b099d7
Packit b099d7
    SetTargetsTable (display, targetsTable);
Packit b099d7
    return (targetsTable);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  CreateDefaultAtomsTable ()
Packit b099d7
 *
Packit b099d7
 *  Create the default atoms table.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static xmAtomsTable 
Packit b099d7
CreateDefaultAtomsTable(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    xmAtomsTable	atomsTable;
Packit b099d7
Packit b099d7
    atomsTable = (xmAtomsTable) XtMalloc(sizeof(xmAtomsTableRec));
Packit b099d7
Packit b099d7
    atomsTable->numEntries = 1;
Packit b099d7
    atomsTable->entries =
Packit b099d7
	(xmAtomsTableEntry) XtMalloc(sizeof(xmAtomsTableEntryRec));
Packit b099d7
Packit b099d7
    atomsTable->entries[0].atom =
Packit b099d7
	XInternAtom (display, XmS_MOTIF_ATOM_0, False);
Packit b099d7
    atomsTable->entries[0].time = 0;
Packit b099d7
Packit b099d7
    SetAtomsTable (display, atomsTable);
Packit b099d7
    return (atomsTable);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmInitTargetsTable ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmInitTargetsTable(
Packit b099d7
        Display *display )
Packit b099d7
{
Packit b099d7
    Window	motifWindow;
Packit b099d7
    Boolean	grabbed = False;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Read the motifWindow property on the root.  If the property is not
Packit b099d7
     *    there, create a persistant motifWindow and put it on the property.
Packit b099d7
     *  Reading the atom pair, atoms table, and targets table properties
Packit b099d7
     *    on motifWindow is delayed so they can be saved in contexts indexed
Packit b099d7
     *    by the original display.
Packit b099d7
     */
Packit b099d7
Packit b099d7
Packit b099d7
    if ((motifWindow = ReadMotifWindow (display)) == None) {
Packit b099d7
	motifWindow = CreateMotifWindow (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    SetMotifWindow (display, motifWindow);
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * At this time, we are not sure the motifWindow id is valid,
Packit b099d7
     * but we will find out in the ReadAtomsTable. We will try to
Packit b099d7
     * recreate it there.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!ReadAtomsTable (display, GetAtomsTable (display))) {
Packit b099d7
        XGrabServer(display);
Packit b099d7
        grabbed = True;
Packit b099d7
        if (!ReadAtomsTable (display, GetAtomsTable (display))) {
Packit b099d7
            WriteAtomsTable (display, CreateDefaultAtomsTable (display));
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!ReadTargetsTable (display, GetTargetsTable (display))) {
Packit b099d7
        if (!grabbed) {
Packit b099d7
	    XGrabServer(display);
Packit b099d7
            grabbed = True;
Packit b099d7
	    if (!ReadTargetsTable (display, GetTargetsTable (display))) {
Packit b099d7
                WriteTargetsTable (display,
Packit b099d7
				   CreateDefaultTargetsTable (display));
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
            WriteTargetsTable (display, CreateDefaultTargetsTable (display));
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (grabbed) {
Packit b099d7
	XUngrabServer (display);
Packit b099d7
        XFlush (display);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
void _XmClearDisplayTables (Display *display)
Packit b099d7
{
Packit b099d7
       SetAtomsTable(display,NULL);
Packit b099d7
       SetTargetsTable(display,NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmIndexToTargets ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
_XmIndexToTargets(
Packit b099d7
        Widget shell,
Packit b099d7
        Cardinal t_index,
Packit b099d7
        Atom **targetsRtn )
Packit b099d7
{
Packit b099d7
    Display		*display = XtDisplay (shell);
Packit b099d7
    xmTargetsTable	targetsTable;
Packit b099d7
Packit b099d7
    if (!(targetsTable = GetTargetsTable (display))) {
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
        targetsTable = GetTargetsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (t_index >= targetsTable->numEntries) {
Packit b099d7
        /*
Packit b099d7
	 *  Retrieve the targets table from motifWindow.
Packit b099d7
	 *  If this fails, then either the motifWindow or the targets table
Packit b099d7
	 *  property on motifWindow has been destroyed, so reinitialize.
Packit b099d7
	 */
Packit b099d7
        if (!ReadTargetsTable (display, targetsTable)) {
Packit b099d7
            _XmInitTargetsTable (display);
Packit b099d7
            targetsTable = GetTargetsTable (display);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (t_index >= targetsTable->numEntries) {
Packit b099d7
	XmeWarning ((Widget) XmGetXmDisplay (display), MESSAGE7);
Packit b099d7
        *targetsRtn = NULL;
Packit b099d7
        return 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    *targetsRtn = targetsTable->entries[t_index].targets;
Packit b099d7
    return targetsTable->entries[t_index].numTargets;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmAtomCompare ()
Packit b099d7
 *
Packit b099d7
 *  The routine must return an integer less than, equal to, or greater than
Packit b099d7
 *  0 according as the first argument is to be considered less
Packit b099d7
 *  than, equal to, or greater than the second.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
static int 
Packit b099d7
AtomCompare(
Packit b099d7
        XmConst void *atom1,
Packit b099d7
        XmConst void *atom2 )
Packit b099d7
{
Packit b099d7
    return (*((Atom *) atom1) - *((Atom *) atom2));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmTargetsToIndex ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
_XmTargetsToIndex(
Packit b099d7
        Widget shell,
Packit b099d7
        Atom *targets,
Packit b099d7
        Cardinal numTargets )
Packit b099d7
{
Packit b099d7
    Display		*display = XtDisplay (shell);
Packit b099d7
    Cardinal		i, j;
Packit b099d7
    Cardinal		size;
Packit b099d7
    Cardinal		oldNumEntries;
Packit b099d7
    Atom		*newTargets;
Packit b099d7
    xmTargetsTable	targetsTable;
Packit b099d7
Packit b099d7
    if(!numTargets) return 0;
Packit b099d7
    _XmProcessLock();
Packit b099d7
Packit b099d7
    if (!(targetsTable = GetTargetsTable (display))) {
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
        targetsTable = GetTargetsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Create a new targets list, sorted in ascending order.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    size =  sizeof(Atom) * numTargets;
Packit b099d7
    newTargets = (Atom *) XtMalloc(size);
Packit b099d7
    memcpy (newTargets, targets, size);
Packit b099d7
    qsort ((void *)newTargets, (size_t)numTargets, (size_t)sizeof(Atom),
Packit b099d7
           AtomCompare);
Packit b099d7
    /*
Packit b099d7
     *  Try to find the targets list in the targets table.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    for (i = 0; i < targetsTable->numEntries; i++) {
Packit b099d7
	if (numTargets == targetsTable->entries[i].numTargets) {
Packit b099d7
            for (j = 0; j < numTargets; j++) {
Packit b099d7
	        if (newTargets[j] != targetsTable->entries[i].targets[j]) {
Packit b099d7
	            break;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    if (j == numTargets) {
Packit b099d7
	        XtFree ((char *)newTargets);
Packit b099d7
                _XmProcessUnlock();
Packit b099d7
	        return i;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    oldNumEntries = targetsTable->numEntries;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Lock and retrieve the target table from motifWindow.
Packit b099d7
     *  If this fails, then either the motifWindow or the targets table
Packit b099d7
     *  property on motifWindow has been destroyed, so reinitialize.
Packit b099d7
     *  If the target list is still not in the table, add the target list
Packit b099d7
     *  to the table and write the table out to its property.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XGrabServer (display);
Packit b099d7
    if (!ReadTargetsTable (display, targetsTable)) {
Packit b099d7
	XUngrabServer (display);
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
	XGrabServer (display);
Packit b099d7
        targetsTable = GetTargetsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    for (i = oldNumEntries; i < targetsTable->numEntries; i++) {
Packit b099d7
	if (numTargets == targetsTable->entries[i].numTargets) {
Packit b099d7
	    for (j = 0; j < numTargets; j++) {
Packit b099d7
		if (newTargets[j] != targetsTable->entries[i].targets[j]) {
Packit b099d7
	            break;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    if (j == numTargets) {
Packit b099d7
	        XtFree ((char *)newTargets);
Packit b099d7
		break;
Packit b099d7
            }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    if (i == targetsTable->numEntries) {
Packit b099d7
        targetsTable->numEntries++;
Packit b099d7
Packit b099d7
        targetsTable->entries = (xmTargetsTableEntry) XtRealloc(
Packit b099d7
	    (char *)targetsTable->entries,	/* NULL ok */
Packit b099d7
	    sizeof(xmTargetsTableEntryRec) * (targetsTable->numEntries));
Packit b099d7
Packit b099d7
        targetsTable->entries[i].numTargets = numTargets;
Packit b099d7
        targetsTable->entries[i].targets = newTargets;
Packit b099d7
        WriteTargetsTable (display, targetsTable);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XUngrabServer (display);
Packit b099d7
    XFlush (display);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    return i;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmAllocMotifAtom ()
Packit b099d7
 *
Packit b099d7
 *  Allocate an atom in the atoms table with the specified time stamp.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Atom 
Packit b099d7
_XmAllocMotifAtom(
Packit b099d7
        Widget shell,
Packit b099d7
        Time time )
Packit b099d7
{
Packit b099d7
    Display		*display = XtDisplay (shell);
Packit b099d7
    xmAtomsTable	atomsTable;
Packit b099d7
    xmAtomsTableEntry	p;
Packit b099d7
    Cardinal		i;
Packit b099d7
    char		atomname[80];
Packit b099d7
    Atom		atomReturn = None;
Packit b099d7
Packit b099d7
    if (!(atomsTable = GetAtomsTable (display))) {
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Lock and retrieve the atoms table from motifWindow.
Packit b099d7
     *  If this fails, then either the motifWindow or the atoms table
Packit b099d7
     *  property on motifWindow has been destroyed, so reinitialize.
Packit b099d7
     *  Try to find an available atom in the table (time == 0).
Packit b099d7
     *  If no atom is available, add an atom to the table.
Packit b099d7
     *  Write the atoms table out to its property.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XGrabServer (display);
Packit b099d7
    if (!ReadAtomsTable (display, atomsTable)) {
Packit b099d7
	XUngrabServer (display);
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
	XGrabServer (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    for (p = atomsTable->entries, i = atomsTable->numEntries; i; p++, i--) {
Packit b099d7
        if ((p->time) == 0) {
Packit b099d7
            p->time = time;
Packit b099d7
            atomReturn = p->atom;
Packit b099d7
	    break;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (atomReturn == None) {
Packit b099d7
	i = atomsTable->numEntries++;
Packit b099d7
Packit b099d7
        atomsTable->entries = (xmAtomsTableEntry) XtRealloc(
Packit b099d7
	    (char *)atomsTable->entries,	/* NULL ok */
Packit b099d7
  	    (atomsTable->numEntries * sizeof(xmAtomsTableEntryRec)));
Packit b099d7
Packit b099d7
        sprintf(atomname, "%s%d", "_MOTIF_ATOM_", i);
Packit b099d7
        atomsTable->entries[i].atom = XInternAtom (display, atomname, False);
Packit b099d7
        atomsTable->entries[i].time = time;
Packit b099d7
        atomReturn = atomsTable->entries[i].atom;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    WriteAtomsTable (display, atomsTable);
Packit b099d7
    XUngrabServer (display);
Packit b099d7
    XFlush (display);
Packit b099d7
    return (atomReturn);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmGetMotifAtom ()
Packit b099d7
 *
Packit b099d7
 *  Get the atom from the atoms table with nonzero timestamp less than but
Packit b099d7
 *  closest to the specified value.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Atom 
Packit b099d7
_XmGetMotifAtom(
Packit b099d7
        Widget shell,
Packit b099d7
        Time time )
Packit b099d7
{
Packit b099d7
    Display		*display = XtDisplay (shell);
Packit b099d7
    xmAtomsTable	atomsTable;
Packit b099d7
    Cardinal		i;
Packit b099d7
    Atom		atomReturn = None;
Packit b099d7
    Time		c_time;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Get the atoms table saved in the display's context.
Packit b099d7
     *  This table will be updated from the motifWindow property.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(atomsTable = GetAtomsTable (display))) {
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Lock and retrieve the atoms table from motifWindow.
Packit b099d7
     *  If this fails, then either the motifWindow or the atoms table
Packit b099d7
     *  property on motifWindow has been destroyed, so reinitialize.
Packit b099d7
     *  Try to find the atom with nonzero timestamp less than but closest
Packit b099d7
     *  to the specified value.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XGrabServer (display);
Packit b099d7
    if (!ReadAtomsTable (display, atomsTable)) {
Packit b099d7
	XUngrabServer (display);
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
	XGrabServer (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    for (i = 0; i < atomsTable->numEntries; i++) {
Packit b099d7
        if ((atomsTable->entries[i].time) &&
Packit b099d7
            (atomsTable->entries[i].time <= time)) {
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (i < atomsTable->numEntries) {
Packit b099d7
        atomReturn = atomsTable->entries[i].atom;
Packit b099d7
        c_time = atomsTable->entries[i++].time;
Packit b099d7
        for (; i < atomsTable->numEntries; i++) {
Packit b099d7
            if ((atomsTable->entries[i].time > c_time) &&
Packit b099d7
                (atomsTable->entries[i].time < time)) {
Packit b099d7
                atomReturn = atomsTable->entries[i].atom;
Packit b099d7
                c_time = atomsTable->entries[i].time;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XUngrabServer (display);
Packit b099d7
    XFlush (display);
Packit b099d7
    return (atomReturn);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmFreeMotifAtom ()
Packit b099d7
 *
Packit b099d7
 *  Free an atom in the atoms table by giving it a zero timestamp.
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmFreeMotifAtom(
Packit b099d7
        Widget shell,
Packit b099d7
        Atom atom )
Packit b099d7
{
Packit b099d7
    Display		*display = XtDisplay (shell);
Packit b099d7
    xmAtomsTable	atomsTable;
Packit b099d7
    xmAtomsTableEntry	p;
Packit b099d7
    Cardinal		i;
Packit b099d7
Packit b099d7
    if (atom == None) {
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Get the atoms table saved in the display's context.
Packit b099d7
     *  This table will be updated from the motifWindow property.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(atomsTable = GetAtomsTable (display))) {
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Lock and retrieve the atoms table from its property.
Packit b099d7
     *  If this fails, then either the motifWindow or the atoms table
Packit b099d7
     *  property on motifWindow has been destroyed, so reinitialize.
Packit b099d7
     *  Free the matched atom, if present, and write the atoms table out
Packit b099d7
     *  to its property.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XGrabServer (display);
Packit b099d7
    if (!ReadAtomsTable (display, atomsTable)) {
Packit b099d7
	XUngrabServer (display);
Packit b099d7
        _XmInitTargetsTable (display);
Packit b099d7
	XGrabServer (display);
Packit b099d7
        atomsTable = GetAtomsTable (display);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    for (p = atomsTable->entries, i = atomsTable->numEntries; i; p++, i--) {
Packit b099d7
        if (p->atom == atom) {
Packit b099d7
            p->time = (Time) 0;
Packit b099d7
            WriteAtomsTable (display, atomsTable);
Packit b099d7
	    break;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XUngrabServer (display);
Packit b099d7
    XFlush (display);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmDestroyMotifWindow ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmDestroyMotifWindow(
Packit b099d7
        Display  *display )
Packit b099d7
{
Packit b099d7
    Window	motifWindow;
Packit b099d7
    Atom	motifWindowAtom;
Packit b099d7
Packit b099d7
    if ((motifWindow = ReadMotifWindow (display)) != None) {
Packit b099d7
        motifWindowAtom = XInternAtom (display, XmI_MOTIF_DRAG_WINDOW, False);
Packit b099d7
        XDeleteProperty (display,
Packit b099d7
                         DefaultRootWindow (display),
Packit b099d7
                         motifWindowAtom);
Packit b099d7
	XDestroyWindow (display, motifWindow);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*****************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmGetDragProxyWindow ()
Packit b099d7
 *
Packit b099d7
 ***************************************************************************/
Packit b099d7
Packit b099d7
Window
Packit b099d7
_XmGetDragProxyWindow(
Packit b099d7
        Display  *display )
Packit b099d7
{
Packit b099d7
    Atom		motifProxyWindowAtom;
Packit b099d7
    Atom		type;
Packit b099d7
    int			format;
Packit b099d7
    unsigned long	lengthRtn;
Packit b099d7
    unsigned long	bytesafter;
Packit b099d7
    Window		*property = NULL;
Packit b099d7
    Window		motifWindow;
Packit b099d7
    Window		motifProxyWindow = None;
Packit b099d7
Packit b099d7
    if ((motifWindow = ReadMotifWindow (display)) != None) {
Packit b099d7
Packit b099d7
	motifProxyWindowAtom =
Packit b099d7
	    XInternAtom (display, XmI_MOTIF_DRAG_PROXY_WINDOW, False);
Packit b099d7
Packit b099d7
	_XmProcessLock();
Packit b099d7
	StartProtectedSection (display, motifWindow);
Packit b099d7
Packit b099d7
	if ((XGetWindowProperty (display,
Packit b099d7
                                 motifWindow,
Packit b099d7
                                 motifProxyWindowAtom,
Packit b099d7
                                 0L, MAXPROPLEN,
Packit b099d7
			         False,
Packit b099d7
                                 AnyPropertyType,
Packit b099d7
                                 &type,
Packit b099d7
			         &format,
Packit b099d7
			         &lengthRtn,
Packit b099d7
			         &bytesafter, 
Packit b099d7
			         (unsigned char **) &property) == Success) &&
Packit b099d7
             (type == XA_WINDOW) &&
Packit b099d7
	     (format == 32) &&
Packit b099d7
	     (lengthRtn == 1)) {
Packit b099d7
	    motifProxyWindow = *property;
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	EndProtectedSection (display);
Packit b099d7
	_XmProcessUnlock();
Packit b099d7
	
Packit b099d7
	if (property) {
Packit b099d7
	    XFree ((char *)property);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return (motifProxyWindow);
Packit b099d7
}