931 lines
24 KiB
C
931 lines
24 KiB
C
/*
|
||
|
||
Copyright 1990, 1998 The Open Group
|
||
|
||
Permission to use, copy, modify, distribute, and sell this software and its
|
||
documentation for any purpose is hereby granted without fee, provided that
|
||
the above copyright notice appear in all copies and that both that
|
||
copyright notice and this permission notice appear in supporting
|
||
documentation.
|
||
|
||
The above copyright notice and this permission notice shall be included
|
||
in all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
Except as contained in this notice, the name of The Open Group shall
|
||
not be used in advertising or otherwise to promote the sale, use or
|
||
other dealings in this Software without prior written authorization
|
||
from The Open Group.
|
||
|
||
*/
|
||
|
||
|
||
/*
|
||
* This file contains the code to communicate with the client that is
|
||
* being edited.
|
||
*/
|
||
|
||
#include <X11/Intrinsic.h>
|
||
#include <X11/StringDefs.h> /* Get standard string definitions. */
|
||
#include <X11/Xatom.h>
|
||
#include <X11/cursorfont.h> /* For crosshair cursor. */
|
||
#include <X11/Xproto.h>
|
||
#include <X11/Xos.h> /* for XtNewString */
|
||
|
||
#include <stdio.h>
|
||
#include <X11/Xmu/Error.h>
|
||
#include <X11/Xmu/WinUtil.h>
|
||
|
||
#include "editresP.h"
|
||
|
||
/*
|
||
* static Globals.
|
||
*/
|
||
|
||
static Atom atom_comm, atom_command, atom_resource_editor, atom_client_value;
|
||
static Atom atom_editres_protocol;
|
||
|
||
extern Widget CM_entries[NUM_CM_ENTRIES], TM_entries[NUM_TM_ENTRIES];
|
||
|
||
static void ClientTimedOut ( XtPointer data, XtIntervalId * id );
|
||
static void TellUserAboutMessage ( Widget label, ResCommand command );
|
||
static Boolean ConvertCommand ( Widget w, Atom * selection, Atom * target,
|
||
Atom * type_ret, XtPointer *value_ret,
|
||
unsigned long * length_ret, int * format_ret );
|
||
static void SelectionDone ( Widget w, Atom *sel, Atom *targ );
|
||
static void LoseSelection ( Widget w, Atom * sel );
|
||
static void GetClientValue ( Widget w, XtPointer data, Atom *selection,
|
||
Atom *type, XtPointer value,
|
||
unsigned long *length, int * format );
|
||
static void BuildHeader ( CurrentClient * client_data );
|
||
static Event * BuildEvent ( ProtocolStream * stream );
|
||
static void FreeEvent ( Event * event );
|
||
static char * DispatchEvent ( Event * event );
|
||
|
||
|
||
|
||
/* Function Name: ClientTimedOut
|
||
* Description: Called if the client takes too long to take our selection.
|
||
* Arguments: data - The widget that owns the client
|
||
* communication selection.
|
||
* id - *** UNUSED ***
|
||
* Returns: none.
|
||
*/
|
||
|
||
/* ARGSUSED */
|
||
static void
|
||
ClientTimedOut(XtPointer data, XtIntervalId *id)
|
||
{
|
||
char msg[BUFSIZ];
|
||
Widget w = (Widget) data;
|
||
|
||
global_client.ident = NO_IDENT;
|
||
XtDisownSelection(w, global_client.atom,
|
||
XtLastTimestampProcessed(XtDisplay(w)));
|
||
|
||
sprintf(msg, res_labels[4],
|
||
"the Editres Protocol.");
|
||
SetMessage(global_screen_data.info_label, msg);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: GetClientWindow
|
||
* Description: Gets the Client's window by asking the user.
|
||
* Arguments: w - a widget.
|
||
* Returns: a clients window, or None.
|
||
*/
|
||
|
||
Window
|
||
GetClientWindow(Widget w, int *x, int *y)
|
||
{
|
||
int status;
|
||
Cursor cursor;
|
||
XEvent event;
|
||
int buttons = 0;
|
||
Display * dpy = XtDisplayOfObject(w);
|
||
Window target_win = None, root = RootWindowOfScreen(XtScreenOfObject(w));
|
||
XtAppContext app = XtWidgetToApplicationContext(w);
|
||
|
||
/* Make the target cursor */
|
||
cursor = XCreateFontCursor(dpy, XC_crosshair);
|
||
|
||
/* Grab the pointer using target cursor, letting it room all over */
|
||
status = XGrabPointer(dpy, root, False,
|
||
ButtonPressMask|ButtonReleaseMask, GrabModeSync,
|
||
GrabModeAsync, root, cursor, CurrentTime);
|
||
if (status != GrabSuccess) {
|
||
SetMessage(global_screen_data.info_label, res_labels[5]);
|
||
return(None);
|
||
}
|
||
|
||
/* Let the user select a window... */
|
||
while ((target_win == None) || (buttons != 0)) {
|
||
/* allow one more event */
|
||
XAllowEvents(dpy, SyncPointer, CurrentTime);
|
||
XtAppNextEvent(app, &event);
|
||
switch (event.type) {
|
||
case ButtonPress:
|
||
if (event.xbutton.window != root) {
|
||
XtDispatchEvent(&event);
|
||
break;
|
||
}
|
||
|
||
if (target_win == None) {
|
||
target_win = event.xbutton.subwindow; /* window selected */
|
||
if (x != NULL)
|
||
*x = event.xbutton.x_root;
|
||
if (y != NULL)
|
||
*y = event.xbutton.y_root;
|
||
}
|
||
buttons++;
|
||
break;
|
||
case ButtonRelease:
|
||
if (event.xbutton.window != root) {
|
||
XtDispatchEvent(&event);
|
||
break;
|
||
}
|
||
|
||
if (buttons > 0) /* There may have been some
|
||
down before we started */
|
||
buttons--;
|
||
break;
|
||
default:
|
||
XtDispatchEvent(&event);
|
||
break;
|
||
}
|
||
}
|
||
|
||
XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
|
||
|
||
return(XmuClientWindow(dpy, target_win));
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: SetCommand
|
||
* Description: Causes this widget to own the resource editor's
|
||
* command selection.
|
||
* Arguments: w - the widget that will own the selection.
|
||
* command - command to send to client.
|
||
* msg - message to prompt the user to select a client.
|
||
* Returns: none.
|
||
*/
|
||
|
||
/* ARGSUSED */
|
||
void
|
||
SetCommand(Widget w, ResCommand command, char *msg)
|
||
{
|
||
XClientMessageEvent client_event;
|
||
Display * dpy = XtDisplay(w);
|
||
|
||
if (msg == NULL)
|
||
msg = res_labels[6];
|
||
|
||
SetMessage(global_screen_data.info_label, msg);
|
||
|
||
if (global_client.window == None)
|
||
if ( (global_client.window = GetClientWindow(w, NULL, NULL)) == None)
|
||
return;
|
||
|
||
global_client.ident = GetNewIdent();
|
||
|
||
global_client.command = command;
|
||
global_client.atom = atom_comm;
|
||
|
||
BuildHeader(&(global_client));
|
||
|
||
if (!XtOwnSelection(w, global_client.atom, CurrentTime, ConvertCommand,
|
||
LoseSelection, SelectionDone))
|
||
SetMessage(global_screen_data.info_label,
|
||
res_labels[7]);
|
||
|
||
client_event.window = global_client.window;
|
||
client_event.type = ClientMessage;
|
||
client_event.message_type = atom_resource_editor;
|
||
client_event.format = EDITRES_SEND_EVENT_FORMAT;
|
||
client_event.data.l[0] = XtLastTimestampProcessed(dpy);
|
||
client_event.data.l[1] = global_client.atom;
|
||
client_event.data.l[2] = (long) global_client.ident;
|
||
client_event.data.l[3] = global_effective_protocol_version;
|
||
|
||
global_error_code = NO_ERROR; /* Reset Error code. */
|
||
global_old_error_handler = XSetErrorHandler(HandleXErrors);
|
||
global_serial_num = NextRequest(dpy);
|
||
|
||
XSendEvent(dpy, global_client.window, FALSE, (long) 0,
|
||
(XEvent *) &client_event);
|
||
|
||
XSync(dpy, FALSE);
|
||
XSetErrorHandler(global_old_error_handler);
|
||
if (global_error_code == NO_WINDOW) {
|
||
char error_buf[BUFSIZ];
|
||
|
||
global_error_code = NO_ERROR; /* Reset Error code. */
|
||
sprintf(error_buf, "The communication window with%s%s.",
|
||
" application is no longer available\n",
|
||
"Please select a new widget tree");
|
||
|
||
global_client.window = None;
|
||
SetCommand(w, LocalSendWidgetTree, error_buf);
|
||
return;
|
||
}
|
||
|
||
TellUserAboutMessage(global_screen_data.info_label, command);
|
||
global_client.timeout = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
|
||
CLIENT_TIME_OUT,
|
||
ClientTimedOut, (XtPointer) w);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: TellUserAboutMessage
|
||
* Description: Informs the user that we have sent a message to the client
|
||
* Arguments: label - the info label.
|
||
* command - command that we have executed.
|
||
* Returns: none.
|
||
*/
|
||
|
||
static void
|
||
TellUserAboutMessage(Widget label, ResCommand command)
|
||
{
|
||
char msg[BUFSIZ], *str;
|
||
|
||
switch(command) {
|
||
case LocalSendWidgetTree:
|
||
str = " asking for widget tree";
|
||
break;
|
||
case LocalSetValues:
|
||
str = " asking it to perform SetValues()";
|
||
break;
|
||
case LocalFlashWidget:
|
||
case LocalGetGeometry:
|
||
str = " asking it to perform GetGeometry()";
|
||
break;
|
||
case LocalGetResources:
|
||
str = " asking it to get a widget's resource list";
|
||
break;
|
||
case LocalFindChild:
|
||
str = " asking it to find the child Widget.";
|
||
break;
|
||
default:
|
||
str = "";
|
||
break;
|
||
}
|
||
|
||
sprintf(msg, res_labels[8], str);
|
||
SetMessage(label, msg);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: ConvertCommand
|
||
* Description: Converts the command string into a selection that can
|
||
* be sent to the client.
|
||
* Arguments: (see Xt)
|
||
* Returns: TRUE if we could convert the selection and target asked for.
|
||
*/
|
||
|
||
/* ARGSUSED */
|
||
static Boolean
|
||
ConvertCommand(Widget w, Atom *selection, Atom *target, Atom *type_ret,
|
||
XtPointer *value_ret, unsigned long *length_ret, int *format_ret)
|
||
{
|
||
if ((*selection != atom_comm) || (*target != atom_command))
|
||
return(FALSE);
|
||
|
||
*type_ret = atom_editres_protocol;
|
||
*value_ret = (XtPointer) global_client.stream.real_top;
|
||
*length_ret = global_client.stream.size + HEADER_SIZE;
|
||
*format_ret = EDITRES_FORMAT;
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: SelectionDone
|
||
* Description: done with the selection.
|
||
* Arguments: *** UNUSED ***
|
||
* Returns: none.
|
||
*/
|
||
|
||
/* ARGSUSED */
|
||
static void
|
||
SelectionDone(Widget w, Atom *sel, Atom *targ)
|
||
{
|
||
/* Keep the toolkit from automaticaly freeing the selection value */
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: LoseSelection
|
||
* Description: Called when we have lost the selection, asks client
|
||
* for the selection value.
|
||
* Arguments: w - the widget that just lost the selection.
|
||
* sel - the selection.
|
||
* Returns: none.
|
||
*/
|
||
|
||
static void
|
||
LoseSelection(Widget w, Atom *sel)
|
||
{
|
||
if (global_client.timeout != 0) {
|
||
XtRemoveTimeOut(global_client.timeout);
|
||
global_client.timeout = 0;
|
||
}
|
||
|
||
XtGetSelectionValue(w, *sel, atom_client_value, GetClientValue,
|
||
NULL, XtLastTimestampProcessed(XtDisplay(w)));
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: GetClientValue
|
||
* Description: Gets the value out of the client, and does good things
|
||
* to it.
|
||
* Arguments: w - the widget that asked for the selection.
|
||
* data - client_data *** UNUSED ***.
|
||
* sel - the selection.
|
||
* type - the type of the selection.
|
||
* value - the selection's value.
|
||
* length - the length of the selection's value.
|
||
* format - the format of the selection.
|
||
* Returns: none.
|
||
*/
|
||
|
||
static Boolean reset_protocol_level = True;
|
||
|
||
/* ARGSUSED */
|
||
static void
|
||
GetClientValue(Widget w, XtPointer data, Atom *selection, Atom *type,
|
||
XtPointer value, unsigned long *length, int *format)
|
||
{
|
||
Event * event;
|
||
ProtocolStream alloc_stream, *stream;
|
||
unsigned char ident, error_code;
|
||
char * error_str = NULL, msg[BUFSIZ];
|
||
|
||
if (*length == 0)
|
||
return;
|
||
|
||
stream = &alloc_stream; /* easier to think of it this way... */
|
||
|
||
stream->current = stream->top = (unsigned char *) value;
|
||
stream->size = HEADER_SIZE; /* size of header. */
|
||
|
||
/*
|
||
* Retrieve the Header.
|
||
*/
|
||
|
||
if (*length < HEADER_SIZE) {
|
||
SetMessage(global_screen_data.info_label,
|
||
res_labels[9]);
|
||
return;
|
||
}
|
||
|
||
(void) _XEditResGet8(stream, &ident);
|
||
if (global_client.ident != ident) {
|
||
#ifdef DEBUG
|
||
if (global_resources.debug)
|
||
printf("Incorrect ident from client.\n");
|
||
#endif
|
||
if (!XtOwnSelection(w, *selection, CurrentTime, ConvertCommand,
|
||
LoseSelection, SelectionDone))
|
||
SetMessage(global_screen_data.info_label,
|
||
res_labels[10]);
|
||
return;
|
||
}
|
||
|
||
(void) _XEditResGet8(stream, &error_code);
|
||
(void) _XEditResGet32(stream, &(stream->size));
|
||
stream->top = stream->current; /* reset stream to top of value.*/
|
||
|
||
switch ((int) error_code) {
|
||
case PartialSuccess:
|
||
/*****
|
||
if (global_client.command == LocalSendWidgetTree &&
|
||
global_effective_protocol_version < CURRENT_PROTOCOL_VERSION)
|
||
++global_effective_protocol_version;
|
||
*****/
|
||
if ((event = BuildEvent(stream)) != NULL) {
|
||
error_str = DispatchEvent(event);
|
||
FreeEvent(event);
|
||
}
|
||
else {
|
||
sprintf(msg, "Unable to unpack protocol request.");
|
||
error_str = XtNewString(msg);
|
||
}
|
||
break;
|
||
case Failure:
|
||
error_str = GetFailureMessage(stream);
|
||
break;
|
||
case ProtocolMismatch:
|
||
error_str = ProtocolFailure(stream);
|
||
--global_effective_protocol_version;
|
||
/* normaly protocol version is reset to current during a SendWidgetTree
|
||
* request, however, after a protocol failure this is skiped once for
|
||
* a retry.
|
||
*/
|
||
reset_protocol_level = False;
|
||
SetCommand(w, LocalSendWidgetTree, NULL);
|
||
break;
|
||
default:
|
||
sprintf(msg, res_labels[11], (int) error_code);
|
||
SetMessage(global_screen_data.info_label, msg);
|
||
break;
|
||
}
|
||
|
||
if (error_str == NULL) {
|
||
WNode * top;
|
||
|
||
if (global_tree_info == NULL)
|
||
return;
|
||
|
||
top = global_tree_info->top_node;
|
||
sprintf(msg, res_labels[12], top->name, top->class);
|
||
SetMessage(global_screen_data.info_label, msg);
|
||
return;
|
||
}
|
||
SetMessage(global_screen_data.info_label, error_str);
|
||
XtFree(error_str);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: BuildHeader
|
||
* Description: Puts the header into the message.
|
||
* Arguments: client_data - the client data.
|
||
* Returns: none.
|
||
*/
|
||
|
||
static void
|
||
BuildHeader(CurrentClient *client_data)
|
||
{
|
||
unsigned long old_alloc, old_size;
|
||
unsigned char * old_current;
|
||
EditresCommand command;
|
||
ProtocolStream * stream = &(client_data->stream);
|
||
|
||
/*
|
||
* We have cleverly keep enough space at the top of the header
|
||
* for the return protocol stream, so all we have to do is
|
||
* fill in the space.
|
||
*/
|
||
|
||
/*
|
||
* Fool the insert routines into putting the header in the right
|
||
* place while being damn sure not to realloc (that would be very bad.
|
||
*/
|
||
|
||
old_current = stream->current;
|
||
old_alloc = stream->alloc;
|
||
old_size = stream->size;
|
||
|
||
stream->current = stream->real_top;
|
||
stream->alloc = stream->size + (2 * HEADER_SIZE);
|
||
|
||
_XEditResPut8(stream, client_data->ident);
|
||
switch(client_data->command) {
|
||
case LocalSendWidgetTree:
|
||
if (reset_protocol_level) global_effective_protocol_version =
|
||
CURRENT_PROTOCOL_VERSION;
|
||
reset_protocol_level = True;
|
||
command = SendWidgetTree;
|
||
break;
|
||
case LocalSetValues:
|
||
command = SetValues;
|
||
break;
|
||
case LocalFlashWidget:
|
||
command = GetGeometry;
|
||
break;
|
||
case LocalGetResources:
|
||
command = GetResources;
|
||
break;
|
||
case LocalFindChild:
|
||
command = FindChild;
|
||
break;
|
||
case LocalGetValues:
|
||
command = GetValues;
|
||
break;
|
||
default:
|
||
command = SendWidgetTree;
|
||
break;
|
||
}
|
||
|
||
_XEditResPut8(stream, (unsigned char) command);
|
||
_XEditResPut32(stream, old_size);
|
||
|
||
stream->alloc = old_alloc;
|
||
stream->current = old_current;
|
||
stream->size = old_size;
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: BuildEvent
|
||
* Description: Builds the event structure from the
|
||
* Arguments: stream - the protocol data stream.
|
||
* Returns: event - the event.
|
||
*/
|
||
|
||
static Event *
|
||
BuildEvent(ProtocolStream *stream)
|
||
{
|
||
int i;
|
||
Event * event = (Event *) XtCalloc(sizeof(Event), 1);
|
||
|
||
/*
|
||
* The return value will be different depending upon the
|
||
* request sent out.
|
||
*/
|
||
|
||
switch(global_client.command) {
|
||
case LocalSendWidgetTree:
|
||
{
|
||
SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
|
||
|
||
send_event->type = SendWidgetTree;
|
||
|
||
if (!_XEditResGet16(stream, &(send_event->num_entries)))
|
||
goto done;
|
||
|
||
send_event->info = (WidgetTreeInfo *)
|
||
XtCalloc(sizeof(WidgetTreeInfo),
|
||
send_event->num_entries);
|
||
|
||
for (i = 0; i < (int)send_event->num_entries; i++) {
|
||
WidgetTreeInfo * info = send_event->info + i;
|
||
if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
|
||
_XEditResGetString8(stream, &(info->name)) &&
|
||
_XEditResGetString8(stream, &(info->class)) &&
|
||
_XEditResGet32(stream, &(info->window))))
|
||
{
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
if (global_effective_protocol_version ==
|
||
CURRENT_PROTOCOL_VERSION) {
|
||
/* get toolkit type and reset if necessary */
|
||
if (!_XEditResGetString8(stream, &(send_event->toolkit)))
|
||
goto done;
|
||
}
|
||
/* set the command menu entries senitive */
|
||
SetEntriesSensitive(&CM_entries[CM_OFFSET], CM_NUM, True);
|
||
/* set the tree menu entries senitive */
|
||
SetEntriesSensitive(TM_entries, TM_NUM, True);
|
||
if (global_effective_protocol_version ==
|
||
CURRENT_PROTOCOL_VERSION) {
|
||
if (!strcmp(send_event->toolkit, "InterViews"))
|
||
RebuildMenusAndLabel("iv");
|
||
}
|
||
else
|
||
RebuildMenusAndLabel("xt");
|
||
}
|
||
break;
|
||
case LocalSetValues:
|
||
{
|
||
SetValuesEvent * sv_event = (SetValuesEvent *) event;
|
||
|
||
sv_event->type = SetValues;
|
||
|
||
if (!_XEditResGet16(stream, &(sv_event->num_entries)))
|
||
goto done;
|
||
|
||
sv_event->info = (SetValuesInfo *) XtCalloc(sizeof(SetValuesInfo),
|
||
sv_event->num_entries);
|
||
|
||
for (i = 0; i < (int)sv_event->num_entries; i++) {
|
||
SetValuesInfo * info = sv_event->info + i;
|
||
if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
|
||
_XEditResGetString8(stream, &(info->message))))
|
||
{
|
||
goto done;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case LocalGetResources:
|
||
{
|
||
GetResourcesEvent * res_event = (GetResourcesEvent *) event;
|
||
|
||
res_event->type = GetGeometry;
|
||
|
||
if (!_XEditResGet16(stream, &(res_event->num_entries)))
|
||
goto done;
|
||
|
||
res_event->info = (GetResourcesInfo *)
|
||
XtCalloc(sizeof(GetResourcesInfo),
|
||
res_event->num_entries);
|
||
|
||
for (i = 0; i < (int)res_event->num_entries; i++) {
|
||
GetResourcesInfo * res_info = res_event->info + i;
|
||
if (!(_XEditResGetWidgetInfo(stream, &(res_info->widgets)) &&
|
||
_XEditResGetBoolean(stream, &(res_info->error))))
|
||
{
|
||
goto done;
|
||
}
|
||
if (res_info->error) {
|
||
if (!_XEditResGetString8(stream, &(res_info->message)))
|
||
goto done;
|
||
}
|
||
else {
|
||
unsigned int j;
|
||
|
||
if (!_XEditResGet16(stream, &(res_info->num_resources)))
|
||
goto done;
|
||
|
||
res_info->res_info = (ResourceInfo *)
|
||
XtCalloc(sizeof(ResourceInfo),
|
||
res_info->num_resources);
|
||
|
||
for (j = 0; j < res_info->num_resources; j++) {
|
||
unsigned char temp;
|
||
ResourceInfo * info = res_info->res_info + j;
|
||
if (!(_XEditResGetResType(stream, &(temp)) &&
|
||
_XEditResGetString8(stream, &(info->name)) &&
|
||
_XEditResGetString8(stream, &(info->class)) &&
|
||
_XEditResGetString8(stream, &(info->type))))
|
||
{
|
||
goto done;
|
||
}
|
||
else
|
||
info->res_type = (ResourceType) temp;
|
||
} /* for */
|
||
} /* else */
|
||
} /* for */
|
||
}
|
||
break;
|
||
case LocalFlashWidget:
|
||
case LocalGetGeometry:
|
||
{
|
||
GetGeomEvent * geom_event = (GetGeomEvent *) event;
|
||
|
||
geom_event->type = GetGeometry;
|
||
|
||
if (!_XEditResGet16(stream, &(geom_event->num_entries)))
|
||
goto done;
|
||
|
||
geom_event->info = (GetGeomInfo *) XtCalloc(sizeof(GetGeomInfo),
|
||
geom_event->num_entries);
|
||
|
||
for (i = 0; i < (int)geom_event->num_entries; i++) {
|
||
GetGeomInfo * info = geom_event->info + i;
|
||
if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
|
||
_XEditResGetBoolean(stream, &(info->error))))
|
||
{
|
||
goto done;
|
||
}
|
||
if (info->error) {
|
||
if (!_XEditResGetString8(stream, &(info->message)))
|
||
goto done;
|
||
}
|
||
else {
|
||
if (!(_XEditResGetBoolean(stream, &(info->visable)) &&
|
||
_XEditResGetSigned16(stream, &(info->x)) &&
|
||
_XEditResGetSigned16(stream, &(info->y)) &&
|
||
_XEditResGet16(stream, &(info->width)) &&
|
||
_XEditResGet16(stream, &(info->height)) &&
|
||
_XEditResGet16(stream, &(info->border_width))))
|
||
{
|
||
goto done;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case LocalFindChild:
|
||
{
|
||
FindChildEvent * find_event = (FindChildEvent *) event;
|
||
|
||
find_event->type = FindChild;
|
||
|
||
if (!_XEditResGetWidgetInfo(stream, &(find_event->widgets)))
|
||
goto done;
|
||
}
|
||
break;
|
||
case LocalGetValues: /* This is for REPLY... */
|
||
{
|
||
Arg args[1];
|
||
GetValuesEvent * gv_event = (GetValuesEvent *) event;
|
||
|
||
gv_event->type = GetValues;
|
||
|
||
if (!_XEditResGet16(stream, &(gv_event->num_entries)))
|
||
goto done;
|
||
|
||
gv_event->info = (GetValuesInfo*)XtCalloc(sizeof(GetValuesInfo),1);
|
||
|
||
{
|
||
GetValuesInfo * info = gv_event->info;
|
||
if (!(_XEditResGetString8(stream, &(info->value))))
|
||
{
|
||
goto done;
|
||
}
|
||
|
||
/* set the string value of the asciitext widget. note that only
|
||
* one active node is dealt with here. This is ok because only
|
||
* one node can be active when the resource box is up.
|
||
*/
|
||
|
||
XtSetArg (args[0], XtNstring, info->value);
|
||
|
||
XtSetValues(
|
||
global_tree_info->active_nodes[0]->resources->res_box->value_wid,
|
||
args, 1
|
||
);
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
goto done;
|
||
}
|
||
|
||
return(event);
|
||
|
||
done:
|
||
FreeEvent(event);
|
||
return(NULL);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: FreeEvent
|
||
* Description: Frees all memory associated with the event.
|
||
* Arguments: event - the event.
|
||
* Returns: none.
|
||
*
|
||
* NOTE: XtFree() returns w/o freeing if ptr is NULL.
|
||
*/
|
||
|
||
static void
|
||
FreeEvent(Event *event)
|
||
{
|
||
unsigned int i;
|
||
|
||
switch(event->any_event.type) {
|
||
case SendWidgetTree:
|
||
{
|
||
SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
|
||
WidgetTreeInfo * info = send_event->info;
|
||
|
||
if (info != NULL) {
|
||
for (i = 0; i < send_event->num_entries; i++, info++) {
|
||
XtFree((char *)info->widgets.ids);
|
||
XtFree(info->name);
|
||
XtFree(info->class);
|
||
}
|
||
XtFree((char *)send_event->info);
|
||
}
|
||
}
|
||
break;
|
||
case SetValues:
|
||
{
|
||
SetValuesEvent * sv_event = (SetValuesEvent *) event;
|
||
SetValuesInfo * info = sv_event->info;
|
||
|
||
if (info != NULL) {
|
||
for (i = 0; i < sv_event->num_entries; i++, info++) {
|
||
XtFree((char *)info->widgets.ids);
|
||
XtFree(info->message);
|
||
}
|
||
XtFree((char *)sv_event->info);
|
||
}
|
||
}
|
||
break;
|
||
case GetResources:
|
||
{
|
||
GetResourcesEvent * get_event = (GetResourcesEvent *) event;
|
||
GetResourcesInfo * info = get_event->info;
|
||
|
||
if (info != NULL) {
|
||
for (i = 0; i < get_event->num_entries; i++, info++) {
|
||
XtFree((char *)info->widgets.ids);
|
||
if (info->error)
|
||
XtFree(info->message);
|
||
else {
|
||
unsigned int j;
|
||
ResourceInfo * res_info = info->res_info;
|
||
|
||
if (res_info != NULL) {
|
||
for (j = 0;
|
||
j < info->num_resources; j++, res_info++)
|
||
{
|
||
XtFree(res_info->name);
|
||
XtFree(res_info->class);
|
||
XtFree(res_info->type);
|
||
}
|
||
XtFree((char *)info->res_info);
|
||
}
|
||
}
|
||
}
|
||
XtFree((char *)get_event->info);
|
||
}
|
||
}
|
||
break;
|
||
case GetGeometry:
|
||
{
|
||
GetGeomEvent * geom_event = (GetGeomEvent *) event;
|
||
GetGeomInfo * info = geom_event->info;
|
||
|
||
if (info != NULL) {
|
||
for (i = 0; i < geom_event->num_entries; i++, info++) {
|
||
XtFree((char *)info->widgets.ids);
|
||
if (info->error)
|
||
XtFree(info->message);
|
||
}
|
||
XtFree((char *)geom_event->info);
|
||
}
|
||
}
|
||
break;
|
||
case FindChild:
|
||
{
|
||
FindChildEvent * find_event = (FindChildEvent *) event;
|
||
|
||
XtFree((char *)find_event->widgets.ids);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: DispatchEvent
|
||
* Description: Handles the event, calling the proper function.
|
||
* Arguments: event - the event.
|
||
* Returns: one.
|
||
*/
|
||
|
||
static char *
|
||
DispatchEvent(Event *event)
|
||
{
|
||
char * error = NULL;
|
||
|
||
switch(global_client.command) {
|
||
case LocalSendWidgetTree:
|
||
BuildVisualTree(global_tree_parent, event);
|
||
break;
|
||
case LocalSetValues:
|
||
error = PrintSetValuesError(event);
|
||
break;
|
||
case LocalFlashWidget:
|
||
error = HandleFlashWidget(event);
|
||
break;
|
||
case LocalGetResources:
|
||
error = HandleGetResources(event);
|
||
break;
|
||
case LocalFindChild:
|
||
DisplayChild(event);
|
||
break;
|
||
case LocalGetValues:
|
||
break;
|
||
default:
|
||
{
|
||
char msg[BUFSIZ];
|
||
sprintf(msg, "Internal error: Unknown command %d.",
|
||
global_client.command);
|
||
error = XtNewString(msg);
|
||
}
|
||
break;
|
||
}
|
||
return(error);
|
||
}
|
||
|
||
|
||
|
||
/* Function Name: InternAtoms
|
||
* Description: interns all static atoms.
|
||
* Arguments: display - the current display.
|
||
* Returns: none.
|
||
*/
|
||
|
||
void
|
||
InternAtoms(Display * dpy)
|
||
{
|
||
atom_comm = XInternAtom(dpy, EDITRES_COMM_ATOM, False);
|
||
atom_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
|
||
atom_resource_editor = XInternAtom(dpy, EDITRES_NAME, False);
|
||
atom_client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
|
||
atom_editres_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM, False);
|
||
}
|
||
|
||
ResIdent
|
||
GetNewIdent(void)
|
||
{
|
||
static ResIdent ident = 1;
|
||
|
||
return(ident++);
|
||
}
|
||
|