diff options
Diffstat (limited to 'comm.c')
-rw-r--r-- | comm.c | 962 |
1 files changed, 962 insertions, 0 deletions
@@ -0,0 +1,962 @@ +/* $Xorg: comm.c,v 1.5 2001/02/09 02:05:29 xorgcvs Exp $ */ +/* + +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 "editresP.h" + +/* + * static Globals. + */ + +static Atom atom_comm, atom_command, atom_resource_editor, atom_client_value; +static Atom atom_editres_protocol; + +/* + * external function definitions. + */ + +extern void RebuildMenusAndLabel(); +extern ResIdent GetNewIdent(); +extern void SetMessage(), BuildVisualTree(),DisplayChild(); +extern char * GetFormattedSetValuesError(), *HandleFlashWidget(); +extern char * HandleGetResources(), *PrintSetValuesError(); +char * GetFailureMessage(), * ProtocolFailure(); +extern int HandleXErrors(); +extern void SetEntriesSensitive(); + +static void TellUserAboutMessage(), BuildHeader(), FreeEvent(); +static Event * BuildEvent(); +static char * DispatchEvent(); +static void GetClientValue(); +static void ClientTimedOut(), LoseSelection(), SelectionDone(); +static Boolean ConvertCommand(); + + +extern Widget CM_entries[NUM_CM_ENTRIES], TM_entries[NUM_TM_ENTRIES]; + + + +/* 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(data, id) +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(w, x, y) +Widget w; +int *x, *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(w, command, msg) + 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(label, command) +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(w,selection,target,type_ret, value_ret, length_ret, format_ret) +Widget w; +Atom * selection, * target, * 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(w, sel, targ) + Widget w; + Atom *sel, *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(w, sel) +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(w, data, selection, type, value, length, format) +Widget w; +XtPointer data, value; +Atom *selection, *type; +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(client_data) +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(stream) +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 * 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 * 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(dpy) +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() +{ + static ResIdent ident = 1; + + return(ident++); +} + |