2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /************************************<+>*************************************
24 ****************************************************************************
28 ** RCS: $XConsortium: WmWsCallB.c /main/6 1996/11/06 18:42:04 drk $
30 ** Project: DT Workspace Manager
32 ** Description: Workspace change callback functions
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.
39 ****************************************************************************
40 ************************************<+>*************************************/
42 #include <Dt/Service.h>
47 #include "DtSvcLock.h"
49 /*************************************<->*************************************
51 * DtWsmWsModifiedProc _DtWsmWsChangeHandler (widget, aWS,
52 * reason, client_data);
57 * Internal function called when workspace changes.
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
74 *************************************<->***********************************/
76 _DtWsmWsChangeHandler (
80 XtPointer client_data)
82 struct _DtWsmCBContext *pCbCtx;
84 pCbCtx = (struct _DtWsmCBContext *) client_data;
87 * We only deal with the workspace changes
89 if (reason == DtWSM_REASON_CURRENT)
92 * Call registered callback function.
94 (*(pCbCtx->ws_cb)) (pCbCtx->widget, aWS,
98 } /* END OF FUNCTION _DtWsmWsChangeHandler */
100 /*************************************<->*************************************
102 * DtWsmCBContext * DtWsmAddCurrentWorkspaceCallback (widget,
109 * Register a function to be called when the workspace changes.
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.
120 * Return - ptr to callback context data (opaque)
124 * The callback context data ptr should be saved if you intend to
125 * removed this callback at some point in the future.
127 *************************************<->***********************************/
129 DtWsmAddCurrentWorkspaceCallback (
131 DtWsmWsChangeProc ws_change,
132 XtPointer client_data)
134 struct _DtWsmCBContext *pCbCtx;
135 _DtSvcWidgetToAppContext(widget);
140 * Allocate data to remember stuff about this callback
142 pCbCtx = (struct _DtWsmCBContext * )
143 XtMalloc (sizeof(struct _DtWsmCBContext));
147 * Save what we want to remember
149 pCbCtx->widget = widget;
150 pCbCtx->ws_cb = ws_change;
151 pCbCtx->client_data = client_data;
154 * Register interest in the workspace change message
156 pCbCtx->nested_context = (XtPointer)
157 DtWsmAddWorkspaceModifiedCallback (widget,
158 (DtWsmWsModifiedProc)_DtWsmWsChangeHandler,
161 _DtSvcAppUnlock(app);
164 } /* END OF FUNCTION DtWsmAddCurrentWorkspaceCallback */
167 ----------------------------------------------------------------------
170 /*************************************<->*************************************
172 * Tt_callback_action _WsModifiedCB (Tt_message m, tt_pattern p)
177 * Internal function called when a workspace is modified.
182 * m - ToolTalk message
183 * p - ToolTalk pattern
187 * Return - ToolTalk callback status
192 *************************************<->***********************************/
193 static Tt_callback_action
194 _WsModifiedCB (Tt_message m, Tt_pattern p)
196 struct _DtWsmCBContext *pCbCtx;
198 DtWsmWsReason reason;
201 DtWsmWsModifiedProc ws_modify;
202 XtPointer client_data;
205 * user data 0: Widget widget;
206 * user data 1: DtWsmWsModifiedProc ws_modify;
207 * user data 2: XtPointer client_data;
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);
214 * 0th arg: screen number, string, not used
218 * Convert the atom to binary.
220 aWs = (Atom)strtoul(tt_message_arg_val(m, 1), (char **)NULL, 0);
223 * Convert "reason" of workspace modification
225 reason = (DtWsmWsReason)strtoul(tt_message_arg_val(m, 2), (char **)NULL, 0);
228 * Call registered callback function.
230 (*ws_modify)(widget, aWs, reason, client_data);
232 return TT_CALLBACK_PROCESSED;
233 } /* END OF FUNCTION _DtWsmWsModifyHandler */
235 /*************************************<->*************************************
237 * DtWsmCBContext * DtWsmAddWorkspaceModifiedCallback (widget,
244 * Register a function to be called when the workspace is modified.
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.
255 * Return - ptr to callback context data (opaque)
259 * The callback context data ptr should be saved if you intend to
260 * removed this callback at some point in the future.
262 *************************************<->***********************************/
264 DtWsmAddWorkspaceModifiedCallback (
266 DtWsmWsModifiedProc ws_modify,
267 XtPointer client_data)
269 struct _DtWsmCBContext *pCbCtx;
277 _DtSvcWidgetToAppContext(widget);
282 * This function register a ToolTalk pattern for every
285 _DtSvcInitToolTalk(widget);
287 pattern = tt_pattern_create();
288 status = tt_ptr_error(pattern);
289 if (status != TT_OK) {
290 _DtSvcAppUnlock(app);
294 if (tt_pattern_scope_add(pattern, TT_SESSION) != TT_OK) {
295 _DtSvcAppUnlock(app);
298 if (tt_pattern_category_set(pattern, TT_OBSERVE) != TT_OK) {
299 _DtSvcAppUnlock(app);
302 if (tt_pattern_class_add(pattern, TT_NOTICE) != TT_OK) {
303 _DtSvcAppUnlock(app);
306 if (tt_pattern_state_add(pattern, TT_SENT) != TT_OK) {
307 _DtSvcAppUnlock(app);
310 sessId = tt_default_session();
311 if (tt_pattern_session_add(pattern, sessId) != TT_OK) {
312 _DtSvcAppUnlock(app);
317 screen = XScreenNumberOfScreen(XtScreen(widget));
318 sprintf(sNum, "%d", screen);
319 sName = _DtWsmSelectionNameForScreen (screen);
322 * Only receive DtWorkspace_Modified notice from the screen
323 * we registered with.
325 status = tt_pattern_arg_add(pattern, TT_IN, Tttk_string, sNum);
326 if (status != TT_OK) {
327 _DtSvcAppUnlock(app);
331 if (tt_pattern_op_add(pattern, "DtWorkspace_Modified") != TT_OK) {
332 _DtSvcAppUnlock(app);
337 * Store information needed by the callback in the user data
338 * fields of the pattern.
340 status = tt_pattern_user_set(pattern, 0, (void *)widget);
341 if (status != TT_OK) {
342 _DtSvcAppUnlock(app);
345 status = tt_pattern_user_set(pattern, 1, (void *)ws_modify);
346 if (status != TT_OK) {
347 _DtSvcAppUnlock(app);
350 status = tt_pattern_user_set(pattern, 2, (void *)client_data);
351 if (status != TT_OK) {
352 _DtSvcAppUnlock(app);
357 * _WsModifiedCB is the ToolTalk callback which will call
360 if (tt_pattern_callback_add(pattern, _WsModifiedCB) != TT_OK) {
361 _DtSvcAppUnlock(app);
365 if (tt_pattern_register(pattern) != TT_OK) {
366 _DtSvcAppUnlock(app);
371 * Allocate data to remember stuff about this callback
373 pCbCtx = (struct _DtWsmCBContext * )
374 XtMalloc (sizeof(struct _DtWsmCBContext));
377 * Save what we want to remember
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;
387 _DtSvcAppUnlock(app);
390 } /* END OF FUNCTION DtWsmAddWorkspaceModifiedCallback */
392 /*************************************<->*************************************
394 * DtWsmRemoveWorkspaceCallback (pCbCtx)
398 * Unregister a workspace callback.
403 * pCbCtx - ptr to context returned when callback added
412 *************************************<->***********************************/
414 DtWsmRemoveWorkspaceCallback (DtWsmCBContext pCbCtx)
417 * Is this somewhat valid?
419 if (pCbCtx && (pCbCtx->widget != NULL)) {
420 _DtSvcWidgetToAppContext(pCbCtx->widget);
423 if (pCbCtx->nested_context) {
425 * This was a convenience callback for just the workspace
428 DtWsmRemoveWorkspaceCallback (
429 (DtWsmCBContext) pCbCtx->nested_context);
433 * Unregister interest in this message
435 tt_pattern_destroy(pCbCtx->pattern);
439 * Free previously allocated data
441 XtFree((char *) pCbCtx);
443 _DtSvcAppUnlock(app);
446 } /* END OF FUNCTION DtWsmRemoveWorkspaceCallback */
448 /*************************************<->*************************************
450 * _DtWsmSelectionNameForScreen (scr)
454 * Returns a string containing the selection name used for
455 * communication with the workspace manager on this screen
460 * scr - number of screen
464 * Return - ptr to string with selection name (free with XtFree)
468 * Assumes the screen number is < 1000.
470 *************************************<->***********************************/
472 _DtWsmSelectionNameForScreen (
477 sName = (String) XtMalloc (strlen(DtWSM_TOOL_CLASS) + 4 + 1);
479 sprintf ((char *)sName, "%s_%d", DtWSM_TOOL_CLASS, (scr % 1000));
482 } /* END OF FUNCTION _DtWsmSelectionNameForScreen */
490 switch (tt_message_state( msg )) {
493 tttk_message_destroy( msg );
494 return TT_CALLBACK_PROCESSED;
496 return TT_CALLBACK_CONTINUE;