1
/* $XConsortium: send.c /main/5 1995/07/15 20:38:50 drk $ */
3
* @OPENGROUP_COPYRIGHT@
5
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
6
* Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
7
* ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
8
* the full copyright text.
10
* This software is subject to an open license. It may only be
11
* used on, with or for operating systems which are themselves open
12
* source systems. You must contact The Open Group for a license
13
* allowing distribution and sublicensing of this software on, with,
14
* or for operating systems which are not Open Source programs.
16
* See http://www.opengroup.org/openmotif/license for full
17
* details of the license agreement. Any use, reproduction, or
18
* distribution of the program constitutes recipient's acceptance of
21
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
22
* PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23
* KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
24
* WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
25
* OR FITNESS FOR A PARTICULAR PURPOSE
27
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
28
* NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
29
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
31
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
* ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
34
* EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
35
* POSSIBILITY OF SUCH DAMAGES.
42
#include <Xm/Transfer.h>
43
#include "wsm_proto.h"
46
typedef struct _RequestInfo {
47
WSMReplyCallbackFunc reply_callback; /* The reply callback func */
48
XtPointer reply_data; /* The user data for the callback func */
49
WSMRequestType request_type; /* The kind of request for cross check. */
50
Atom send_atom; /* The atom that we sent this message to. */
53
static void UTMReplyReceived(
54
Widget, XtPointer, XtPointer
57
static void ReplyReceived(
58
Widget, XtPointer, Atom *, Atom *, XtPointer, unsigned long *, int *
61
/* Function Name: WSMSendMessage
62
* Description: Sends a message to WSM or WM on the screen
63
* and display specified.
64
* Arguments: w - any widget on this display and screen that
65
* also has destination callback.
66
* Note - This widget MUST have the destination
67
* callback set to UTMDestinationProc that
68
* is defined in utm_send.c.
69
* send_to - either WSMWorkspaceManager or WSMWindowManager
70
* request - the request to send.
71
* reply_callback - The routine to call when the
73
* reply_data - Client data passed to the reply_callback.
74
* Returns: True if an attempt is made to retrieve the selection,
75
* False if an obvious error occured.
77
* NOTE: Reply callback will be called with reply == NULL if unable
82
WSMSendMessage(Widget w, WSMClientType send_to, WSMRequest *request,
83
WSMReplyCallbackFunc reply_callback, XtPointer reply_data)
85
int screen_num = XScreenNumberOfScreen(XtScreen(w));
86
Display *dpy = XtDisplay(w);
87
Atom send_atom = _WSMGetSelectionAtom(dpy, screen_num, send_to);
89
unsigned long msg_len;
90
RequestInfo *req_info;
92
Time time = GetTimestamp(dpy);
94
if (send_atom == None) {
95
fprintf(stderr, "%s: Could not get selection atom to send message\n",
101
* Package human-readable request data into protocol package.
103
msg_data = _WSMPackRequest(dpy, screen_num, request, &msg_len, &error);
104
if (msg_data == NULL) {
105
(*reply_callback)(w, reply_data, NULL, error);
109
req_info = (RequestInfo *) XtMalloc(sizeof(RequestInfo));
110
req_info->reply_callback = reply_callback; /* The reply callback func */
111
req_info->reply_data = reply_data; /* user data for the callback func */
112
req_info->request_type = request->any.type;/*request kind for cross check*/
113
req_info->send_atom = send_atom; /* Atom we sent this message to. */
115
if (!XtIsRealized(w)) {
116
fprintf(stderr, "%s WSMSendMessage must be realized, and is not.\n",
117
"Programmer Error: Widget passed to");
123
_WSMReqTypeToTarget(dpy, request->any.type),
124
(XtPointer) msg_data, msg_len, WSM_PROTO_FMT,
125
UTMReplyReceived, req_info,
131
/************************************************************
135
************************************************************/
138
/* Function Name: UTMReplyReceived
139
* Description: Called after the selection owner's convert proc
141
* Arguments: w - The widget who initiated the request.
147
UTMReplyReceived(Widget w, XtPointer clientData, XtPointer callData)
149
XmSelectionCallbackStruct *scs = (XmSelectionCallbackStruct *) callData;
150
RequestInfo *req_info = (RequestInfo *) clientData;
151
Boolean errorFound = False;
152
Atom type = _WSMReqTypeToTarget(XtDisplay(w), req_info->request_type);
154
/* Let's check some other values just to make sure things are ok. */
155
if (scs->reason != XmCR_OK) {
156
fprintf(stderr, "ERROR: Bad reason value received in UTMReplyReceived.\n");
159
if (scs->type == XT_CONVERT_FAIL) {
160
fprintf(stderr, "ERROR: Convert failure detected in UTMReplyReceived.\n");
163
if (scs->flags != XmSELECTION_DEFAULT) {
164
fprintf(stderr, "ERROR: Bad flags value received in UTMReplyReceived.\n");
171
req_info, /* the request info pointer to fill in. */
173
&type, /* type of request that was made. */
174
scs->value, /* data returned from conversion. */
180
/* Function Name: ReplyReceived
181
* Description: Called when a reply is received from a request
182
* initiated by a WSMSendMessage.
183
* Arguments: w - The widget who initiated the request.
184
* req_info_ptr - pointer to the request info.
185
* selection - The selection that has been converted.
186
* req_type_atom - The type of request that was made.
187
* length - the amount of message data.
188
* format - the format of the reply.
192
ReplyReceived(Widget w, XtPointer req_info_ptr,
193
Atom *selection, Atom *req_type_atom,
194
XtPointer value, unsigned long *length, int *format)
196
RequestInfo *req_info = (RequestInfo *) req_info_ptr;
198
Display *dpy = XtDisplay(w);
200
WSMErrorCode fail_code = WSM_SUCCESS;
203
* First a few checks to make sure everything is as we expect.
206
if (*selection != req_info->send_atom) {
207
fprintf(stderr, "%s, request %d - reply %d\n",
208
"Selection of the reply is not the same as the request",
209
(int) req_info->send_atom, (int) *selection);
211
fail_code = WSM_ERROR_INTERNAL;
213
if (*req_type_atom != _WSMReqTypeToTarget(dpy, req_info->request_type)) {
214
if (*req_type_atom == None) {
215
if (XGetSelectionOwner(dpy, *selection) == None)
217
fail_code = WSM_ERROR_NO_SEL_OWNER;
218
fprintf(stderr, "No owner for selection #%d\n", (int)*selection);
221
fail_code = WSM_ERROR_CONVERSION_FAILED;
223
else if (*req_type_atom == XT_CONVERT_FAIL)
224
fail_code = WSM_ERROR_TIMEOUT;
226
fprintf(stderr, "%s, request %s - reply %d:%s\n",
227
"Target of the reply is not the same as the request",
228
_WSMReqTypeToName(req_info->request_type),
229
(int) *req_type_atom,
230
_WSMReqTypeToName(_WSMTargetToReqType(dpy, *req_type_atom)));
232
fail_code = WSM_ERROR_INTERNAL;
235
if (*format != WSM_PROTO_FMT) {
236
fprintf(stderr, "%s, request %d - reply %d\n",
237
"Format of the reply is not the same as the request",
238
(int) WSM_PROTO_FMT, (int) *format);
240
fail_code = WSM_ERROR_INTERNAL;
243
if (fail_code != WSM_SUCCESS) {
245
* Failure, call callback with NULL reply.
248
(*req_info->reply_callback)(w, req_info->reply_data, NULL, fail_code);
251
screen_num = XScreenNumberOfScreen(XtScreen(w));
253
_WSMUnpackReply(dpy, screen_num, value, *length,
254
req_info->request_type, &reply);
256
(*req_info->reply_callback)(w, req_info->reply_data, &reply,fail_code);
261
XtFree((XtPointer) req_info_ptr);