WmWsCallB.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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 <stdlib.h>
  42. #include <Tt/tttk.h>
  43. #include <Dt/Service.h>
  44. #include <Dt/Wsm.h>
  45. #include <Dt/WsmM.h>
  46. #include <Dt/SvcTT.h>
  47. #include "WsmP.h"
  48. #include "DtSvcLock.h"
  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. pCbCtx = (struct _DtWsmCBContext *) client_data;
  84. /*
  85. * We only deal with the workspace changes
  86. */
  87. if (reason == DtWSM_REASON_CURRENT)
  88. {
  89. /*
  90. * Call registered callback function.
  91. */
  92. (*(pCbCtx->ws_cb)) (pCbCtx->widget, aWS,
  93. pCbCtx->client_data);
  94. }
  95. } /* END OF FUNCTION _DtWsmWsChangeHandler */
  96. /*************************************<->*************************************
  97. *
  98. * DtWsmCBContext * DtWsmAddCurrentWorkspaceCallback (widget,
  99. * ws_change,
  100. * client_data)
  101. *
  102. *
  103. * Description:
  104. * -----------
  105. * Register a function to be called when the workspace changes.
  106. *
  107. *
  108. * Inputs:
  109. * ------
  110. * widget - widget for this client
  111. * ws_change - function to call when workspace changes
  112. * client_data - additional data to pass back to client when called.
  113. *
  114. * Outputs:
  115. * --------
  116. * Return - ptr to callback context data (opaque)
  117. *
  118. * Comments:
  119. * ---------
  120. * The callback context data ptr should be saved if you intend to
  121. * removed this callback at some point in the future.
  122. *
  123. *************************************<->***********************************/
  124. DtWsmCBContext
  125. DtWsmAddCurrentWorkspaceCallback (
  126. Widget widget,
  127. DtWsmWsChangeProc ws_change,
  128. XtPointer client_data)
  129. {
  130. struct _DtWsmCBContext *pCbCtx;
  131. _DtSvcWidgetToAppContext(widget);
  132. _DtSvcAppLock(app);
  133. /*
  134. * Allocate data to remember stuff about this callback
  135. */
  136. pCbCtx = (struct _DtWsmCBContext * )
  137. XtMalloc (sizeof(struct _DtWsmCBContext));
  138. /*
  139. * Save what we want to remember
  140. */
  141. pCbCtx->widget = widget;
  142. pCbCtx->ws_cb = ws_change;
  143. pCbCtx->client_data = client_data;
  144. /*
  145. * Register interest in the workspace change message
  146. */
  147. pCbCtx->nested_context = (XtPointer)
  148. DtWsmAddWorkspaceModifiedCallback (widget,
  149. (DtWsmWsModifiedProc)_DtWsmWsChangeHandler,
  150. (XtPointer) pCbCtx);
  151. _DtSvcAppUnlock(app);
  152. return (pCbCtx);
  153. } /* END OF FUNCTION DtWsmAddCurrentWorkspaceCallback */
  154. /*
  155. ----------------------------------------------------------------------
  156. */
  157. /*************************************<->*************************************
  158. *
  159. * Tt_callback_action _WsModifiedCB (Tt_message m, tt_pattern p)
  160. *
  161. *
  162. * Description:
  163. * -----------
  164. * Internal function called when a workspace is modified.
  165. *
  166. *
  167. * Inputs:
  168. * ------
  169. * m - ToolTalk message
  170. * p - ToolTalk pattern
  171. *
  172. * Outputs:
  173. * --------
  174. * Return - ToolTalk callback status
  175. *
  176. * Comments:
  177. * ---------
  178. *
  179. *************************************<->***********************************/
  180. static Tt_callback_action
  181. _WsModifiedCB (Tt_message m, Tt_pattern p)
  182. {
  183. struct _DtWsmCBContext *pCbCtx;
  184. Atom aWs;
  185. DtWsmWsReason reason;
  186. Widget widget;
  187. DtWsmWsModifiedProc ws_modify;
  188. XtPointer client_data;
  189. /*
  190. * user data 0: Widget widget;
  191. * user data 1: DtWsmWsModifiedProc ws_modify;
  192. * user data 2: XtPointer client_data;
  193. */
  194. widget = (Widget)tt_pattern_user(p, 0);
  195. ws_modify = (DtWsmWsModifiedProc)tt_pattern_user(p, 1);
  196. client_data = (XtPointer)tt_pattern_user(p, 2);
  197. /*
  198. * 0th arg: screen number, string, not used
  199. */
  200. /*
  201. * Convert the atom to binary.
  202. */
  203. aWs = (Atom)strtoul(tt_message_arg_val(m, 1), (char **)NULL, 0);
  204. /*
  205. * Convert "reason" of workspace modification
  206. */
  207. reason = (DtWsmWsReason)strtoul(tt_message_arg_val(m, 2), (char **)NULL, 0);
  208. /*
  209. * Call registered callback function.
  210. */
  211. (*ws_modify)(widget, aWs, reason, client_data);
  212. return TT_CALLBACK_PROCESSED;
  213. } /* END OF FUNCTION _DtWsmWsModifyHandler */
  214. /*************************************<->*************************************
  215. *
  216. * DtWsmCBContext * DtWsmAddWorkspaceModifiedCallback (widget,
  217. * ws_modify,
  218. * client_data)
  219. *
  220. *
  221. * Description:
  222. * -----------
  223. * Register a function to be called when the workspace is modified.
  224. *
  225. *
  226. * Inputs:
  227. * ------
  228. * widget - widget for this client
  229. * ws_modify - function to call when workspace is modified
  230. * client_data - additional data to pass back to client when called.
  231. *
  232. * Outputs:
  233. * --------
  234. * Return - ptr to callback context data (opaque)
  235. *
  236. * Comments:
  237. * ---------
  238. * The callback context data ptr should be saved if you intend to
  239. * removed this callback at some point in the future.
  240. *
  241. *************************************<->***********************************/
  242. DtWsmCBContext
  243. DtWsmAddWorkspaceModifiedCallback (
  244. Widget widget,
  245. DtWsmWsModifiedProc ws_modify,
  246. XtPointer client_data)
  247. {
  248. struct _DtWsmCBContext *pCbCtx;
  249. int screen;
  250. String sName;
  251. char sNum[32];
  252. Tt_status status;
  253. Tt_pattern pattern;
  254. char * sessId;
  255. _DtSvcWidgetToAppContext(widget);
  256. _DtSvcAppLock(app);
  257. /*
  258. * This function register a ToolTalk pattern for every
  259. * callback added.
  260. */
  261. _DtSvcInitToolTalk(widget);
  262. pattern = tt_pattern_create();
  263. status = tt_ptr_error(pattern);
  264. if (status != TT_OK) {
  265. _DtSvcAppUnlock(app);
  266. return NULL;
  267. }
  268. if (tt_pattern_scope_add(pattern, TT_SESSION) != TT_OK) {
  269. _DtSvcAppUnlock(app);
  270. return NULL;
  271. }
  272. if (tt_pattern_category_set(pattern, TT_OBSERVE) != TT_OK) {
  273. _DtSvcAppUnlock(app);
  274. return NULL;
  275. }
  276. if (tt_pattern_class_add(pattern, TT_NOTICE) != TT_OK) {
  277. _DtSvcAppUnlock(app);
  278. return NULL;
  279. }
  280. if (tt_pattern_state_add(pattern, TT_SENT) != TT_OK) {
  281. _DtSvcAppUnlock(app);
  282. return NULL;
  283. }
  284. sessId = tt_default_session();
  285. if (tt_pattern_session_add(pattern, sessId) != TT_OK) {
  286. _DtSvcAppUnlock(app);
  287. return NULL;
  288. }
  289. tt_free( sessId );
  290. screen = XScreenNumberOfScreen(XtScreen(widget));
  291. sprintf(sNum, "%d", screen);
  292. sName = _DtWsmSelectionNameForScreen (screen);
  293. /*
  294. * Only receive DtWorkspace_Modified notice from the screen
  295. * we registered with.
  296. */
  297. status = tt_pattern_arg_add(pattern, TT_IN, Tttk_string, sNum);
  298. if (status != TT_OK) {
  299. _DtSvcAppUnlock(app);
  300. return NULL;
  301. }
  302. if (tt_pattern_op_add(pattern, "DtWorkspace_Modified") != TT_OK) {
  303. _DtSvcAppUnlock(app);
  304. return NULL;
  305. }
  306. /*
  307. * Store information needed by the callback in the user data
  308. * fields of the pattern.
  309. */
  310. status = tt_pattern_user_set(pattern, 0, (void *)widget);
  311. if (status != TT_OK) {
  312. _DtSvcAppUnlock(app);
  313. return NULL;
  314. }
  315. status = tt_pattern_user_set(pattern, 1, (void *)ws_modify);
  316. if (status != TT_OK) {
  317. _DtSvcAppUnlock(app);
  318. return NULL;
  319. }
  320. status = tt_pattern_user_set(pattern, 2, (void *)client_data);
  321. if (status != TT_OK) {
  322. _DtSvcAppUnlock(app);
  323. return NULL;
  324. }
  325. /*
  326. * _WsModifiedCB is the ToolTalk callback which will call
  327. * the user callback.
  328. */
  329. if (tt_pattern_callback_add(pattern, _WsModifiedCB) != TT_OK) {
  330. _DtSvcAppUnlock(app);
  331. return NULL;
  332. }
  333. if (tt_pattern_register(pattern) != TT_OK) {
  334. _DtSvcAppUnlock(app);
  335. return NULL;
  336. }
  337. /*
  338. * Allocate data to remember stuff about this callback
  339. */
  340. pCbCtx = (struct _DtWsmCBContext * )
  341. XtMalloc (sizeof(struct _DtWsmCBContext));
  342. /*
  343. * Save what we want to remember
  344. */
  345. pCbCtx->pattern = pattern;
  346. pCbCtx->widget = widget;
  347. pCbCtx->ws_cb = ws_modify;
  348. pCbCtx->client_data = client_data;
  349. pCbCtx->nested_context = NULL;
  350. XtFree (sName);
  351. _DtSvcAppUnlock(app);
  352. return (pCbCtx);
  353. } /* END OF FUNCTION DtWsmAddWorkspaceModifiedCallback */
  354. /*************************************<->*************************************
  355. *
  356. * DtWsmRemoveWorkspaceCallback (pCbCtx)
  357. *
  358. * Description:
  359. * -----------
  360. * Unregister a workspace callback.
  361. *
  362. *
  363. * Inputs:
  364. * ------
  365. * pCbCtx - ptr to context returned when callback added
  366. *
  367. * Outputs:
  368. * --------
  369. * Return - none
  370. *
  371. * Comments:
  372. * ---------
  373. *
  374. *************************************<->***********************************/
  375. void
  376. DtWsmRemoveWorkspaceCallback (DtWsmCBContext pCbCtx)
  377. {
  378. /*
  379. * Is this somewhat valid?
  380. */
  381. if (pCbCtx && (pCbCtx->widget != NULL)) {
  382. _DtSvcWidgetToAppContext(pCbCtx->widget);
  383. _DtSvcAppLock(app);
  384. if (pCbCtx->nested_context) {
  385. /*
  386. * This was a convenience callback for just the workspace
  387. * change info.
  388. */
  389. DtWsmRemoveWorkspaceCallback (
  390. (DtWsmCBContext) pCbCtx->nested_context);
  391. }
  392. else {
  393. /*
  394. * Unregister interest in this message
  395. */
  396. tt_pattern_destroy(pCbCtx->pattern);
  397. }
  398. /*
  399. * Free previously allocated data
  400. */
  401. XtFree((char *) pCbCtx);
  402. _DtSvcAppUnlock(app);
  403. }
  404. } /* END OF FUNCTION DtWsmRemoveWorkspaceCallback */
  405. /*************************************<->*************************************
  406. *
  407. * _DtWsmSelectionNameForScreen (scr)
  408. *
  409. * Description:
  410. * -----------
  411. * Returns a string containing the selection name used for
  412. * communication with the workspace manager on this screen
  413. *
  414. *
  415. * Inputs:
  416. * ------
  417. * scr - number of screen
  418. *
  419. * Outputs:
  420. * --------
  421. * Return - ptr to string with selection name (free with XtFree)
  422. *
  423. * Comments:
  424. * ---------
  425. * Assumes the screen number is < 1000.
  426. *
  427. *************************************<->***********************************/
  428. String
  429. _DtWsmSelectionNameForScreen (
  430. int scr)
  431. {
  432. String sName;
  433. sName = (String) XtMalloc (strlen(DtWSM_TOOL_CLASS) + 4 + 1);
  434. sprintf ((char *)sName, "%s_%d", DtWSM_TOOL_CLASS, (scr % 1000));
  435. return (sName);
  436. } /* END OF FUNCTION _DtWsmSelectionNameForScreen */
  437. Tt_callback_action
  438. _DtWsmConsumeReply(
  439. Tt_message msg,
  440. Tt_pattern pat )
  441. {
  442. switch (tt_message_state( msg )) {
  443. case TT_HANDLED:
  444. case TT_FAILED:
  445. tttk_message_destroy( msg );
  446. return TT_CALLBACK_PROCESSED;
  447. default:
  448. return TT_CALLBACK_CONTINUE;
  449. }
  450. }