DtSvc/DtUtil1: fix implicit function declarations
[oweals/cde.git] / cde / lib / DtSvc / DtUtil1 / WmWsCallB.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /************************************<+>*************************************
24  ****************************************************************************
25  **
26  **   File:     WmWsCallB.c
27  **
28  **   RCS:      $XConsortium: WmWsCallB.c /main/6 1996/11/06 18:42:04 drk $
29  **
30  **   Project:  DT Workspace Manager
31  **
32  **   Description: Workspace change callback functions
33  **
34  ** (c) Copyright 1993, 1994 Hewlett-Packard Company
35  ** (c) Copyright 1993, 1994 International Business Machines Corp.
36  ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
37  ** (c) Copyright 1993, 1994 Novell, Inc.
38  **
39  ****************************************************************************
40  ************************************<+>*************************************/
41 #include <Tt/tttk.h>
42 #include <Dt/Service.h>
43 #include <Dt/Wsm.h> 
44 #include <Dt/WsmM.h>
45 #include <Dt/SvcTT.h>
46 #include "WsmP.h" 
47 #include "DtSvcLock.h"
48
49 /*************************************<->*************************************
50  *
51  *  DtWsmWsModifiedProc _DtWsmWsChangeHandler (widget, aWS, 
52  *                                              reason, client_data);
53  *
54  *
55  *  Description:
56  *  -----------
57  *  Internal function called when workspace changes.
58  *
59  *
60  *  Inputs:
61  *  ------
62  *  widget              - widget (for window where service is registered)
63  *  aWS                 - Atom for workspace identification
64  *  reason              - type of workspace modification
65  *  client_data         - pointer to data
66  *
67  *  Outputs:
68  *  --------
69  *  Return      - none
70  *
71  *  Comments:
72  *  ---------
73  * 
74  *************************************<->***********************************/
75 static void
76 _DtWsmWsChangeHandler (
77         Widget                  widget,
78         Atom                    aWS,
79         DtWsmWsReason           reason,
80         XtPointer               client_data)
81 {
82     struct _DtWsmCBContext *pCbCtx;
83
84     pCbCtx = (struct _DtWsmCBContext *) client_data;
85
86     /*
87      * We only deal with the workspace changes
88      */
89     if (reason == DtWSM_REASON_CURRENT)
90     {
91         /*
92          * Call registered callback function.
93          */
94         (*(pCbCtx->ws_cb)) (pCbCtx->widget, aWS, 
95                                         pCbCtx->client_data);
96     }
97     
98 } /* END OF FUNCTION _DtWsmWsChangeHandler */
99
100 /*************************************<->*************************************
101  *
102  *  DtWsmCBContext * DtWsmAddCurrentWorkspaceCallback (widget, 
103  *                                                      ws_change, 
104  *                                                      client_data)
105  *
106  *
107  *  Description:
108  *  -----------
109  *  Register a function to be called when the workspace changes.
110  *
111  *
112  *  Inputs:
113  *  ------
114  *  widget      - widget for this client
115  *  ws_change   - function to call when workspace changes
116  *  client_data - additional data to pass back to client when called.
117  *
118  *  Outputs:
119  *  --------
120  *  Return      - ptr to callback context data (opaque) 
121  *
122  *  Comments:
123  *  ---------
124  *  The callback context data ptr should be saved if you intend to
125  *  removed this callback at some point in the future. 
126  * 
127  *************************************<->***********************************/
128 DtWsmCBContext 
129 DtWsmAddCurrentWorkspaceCallback (
130         Widget                  widget,
131         DtWsmWsChangeProc       ws_change,
132         XtPointer               client_data)
133 {
134     struct _DtWsmCBContext *pCbCtx;
135     _DtSvcWidgetToAppContext(widget);
136
137     _DtSvcAppLock(app);
138
139     /*
140      * Allocate data to remember stuff about this callback
141      */
142     pCbCtx = (struct _DtWsmCBContext * ) 
143                 XtMalloc (sizeof(struct _DtWsmCBContext));
144
145
146     /* 
147      * Save what we want to remember
148      */
149     pCbCtx->widget = widget;
150     pCbCtx->ws_cb = ws_change;
151     pCbCtx->client_data = client_data;
152
153     /*
154      * Register interest in the workspace change message
155      */
156     pCbCtx->nested_context = (XtPointer)
157         DtWsmAddWorkspaceModifiedCallback (widget, 
158                               (DtWsmWsModifiedProc)_DtWsmWsChangeHandler, 
159                               (XtPointer) pCbCtx);
160
161     _DtSvcAppUnlock(app);
162     return (pCbCtx);
163
164 } /* END OF FUNCTION DtWsmAddCurrentWorkspaceCallback */
165
166 /*
167 ----------------------------------------------------------------------
168 */
169
170 /*************************************<->*************************************
171  *
172  *  Tt_callback_action _WsModifiedCB (Tt_message m, tt_pattern p)
173  *
174  *
175  *  Description:
176  *  -----------
177  *  Internal function called when a workspace is modified.
178  *
179  *
180  *  Inputs:
181  *  ------
182  *  m           - ToolTalk message
183  *  p           - ToolTalk pattern
184  *
185  *  Outputs:
186  *  --------
187  *  Return      - ToolTalk callback status
188  *
189  *  Comments:
190  *  ---------
191  * 
192  *************************************<->***********************************/
193 static Tt_callback_action
194 _WsModifiedCB (Tt_message m, Tt_pattern p)
195 {
196     struct _DtWsmCBContext *pCbCtx;
197     Atom        aWs;
198     DtWsmWsReason       reason;
199
200     Widget              widget;
201     DtWsmWsModifiedProc ws_modify;
202     XtPointer           client_data;
203
204     /*
205      * user data 0: Widget              widget;
206      * user data 1: DtWsmWsModifiedProc ws_modify;
207      * user data 2: XtPointer           client_data;
208      */
209     widget = (Widget)tt_pattern_user(p, 0);
210     ws_modify = (DtWsmWsModifiedProc)tt_pattern_user(p, 1);
211     client_data = (XtPointer)tt_pattern_user(p, 2);
212
213     /*
214      * 0th arg: screen number, string, not used
215      */
216
217     /*
218      * Convert the atom to binary.
219      */
220     aWs = (Atom)strtoul(tt_message_arg_val(m, 1), (char **)NULL, 0);
221
222     /*
223      * Convert "reason" of workspace modification
224      */
225     reason = (DtWsmWsReason)strtoul(tt_message_arg_val(m, 2), (char **)NULL, 0);
226
227     /*
228      * Call registered callback function.
229      */
230     (*ws_modify)(widget, aWs, reason, client_data);
231     
232     return TT_CALLBACK_PROCESSED;
233 } /* END OF FUNCTION _DtWsmWsModifyHandler */
234
235 /*************************************<->*************************************
236  *
237  *  DtWsmCBContext * DtWsmAddWorkspaceModifiedCallback (widget, 
238  *                                                      ws_modify, 
239  *                                                      client_data)
240  *
241  *
242  *  Description:
243  *  -----------
244  *  Register a function to be called when the workspace is modified.
245  *
246  *
247  *  Inputs:
248  *  ------
249  *  widget      - widget for this client
250  *  ws_modify   - function to call when workspace is modified
251  *  client_data - additional data to pass back to client when called.
252  *
253  *  Outputs:
254  *  --------
255  *  Return      - ptr to callback context data (opaque) 
256  *
257  *  Comments:
258  *  ---------
259  *  The callback context data ptr should be saved if you intend to
260  *  removed this callback at some point in the future. 
261  * 
262  *************************************<->***********************************/
263 DtWsmCBContext 
264 DtWsmAddWorkspaceModifiedCallback (
265         Widget                  widget,
266         DtWsmWsModifiedProc     ws_modify,
267         XtPointer               client_data)
268 {
269     struct _DtWsmCBContext *pCbCtx;
270     int         screen;
271     String      sName;
272     char        sNum[32];
273
274     Tt_status   status;
275     Tt_pattern  pattern;
276     char *      sessId;
277     _DtSvcWidgetToAppContext(widget);
278
279     _DtSvcAppLock(app);
280
281     /*
282      * This function register a ToolTalk pattern for every
283      * callback added.
284      */
285     _DtSvcInitToolTalk(widget);
286
287     pattern = tt_pattern_create();
288     status = tt_ptr_error(pattern);
289     if (status != TT_OK) {
290         _DtSvcAppUnlock(app);
291         return NULL;
292     }
293
294     if (tt_pattern_scope_add(pattern, TT_SESSION) != TT_OK) {
295         _DtSvcAppUnlock(app);
296         return NULL;
297     }
298     if (tt_pattern_category_set(pattern, TT_OBSERVE) != TT_OK) {
299         _DtSvcAppUnlock(app);
300         return NULL;
301     }
302     if (tt_pattern_class_add(pattern, TT_NOTICE) != TT_OK) {
303         _DtSvcAppUnlock(app);
304         return NULL;
305     }
306     if (tt_pattern_state_add(pattern, TT_SENT) != TT_OK) {
307         _DtSvcAppUnlock(app);
308         return NULL;
309     }
310     sessId = tt_default_session();
311     if (tt_pattern_session_add(pattern, sessId) != TT_OK) {
312         _DtSvcAppUnlock(app);
313         return NULL;
314     }
315     tt_free( sessId );
316
317     screen = XScreenNumberOfScreen(XtScreen(widget));
318     sprintf(sNum, "%d", screen);
319     sName = _DtWsmSelectionNameForScreen (screen);
320
321     /*
322      * Only receive DtWorkspace_Modified notice from the screen
323      * we registered with.
324      */
325     status = tt_pattern_arg_add(pattern, TT_IN, Tttk_string, sNum);
326     if (status != TT_OK) {
327         _DtSvcAppUnlock(app);
328         return NULL;
329     }
330
331     if (tt_pattern_op_add(pattern, "DtWorkspace_Modified") != TT_OK) {
332         _DtSvcAppUnlock(app);
333         return NULL;
334     }
335
336     /*
337      * Store information needed by the callback in the user data
338      * fields of the pattern.
339      */
340     status = tt_pattern_user_set(pattern, 0, (void *)widget);
341     if (status != TT_OK) {
342         _DtSvcAppUnlock(app);
343         return NULL;
344     }
345     status = tt_pattern_user_set(pattern, 1, (void *)ws_modify);
346     if (status != TT_OK) {
347         _DtSvcAppUnlock(app);
348         return NULL;
349     }
350     status = tt_pattern_user_set(pattern, 2, (void *)client_data);
351     if (status != TT_OK) {
352         _DtSvcAppUnlock(app);
353         return NULL;
354     }
355
356     /*
357      * _WsModifiedCB is the ToolTalk callback which will call
358      * the user callback.
359      */
360     if (tt_pattern_callback_add(pattern, _WsModifiedCB) != TT_OK) {
361         _DtSvcAppUnlock(app);
362         return NULL;
363     }
364
365     if (tt_pattern_register(pattern) != TT_OK) {
366         _DtSvcAppUnlock(app);
367         return NULL;
368     }
369
370     /*
371      * Allocate data to remember stuff about this callback
372      */
373     pCbCtx = (struct _DtWsmCBContext * ) 
374                 XtMalloc (sizeof(struct _DtWsmCBContext));
375
376     /* 
377      * Save what we want to remember
378      */
379     pCbCtx->pattern = pattern;
380     pCbCtx->widget = widget;
381     pCbCtx->ws_cb = ws_modify;
382     pCbCtx->client_data = client_data;
383     pCbCtx->nested_context = NULL;
384
385     XtFree (sName);
386
387     _DtSvcAppUnlock(app);
388     return (pCbCtx);
389
390 } /* END OF FUNCTION DtWsmAddWorkspaceModifiedCallback */
391
392 /*************************************<->*************************************
393  *
394  *  DtWsmRemoveWorkspaceCallback (pCbCtx)
395  *
396  *  Description:
397  *  -----------
398  *  Unregister a workspace callback.
399  *
400  *
401  *  Inputs:
402  *  ------
403  *  pCbCtx      - ptr to context returned when callback added
404  *
405  *  Outputs:
406  *  --------
407  *  Return      - none
408  *
409  *  Comments:
410  *  ---------
411  * 
412  *************************************<->***********************************/
413 void
414 DtWsmRemoveWorkspaceCallback (DtWsmCBContext    pCbCtx)
415 {
416     /*
417      * Is this somewhat valid?
418      */
419     if (pCbCtx && (pCbCtx->widget != NULL)) {
420         _DtSvcWidgetToAppContext(pCbCtx->widget);
421         _DtSvcAppLock(app);
422
423         if (pCbCtx->nested_context) {
424             /*
425              * This was a convenience callback for just the workspace
426              * change info.
427              */
428             DtWsmRemoveWorkspaceCallback (
429                                 (DtWsmCBContext) pCbCtx->nested_context);
430         }
431         else {
432             /*
433              * Unregister interest in this message
434              */
435             tt_pattern_destroy(pCbCtx->pattern);
436         }
437
438         /*
439          * Free previously allocated data
440          */
441         XtFree((char *) pCbCtx);
442
443         _DtSvcAppUnlock(app);
444     }
445
446 } /* END OF FUNCTION DtWsmRemoveWorkspaceCallback */
447
448 /*************************************<->*************************************
449  *
450  *  _DtWsmSelectionNameForScreen (scr)
451  *
452  *  Description:
453  *  -----------
454  *  Returns a string containing the selection name used for
455  *  communication with the workspace manager on this screen
456  *
457  *
458  *  Inputs:
459  *  ------
460  *  scr         - number of screen
461  *
462  *  Outputs:
463  *  --------
464  *  Return      - ptr to string with selection name (free with XtFree)
465  *
466  *  Comments:
467  *  ---------
468  *  Assumes the screen number is < 1000.
469  * 
470  *************************************<->***********************************/
471 String
472 _DtWsmSelectionNameForScreen (
473         int                     scr)
474 {
475     String sName;
476
477     sName = (String) XtMalloc (strlen(DtWSM_TOOL_CLASS) + 4 + 1);
478
479     sprintf ((char *)sName, "%s_%d", DtWSM_TOOL_CLASS, (scr % 1000));
480
481     return (sName);
482 } /* END OF FUNCTION _DtWsmSelectionNameForScreen */
483
484
485 Tt_callback_action
486 _DtWsmConsumeReply(
487         Tt_message msg,
488         Tt_pattern pat )
489 {
490         switch (tt_message_state( msg )) {
491             case TT_HANDLED:
492             case TT_FAILED:
493                 tttk_message_destroy( msg );
494                 return TT_CALLBACK_PROCESSED;
495             default:
496                 return TT_CALLBACK_CONTINUE;
497         }
498 }