2516 lines
69 KiB
C
2516 lines
69 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-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 libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: Encaps.c /main/10 1996/10/30 11:10:16 drk $ */
|
|
/************************************<+>*************************************
|
|
****************************************************************************
|
|
*
|
|
* FILE: Encaps.c
|
|
*
|
|
* COMPONENT_NAME: Desktop File Manager (dtfile)
|
|
*
|
|
* Description: Source file for the dialog encapsulation functions.
|
|
*
|
|
* FUNCTIONS: DataChangeCallback
|
|
* DataCloseCallback
|
|
* DialogStructureNotifyHandler
|
|
* IntDialogGetResources
|
|
* IntDialogPutResources
|
|
* SetIconifyState
|
|
* TimerEvent
|
|
* _DtBooleanToString
|
|
* _DtBuildDialog
|
|
* _DtChildPosition
|
|
* _DtDialogGetResources
|
|
* _DtDialogPutResources
|
|
* _DtDimensionToString
|
|
* _DtEncapSetWorkSpaceHints
|
|
* _DtFreeDialogData
|
|
* _DtGetDefaultDialogData
|
|
* _DtGetDialogData
|
|
* _DtGetDialogInstance
|
|
* _DtGetDialogShell
|
|
* _DtGetInstanceData
|
|
* _DtGetResourceDialogData
|
|
* _DtHideDialog
|
|
* _DtInitializeEncapsulation
|
|
* _DtInstallDialog
|
|
* _DtIntToString
|
|
* _DtIsDialogShowing
|
|
* _DtPositionToString
|
|
* _DtShortToString
|
|
* _DtShowBuiltDialog
|
|
* _DtShowDialog
|
|
* _DtStringToString
|
|
* _DtWriteDialogData
|
|
* _DtXmStringTableToString
|
|
* _DtXmStringToString
|
|
* _DtmapCB
|
|
* _DtChangeTo
|
|
*
|
|
* (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
|
|
* (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
|
|
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
|
|
* (c) Copyright 1993, 1994, 1995 Novell, Inc.
|
|
*
|
|
****************************************************************************
|
|
************************************<+>*************************************/
|
|
|
|
|
|
#include <string.h>
|
|
#include <Xm/XmP.h>
|
|
#include <Xm/Xm.h>
|
|
#include <Xm/BulletinB.h>
|
|
#include <Xm/AtomMgr.h>
|
|
#include <Xm/MwmUtil.h>
|
|
#include <Xm/VendorSEP.h>
|
|
#include <Xm/XmPrivate.h> /* _XmStringUngenerate, _XmGetWidgetExtData */
|
|
#include <X11/ShellP.h>
|
|
#include <X11/Shell.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Intrinsic.h>
|
|
|
|
#include <Dt/Wsm.h>
|
|
#include <Dt/DtNlUtils.h>
|
|
|
|
#include "Encaps.h"
|
|
#include "Desktop.h"
|
|
#include "Filter.h"
|
|
#include "FileMgr.h"
|
|
#include "Main.h"
|
|
#include "ModAttr.h"
|
|
#ifdef USE_XINERAMA
|
|
#include <Dt/DtXinerama.h>
|
|
#endif
|
|
|
|
#define MAX_NAME_LIST_SIZE 25
|
|
#define MAX_RESOURCE_LENGTH 256
|
|
|
|
|
|
/* Cache array handling defines, structure, and global statics */
|
|
|
|
#define INCREMENT_SIZE 10
|
|
|
|
|
|
typedef struct _Dialog
|
|
{
|
|
Boolean in_use;
|
|
Widget dialog_widget;
|
|
XtPointer dialog;
|
|
DialogData * dialog_data;
|
|
DialogChangedProc change;
|
|
XtPointer change_client_data;
|
|
DialogClosedProc close;
|
|
XtPointer close_client_data;
|
|
struct _Dialog * next;
|
|
} Dialog;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
DialogClass * class;
|
|
Dialog * dialog_list;
|
|
Boolean cache;
|
|
Boolean destroyPopups;
|
|
} ClassSet;
|
|
|
|
extern int filter_dialog,mod_attr_dialog;
|
|
|
|
static ClassSet * class_set = NULL;
|
|
static int class_set_size = 0;
|
|
static int num_classes = 0;
|
|
static int NumberOfDialogMapped = 0;
|
|
|
|
static char * resourceBuf = NULL;
|
|
static int commonResourceCount = 5;
|
|
static DialogResource commonResources[] =
|
|
{
|
|
{ "displayed", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(DialogInstanceDataPtr, displayed),
|
|
(caddr_t) False, _DtBooleanToString },
|
|
|
|
{ "x", XmRPosition, sizeof(Position),
|
|
XtOffset(DialogInstanceDataPtr, x),
|
|
(caddr_t) 0, _DtPositionToString},
|
|
|
|
{ "y", XmRPosition, sizeof(Position),
|
|
XtOffset(DialogInstanceDataPtr, y),
|
|
(caddr_t) 0, _DtPositionToString },
|
|
|
|
{ "width", XmRHorizontalDimension, sizeof(Dimension),
|
|
XtOffset(DialogInstanceDataPtr, width),
|
|
(caddr_t) 0, _DtDimensionToString },
|
|
|
|
{ "height", XmRVerticalDimension, sizeof(Dimension),
|
|
XtOffset(DialogInstanceDataPtr, height),
|
|
(caddr_t) 0, _DtDimensionToString },
|
|
};
|
|
|
|
static Widget encap_parent_shell;
|
|
|
|
extern int file_mgr_dialog;
|
|
|
|
/* Timer globals */
|
|
/*
|
|
* initialTimeoutLength is used to specify how long to wait before initially
|
|
* kicking of the building of the dialog cache.
|
|
* activeTimeoutLength is used to specify how long to wait after adding
|
|
* a dialog to the cache, before adding the next dialog.
|
|
* idleTimeoutLength is used to specify how long to wait after all dialogs
|
|
* have been built, and the cache is full.
|
|
*/
|
|
int initialTimeoutLength = 180000; /* 3 minutes, in milliseconds */
|
|
int activeTimeoutLength = 30000; /* 30 seconds, in milliseconds */
|
|
int idleTimeoutLength = 900000; /* 15 minutes, in milliseconds */
|
|
|
|
#define TIMER_STARTUP_STATE 0
|
|
#define TIMER_ACTIVE_STATE 1
|
|
#define TIMER_IDLE_STATE 2
|
|
|
|
static int timerState = TIMER_STARTUP_STATE;
|
|
static XtIntervalId timerId = 0;
|
|
|
|
|
|
/*
|
|
* This global is used when positioning a dialog ABOVE (not below) its
|
|
* parent window. The 'y' position is defined to be the 'y' position
|
|
* of the parent, minus the 'height' of the dialog, minus the value
|
|
* assigned to 'topPositionOffset'; this allows the application to control
|
|
* how much, if any, of the parent's title bar is covered.
|
|
*/
|
|
int topPositionOffset = 20;
|
|
|
|
|
|
/******** Static Function Declarations ********/
|
|
|
|
static void DialogStructureNotifyHandler(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XEvent *event );
|
|
static void SetIconifyState(
|
|
Widget shell,
|
|
Boolean iconify) ;
|
|
static void DataChangeCallback(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data) ;
|
|
static void DataCloseCallback(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data) ;
|
|
static void TimerEvent(
|
|
Widget widget,
|
|
XtIntervalId *id) ;
|
|
static void IntDialogGetResources(
|
|
XrmDatabase database,
|
|
char *base,
|
|
DialogResource *resource,
|
|
XrmName *xrmName,
|
|
int nameCount,
|
|
XrmQuark stringQuark) ;
|
|
static void IntDialogPutResources(
|
|
int fd,
|
|
char **nameList,
|
|
char *dialogName,
|
|
char *base,
|
|
DialogResource *resource) ;
|
|
#ifdef USE_XINERAMA
|
|
static Boolean GetXineramaScreenDimensions(
|
|
Widget w,int *xorg, int *yorg, int *width,int *height);
|
|
#endif /* USE_XINERAMA */
|
|
|
|
/******** End Static Function Declarations ********/
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtInitializeEncapsulation
|
|
* This function is used to initialize the dialog encapsulation.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtInitializeEncapsulation(
|
|
Display *display,
|
|
char *name,
|
|
char *class )
|
|
|
|
{
|
|
Arg args[5];
|
|
|
|
/* Create an application shell that will never be */
|
|
/* displayed that is used as a parent of all of the */
|
|
/* dialog created. */
|
|
|
|
encap_parent_shell = XtAppCreateShell (name, class,
|
|
applicationShellWidgetClass,
|
|
display, NULL, 0);
|
|
|
|
/* Supposedly required to be ICCCM complient */
|
|
XtSetArg(args[0], XmNmappedWhenManaged, False);
|
|
XtSetArg(args[1], XmNwidth, 1);
|
|
XtSetArg(args[2], XmNheight, 1);
|
|
XtSetValues(encap_parent_shell, args, 3);
|
|
XtRealizeWidget(encap_parent_shell);
|
|
|
|
/* Get a timer going that is used for auto creation of dialogs. */
|
|
|
|
timerState = TIMER_STARTUP_STATE;
|
|
timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(encap_parent_shell),
|
|
initialTimeoutLength, (XtTimerCallbackProc)
|
|
TimerEvent, (caddr_t) encap_parent_shell);
|
|
|
|
/* Allocate a buffer for writing out resource values */
|
|
resourceBuf = XtMalloc(20);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtInstallDialog
|
|
* This function is used to register a dialog class with the
|
|
* encapsulation functions.
|
|
*
|
|
************************************************************************/
|
|
|
|
int
|
|
_DtInstallDialog(
|
|
DialogClass *dialog_class,
|
|
Boolean cache,
|
|
Boolean destroyPopups )
|
|
|
|
{
|
|
/* Allocate additional dialog cache space if needed */
|
|
|
|
if (num_classes == class_set_size)
|
|
{
|
|
class_set_size += INCREMENT_SIZE;
|
|
class_set =
|
|
(ClassSet *) XtRealloc ((char *)class_set,
|
|
sizeof (ClassSet) * class_set_size);
|
|
}
|
|
|
|
class_set[num_classes].class = dialog_class;
|
|
class_set[num_classes].dialog_list = NULL;
|
|
class_set[num_classes].cache = cache;
|
|
class_set[num_classes].destroyPopups = destroyPopups;
|
|
|
|
num_classes++;
|
|
|
|
return (num_classes - 1);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetDialogData
|
|
* This function is used to get a structure containing the
|
|
* current dialog data for a particular dialog instance.
|
|
*
|
|
************************************************************************/
|
|
|
|
DialogData *
|
|
_DtGetDialogData(
|
|
DialogData *dialog_data )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
DialogData * new_data;
|
|
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog_data == dialog_data)
|
|
{
|
|
new_data = (DialogData *) XtMalloc (sizeof (DialogData));
|
|
|
|
new_data->type = dialog->dialog_data->type;
|
|
new_data->data = NULL;
|
|
if (class_set[new_data->type].class->get_values)
|
|
{
|
|
new_data->data =
|
|
(*(class_set[new_data->type].class->get_values)) (dialog->dialog);
|
|
}
|
|
|
|
return (new_data);
|
|
}
|
|
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetDefaultDialogData
|
|
* This function is used to get a structure containing the
|
|
* default data for a particular dialog type.
|
|
*
|
|
************************************************************************/
|
|
|
|
DialogData *
|
|
_DtGetDefaultDialogData(
|
|
int dialog_type )
|
|
|
|
|
|
{
|
|
DialogData * dialog_data;
|
|
|
|
dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
|
|
|
|
dialog_data->type = dialog_type;
|
|
dialog_data->data = (*(class_set[dialog_type].class->get_default_values))();
|
|
|
|
return (dialog_data);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetResourceDialogData
|
|
* This function is used to get a structure containing the
|
|
* data for a particular dialog type from a resource data base.
|
|
*
|
|
************************************************************************/
|
|
|
|
DialogData *
|
|
_DtGetResourceDialogData(
|
|
int dialog_type,
|
|
XrmDatabase data_base,
|
|
char **name_list )
|
|
|
|
{
|
|
DialogData * dialog_data;
|
|
|
|
dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
|
|
|
|
dialog_data->type = dialog_type;
|
|
dialog_data->data = (*(class_set[dialog_type].class->get_resource_values))
|
|
(data_base, name_list);
|
|
|
|
return (dialog_data);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtShowDialog
|
|
* This functions is used to display an instance of a dialog with
|
|
* the provided data. The functions and data to be set back to
|
|
* the application upon change or close of the dialog is also
|
|
* provided as parameters.
|
|
*
|
|
************************************************************************/
|
|
void
|
|
_DtShowDialog(
|
|
Widget parent,
|
|
Widget map_parent,
|
|
XtPointer top_rec,
|
|
DialogData *dialog_data,
|
|
DialogChangedProc change_proc,
|
|
XtPointer change_data,
|
|
DialogClosedProc close_proc,
|
|
XtPointer close_data,
|
|
char *workspaces,
|
|
Boolean iconify_state,
|
|
Boolean ignoreCache,
|
|
char * title,
|
|
XClassHint * classHints )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
int dialog_type, n;
|
|
DialogInstanceData * instance_data;
|
|
char geometry[40];
|
|
Arg args[5];
|
|
Boolean doCenter = False;
|
|
Boolean doParentRelativePositioning = False;
|
|
int availableDialogCount;
|
|
|
|
|
|
/* See if there is a cached, unused dialog of the correct type. */
|
|
|
|
dialog_type = dialog_data->type;
|
|
dialog = NULL;
|
|
|
|
if (!ignoreCache)
|
|
{
|
|
Dialog * availableDialog;
|
|
|
|
availableDialog = class_set[dialog_type].dialog_list;
|
|
availableDialogCount = 0;
|
|
|
|
/*
|
|
* In addition to looking for an available dialog in the cache to use,
|
|
* we also want to count up the number of unused dialogs in the cache.
|
|
* This lets us know it we need to restart the timer, to again build
|
|
* up the cache.
|
|
*/
|
|
while (availableDialog != NULL)
|
|
{
|
|
if (availableDialog->in_use == False)
|
|
{
|
|
if (dialog == NULL)
|
|
dialog = availableDialog;
|
|
else
|
|
availableDialogCount++;
|
|
}
|
|
availableDialog = availableDialog->next;
|
|
}
|
|
}
|
|
|
|
if (dialog == NULL)
|
|
{
|
|
dialog = (Dialog *) XtMalloc (sizeof (Dialog));
|
|
|
|
(*(class_set[dialog_type].class->create))
|
|
(XtDisplay (encap_parent_shell), encap_parent_shell,
|
|
&(dialog->dialog_widget), &dialog->dialog);
|
|
|
|
/* if this is a File Manager view we want to update the headers
|
|
* (i.e icon_path, current_directory, status_line), now so that they
|
|
* don't get managed up front. This is to make the Application
|
|
* Manager (toolbox) happy.
|
|
*/
|
|
if(dialog_type == file_mgr_dialog)
|
|
UpdateHeaders(dialog->dialog, dialog_data->data, False);
|
|
|
|
/* Add the change and close callbacks into the dialog */
|
|
|
|
if (class_set[dialog_type].class->install_change_callback)
|
|
(*(class_set[dialog_type].class->install_change_callback))
|
|
(dialog->dialog, DataChangeCallback, (XtPointer)dialog);
|
|
|
|
if (class_set[dialog_type].class->install_close_callback)
|
|
(*(class_set[dialog_type].class->install_close_callback))
|
|
(dialog->dialog, DataCloseCallback, (XtPointer)dialog);
|
|
|
|
dialog->next = class_set[dialog_type].dialog_list;
|
|
class_set[dialog_type].dialog_list = dialog;
|
|
}
|
|
else
|
|
{
|
|
if(dialog_type == mod_attr_dialog)
|
|
{
|
|
ModAttrRec *mr = (ModAttrRec *)dialog->dialog;
|
|
ResetFlag(NULL,mr->ok);
|
|
ResetFlag(NULL,mr->cancel);
|
|
}
|
|
else if(dialog_type == filter_dialog)
|
|
{
|
|
FilterRec *fr = (FilterRec *)dialog->dialog;
|
|
ResetFlag(NULL,fr->ok);
|
|
ResetFlag(NULL,fr->close);
|
|
}
|
|
}
|
|
|
|
if ((!ignoreCache) && (class_set[dialog_type].cache) &&
|
|
(availableDialogCount < 1) && (timerState == TIMER_IDLE_STATE))
|
|
{
|
|
/*
|
|
* We need to reset the cache building timer, so that it gets kicked
|
|
* off quickly, instead of after the longer idle delay.
|
|
*/
|
|
if (timerId)
|
|
XtRemoveTimeOut(timerId);
|
|
timerState = TIMER_ACTIVE_STATE;
|
|
timerId = XtAppAddTimeOut(
|
|
XtWidgetToApplicationContext(encap_parent_shell),
|
|
activeTimeoutLength, (XtTimerCallbackProc) TimerEvent,
|
|
(XtPointer) encap_parent_shell);
|
|
}
|
|
|
|
/*
|
|
* Set pointer to top dialog data in child of the shell.
|
|
* This is needed to get help to work.
|
|
*/
|
|
if (top_rec == NULL)
|
|
top_rec = dialog->dialog;
|
|
XtSetArg(args[0], XmNuserData, top_rec);
|
|
XtSetValues(dialog->dialog_widget, args, 1);
|
|
|
|
/* Need to add the map callback in relation to the parent */
|
|
if (class_set[dialog_type].class->map)
|
|
{
|
|
/*
|
|
* The map_parent parameter gives us the ability to position
|
|
* the dialog relative to a window which is not the transientFor
|
|
* parent. This is used for the audio preview dialog.
|
|
*/
|
|
if (map_parent == NULL)
|
|
map_parent = parent;
|
|
|
|
(*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
|
|
}
|
|
|
|
|
|
/* Set the dialog structure fields to the parameter data. */
|
|
|
|
dialog->in_use = True;
|
|
dialog->dialog_data = dialog_data;
|
|
dialog->change = change_proc;
|
|
dialog->change_client_data = change_data;
|
|
dialog->close = close_proc;
|
|
dialog->close_client_data = close_data;
|
|
|
|
|
|
instance_data = (DialogInstanceData *) dialog_data->data;
|
|
|
|
/* If a special title has been specified, we need to set it now */
|
|
if (title)
|
|
{
|
|
XtSetArg(args[0], XmNtitle, title);
|
|
XtSetValues(XtParent(dialog->dialog_widget), args, 1);
|
|
}
|
|
|
|
/* If this is a top level shell, get it realized */
|
|
|
|
if (XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass))
|
|
{
|
|
if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
(void) sprintf (geometry, "=%dx%d+%d+%d",
|
|
instance_data->width, instance_data->height,
|
|
instance_data->x, instance_data->y);
|
|
|
|
XtSetArg (args[0], XmNgeometry, geometry);
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, 1);
|
|
}
|
|
else if ((instance_data->width != 0) && (instance_data->height != 0))
|
|
{
|
|
n=0;
|
|
XtSetArg (args[n], XmNwidth, instance_data->width); n++;
|
|
XtSetArg (args[n], XmNheight, instance_data->height); n++;
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, n);
|
|
}
|
|
|
|
/* Toggle mappedWhenManaged to false */
|
|
XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
|
|
XtRealizeWidget (XtParent(dialog->dialog_widget));
|
|
|
|
/* Set the proper workspaces if needed */
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
|
|
/* Set any application-specified class hints for the window */
|
|
if (classHints)
|
|
{
|
|
XSetClassHint(XtDisplay(dialog->dialog_widget),
|
|
XtWindow(XtParent(dialog->dialog_widget)),
|
|
classHints);
|
|
}
|
|
|
|
/* Set the iconify state */
|
|
SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
|
|
|
|
/* Map the window */
|
|
XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), True);
|
|
XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
|
|
XSync(XtDisplay(dialog->dialog_widget), False);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
|
|
|
|
wm->wm.size_hints.flags |= USPosition;
|
|
XtSetArg (args[0], XmNx, instance_data->x);
|
|
XtSetArg (args[1], XmNy, instance_data->y);
|
|
XtSetArg (args[2], XmNwidth, instance_data->width);
|
|
XtSetArg (args[3], XmNheight, instance_data->height);
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, 4);
|
|
}
|
|
else if ((instance_data->width != 0) && (instance_data->height != 0))
|
|
{
|
|
n=0;
|
|
XtSetArg (args[n], XmNwidth, instance_data->width); n++;
|
|
XtSetArg (args[n], XmNheight, instance_data->height); n++;
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, n);
|
|
}
|
|
|
|
/* Set the proper workspaces if needed */
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
|
|
/* Set any application-specified class hints for the window */
|
|
if (classHints)
|
|
{
|
|
XSetClassHint(XtDisplay(dialog->dialog_widget),
|
|
XtWindow(XtParent(dialog->dialog_widget)),
|
|
classHints);
|
|
}
|
|
|
|
/* Set the iconify state */
|
|
SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
|
|
|
|
/* Map the window */
|
|
XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
XtSetArg (args[0], XmNx, instance_data->x);
|
|
XtSetArg (args[1], XmNy, instance_data->y);
|
|
XtSetArg (args[2], XmNwidth, instance_data->width);
|
|
XtSetArg (args[3], XmNheight, instance_data->height);
|
|
XtSetArg (args[4], XmNdefaultPosition, False);
|
|
XtSetValues (dialog->dialog_widget, args, 5);
|
|
XtRealizeWidget (dialog->dialog_widget);
|
|
}
|
|
else
|
|
{
|
|
XtSetArg (args[0], XmNdefaultPosition, False);
|
|
XtSetValues (dialog->dialog_widget, args, 1);
|
|
|
|
XtRealizeWidget (dialog->dialog_widget);
|
|
|
|
if (parent)
|
|
{
|
|
/* Position relative to the parent dialog */
|
|
/*
|
|
* Must be done after the set_values call, since the dialog
|
|
* may get forced to a different size.
|
|
*/
|
|
doParentRelativePositioning = True;
|
|
}
|
|
else
|
|
{
|
|
/* Center in the display */
|
|
/*
|
|
* Must be done after the set_values call, since the dialog
|
|
* may get forced to a different size.
|
|
*/
|
|
doCenter = True;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Dialogs with no controlling parent window, need to have their
|
|
* own workspace perperty set, if some workspaces have been requested.
|
|
*/
|
|
if ((parent == NULL) && workspaces)
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
}
|
|
|
|
|
|
/* Set Values onto the dialog to set it to the correct data. */
|
|
|
|
(*(class_set[dialog_data->type].class->set_values))
|
|
(dialog->dialog, dialog_data->data);
|
|
|
|
/*
|
|
* These two adjustments MUST be done AFTER the dialog's SetValues()
|
|
* procedure is called. This is due to the fact that the setvalues
|
|
* may cause the dialog size to change, and since both of the following
|
|
* positioning algorithms are dependent upon the dialog size, we want
|
|
* to make sure that the correct size is used.
|
|
*/
|
|
if (doCenter)
|
|
{
|
|
XtSetArg (args[0], XmNx,
|
|
(Dimension)(WidthOfScreen(XtScreen(dialog->dialog_widget)) -
|
|
dialog->dialog_widget->core.width) / (Dimension)2);
|
|
XtSetArg (args[1], XmNy,
|
|
(Dimension)(HeightOfScreen(XtScreen(dialog->dialog_widget)) -
|
|
dialog->dialog_widget->core.height) / (Dimension)2);
|
|
XtSetValues (dialog->dialog_widget, args, 2);
|
|
}
|
|
else if (doParentRelativePositioning)
|
|
{
|
|
XtSetArg (args[0], XmNx,
|
|
parent->core.x +
|
|
(Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
|
|
XtSetArg (args[1], XmNy,
|
|
parent->core.y +
|
|
(Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
|
|
XtSetValues (XtParent(dialog->dialog_widget), args, 2);
|
|
}
|
|
|
|
|
|
/* Fix up the transient-for windowing information so that */
|
|
/* the window manager will shuffle and iconify as a group */
|
|
|
|
if (parent != NULL)
|
|
{
|
|
if (XtIsRealized(parent))
|
|
{
|
|
XSetTransientForHint (XtDisplay (parent),
|
|
XtWindow (XtParent (dialog->dialog_widget)),
|
|
XtWindow (parent));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass))
|
|
{
|
|
XSetTransientForHint (XtDisplay (encap_parent_shell),
|
|
XtWindow (XtParent (dialog->dialog_widget)),
|
|
XtWindow (encap_parent_shell));
|
|
}
|
|
}
|
|
|
|
|
|
/* Display the dialogs, application shells are displayed above. */
|
|
|
|
if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass)))
|
|
{
|
|
XtManageChild (dialog->dialog_widget);
|
|
}
|
|
|
|
|
|
/* Set the dialog instance data to indicate that the dialog */
|
|
/* is displayed. */
|
|
|
|
((DialogInstanceData *) (dialog_data->data))->displayed = True;
|
|
|
|
|
|
/* Give the dialog a chance to set its focus widget, if necessary */
|
|
|
|
if (class_set[dialog_data->type].class->set_focus)
|
|
{
|
|
(*(class_set[dialog_data->type].class->set_focus))
|
|
(dialog->dialog, dialog_data->data);
|
|
}
|
|
|
|
|
|
|
|
XtAddEventHandler( XtParent( dialog->dialog_widget ),
|
|
StructureNotifyMask,
|
|
False,
|
|
(XtEventHandler)DialogStructureNotifyHandler,
|
|
NULL );
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtHideDialog
|
|
* This function is used to undisplay a dialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtHideDialog(
|
|
DialogData *dialog_data,
|
|
Boolean call_callbacks )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
DialogData * new_data;
|
|
CorePart * core;
|
|
int i;
|
|
|
|
|
|
/* Find the dialog and then hide it. */
|
|
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if ((dialog->dialog_data &&
|
|
dialog->dialog_data == dialog_data) && dialog->in_use == True)
|
|
|
|
{
|
|
|
|
/* Free up any dialogs attached to the dialog widget */
|
|
|
|
if(class_set[dialog_data->type].destroyPopups)
|
|
{
|
|
core = (CorePart *) (XtParent (dialog->dialog_widget));
|
|
|
|
for (i = core->num_popups - 1; i >= 0; i--)
|
|
XtDestroyWidget (core->popup_list[i]);
|
|
}
|
|
|
|
|
|
/* Get the dialog down, invoke the close callbacks, and */
|
|
/* take it out of use. */
|
|
|
|
if (XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass))
|
|
{
|
|
ShellWidget shell_widget;
|
|
|
|
/*
|
|
* If we had been iconified, then our popped_up flag will
|
|
* have been cleared by the vendor shell. When we call
|
|
* XtPopdown(), it will see that we are no longer popped
|
|
* up, and will not notify the window manager that our
|
|
* icon should be removed; this can cause a subsequent
|
|
* core dump if the user later tries to deiconify the window.
|
|
* This fix should not be necessary once the toolkit is
|
|
* fixed to properly track the shell's state.
|
|
*/
|
|
shell_widget = (ShellWidget) XtParent(dialog->dialog_widget);
|
|
shell_widget->shell.popped_up = True;
|
|
|
|
XtPopdown ((Widget)shell_widget);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* The following is for the condition described above. However,
|
|
* for a dialog shell, what happens it that the 'managed' flag
|
|
* was set to 'False' when the windows were iconified (apparently
|
|
* by the dialog shell), and when we tell the intrinsics to
|
|
* really unmanage the child, it thinks it already has, so
|
|
* nothing happens; as a result, the dialog shell is left with
|
|
* its 'popped_up' flag set to 'True'. The next time we try
|
|
* to post this dialog, the intrinsics think that it is already
|
|
* up, so it does nothing.
|
|
*/
|
|
dialog->dialog_widget->core.managed = True;
|
|
XtUnmanageChild (dialog->dialog_widget);
|
|
}
|
|
|
|
|
|
/* Set the dialog data to hidden */
|
|
|
|
((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
|
|
|
|
|
|
if (call_callbacks && dialog->close)
|
|
{
|
|
new_data = (DialogData *) XtMalloc (sizeof (DialogData));
|
|
|
|
new_data->type = dialog->dialog_data->type;
|
|
new_data->data = NULL;
|
|
if (class_set[new_data->type].class->get_values)
|
|
{
|
|
new_data->data =
|
|
(*(class_set[new_data->type].class->get_values))(dialog->dialog);
|
|
}
|
|
|
|
dialog->in_use = False;
|
|
if (new_data->data)
|
|
((DialogInstanceData *) (new_data->data))->displayed = False;
|
|
|
|
(*(dialog->close))
|
|
(dialog->close_client_data, dialog->dialog_data, new_data);
|
|
}
|
|
else
|
|
{
|
|
dialog->in_use = False;
|
|
((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
dialog = dialog->next;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetDialogShell
|
|
* This function is used return the shell widget of a dialog that
|
|
* is currently displayed.
|
|
*
|
|
************************************************************************/
|
|
|
|
Widget
|
|
_DtGetDialogShell(
|
|
DialogData *dialog_data )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
|
|
|
|
/* Find the dialog and then return the shell. */
|
|
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog_data == dialog_data)
|
|
return (dialog->dialog_widget);
|
|
else
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetDialogInstance
|
|
* This function is used return the dialog instance structure
|
|
* of a currently in use dialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
XtPointer
|
|
_DtGetDialogInstance(
|
|
DialogData *dialog_data )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
|
|
|
|
/* Find the dialog and then return the instance */
|
|
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog_data && dialog->dialog_data == dialog_data)
|
|
return (dialog->dialog);
|
|
else
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtGetInstanceData
|
|
* This function is used return the dialog data structure contained
|
|
* within the cache structure referenced by instance.
|
|
*
|
|
************************************************************************/
|
|
|
|
DialogData *
|
|
_DtGetInstanceData(
|
|
XtPointer instance )
|
|
|
|
{
|
|
int i;
|
|
Dialog * dialog;
|
|
|
|
|
|
/* Find the dialog and then return the instance */
|
|
|
|
for (i = 0; i < num_classes; i++)
|
|
{
|
|
dialog = class_set[i].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog == instance && dialog->in_use == True)
|
|
return (dialog->dialog_data);
|
|
else
|
|
dialog = dialog->next;
|
|
}
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtIsDialogShowing
|
|
* This function is used return a boolean indicating whether the
|
|
* a dialog is displayed which contains the dialog data.
|
|
* of a currently in use dialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
Boolean
|
|
_DtIsDialogShowing(
|
|
DialogData *dialog_data )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
|
|
|
|
/* Find the dialog and then return the instance */
|
|
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->in_use && dialog->dialog_data == dialog_data)
|
|
return (True);
|
|
else
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
return (False);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtWriteDialogData
|
|
* This function is used to write, as resources, the data
|
|
* for a dialog contained in dialog_data to the open file fd.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtWriteDialogData(
|
|
DialogData *dialog_data,
|
|
int fd,
|
|
char **name_list )
|
|
|
|
{
|
|
if (dialog_data != NULL)
|
|
(*(class_set[dialog_data->type].class->write_resource_values))
|
|
(dialog_data, fd, name_list);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtFreeDialogData
|
|
* This function is used to free up the data space allocated
|
|
* by a dialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtFreeDialogData(
|
|
DialogData *dialog_data )
|
|
|
|
{
|
|
if (dialog_data != NULL)
|
|
{
|
|
(*(class_set[dialog_data->type].class->free_values)) (dialog_data->data);
|
|
XtFree ((char *) dialog_data);
|
|
dialog_data = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtDialogGetResources
|
|
* This function accesses data_base to extract the resource set
|
|
* described by the resoruces array. Resources values are
|
|
* converted to the proper type and defaults are used if not
|
|
* data is found in the resource data base.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtDialogGetResources(
|
|
XrmDatabase database,
|
|
char **name_list,
|
|
char *dialog_name,
|
|
char *base,
|
|
DialogResource *resources,
|
|
int resource_count )
|
|
|
|
{
|
|
XrmName xrmName[MAX_NAME_LIST_SIZE];
|
|
XrmQuark stringQuark;
|
|
int nameCount;
|
|
int i;
|
|
|
|
/* Build the quarkified name list from name_list and dialog_name */
|
|
/* provided by the calling procedure. */
|
|
|
|
nameCount = 0;
|
|
if (name_list != NULL)
|
|
{
|
|
while (name_list[nameCount] != NULL)
|
|
{
|
|
xrmName[nameCount] = XrmStringToQuark (name_list[nameCount]);
|
|
nameCount++;
|
|
}
|
|
}
|
|
|
|
if (dialog_name)
|
|
xrmName[nameCount] = XrmStringToQuark (dialog_name);
|
|
else
|
|
nameCount--;
|
|
|
|
xrmName[nameCount + 2] = 0;
|
|
stringQuark = XrmStringToQuark (XmRString);
|
|
|
|
|
|
/* Load the common dialog size/position resources */
|
|
for (i = 0; i < resource_count; i++)
|
|
{
|
|
IntDialogGetResources(database, base, resources + i, xrmName, nameCount,
|
|
stringQuark);
|
|
}
|
|
|
|
/*
|
|
* Load the dialog specific resources. If no value found, use the default.
|
|
*/
|
|
for (i = 0; i < commonResourceCount; i++)
|
|
{
|
|
IntDialogGetResources(database, base, commonResources + i, xrmName,
|
|
nameCount, stringQuark);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* This internal function does the real work of loading a single resource
|
|
* value. If the value is not found in the resource database, then the
|
|
* specified default value is used.
|
|
*/
|
|
|
|
static void
|
|
IntDialogGetResources(
|
|
XrmDatabase database,
|
|
char *base,
|
|
DialogResource *resource,
|
|
XrmName *xrmName,
|
|
int nameCount,
|
|
XrmQuark stringQuark )
|
|
|
|
{
|
|
XrmRepresentation repType;
|
|
XrmValue value;
|
|
XrmValue convertedValue;
|
|
char charVal;
|
|
short shortVal;
|
|
int intVal;
|
|
long longVal;
|
|
|
|
{
|
|
xrmName[nameCount + 1] = XrmStringToQuark (resource->name);
|
|
|
|
if (XrmQGetResource (database, xrmName, xrmName, &repType, &value))
|
|
{
|
|
if (repType == stringQuark)
|
|
if (strcmp (resource->type, XmRString) != 0)
|
|
{
|
|
XtConvert (encap_parent_shell, XmRString, &value,
|
|
resource->type, &convertedValue);
|
|
}
|
|
else
|
|
{
|
|
*((char **)(base + resource->offset)) = (char *)value.addr;
|
|
return;
|
|
}
|
|
else
|
|
convertedValue.addr = NULL;
|
|
|
|
}
|
|
else
|
|
convertedValue.addr = NULL;
|
|
|
|
|
|
/* Set the converted value address pointer and value to */
|
|
/* the proper default value if the addr is NULL. */
|
|
|
|
if (convertedValue.addr == NULL)
|
|
{
|
|
if (resource->size == sizeof(char))
|
|
{
|
|
charVal = (char)(XtArgVal)resource->default_value;
|
|
convertedValue.addr = (caddr_t) &charVal;
|
|
}
|
|
else if (resource->size == sizeof(short))
|
|
{
|
|
shortVal = (short)(XtArgVal)resource->default_value;
|
|
convertedValue.addr = (caddr_t) &shortVal;
|
|
}
|
|
else if (resource->size == sizeof(int))
|
|
{
|
|
intVal = (int)(XtArgVal)resource->default_value;
|
|
convertedValue.addr = (caddr_t) &intVal;
|
|
}
|
|
else
|
|
{
|
|
longVal = (long)(XtArgVal)resource->default_value;
|
|
convertedValue.addr = (caddr_t) &longVal;
|
|
}
|
|
}
|
|
|
|
|
|
/* Stuff the converted value into the calling functions */
|
|
/* structure according to the size of the piece of data. */
|
|
|
|
if (resource->size == sizeof(char))
|
|
*((char *)(base + resource->offset)) = *((char *)convertedValue.addr);
|
|
else if (resource->size == sizeof(short))
|
|
*((short *)(base + resource->offset))= *((short *)convertedValue.addr);
|
|
else if (resource->size == sizeof(int))
|
|
*((int *)(base + resource->offset))= *((int *)convertedValue.addr);
|
|
else
|
|
*((long *)(base + resource->offset)) = *((long *)convertedValue.addr);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtDialogPutResources
|
|
* This function writes a resource set to a file.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtDialogPutResources(
|
|
int fd,
|
|
char **nameList,
|
|
char *dialogName,
|
|
char *base,
|
|
DialogResource *resources,
|
|
int resourceCount )
|
|
|
|
{
|
|
int i;
|
|
DialogInstanceData * dialogInstanceData;
|
|
|
|
/*
|
|
* Write out the common dialog size/position resources, only if the
|
|
* dialog is currently displayed.
|
|
*/
|
|
dialogInstanceData = (DialogInstanceData *)base;
|
|
if (dialogInstanceData->displayed)
|
|
{
|
|
for (i = 0; i < commonResourceCount; i++)
|
|
{
|
|
IntDialogPutResources(fd, nameList, dialogName, base,
|
|
commonResources + i);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Loop through the dialog specific resources, write the name list and
|
|
* resource name.
|
|
*/
|
|
for (i = 0; i < resourceCount; i++)
|
|
IntDialogPutResources( fd, nameList, dialogName, base, resources + i);
|
|
}
|
|
|
|
|
|
/*
|
|
* This internal function does the real work involved in writing a single
|
|
* resource out to a session file.
|
|
*/
|
|
|
|
static void
|
|
IntDialogPutResources(
|
|
int fd,
|
|
char **nameList,
|
|
char *dialogName,
|
|
char *base,
|
|
DialogResource *resource )
|
|
|
|
{
|
|
static char outBuf[MAX_RESOURCE_LENGTH];
|
|
int nameCount;
|
|
|
|
outBuf[0] = '\0';
|
|
|
|
(void) strcat (outBuf, "*");
|
|
|
|
nameCount = 0;
|
|
if (nameList != NULL)
|
|
{
|
|
while (nameList[nameCount] != NULL)
|
|
{
|
|
(void) strcat (outBuf, nameList[nameCount]);
|
|
(void) strcat (outBuf, ".");
|
|
nameCount++;
|
|
}
|
|
}
|
|
|
|
if (dialogName != NULL)
|
|
{
|
|
(void) strcat (outBuf, dialogName);
|
|
(void) strcat (outBuf, ".");
|
|
}
|
|
|
|
(void) strcat (outBuf, resource->name);
|
|
(void) strcat (outBuf, ": ");
|
|
|
|
(*(resource->write_resource))
|
|
(fd, (XtPointer) (base + resource->offset), outBuf);
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
************************************************************************
|
|
*
|
|
* Internal functions
|
|
*
|
|
************************************************************************
|
|
************************************************************************/
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtEncapSetWorkSpaceHints
|
|
* This function sets a given shell to a given set(s) of
|
|
* workspaces.
|
|
*
|
|
************************************************************************/
|
|
void
|
|
_DtEncapSetWorkSpaceHints(
|
|
Widget shell,
|
|
char *workspaces )
|
|
|
|
{
|
|
char * ptr;
|
|
Atom * workspace_atoms = NULL;
|
|
int num_workspaces=0;
|
|
|
|
if (workspaces)
|
|
{
|
|
do
|
|
{
|
|
ptr = DtStrchr (workspaces, '*');
|
|
|
|
if (ptr != NULL) *ptr = '\0';
|
|
|
|
workspace_atoms = (Atom *) XtRealloc ((char *)workspace_atoms,
|
|
sizeof (Atom) * (num_workspaces + 1));
|
|
|
|
workspace_atoms[num_workspaces] =
|
|
XmInternAtom (XtDisplay(shell), workspaces, True);
|
|
|
|
num_workspaces++;
|
|
|
|
if (ptr != NULL)
|
|
{
|
|
*ptr = '*';
|
|
workspaces = ptr + 1;
|
|
}
|
|
} while (ptr != NULL);
|
|
|
|
DtWsmSetWorkspacesOccupied (XtDisplay(shell), XtWindow (shell), workspace_atoms,
|
|
num_workspaces);
|
|
|
|
XtFree ((char *) workspace_atoms);
|
|
workspace_atoms = NULL;
|
|
}
|
|
else
|
|
{
|
|
Window rootWindow;
|
|
Atom pCurrent;
|
|
Screen *currentScreen;
|
|
int screen;
|
|
char *workspace_name;
|
|
|
|
/*
|
|
* Since no specific workspaces were specified, we will force the
|
|
* dialog to the current workspace.
|
|
*/
|
|
screen = XDefaultScreen(XtDisplay(shell));
|
|
currentScreen = XScreenOfDisplay(XtDisplay(shell), screen);
|
|
rootWindow = RootWindowOfScreen(currentScreen);
|
|
|
|
if(DtWsmGetCurrentWorkspace(XtDisplay(shell), rootWindow, &pCurrent) ==
|
|
Success)
|
|
{
|
|
DtWsmSetWorkspacesOccupied(XtDisplay(shell), XtWindow (shell), &pCurrent, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* SetIconifyState
|
|
* This function sets a given shell to a given iconify state.
|
|
* (e.g. Mapped or iconified)
|
|
*
|
|
************************************************************************/
|
|
static void
|
|
SetIconifyState(
|
|
Widget shell,
|
|
Boolean iconify )
|
|
|
|
{
|
|
Arg args[1];
|
|
XWMHints *wmhints;
|
|
|
|
if (iconify)
|
|
{
|
|
/* add the iconify hint to the current shell */
|
|
XtSetArg(args[0], XmNinitialState, IconicState);
|
|
XtSetValues(shell, args, 1);
|
|
}
|
|
else
|
|
{
|
|
/* Remove the iconify hint from the current shell */
|
|
wmhints = XGetWMHints(XtDisplay(shell), XtWindow(shell));
|
|
wmhints->flags |= IconWindowHint;
|
|
wmhints->initial_state = NormalState;
|
|
XSetWMHints(XtDisplay(shell), XtWindow(shell), wmhints);
|
|
XFree(wmhints);
|
|
}
|
|
|
|
}
|
|
/************************************************************************
|
|
*
|
|
* DataChangeCallback
|
|
* This callback is invoked from a dialog upon an action on the
|
|
* dialog that means that the data within the dialog has been
|
|
* changed.
|
|
*
|
|
************************************************************************/
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
DataChangeCallback(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
|
|
{
|
|
Dialog * dialog = (Dialog *) client_data;
|
|
DialogData * new_data;
|
|
|
|
new_data = (DialogData *) XtMalloc (sizeof (DialogData));
|
|
|
|
new_data->type = dialog->dialog_data->type;
|
|
new_data->data = NULL;
|
|
if (class_set[new_data->type].class->get_values)
|
|
{
|
|
new_data->data = (*(class_set[new_data->type].class->get_values))
|
|
(dialog->dialog);
|
|
}
|
|
|
|
if (dialog->change)
|
|
(*(dialog->change))
|
|
(dialog->change_client_data, dialog->dialog_data, new_data, call_data);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* DataCloseCallback
|
|
* This callback is invoked from a dialog upon an action on the
|
|
* dialog that means the dialog has been closed.
|
|
*
|
|
************************************************************************/
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
DataCloseCallback(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
|
|
|
|
{
|
|
Dialog * dialog = (Dialog *) client_data;
|
|
|
|
if(RecheckFlag(NULL,widget)) /* cancel flag already set, just return */
|
|
return;
|
|
_DtHideDialog (dialog->dialog_data, True);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* TimerEvent
|
|
* This action function is called upon the encapsulations
|
|
* timeout going off. Its function is to precreate and destroy
|
|
* extra dialogs.
|
|
*
|
|
************************************************************************/
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
TimerEvent(
|
|
Widget widget,
|
|
XtIntervalId *id )
|
|
|
|
{
|
|
int i;
|
|
Dialog * dialog;
|
|
Dialog * prev_dialog;
|
|
int count;
|
|
|
|
|
|
/* First pass through the dialog set to see if any */
|
|
/* need to be created. This is based on having 0 */
|
|
/* not in use dialogs of each type. */
|
|
|
|
for (i = 0; i < num_classes; i++)
|
|
{
|
|
dialog = class_set[i].dialog_list;
|
|
|
|
/* Only attempt to cache dialogs requesting this feature */
|
|
if (!class_set[i].cache)
|
|
continue;
|
|
|
|
while (dialog != NULL)
|
|
if (dialog->in_use == False)
|
|
break;
|
|
else
|
|
dialog = dialog->next;
|
|
|
|
if (dialog == NULL)
|
|
{
|
|
dialog = (Dialog *) XtMalloc (sizeof (Dialog));
|
|
|
|
(*(class_set[i].class->create))
|
|
(XtDisplay (encap_parent_shell), encap_parent_shell,
|
|
&(dialog->dialog_widget), &dialog->dialog);
|
|
|
|
|
|
/* Add the change and close callbacks into the dialog */
|
|
|
|
if (class_set[i].class->install_change_callback)
|
|
(*(class_set[i].class->install_change_callback))
|
|
(dialog->dialog, DataChangeCallback, (XtPointer)dialog);
|
|
|
|
if (class_set[i].class->install_close_callback)
|
|
(*(class_set[i].class->install_close_callback))
|
|
(dialog->dialog, DataCloseCallback, (XtPointer)dialog);
|
|
|
|
|
|
dialog->next = class_set[i].dialog_list;
|
|
class_set[i].dialog_list = dialog;
|
|
|
|
dialog->in_use = False;
|
|
|
|
timerState = TIMER_ACTIVE_STATE;
|
|
timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
|
|
activeTimeoutLength,
|
|
(XtTimerCallbackProc) TimerEvent,
|
|
(XtPointer) widget);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/* Pass through the dialog set to see if any need to be destroyed */
|
|
/* This is based on having more than 1 not in use dialog of a type. */
|
|
|
|
for (i = 0; i < num_classes; i++)
|
|
{
|
|
dialog = class_set[i].dialog_list;
|
|
count = 0;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->in_use == False)
|
|
count++;
|
|
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
if (count > 1)
|
|
{
|
|
dialog = class_set[i].dialog_list;
|
|
|
|
if (dialog->in_use == False)
|
|
class_set[i].dialog_list = dialog->next;
|
|
else
|
|
{
|
|
prev_dialog = class_set[i].dialog_list;
|
|
dialog = dialog->next;
|
|
|
|
while (dialog->in_use == True)
|
|
{
|
|
prev_dialog = dialog;
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
prev_dialog->next = dialog->next;
|
|
}
|
|
|
|
(*(class_set[i].class->destroy)) (dialog->dialog);
|
|
XtFree ((char *) dialog);
|
|
dialog = NULL;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
timerState = TIMER_IDLE_STATE;
|
|
timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
|
|
idleTimeoutLength,
|
|
(XtTimerCallbackProc)TimerEvent,
|
|
(XtPointer)widget);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
************************************************************************
|
|
*
|
|
* Externed Type to String Converters and writers
|
|
*
|
|
************************************************************************
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtIntToString(
|
|
int fd,
|
|
int *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
(void) sprintf (resourceBuf, "%d", *value);
|
|
_DtStringToString( fd, &resourceBuf, out_buf );
|
|
}
|
|
|
|
|
|
void
|
|
_DtShortToString(
|
|
int fd,
|
|
short *value,
|
|
char *out_buf )
|
|
|
|
|
|
{
|
|
(void) sprintf (resourceBuf, "%d", *value);
|
|
_DtStringToString( fd, &resourceBuf, out_buf );
|
|
}
|
|
|
|
|
|
|
|
void
|
|
_DtPositionToString(
|
|
int fd,
|
|
Position *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
(void) sprintf (resourceBuf, "%d", *value);
|
|
_DtStringToString( fd, &resourceBuf, out_buf );
|
|
}
|
|
|
|
|
|
|
|
void
|
|
_DtDimensionToString(
|
|
int fd,
|
|
Dimension *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
(void) sprintf (resourceBuf, "%d", *value);
|
|
_DtStringToString( fd, &resourceBuf, out_buf );
|
|
}
|
|
|
|
|
|
|
|
void
|
|
_DtBooleanToString(
|
|
int fd,
|
|
Boolean *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
char * buf;
|
|
|
|
if (*value == True)
|
|
buf = "True";
|
|
else
|
|
buf = "False";
|
|
_DtStringToString( fd, (char **)&buf, out_buf );
|
|
}
|
|
|
|
|
|
void
|
|
_DtXmStringToString(
|
|
int fd,
|
|
XmString *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
char *out_value = NULL;
|
|
|
|
if (*value != NULL)
|
|
{
|
|
out_value = (char *) _XmStringUngenerate(*value, XmFONTLIST_DEFAULT_TAG,
|
|
XmCHARSET_TEXT, XmCHARSET_TEXT);
|
|
if ( out_value != NULL)
|
|
{
|
|
if (strlen (out_value) != 0)
|
|
{
|
|
(void) write (fd, out_value, strlen (out_value));
|
|
_DtStringToString( fd, &out_value, out_buf );
|
|
|
|
XtFree ((char *) out_value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
_DtXmStringTableToString(
|
|
int fd,
|
|
XmStringTable *value,
|
|
char *out_buf )
|
|
|
|
{
|
|
int i;
|
|
char *out_value = NULL;
|
|
Boolean first = True;
|
|
|
|
if ((value != NULL) && (*value != NULL))
|
|
{
|
|
i = 0;
|
|
while ((*value)[i] != NULL)
|
|
{
|
|
out_value = (char *)_XmStringUngenerate((*value)[i],
|
|
XmFONTLIST_DEFAULT_TAG,
|
|
XmCHARSET_TEXT, XmCHARSET_TEXT);
|
|
if ( out_value != NULL)
|
|
{
|
|
if (first)
|
|
{
|
|
(void) write (fd, out_buf, strlen (out_buf));
|
|
first = False;
|
|
}
|
|
else
|
|
(void) write (fd, ", ", strlen (", "));
|
|
|
|
(void) write (fd, out_value, strlen (out_value));
|
|
|
|
XtFree ((char *) out_value);
|
|
out_value = NULL;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if (first == False)
|
|
(void) write (fd, "\n", strlen ("\n"));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
_DtStringToString(
|
|
int fd,
|
|
char **value,
|
|
char *out_buf )
|
|
|
|
{
|
|
if (*value == NULL || strlen (*value) == 0)
|
|
;
|
|
else
|
|
{
|
|
(void) write (fd, out_buf, strlen (out_buf));
|
|
(void) write (fd, *value, strlen (*value));
|
|
(void) write (fd, "\n", strlen ("\n"));
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* _DtChildPosition:
|
|
* Choose a position for a popup window ("child") so that the main
|
|
* window ("parent") is not obscured. The child will be positioned
|
|
* to the right, below, left, or above the parent, depending on where
|
|
* there is the most space.
|
|
*/
|
|
|
|
void
|
|
_DtChildPosition(
|
|
Widget w,
|
|
Widget parent,
|
|
Position *newX,
|
|
Position *newY)
|
|
{
|
|
Position pY, pX;
|
|
XmVendorShellExtObject vendorExt;
|
|
XmWidgetExtData extData;
|
|
int xOffset, yOffset;
|
|
int pHeight, myHeight, sHeight;
|
|
int pWidth, myWidth, sWidth;
|
|
enum { posRight, posBelow, posLeft, posAbove } pos;
|
|
int space;
|
|
int xOrg=0, yOrg=0; /* Xinerama screen origin */
|
|
|
|
/* get x, y offsets for the parent's window frame */
|
|
extData = _XmGetWidgetExtData(parent, XmSHELL_EXTENSION);
|
|
if (extData)
|
|
{
|
|
vendorExt = (XmVendorShellExtObject)extData->widget;
|
|
xOffset = vendorExt->vendor.xOffset;
|
|
yOffset = vendorExt->vendor.yOffset;
|
|
}
|
|
else
|
|
xOffset = yOffset = 0;
|
|
|
|
#ifdef USE_XINERAMA
|
|
if(!GetXineramaScreenDimensions(parent,&xOrg,&yOrg,&sWidth,&sHeight)){
|
|
sHeight = HeightOfScreen(XtScreen(parent));
|
|
sWidth = WidthOfScreen(XtScreen(parent));
|
|
}
|
|
#else
|
|
/* get size/position of screen, parent, and widget */
|
|
sHeight = HeightOfScreen(XtScreen(parent));
|
|
sWidth = WidthOfScreen(XtScreen(parent));
|
|
#endif /* USE_XINERAMA */
|
|
|
|
pX = XtX(parent) - xOffset - xOrg;
|
|
pY = XtY(parent) - yOffset - yOrg;
|
|
pHeight = XtHeight(parent) + yOffset + xOffset;
|
|
pWidth = XtWidth(parent) + 2*xOffset;
|
|
myHeight = XtHeight(w) + yOffset + xOffset;
|
|
myWidth = XtWidth(w) + 2*xOffset;
|
|
|
|
/*
|
|
* Determine how much space would be left if the child was positioned
|
|
* to the right, below, left, or above the parent. Choose the child
|
|
* positioning so that the maximum space is left.
|
|
*/
|
|
pos = posRight;
|
|
space = sWidth - (pX + pWidth + myWidth);
|
|
|
|
if (sHeight - (pY + pHeight + myHeight) > space)
|
|
{
|
|
pos = posBelow;
|
|
space = sHeight - (pY + pHeight + myHeight);
|
|
}
|
|
|
|
if (pX - myWidth > space)
|
|
{
|
|
pos = posLeft;
|
|
space = pX - myWidth;
|
|
}
|
|
|
|
if (pY - myHeight > space)
|
|
{
|
|
pos = posAbove;
|
|
space = pY - myHeight;
|
|
}
|
|
|
|
/* Given relative positioning, determine x, y coordinates for the child */
|
|
|
|
switch (pos)
|
|
{
|
|
case posRight:
|
|
*newX = pX + pWidth + 5;
|
|
*newY = pY + (pHeight - myHeight)/2;
|
|
break;
|
|
|
|
case posBelow:
|
|
*newX = pX + (pWidth - myWidth)/2;
|
|
*newY = pY + pHeight + 5;
|
|
break;
|
|
|
|
case posLeft:
|
|
*newX = pX - myWidth - 5;
|
|
*newY = pY + (pHeight - myHeight)/2;
|
|
break;
|
|
|
|
case posAbove:
|
|
*newX = pX + (pWidth - myWidth)/2;
|
|
*newY = pY - myHeight - 5;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* The above calculations may put the dialog offscreen so one
|
|
* last check must be made. One way this can happen is if the
|
|
* parent has been resized to fill almost the entire screen.
|
|
* This can also happen if the parent has been maximized
|
|
* and the window manager has its 'positionOnScreen' resource
|
|
* set to False.
|
|
*/
|
|
if ((*newX >= (sWidth - 10)) || (*newX < 0))
|
|
*newX = sWidth - myWidth + 5;
|
|
if ((*newY >= (sHeight - 10)) || (*newY < 0))
|
|
*newY = (sHeight - myHeight) / 2;
|
|
|
|
*newX+=xOrg;
|
|
*newY+=yOrg;
|
|
}
|
|
|
|
|
|
/* ARGSUSED */
|
|
void
|
|
_DtmapCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
{
|
|
Arg args[2];
|
|
Widget parent;
|
|
Position newX, newY;
|
|
|
|
parent = (Widget)client_data;
|
|
|
|
if (parent)
|
|
{
|
|
_DtChildPosition(w, parent, &newX, &newY);
|
|
XtSetArg(args[0], XmNx, newX);
|
|
XtSetArg(args[1], XmNy, newY);
|
|
XtSetValues(w, args, 2);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtBuildDialog
|
|
* This functions is used to build an instance of a dialog with
|
|
* the provided data but not display it. The functions and data
|
|
* to be set back to the application upon change or close of the
|
|
* dialog is also provided as parameters.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtBuildDialog(
|
|
Widget parent,
|
|
Widget map_parent,
|
|
XtPointer top_rec,
|
|
DialogData *dialog_data,
|
|
DialogChangedProc change_proc,
|
|
XtPointer change_data,
|
|
DialogClosedProc close_proc,
|
|
XtPointer close_data,
|
|
char *workspaces,
|
|
Boolean iconify_state,
|
|
Boolean ignoreCache,
|
|
char * title,
|
|
XClassHint * classHints )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
int dialog_type, n;
|
|
DialogInstanceData * instance_data;
|
|
char geometry[40];
|
|
Arg args[5];
|
|
Boolean doCenter = False;
|
|
Boolean doParentRelativePositioning = False;
|
|
int availableDialogCount;
|
|
|
|
|
|
/* See if there is a cached, unused dialog of the correct type. */
|
|
|
|
dialog_type = dialog_data->type;
|
|
dialog = NULL;
|
|
|
|
if (!ignoreCache)
|
|
{
|
|
Dialog * availableDialog;
|
|
|
|
availableDialog = class_set[dialog_type].dialog_list;
|
|
availableDialogCount = 0;
|
|
|
|
/*
|
|
* In addition to looking for an available dialog in the cache to use,
|
|
* we also want to count up the number of unused dialogs in the cache.
|
|
* This lets us know it we need to restart the timer, to again build
|
|
* up the cache.
|
|
*/
|
|
while (availableDialog != NULL)
|
|
{
|
|
if (availableDialog->in_use == False)
|
|
{
|
|
if (dialog == NULL)
|
|
dialog = availableDialog;
|
|
else
|
|
availableDialogCount++;
|
|
}
|
|
availableDialog = availableDialog->next;
|
|
}
|
|
}
|
|
|
|
if (dialog == NULL)
|
|
{
|
|
dialog = (Dialog *) XtMalloc (sizeof (Dialog));
|
|
|
|
(*(class_set[dialog_type].class->create))
|
|
(XtDisplay (encap_parent_shell), encap_parent_shell,
|
|
&(dialog->dialog_widget), &dialog->dialog);
|
|
|
|
/* Add the change and close callbacks into the dialog */
|
|
|
|
if (class_set[dialog_type].class->install_change_callback)
|
|
(*(class_set[dialog_type].class->install_change_callback))
|
|
(dialog->dialog, DataChangeCallback, (XtPointer)dialog);
|
|
|
|
if (class_set[dialog_type].class->install_close_callback)
|
|
(*(class_set[dialog_type].class->install_close_callback))
|
|
(dialog->dialog, DataCloseCallback, (XtPointer)dialog);
|
|
|
|
dialog->next = class_set[dialog_type].dialog_list;
|
|
class_set[dialog_type].dialog_list = dialog;
|
|
}
|
|
|
|
/*
|
|
* Set pointer to top dialog data in child of the shell.
|
|
* This is needed to get help to work.
|
|
*/
|
|
if (top_rec == NULL)
|
|
top_rec = dialog->dialog;
|
|
XtSetArg(args[0], XmNuserData, top_rec);
|
|
XtSetValues(dialog->dialog_widget, args, 1);
|
|
|
|
/* Set the dialog structure fields to the parameter data. */
|
|
|
|
dialog->in_use = True;
|
|
dialog->dialog_data = dialog_data;
|
|
dialog->change = change_proc;
|
|
dialog->change_client_data = change_data;
|
|
dialog->close = close_proc;
|
|
dialog->close_client_data = close_data;
|
|
|
|
/* If a special title has been specified, we need to set it now */
|
|
if (title)
|
|
{
|
|
XtSetArg(args[0], XmNtitle, title);
|
|
XtSetValues(XtParent(dialog->dialog_widget), args, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* _DtShowBuiltDialog
|
|
* This functions is used to display an instance of a dialog which
|
|
* has already been built with _DtBuildDialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
_DtShowBuiltDialog(
|
|
Widget parent,
|
|
Widget map_parent,
|
|
DialogData *dialog_data,
|
|
char *workspaces,
|
|
Boolean iconify_state,
|
|
XClassHint * classHints )
|
|
|
|
{
|
|
Dialog * dialog;
|
|
int dialog_type, n;
|
|
DialogInstanceData * instance_data;
|
|
char geometry[40];
|
|
Arg args[5];
|
|
Boolean doCenter = False;
|
|
Boolean doParentRelativePositioning = False;
|
|
int availableDialogCount;
|
|
|
|
|
|
dialog_type = dialog_data->type;
|
|
|
|
/* Find the dialog */
|
|
dialog = class_set[dialog_data->type].dialog_list;
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog_data == dialog_data)
|
|
break;
|
|
else
|
|
dialog = dialog->next;
|
|
}
|
|
|
|
/* Need to add the map callback in relation to the parent */
|
|
if (class_set[dialog_type].class->map)
|
|
{
|
|
/*
|
|
* The map_parent parameter gives us the ability to position
|
|
* the dialog relative to a window which is not the transientFor
|
|
* parent. This is used for the audio preview dialog.
|
|
*/
|
|
if (map_parent == NULL)
|
|
map_parent = parent;
|
|
|
|
(*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
|
|
}
|
|
|
|
instance_data = (DialogInstanceData *) dialog_data->data;
|
|
|
|
/* If this is a top level shell, get it realized */
|
|
if (XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass))
|
|
{
|
|
if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
(void) sprintf (geometry, "=%dx%d+%d+%d",
|
|
instance_data->width, instance_data->height,
|
|
instance_data->x, instance_data->y);
|
|
|
|
XtSetArg (args[0], XmNgeometry, geometry);
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, 1);
|
|
}
|
|
else if ((instance_data->width != 0) && (instance_data->height != 0))
|
|
{
|
|
n=0;
|
|
XtSetArg (args[n], XmNwidth, instance_data->width); n++;
|
|
XtSetArg (args[n], XmNheight, instance_data->height); n++;
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, n);
|
|
}
|
|
|
|
/* Toggle mappedWhenManaged to false */
|
|
XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
|
|
XtRealizeWidget (XtParent(dialog->dialog_widget));
|
|
|
|
/* Set the proper workspaces if needed */
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
|
|
/* Set any application-specified class hints for the window */
|
|
if (classHints)
|
|
{
|
|
XSetClassHint(XtDisplay(dialog->dialog_widget),
|
|
XtWindow(XtParent(dialog->dialog_widget)),
|
|
classHints);
|
|
}
|
|
|
|
/* Set the iconify state */
|
|
SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
|
|
|
|
/* Map the window */
|
|
XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), True);
|
|
XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
|
|
XSync(XtDisplay(dialog->dialog_widget), False);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
|
|
|
|
wm->wm.size_hints.flags |= USPosition;
|
|
XtSetArg (args[0], XmNx, instance_data->x);
|
|
XtSetArg (args[1], XmNy, instance_data->y);
|
|
XtSetArg (args[2], XmNwidth, instance_data->width);
|
|
XtSetArg (args[3], XmNheight, instance_data->height);
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, 4);
|
|
}
|
|
else if ((instance_data->width != 0) && (instance_data->height != 0))
|
|
{
|
|
n=0;
|
|
XtSetArg (args[n], XmNwidth, instance_data->width); n++;
|
|
XtSetArg (args[n], XmNheight, instance_data->height); n++;
|
|
XtSetValues (XtParent (dialog->dialog_widget), args, n);
|
|
}
|
|
|
|
/* Set the proper workspaces if needed */
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
|
|
/* Set any application-specified class hints for the window */
|
|
if (classHints)
|
|
{
|
|
XSetClassHint(XtDisplay(dialog->dialog_widget),
|
|
XtWindow(XtParent(dialog->dialog_widget)),
|
|
classHints);
|
|
}
|
|
|
|
/* Set the iconify state */
|
|
SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
|
|
|
|
/* Map the window */
|
|
XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (instance_data->displayed == True)
|
|
{
|
|
XtSetArg (args[0], XmNx, instance_data->x);
|
|
XtSetArg (args[1], XmNy, instance_data->y);
|
|
XtSetArg (args[2], XmNwidth, instance_data->width);
|
|
XtSetArg (args[3], XmNheight, instance_data->height);
|
|
XtSetArg (args[4], XmNdefaultPosition, False);
|
|
XtSetValues (dialog->dialog_widget, args, 5);
|
|
XtRealizeWidget (dialog->dialog_widget);
|
|
}
|
|
else
|
|
{
|
|
XtSetArg (args[0], XmNdefaultPosition, False);
|
|
XtSetValues (dialog->dialog_widget, args, 1);
|
|
|
|
XtRealizeWidget (dialog->dialog_widget);
|
|
|
|
if (parent)
|
|
{
|
|
/* Position relative to the parent dialog */
|
|
/*
|
|
* Must be done after the set_values call, since the dialog
|
|
* may get forced to a different size.
|
|
*/
|
|
doParentRelativePositioning = True;
|
|
}
|
|
else
|
|
{
|
|
/* Center in the display */
|
|
/*
|
|
* Must be done after the set_values call, since the dialog
|
|
* may get forced to a different size.
|
|
*/
|
|
doCenter = True;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Dialogs with no controlling parent window, need to have their
|
|
* own workspace perperty set, if some workspaces have been requested.
|
|
*/
|
|
if ((parent == NULL) && workspaces)
|
|
_DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
|
|
}
|
|
|
|
|
|
/* Set Values onto the dialog to set it to the correct data. */
|
|
|
|
(*(class_set[dialog_data->type].class->set_values))
|
|
(dialog->dialog, dialog_data->data);
|
|
|
|
/*
|
|
* These two adjustments MUST be done AFTER the dialog's SetValues()
|
|
* procedure is called. This is due to the fact that the setvalues
|
|
* may cause the dialog size to change, and since both of the following
|
|
* positioning algorithms are dependent upon the dialog size, we want
|
|
* to make sure that the correct size is used.
|
|
*/
|
|
if (doCenter)
|
|
{
|
|
XtSetArg (args[0], XmNx,
|
|
(Dimension)(WidthOfScreen(XtScreen(dialog->dialog_widget)) -
|
|
dialog->dialog_widget->core.width) / (Dimension)2);
|
|
XtSetArg (args[1], XmNy,
|
|
(Dimension)(HeightOfScreen(XtScreen(dialog->dialog_widget)) -
|
|
dialog->dialog_widget->core.height) / (Dimension)2);
|
|
XtSetValues (dialog->dialog_widget, args, 2);
|
|
}
|
|
else if (doParentRelativePositioning)
|
|
{
|
|
XtSetArg (args[0], XmNx,
|
|
parent->core.x +
|
|
(Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
|
|
XtSetArg (args[1], XmNy,
|
|
parent->core.y +
|
|
(Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
|
|
XtSetValues (XtParent(dialog->dialog_widget), args, 2);
|
|
}
|
|
|
|
|
|
/* Fix up the transient-for windowing information so that */
|
|
/* the window manager will shuffle and iconify as a group */
|
|
|
|
if (parent != NULL)
|
|
{
|
|
if (XtIsRealized(parent))
|
|
{
|
|
XSetTransientForHint (XtDisplay (parent),
|
|
XtWindow (XtParent (dialog->dialog_widget)),
|
|
XtWindow (parent));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass))
|
|
{
|
|
XSetTransientForHint (XtDisplay (encap_parent_shell),
|
|
XtWindow (XtParent (dialog->dialog_widget)),
|
|
XtWindow (encap_parent_shell));
|
|
}
|
|
}
|
|
|
|
|
|
/* Display the dialogs, application shells are displayed above. */
|
|
|
|
if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
|
|
applicationShellWidgetClass)))
|
|
{
|
|
XtManageChild (dialog->dialog_widget);
|
|
}
|
|
|
|
|
|
/* Set the dialog instance data to indicate that the dialog */
|
|
/* is displayed. */
|
|
|
|
((DialogInstanceData *) (dialog_data->data))->displayed = True;
|
|
|
|
|
|
/* Give the dialog a chance to set its focus widget, if necessary */
|
|
|
|
if (class_set[dialog_data->type].class->set_focus)
|
|
{
|
|
(*(class_set[dialog_data->type].class->set_focus))
|
|
(dialog->dialog, dialog_data->data);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
DialogStructureNotifyHandler(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XEvent *event )
|
|
{
|
|
if( event->type == MapNotify )
|
|
{
|
|
if( NumberOfDialogMapped == 0 )
|
|
{
|
|
int timeOut;
|
|
|
|
if( timerState == TIMER_STARTUP_STATE )
|
|
timeOut = initialTimeoutLength;
|
|
else if( timerState == TIMER_ACTIVE_STATE )
|
|
timeOut = activeTimeoutLength;
|
|
else if( timerState == TIMER_IDLE_STATE )
|
|
timeOut = idleTimeoutLength;
|
|
else
|
|
timeOut = 0;
|
|
|
|
if( timeOut )
|
|
{
|
|
if( timerId )
|
|
XtRemoveTimeOut( timerId );
|
|
|
|
timerId = XtAppAddTimeOut( XtWidgetToApplicationContext( w ),
|
|
timeOut,
|
|
(XtTimerCallbackProc)TimerEvent,
|
|
(XtPointer)w );
|
|
}
|
|
}
|
|
++NumberOfDialogMapped;
|
|
}
|
|
else if( event->type == UnmapNotify )
|
|
{
|
|
if( NumberOfDialogMapped )
|
|
--NumberOfDialogMapped;
|
|
|
|
if( NumberOfDialogMapped == 0 )
|
|
{
|
|
if( timerId )
|
|
{
|
|
XtRemoveTimeOut( timerId );
|
|
timerId = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
_DtChangeTo(
|
|
XtPointer client_data,
|
|
char *directory)
|
|
{
|
|
Dialog * dialog = (Dialog *) client_data;
|
|
|
|
ChangeDirectoryToParent(dialog->change_client_data, directory);
|
|
}
|
|
|
|
void
|
|
_DtFreeDialog(
|
|
DialogData *dialog_data)
|
|
{
|
|
Dialog *dialog,**headptr;
|
|
headptr = &class_set[dialog_data->type].dialog_list;
|
|
dialog = *headptr;
|
|
|
|
while (dialog != NULL)
|
|
{
|
|
if (dialog->dialog_data == dialog_data)
|
|
{
|
|
*headptr = dialog->next;
|
|
XtFree((char *) dialog);
|
|
break;
|
|
}
|
|
headptr = &(dialog->next);
|
|
dialog = *headptr;
|
|
}
|
|
}
|
|
|
|
#ifdef USE_XINERAMA
|
|
/*
|
|
* Retrieve dimensions of the Xinerama screen the given widget resides on.
|
|
* Returns True on success, False otherwise.
|
|
*/
|
|
static Boolean GetXineramaScreenDimensions(
|
|
Widget w, int *org_x, int *org_y, int *s_width, int *s_height)
|
|
{
|
|
DtXineramaInfo_t *dt_xi;
|
|
unsigned int wx, wy;
|
|
unsigned int i, sx, sy, sw, sh;
|
|
|
|
while (w && !XtIsShell(w))
|
|
w=XtParent (w);
|
|
|
|
wx=XtX(w);
|
|
wy=XtY(w);
|
|
|
|
if (!(dt_xi=_DtXineramaInit(XtDisplay(w)))) return False;
|
|
|
|
for (i=0; i<dt_xi->numscreens; i++){
|
|
if (!_DtXineramaGetScreen(dt_xi,i,&sw,&sh,&sx,&sy))
|
|
break;
|
|
|
|
if (wx>=sx && wx<(sx+sw) && wy>=sy && wy<(sy+sh))
|
|
{
|
|
*s_width=(int)sw;
|
|
*s_height=(int)sh;
|
|
*org_x=(int)sx;
|
|
*org_y=(int)sy;
|
|
free(dt_xi);
|
|
return True;
|
|
}
|
|
}
|
|
|
|
free(dt_xi);
|
|
return False;
|
|
}
|
|
#endif /* USE_XINERAMA */
|