/* $XConsortium: pack.c /main/5 1995/07/15 20:42:45 drk $ */ /* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * */ /* * HISTORY */ #include "wsm_proto.h" /* this will redifine bzero to memset if needed. */ #include #define COUNT_SIZE (sizeof(CARD16)) #define BOOL_SIZE 1 /* at least 1 byte for a boolean. */ /* * More intuitive names for various functions. */ #define PackBoolean(d, num) PackCARD8((d), (CARD8) (num)) #define PackListNum(d, num) PackCARD16((d), (CARD16) (num)) #define PackWindow(d, num) PackCARD32((d), (CARD32) (num)) #define PackProperty(d, num) PackCARD32((d), (CARD32) (num)) #define UnpackBoolean(data) ((Boolean) UnpackCARD8(data)) #define UnpackListNum(data) ((int) UnpackCARD16(data)) #define UnpackWindow(data) ((Window) UnpackCARD32(data)) #define UnpackProperty(data) ((WindowProperty) UnpackCARD32(data)) #define START_CHECK_MASK 0x80 /************************************************************ * * Function definitions. * ************************************************************/ /* * Routines for getting the amount of space that a request will take in the * protocol data stream. */ static int WinInfoSizePacked(Display *, int, WSMWinInfo *); static int WinEntrySizePacked(Display *, int, WSMWinEntry *); static int WinDataSizePacked(Display *, int, WSMWinData *, int, WSMConfigFormatType); /* * Routines for packing protocol data stream. */ static MessageData PackConfigFormat(MessageData, WSMConfigFormatReply *); static MessageData PackSingleAttribute(MessageData, WSMAttribute *, int); static MessageData PackWinInfo(Display *, int, MessageData, WSMWinInfo *); static MessageData PackWinEntry(Display *, int, MessageData, WSMWinEntry *); static MessageData PackWinData(Display *, int, MessageData, WSMWinData *, int, WSMConfigFormatType); /* public */ MessageData PackCARD16(MessageData, CARD16); /* public */ MessageData PackCARD8(MessageData, CARD8); /* public */ MessageData PackString(MessageData, String); /* public */ MessageData PackCARD32(MessageData, CARD32); /* * Routines for unpacking protocol data stream. */ static void UnpackWinData(MessageData *, Display *, int, WSMConfigFormatType, WSMWinData **, int *); static void UnpackSingleWinDataRec(MessageData *, WSMAttribute *,WSMWinData *); static void UnpackWinInfo(MessageData *, Display *, int, WSMWinInfo *); static void UnpackWinEntry(MessageData *, Display *, int, WSMWinEntry *); /* public */ String UnpackString(MessageData *); /* public */ CARD32 UnpackCARD32(MessageData *); /* public */ CARD16 UnpackCARD16(MessageData *); /* public */ CARD8 UnpackCARD8(MessageData *); /************************************************************ * * These two routines take data stored in a structure that * humans can understand and pack it down into nice little * protocol requests defined by the OSF WSM Protocol spec. * ************************************************************/ /* Function Name: _WSMPackRequest * Description: Packs up the request passed into an appropriate * message data structure. * Arguments: dpy - the display we will be sending this message on. * screen_num - The screen we will be sending this message to. * request - request to send. * RETURNED msg_data_len - The length of the message data. * RETURNED error - An error code if something went wrong. * Returns: A pointer to a message data struct. * * NOTE: The message data struct must be freed by the calling routine. */ MessageData _WSMPackRequest(Display *dpy, int screen_num, WSMRequest *request, unsigned long *msg_data_len, WSMErrorCode *error) { MessageData data, save; int i; long size; WSMWinInfo *win_info; WSMConfigFormatData *global_attrs, *win_attrs, *icon_attrs; *msg_data_len = 0; /* default value. */ global_attrs = _WSMGetConfigFormat(dpy, screen_num, WSM_GLOBAL_FMT); win_attrs = _WSMGetConfigFormat(dpy, screen_num, WSM_WINDOW_FMT); icon_attrs = _WSMGetConfigFormat(dpy, screen_num, WSM_ICON_FMT); *error = WSM_SUCCESS; if (_WSMRequiresConfigFormat(request->any.type) && (global_attrs->num_attrs == 0) && (win_attrs->num_attrs == 0) && (icon_attrs->num_attrs == 0)) { *error = WSM_ERROR_NO_CONFIG_FORMAT; return(NULL); } if (((request->any.type == WSM_CONNECT) || (request->any.type == WSM_CONFIG_FMT)) && ((global_attrs->num_attrs != 0) || (win_attrs->num_attrs != 0) || (icon_attrs->num_attrs != 0))) { *error = WSM_ERROR_ALREADY_HAVE_CONFIG_FORMAT; return(NULL); } /* before sending extensions make sure screen_info config format is cleared */ /* may want to remove this and leave it up to application writer */ if ((request->any.type == WSM_EXTENSIONS) && ((global_attrs->num_attrs != 0) || (win_attrs->num_attrs != 0) || (icon_attrs->num_attrs != 0))) { _WSMClearConfigScreenInfo(dpy,screen_num); } /* * Calculate the size of the request. */ switch (request->any.type) { case WSM_CONNECT: size = COUNT_SIZE; size += sizeof(CARD8) * request->connect.num_versions; break; case WSM_EXTENSIONS: size = COUNT_SIZE; for (i = 0; i < request->extensions.num_extensions; i++) { size += (strlen(request->extensions.extension_suggestions[i]) + COUNT_SIZE); } break; case WSM_CONFIG_FMT: size = 0; break; case WSM_GET_STATE: size = sizeof(CARD32) + BOOL_SIZE; break; case WSM_SET_STATE: size = COUNT_SIZE; /* The count of window info. */ win_info = request->set_state.win_info_list; for (i = 0; i < request->set_state.num_win_info_list; i++,win_info++) size += WinInfoSizePacked(dpy, screen_num, win_info); break; case WSM_REG_WINDOW: size = sizeof(CARD32); break; case WSM_WM_GET_BACKGROUND_WINDOW: size = sizeof(CARD16); break; case WSM_WM_SET_BACKGROUND_WINDOW: size = sizeof(CARD32); break; case WSM_WM_WINDOWS: size = sizeof(CARD32); /* flag */ size += COUNT_SIZE; /* prop count */ size += request->wm_windows.num_window_properties * sizeof(Window); size += COUNT_SIZE; /* num match attributes */ for (i=0; iwm_windows.num_match_attributes; i++) { size += COUNT_SIZE; /* num attributes */ size += 2 * request->wm_windows.match_attributes[i]->num_attributes * sizeof(WindowProperty); } break; case WSM_WM_FOCUS: size = 0; break; case WSM_WM_POINTER: size = 0; break; default: return(NULL); } save = data = (MessageData) XtMalloc(size); /* * Fill in the message. */ switch (request->any.type) { case WSM_CONNECT: data = PackListNum(data, request->connect.num_versions); for (i = 0; i < request->connect.num_versions; i++) data = PackCARD8(data, (CARD8) request->connect.known_versions[i]); break; case WSM_EXTENSIONS: data = PackListNum(data, request->extensions.num_extensions); for (i = 0; i < request->extensions.num_extensions; i++) data=PackString(data,request->extensions.extension_suggestions[i]); break; case WSM_CONFIG_FMT: break; case WSM_GET_STATE: data = PackWindow(data, request->get_state.window); (void) PackBoolean(data, request->get_state.diffs_allowed); break; case WSM_SET_STATE: win_info = request->set_state.win_info_list; data = PackListNum(data, request->set_state.num_win_info_list); for (i = 0; i < request->set_state.num_win_info_list; i++, win_info++) data = PackWinInfo(dpy, screen_num, data, win_info); break; case WSM_REG_WINDOW: (void) PackWindow(data, request->register_window.window); break; case WSM_WM_GET_BACKGROUND_WINDOW: (void) PackCARD16(data, request->get_background.screen); break; case WSM_WM_SET_BACKGROUND_WINDOW: (void) PackWindow(data, request->set_background.window); break; case WSM_WM_WINDOWS: { int i, j; data = PackCARD32(data, request->wm_windows.location_flag); data = PackListNum(data, request->wm_windows.num_window_properties); for (i=0; iwm_windows.num_window_properties; i++) data = PackProperty(data, request->wm_windows.window_properties[i]); data = PackListNum(data, request->wm_windows.num_match_attributes); for (i = 0; i < request->wm_windows.num_match_attributes; i++) { AttributePair *match_attr; match_attr = request->wm_windows.match_attributes[i]; data = PackListNum(data, match_attr->num_attributes); for (j = 0; j < match_attr->num_attributes; j++) data = PackProperty(data, match_attr->allowed_attributes[j]); for (j = 0; j < match_attr->num_attributes; j++) data = PackProperty(data, match_attr->prohibited_attributes[j]); } } break; case WSM_WM_FOCUS: break; case WSM_WM_POINTER: break; default: break; } *msg_data_len = size; return(save); } /* _WSMPackRequest */ /* Function Name: _WSMPackReply * Description: Packs up the Reply passed into an appropriate * message data structure. * Arguments: dpy - the display we will be sending this message on. * screen_num - The screen we will be sending this message to. * reply - reply to send. * RETURNED msg_data_len - The length of the message data. * Returns: A pointer to a message data struct. * * NOTE: The message data struct must be freed by the calling routine. */ MessageData _WSMPackReply(Display *dpy, int screen_num, WSMReply *reply, unsigned long *msg_data_len) { WSMAttribute *attr; WSMWinInfo *win_info; WSMWinEntry *win_entry; register int i; long size; MessageData data, save; *msg_data_len = 0; /* default value. */ switch (reply->any.type) { case WSM_CONNECT: size = sizeof(CARD8); break; case WSM_EXTENSIONS: size = COUNT_SIZE; for (i = 0; i < reply->extensions.num_extensions; i++) { size += (strlen(reply->extensions.extensions[i]) + COUNT_SIZE); } break; case WSM_CONFIG_FMT: size = BOOL_SIZE; /* accept_diffs. */ size += COUNT_SIZE; /* The count of global attributes. */ attr = reply->config_format.global_formats; for (i = 0; i < reply->config_format.num_global_formats; i++) { /* * Bytes in string */ size += strlen(XrmQuarkToString(attr[i].nameq)) * sizeof(CARD8); /* * len of string + size + is_list. */ size += COUNT_SIZE + sizeof(CARD8) + BOOL_SIZE; } size += COUNT_SIZE; /* The count of window attributes. */ attr = reply->config_format.window_formats; for (i = 0; i < reply->config_format.num_window_formats; i++) { /* * Bytes in string */ size += strlen(XrmQuarkToString(attr[i].nameq)) * sizeof(CARD8); /* * len of string + size + is_list. */ size += COUNT_SIZE + sizeof(CARD8) + BOOL_SIZE; } size += COUNT_SIZE; /* The count of icon attributes. */ attr = reply->config_format.icon_formats; for (i = 0; i < reply->config_format.num_icon_formats; i++) { /* * Bytes in string */ size += strlen(XrmQuarkToString(attr[i].nameq)) * sizeof(CARD8); /* * len of string + size + is_list. */ size += COUNT_SIZE + sizeof(CARD8) + BOOL_SIZE; } break; case WSM_GET_STATE: size = COUNT_SIZE; /* The count of window info. */ win_info = reply->get_state.win_info_list; for (i = 0; i < reply->get_state.num_win_info_list; i++,win_info++) size += WinInfoSizePacked(dpy, screen_num, win_info); break; case WSM_SET_STATE: size = 0; break; case WSM_REG_WINDOW: size = WinDataSizePacked(dpy, screen_num, reply->register_window.window_data, reply->register_window.num_window_data, WSM_WINDOW_FMT); break; case WSM_WM_GET_BACKGROUND_WINDOW: size = sizeof(CARD32); break; case WSM_WM_SET_BACKGROUND_WINDOW: size = sizeof(CARD32); break; case WSM_WM_WINDOWS: size = COUNT_SIZE; /* The count of window entries. */ win_entry = reply->wm_windows.win_entry_list; for (i = 0; i < reply->wm_windows.num_win_entry_list; i++,win_entry++) size += WinEntrySizePacked(dpy, screen_num, win_entry); break; case WSM_WM_FOCUS: size = sizeof(CARD32); break; case WSM_WM_POINTER: size = sizeof(CARD32); /* window */ size += sizeof(CARD32); /* flag */ break; default: /* * ||| Error Message. */ return(NULL); } save = data = (MessageData) XtMalloc(size); switch (reply->any.type) { case WSM_CONNECT: (void) PackCARD8(data, (CARD8) (reply->connect.version & 0xFF)); break; case WSM_EXTENSIONS: data = PackListNum(data, reply->extensions.num_extensions); for (i = 0; i < reply->extensions.num_extensions; i++) data = PackString(data, reply->extensions.extensions[i]); break; case WSM_CONFIG_FMT: PackConfigFormat(data, &(reply->config_format)); break; case WSM_GET_STATE: win_info = reply->get_state.win_info_list; data = PackListNum(data, reply->get_state.num_win_info_list); for (i = 0; i < reply->get_state.num_win_info_list; i++, win_info++) data = PackWinInfo(dpy, screen_num, data, win_info); break; case WSM_SET_STATE: break; case WSM_REG_WINDOW: data = PackWinData(dpy, screen_num, data, reply->register_window.window_data, reply->register_window.num_window_data, WSM_WINDOW_FMT); break; case WSM_WM_GET_BACKGROUND_WINDOW: (void) PackWindow(data, reply->get_background.window); break; case WSM_WM_SET_BACKGROUND_WINDOW: (void) PackWindow(data, reply->set_background.window); break; case WSM_WM_WINDOWS: win_entry = reply->wm_windows.win_entry_list; data = PackListNum(data, reply->wm_windows.num_win_entry_list); for (i = 0; i < reply->wm_windows.num_win_entry_list; i++, win_entry++) data = PackWinEntry(dpy, screen_num, data, win_entry); break; case WSM_WM_FOCUS: (void) PackWindow(data, reply->wm_focus.window); break; case WSM_WM_POINTER: (void) PackWindow(data, reply->wm_pointer.window); (void) PackCARD32(data, reply->wm_pointer.location_flag); break; default: break; } *msg_data_len = size; return(save); }/* _WSMPackReply */ /************************************************************ * * These routines take data on the wire and put it into a structure * that can be manipulated by the app. * ************************************************************/ /* Function Name: _WSMUnpackRequest * Description: Unpacks the byte stream from the wire into a request * message structure. * Arguments: dpy - The Display. * screen_num - The Screen number. * data - The bits from accross the wire. * len - The number of bits sent - Better error checking * makes this more necessary. * type - The type of message received. * RETURNED request - This request structure is filled in with the data * unpacked from the protocol. * Returns: none. */ /*ARGSUSED*/ void _WSMUnpackRequest(Display *dpy, int screen_num, MessageData data, unsigned long len, WSMRequestType type, WSMRequest *request) { register int i; request->any.type = type; /* Save the type. */ request->any.allocated = False; switch (request->any.type) { case WSM_CONNECT: request->connect.num_versions = UnpackListNum(&data); request->connect.known_versions = (short *) XtMalloc(sizeof(short) * request->connect.num_versions); request->connect.allocated = True; for (i = 0; i < request->connect.num_versions; i++) request->connect.known_versions[i] = (short) UnpackCARD8(&data); break; case WSM_EXTENSIONS: { register int num; register String *ptr; num = request->extensions.num_extensions = UnpackListNum(&data); ptr = (String *) XtMalloc(sizeof(String) * num); request->extensions.extension_suggestions = ptr; request->extensions.allocated = True; for (i = 0; i < num; i++, ptr++) *ptr = UnpackString(&data); } break; case WSM_CONFIG_FMT: break; case WSM_GET_STATE: request->get_state.window = UnpackWindow(&data); request->get_state.diffs_allowed = UnpackBoolean(&data); break; case WSM_SET_STATE: { int num = UnpackListNum(&data); request->set_state.num_win_info_list = num; request->set_state.win_info_list = (WSMWinInfo *) XtMalloc(sizeof(WSMWinInfo) * num); request->extensions.allocated = True; for (i = 0; i < num; i++) { UnpackWinInfo(&data, dpy, screen_num, request->set_state.win_info_list + i); } } break; case WSM_REG_WINDOW: request->register_window.window = UnpackWindow(&data); break; case WSM_WM_GET_BACKGROUND_WINDOW: request->get_background.screen = (int)UnpackCARD16(&data); break; case WSM_WM_SET_BACKGROUND_WINDOW: request->set_background.window = UnpackWindow(&data); break; case WSM_WM_WINDOWS: { int num, i, j; request->extensions.allocated = True; request->wm_windows.location_flag = UnpackCARD32(&data); num = request->wm_windows.num_window_properties = UnpackListNum(&data); request->wm_windows.window_properties = (WindowProperty *) XtMalloc(sizeof(WindowProperty) * num); for (i=0; iwm_windows.window_properties[i] = UnpackProperty(&data); num = request->wm_windows.num_match_attributes = UnpackListNum(&data); request->wm_windows.match_attributes = (AttributePair **) XtMalloc(sizeof(AttributePair*) * num); for (i=0; iwm_windows.num_match_attributes; i++) { num = UnpackListNum(&data); request->wm_windows.match_attributes[i] = (AttributePair *) XtMalloc(sizeof(AttributePair) * num * 2 + sizeof(int)); request->wm_windows.match_attributes[i]->num_attributes = num; for (j=0; jwm_windows.match_attributes[i]->allowed_attributes[j] = UnpackProperty(&data); } for (j=0; jwm_windows.match_attributes[i]->prohibited_attributes[j] = UnpackProperty(&data); } } } break; case WSM_WM_FOCUS: break; case WSM_WM_POINTER: break; default: break; } } /* _WSMUnpackRequest */ /* Function Name: _WSMUnpackReply * Description: Unpacks the byte stream from the wire into a reply * message structure. * Arguments: dpy - The Display. * screen_num - The Screen number. * data - the bits from accross the wire. * len - The number of bits sent - Better error checking * makes this more necessary. * type - The type of message received. * RETURNED reply - This reply structure is filled in with the data * unpacked from the protocol. * Returns: none. */ /*ARGSUSED*/ void _WSMUnpackReply(Display *dpy, int screen_num, MessageData data, unsigned long len, WSMRequestType type, WSMReply *reply) { register int i; reply->any.type = type; /* Save the type. */ reply->any.allocated = False; switch (reply->any.type) { case WSM_CONNECT: reply->connect.version = (short) UnpackCARD8(&data); break; case WSM_EXTENSIONS: { register int num; register String *ptr; num = reply->extensions.num_extensions = UnpackListNum(&data); ptr = (String *) XtMalloc(sizeof(String) * num); reply->extensions.allocated = True; reply->extensions.extensions = ptr; for (i = 0; i < num; i++, ptr++) *ptr = UnpackString(&data); } break; case WSM_CONFIG_FMT: { register int types; WSMConfigFormatReply * config_format = &(reply->config_format); WSMConfigFormatData *fmt; WSMScreenInfo *scr_info = _WSMGetScreenInfo(dpy, screen_num); config_format->accepts_diffs = UnpackBoolean(&data); for (types = 0; types < 3; types++) { switch(types) { case WSM_GLOBAL_FMT: fmt = &(scr_info->global); break; case WSM_WINDOW_FMT: fmt = &(scr_info->window); break; case WSM_ICON_FMT: fmt = &(scr_info->icon); break; } fmt->num_attrs = UnpackListNum(&data); fmt->attr_list = (WSMAttribute *) XtMalloc(sizeof(WSMAttribute) * fmt->num_attrs); for (i = 0; i < fmt->num_attrs; i++) { String str = UnpackString(&data); fmt->attr_list[i].nameq = XrmStringToQuark(str); XtFree(str); fmt->attr_list[i].size = UnpackCARD8(&data); fmt->attr_list[i].is_list = UnpackCARD8(&data); } } /* * No need to allocate this, since they are just pointers * back to global data. */ config_format->global_formats = scr_info->global.attr_list; config_format->num_global_formats = scr_info->global.num_attrs; config_format->window_formats = scr_info->window.attr_list; config_format->num_window_formats = scr_info->window.num_attrs; config_format->icon_formats = scr_info->icon.attr_list; config_format->num_icon_formats = scr_info->icon.num_attrs; } break; case WSM_GET_STATE: { int num =reply->get_state.num_win_info_list = UnpackListNum(&data); reply->get_state.win_info_list = (WSMWinInfo *) XtMalloc(sizeof(WSMWinInfo) * num); reply->get_state.allocated = True; for (i = 0; i < num; i++) UnpackWinInfo(&data, dpy, screen_num, reply->get_state.win_info_list + i); } break; case WSM_SET_STATE: break; case WSM_REG_WINDOW: UnpackWinData(&data, dpy, screen_num, WSM_WINDOW_FMT, &(reply->register_window.window_data), &(reply->register_window.num_window_data)); reply->register_window.allocated = True; break; case WSM_WM_GET_BACKGROUND_WINDOW: reply->get_background.window = UnpackWindow(&data); break; case WSM_WM_SET_BACKGROUND_WINDOW: reply->set_background.window = UnpackWindow(&data); break; case WSM_WM_WINDOWS: { int num; num = reply->wm_windows.num_win_entry_list = UnpackListNum(&data); reply->wm_windows.win_entry_list = (WSMWinEntry *) XtMalloc(sizeof(WSMWinEntry) * num); reply->wm_windows.allocated = True; for (i = 0; i < num; i++) UnpackWinEntry(&data, dpy, screen_num, reply->wm_windows.win_entry_list + i); } break; case WSM_WM_FOCUS: reply->wm_focus.window = UnpackWindow(&data); break; case WSM_WM_POINTER: reply->wm_pointer.location_flag = UnpackCARD32(&data); break; default: break; } } /* _WSMUnpackReply */ /************************************************************ * * Internal Routines for getting size of packed requests. * ************************************************************/ /* Function Name: WinInfoSizePacked * Description: Returns the size this window structure will take * when packed into a protocol data stream. * Arguments: dpy, screen_num - The display and screen of the client we * are talking to. * win_info - The window info whose size me are checking. * Returns: the size (in bytes) */ static int WinInfoSizePacked(Display *dpy, int screen_num, WSMWinInfo *win_info) { int size = sizeof(CARD32); size += WinDataSizePacked(dpy, screen_num, win_info->data_list, win_info->num_data_list, _WSMGetConfigFormatType(win_info->window)); return(size); } /* Function Name: WinEntrySizePacked * Description: Returns the size this window structure will take * when packed into a protocol data stream. * Arguments: dpy, screen_num - The display and screen of the client we * are talking to. * win_entry - The window entry whose size we are checking. * Returns: the size (in bytes) */ static int WinEntrySizePacked(Display *dpy, int screen_num, WSMWinEntry *win_entry) { int size; size = sizeof(CARD32); size += sizeof(CARD32) * win_entry->num_windows; size = sizeof(CARD32); size += sizeof(WindowProperty) * win_entry->num_match_properties; return(size); } /* Function Name: WinDataSizePacked * Description: The size that will be taken up with this window data * once it is packed into the protocol stream. * Arguments: dpy, screen_num - The screen nmuber and display that * we are talking to. * win_data - The data stored in a window data structure list. * num - number of items in the list. * fmt - The type of format to use to pack this data. * Returns: The size. */ static int WinDataSizePacked(Display *dpy, int screen_num, WSMWinData *win_data, int num, WSMConfigFormatType fmt) { register int i, size; WSMConfigFormatData *fmt_data = _WSMGetConfigFormat(dpy, screen_num, fmt); size = fmt_data->num_attrs / 8 + 1; /* Size of header bits. */ for ( i = 0; i < num; i++, win_data++) { WSMAttribute *attr = _WSMGetMatchingAttr(win_data->nameq, fmt_data); if (attr == NULL) { /* * ||| ERROR. */ continue; } switch(win_data->type) { case WSM_VALUE_DATA: size += attr->size/8; break; default: /* All others are lists. */ size += COUNT_SIZE; size += ((attr->size/8) * win_data->data_len); break; } } return(size); } /************************************************************ * * Internal Routines for packing data into the protocol stream. * ************************************************************/ /* Function Name: PackString * Description: Packs a string into the data stream. * Arguments: data - The data stream to pack into. * str - The string to pack. * Returns: data - A pointer into the next empty location in the * data stream. */ MessageData PackString(MessageData data, String str) { register int i, len = strlen(str); data = PackListNum(data, len); for (i = 0; i < len; i++, str++) data = PackCARD8(data, *str); return(data); } /* Function Name: PackConfigFormat * Description: Packs the configuration format into the data stream. * Arguments: data - the datastream. * config - the reply config format message. * Returns: data - A pointer into the next empty location in the * data stream. */ static MessageData PackConfigFormat(MessageData data, WSMConfigFormatReply *config) { data = PackBoolean(data, config->accepts_diffs); data = PackSingleAttribute(data, config->global_formats, config->num_global_formats); data = PackSingleAttribute(data, config->window_formats, config->num_window_formats); data = PackSingleAttribute(data, config->icon_formats, config->num_icon_formats); return(data); } /* Function Name: PackSingleAttribute * Description: Packs a single attribute into a the data stream. * Arguments: data - the datastream. * attr_list, num - The attribute list to pack into the stream. * The number of items in the list. * Returns: data - A pointer into the next empty location in the * data stream. */ static MessageData PackSingleAttribute(MessageData data, WSMAttribute *attr_list, int num) { register int i; data = PackListNum(data, num); for (i = 0; i < num; i++, attr_list++) { data = PackString(data, XrmQuarkToString(attr_list->nameq)); data = PackCARD8(data, (CARD8) attr_list->size); data = PackBoolean(data, attr_list->is_list); } return(data); } /* Function Name: PackWinInfo * Description: Packs the window information into the data stream. * Arguments: dpy, screen_num - The display and screen of the client * that we are talking to. * data - The message stream. * win_info - The window info list to pack into the data stream. * Returns: data - A pointer into the next empty location in the * data stream. */ static MessageData PackWinInfo(Display *dpy, int screen_num, MessageData data, WSMWinInfo *win_info) { data = PackWindow(data, win_info->window); return(PackWinData(dpy, screen_num, data, win_info->data_list, win_info->num_data_list, _WSMGetConfigFormatType(win_info->window))); } /* Function Name: PackWinEntry * Description: Packs the window information into the data stream. * Arguments: dpy, screen_num - The display and screen of the client * that we are talking to. * data - The message stream. * win_info - The window info list to pack into the data stream. * Returns: data - A pointer into the next empty location in the * data stream. */ static MessageData PackWinEntry(Display *dpy, int screen_num, MessageData data, WSMWinEntry *win_entry) { int i; data = PackListNum(data, win_entry->num_windows); for (i = 0; i < win_entry->num_windows; i++) data = PackWindow(data, win_entry->windows[i]); data = PackListNum(data, win_entry->num_match_properties); for (i = 0; i < win_entry->num_match_properties; i++) data = PackProperty(data, win_entry->match_properties[i]); return(data); } /* Function Name: PackWinData * Description: Packs the window data into the data stream. * Arguments: dpy, screen_num - The display and screen of the client * that we are talking to. * data - The message stream. * win_data, num - The window data to pack * into the data stream, and its size. * fmt - The type of config format to use. * Returns: data - A pointer into the next empty location in the * data stream. */ static MessageData PackWinData(Display *dpy, int screen_num, MessageData data, WSMWinData *win_data, int num, WSMConfigFormatType fmt) { WSMConfigFormatData *conf_fmt = _WSMGetConfigFormat(dpy, screen_num, fmt); MessageData mask_pos = data; WSMAttribute *attr; register int i, size = (conf_fmt->num_attrs / 8) + 1; data = (MessageData) ((char *)data + size); bzero((char *) mask_pos, size); /* Set all bits to zero initially*/ attr = conf_fmt->attr_list; for (i = 0; i < conf_fmt->num_attrs ; i++, attr++) { WSMWinData *this_data; this_data = _WSMGetMatchingWinData(win_data, num, attr->nameq); if (this_data != NULL) { if (this_data->type != WSM_VALUE_DATA) data = PackListNum(data, this_data->data_len); switch(this_data->type) { case WSM_CHAR_LIST_DATA: { register int j; char * ptr = this_data->data.char_ptr; for (j = 0 ; j < this_data->data_len; j++, ptr++) data = PackCARD8(data, (CARD8) *ptr); break; } case WSM_SHORT_LIST_DATA: { register int j; short * ptr = this_data->data.short_ptr; for (j = 0 ; j < this_data->data_len; j++, ptr++) data = PackCARD16(data, (CARD16) *ptr); break; } case WSM_LONG_LIST_DATA: { register int j; long * ptr = this_data->data.long_ptr; for (j = 0 ; j < this_data->data_len; j++, ptr++) data = PackCARD32(data, (CARD32) *ptr); break; } case WSM_VALUE_DATA: switch(attr->size) { case 8: data = PackCARD8(data, (CARD8) this_data->data.value); break; case 16: data = PackCARD16(data, (CARD16) this_data->data.value); break; case 32: data = PackCARD32(data, (CARD32) this_data->data.value); break; } } /* * The first item sets the MSBit, the 8th Item sets the LSBit. * The Nineth sets the MSBit in the second byte. The unused * bits are the LSBits of the last byte. */ (*(unsigned char *)mask_pos) |= (char)(1 << (7 - (i % 8))); } /* * When we get to the end of a char, move to the next one. */ if ((i % 8) == 7) mask_pos = ((char *)mask_pos + 1); } return(data); } /* Function Name: PackCARD32 * Description: Packs an 32 bit value into the data stream. * Arguments: data - The data stream to pack into. * val - The 32 bit value to pack. * Returns: data - A pointer into the next empty location in the * data stream. */ MessageData PackCARD32(MessageData data, CARD32 val) { CARD16 bottom = val & (0xFFFF); CARD16 top = val >> 16; data = PackCARD16(data, top); data = PackCARD16(data, bottom); return(data); } /* Function Name: PackCARD16 * Description: Packs an 16 bit value into the data stream. * Arguments: data - The data stream to pack into. * val - The 16 bit value to pack. * Returns: data - A pointer into the next empty location in the * data stream. */ MessageData PackCARD16(MessageData data, CARD16 val) { CARD8 bottom = val & (0xFF); CARD8 top = val >> 8; data = PackCARD8(data, top); data = PackCARD8(data, bottom); return(data); } /* Function Name: PackCARD8 * Description: Packs an 8 bit value into the data stream. * Arguments: data - The data stream to pack into. * val - The 8 bit value to pack. * Returns: data - A pointer into the next empty location in the * data stream. */ MessageData PackCARD8(MessageData data, CARD8 val) { CARD8 *ptr = (CARD8 *) data; *ptr = (CARD8) val; data = ((char*)data) + 1; return(data); } /************************************************************ * * Internal routines for unpacking the data from the * protocol stream. * ************************************************************/ /* Function Name: UnpackWinData * Description: Unpacks the window data from the protocol stream. * Arguments: data_ptr - A pointer to the message data stream. * dpy, screen_num - The display and screen of the client * that we are talking to. * fmt - The window format to use. * RETURNED win_data - The window data information. * RETURNED num - The number of window data structs in "win_data". * Returns: none */ static void UnpackWinData(MessageData *data_ptr, Display *dpy, int screen_num, WSMConfigFormatType fmt, WSMWinData **win_data, int *num) { register int i, size; WSMConfigFormatData *conf_fmt = _WSMGetConfigFormat(dpy, screen_num, fmt); unsigned char *bit_mask, *current_mask, check_mask; WSMAttribute *attr; WSMWinData *ptr; /* * Figure out how many values have been specified so we know how much * memory to allocate. */ size = conf_fmt->num_attrs / 8 + 1; current_mask = bit_mask = (unsigned char *) XtMalloc(size); /* * Unpack the bits from the wire. */ for (i = 0; i < size; i++, current_mask++) *current_mask = UnpackCARD8(data_ptr); current_mask = bit_mask; check_mask = START_CHECK_MASK; for (*num = 0, i = 0; i < conf_fmt->num_attrs; i++) { if (*current_mask & check_mask) (*num)++; check_mask >>= 1; if ((i % 8) == 7) { current_mask++; check_mask = START_CHECK_MASK; } } ptr = *win_data = (WSMWinData *) XtMalloc(*num * sizeof(WSMWinData)); /* * For each value that was specified pack the data into the window * data record. */ current_mask = bit_mask; check_mask = START_CHECK_MASK; attr = conf_fmt->attr_list; for (i = 0; i < conf_fmt->num_attrs; i++, attr++) { if (*current_mask & check_mask) UnpackSingleWinDataRec(data_ptr, attr, ptr++); check_mask >>= 1; if ((i % 8) == 7) { current_mask++; check_mask = START_CHECK_MASK; } } XtFree((XtPointer) bit_mask); } /* Function Name: UnpackSingleWinDataRec * Description: Packs a single window data record. * Arguments: data_ptr - The data pointer. * attr - The attribute record that defines general information * on how to unpack this data. * win_data - the window data struct. * Returns: none */ static void UnpackSingleWinDataRec(MessageData *data_ptr, WSMAttribute *attr, WSMWinData *win_data) { register int i; /* * Set these no matter what the size. */ win_data->nameq = attr->nameq; /* Save the name. */ if (attr->is_list) { win_data->data_len = UnpackListNum(data_ptr); } else { win_data->type = WSM_VALUE_DATA; win_data->data_len = 0; /* unused... */ } /* * Based on the size, and whether or not this is a list, unpack * the data from the wire. */ switch(attr->size) { case 8: if (attr->is_list) { char *local; win_data->type = WSM_CHAR_LIST_DATA; local = win_data->data.char_ptr = (char *) XtMalloc(sizeof(char) * win_data->data_len); for (i = 0; i < win_data->data_len; i++, local++) *local = UnpackCARD8(data_ptr); } else win_data->data.value = UnpackCARD8(data_ptr); break; case 16: if (attr->is_list) { short *local; win_data->type = WSM_SHORT_LIST_DATA; local = win_data->data.short_ptr = (short *) XtMalloc(sizeof(short) * win_data->data_len); for (i = 0; i < win_data->data_len; i++, local++) *local = UnpackCARD16(data_ptr); } else win_data->data.value = UnpackCARD16(data_ptr); break; case 32: if (attr->is_list) { long *local; win_data->type = WSM_LONG_LIST_DATA; local = win_data->data.long_ptr = (long *) XtMalloc(sizeof(long) * win_data->data_len); for (i = 0; i < win_data->data_len; i++, local++) *local = UnpackCARD32(data_ptr); } else win_data->data.value = UnpackCARD32(data_ptr); break; } } /* Function Name: UnpackWinInfo * Description: Unpacks the window information from the protocol stream. * Arguments: data_ptr - A pointer to the message data stream. * dpy, screen_num - The display and screen of the client * that we are talking to. * win_info - The window information. * Returns: none */ static void UnpackWinInfo(MessageData *data, Display *dpy, int screen_num, WSMWinInfo *win_info) { win_info->window = UnpackWindow(data); UnpackWinData(data, dpy, screen_num, _WSMGetConfigFormatType(win_info->window), &(win_info->data_list), &(win_info->num_data_list)); } /* Function Name: UnpackWinEntry * Description: Unpacks the window entry information from the protocol stream. * Arguments: data_ptr - A pointer to the message data stream. * dpy, screen_num - The display and screen of the client * that we are talking to. * win_entry - The window entry information. * Returns: none */ static void UnpackWinEntry(MessageData *data, Display *dpy, int screen_num, WSMWinEntry *win_entry) { int i; win_entry->num_windows = UnpackListNum(data); win_entry->windows = (Window *) XtMalloc(sizeof(Window) * win_entry->num_windows); for (i=0; inum_windows; i++) win_entry->windows[i] = UnpackWindow(data); win_entry->num_match_properties = UnpackListNum(data); win_entry->match_properties = (WindowProperty *) XtMalloc(sizeof(WindowProperty) * win_entry->num_match_properties); for (i=0; inum_match_properties; i++) win_entry->match_properties[i] = UnpackProperty(data); } /* Function Name: UnpackString * Description: Unpacks a string from the protocol data stream. * Arguments: data - Pointer to the data stream. * Returns: the string from the data stream. * * NOTE: Data is modified to point to the next empty location in the stream. */ String UnpackString(MessageData *data_ptr) { register int i; int len = UnpackListNum(data_ptr); char *str, *top = XtMalloc((len + 1) * sizeof(char)); for (str = top, i = 0; i < len; i++, str++) { *str = (char) UnpackCARD8(data_ptr); } *str = '\0'; return((String) top); } /* Function Name: UnpackCARD32 * Description: Unpacks an 32 bit value from the protocol data stream. * Arguments: data - Pointer to the data stream. * Returns: the CARD32 from the data stream. * * NOTE: data is modified to point to the next empty location in the stream. */ CARD32 UnpackCARD32(MessageData *data_ptr) { CARD32 val = UnpackCARD16(data_ptr) << 16; val |= UnpackCARD16(data_ptr); return(val); } /* Function Name: UnpackCARD16 * Description: Unpacks an 16 bit value from the protocol data stream. * Arguments: data - Pointer to the data stream. * Returns: the CARD16 from the data stream. * * NOTE: data is modified to point to the next empty location in the stream. */ CARD16 UnpackCARD16(MessageData *data_ptr) { CARD16 val = UnpackCARD8(data_ptr) << 8; val |= UnpackCARD8(data_ptr); return(val); } /* Function Name: UnpackCARD8 * Description: Unpacks an 8 bit value from the protocol data stream. * Arguments: data - Pointer to the data stream. * Returns: the CARD8 from the data stream. * * NOTE: data is modified to point to the next empty location in the stream. */ CARD8 UnpackCARD8(MessageData *data_ptr) { CARD8 ret_val = *((char *) *data_ptr); *data_ptr = ((char *) *data_ptr) + 1; return(ret_val); }