SharedProcs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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. /* $XConsortium: SharedProcs.c /main/7 1996/08/28 17:19:21 drk $ */
  24. /*
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  26. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  27. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  28. * (c) Copyright 1993, 1994 Novell, Inc. *
  29. */
  30. /*************************************<+>*************************************
  31. *****************************************************************************
  32. **
  33. ** File: SharedProcs.c
  34. **
  35. ** Project: DT
  36. **
  37. ** Description: Contains the set of functions which are of general
  38. ** use to all DT clients.
  39. **
  40. **
  41. ****************************************************************************
  42. ************************************<+>*************************************/
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #include <ctype.h>
  46. #include <errno.h>
  47. #include <fcntl.h>
  48. #include <limits.h>
  49. #include <stdio.h>
  50. #include <time.h>
  51. #include <Xm/Xm.h>
  52. #include <Xm/XmP.h>
  53. #include <Xm/VendorSEP.h>
  54. #include <Xm/MessageB.h>
  55. #include <Xm/RowColumn.h>
  56. #include <Xm/MwmUtil.h>
  57. #include <Xm/Protocols.h>
  58. #include <X11/ShellP.h>
  59. #include <X11/Shell.h>
  60. #include <X11/Xatom.h>
  61. #include <Dt/DtP.h>
  62. #include <Dt/Connect.h>
  63. #include <Dt/DtNlUtils.h>
  64. #ifdef USE_XINERAMA
  65. #include <DtXinerama.h>
  66. #endif
  67. #include "SharedProcs.h"
  68. /* Defines */
  69. #define RW_ALL S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
  70. /******** Static Function Declarations ********/
  71. static void MessageDialogPopupCB(Widget w, XtPointer client_data,
  72. XtPointer call_data);
  73. /******** End Static Function Declarations ********/
  74. /************************************************************************
  75. *
  76. * _DtStripSpaces
  77. *
  78. * Strip all leading and trailing spaces.
  79. *
  80. ************************************************************************/
  81. String
  82. _DtStripSpaces(
  83. String string )
  84. {
  85. int i;
  86. String space;
  87. if (string == NULL)
  88. return (string);
  89. /* Strip off leading spaces first */
  90. i = 0;
  91. while (
  92. #ifdef NLS16
  93. (!is_multibyte || (mblen(string + i, MB_CUR_MAX) == 1)) &&
  94. #endif
  95. isspace((u_char)string[i]))
  96. {
  97. i++;
  98. }
  99. /* Copy over the leading spaces */
  100. strcpy(string, string + i);
  101. /* Drop out, if the string is now empty */
  102. if ((i = strlen(string) - 1) < 0)
  103. return(string);
  104. /* Strip off trailing spaces */
  105. #ifdef NLS16
  106. if (!is_multibyte)
  107. {
  108. #endif
  109. /* No multibyte; simply work back through the string */
  110. while ((i >= 0) && (isspace((u_char)string[i])))
  111. i--;
  112. string[i + 1] = '\0';
  113. #ifdef NLS16
  114. }
  115. else
  116. {
  117. /* Work forward, looking for a trailing space of spaces */
  118. int len;
  119. i = 0;
  120. space = NULL;
  121. while (string[i])
  122. {
  123. if (((len = mblen(string + i, MB_CUR_MAX)) == 1) && isspace((u_char)string[i]))
  124. {
  125. /* Found a space */
  126. if (space == NULL)
  127. space = string + i;
  128. }
  129. else if (space)
  130. space = NULL;
  131. /* if there is an invalid character, treat as a valid one-byte */
  132. if (len == -1)
  133. len = 1;
  134. i += len;
  135. }
  136. if (space)
  137. *space = '\0';
  138. }
  139. #endif
  140. return (string);
  141. }
  142. /************************************************************************
  143. *
  144. * _DtMessage
  145. * Create and display an error message.
  146. *
  147. ************************************************************************/
  148. void
  149. _DtMessage(
  150. Widget w,
  151. char *title,
  152. char *message_text,
  153. XtPointer helpIdStr,
  154. void (*helpCallback)() )
  155. {
  156. _DtMessageDialog(w, title, message_text, helpIdStr, False,
  157. NULL, _DtMessageOK, _DtMessageClose, helpCallback, True,
  158. ERROR_DIALOG);
  159. }
  160. /************************************************************************
  161. *
  162. * Generic warning/error dialog creation function.
  163. *
  164. ************************************************************************/
  165. Widget
  166. _DtMessageDialog(
  167. Widget w,
  168. char *title,
  169. char *message_text,
  170. XtPointer helpIdStr,
  171. Boolean cancel_btn,
  172. void (*cancel_callback)(),
  173. void (*ok_callback)(),
  174. void (*close_callback)(),
  175. void (*help_callback)(),
  176. Boolean deleteOnClose,
  177. int dialogType )
  178. {
  179. Widget message;
  180. Widget widget;
  181. XmString message_string;
  182. XWindowAttributes attributes;
  183. Arg args[10];
  184. XmString okString, cancelString, helpString;
  185. okString = XmStringCreateLocalized((Dt11GETMESSAGE(28,1, "OK")));
  186. cancelString = XmStringCreateLocalized((Dt11GETMESSAGE(28,2, "Cancel")));
  187. helpString = XmStringCreateLocalized((Dt11GETMESSAGE(28,3, "Help")));
  188. XtSetArg (args[0], XmNautoUnmanage, False);
  189. XtSetArg (args[1], XmNcancelLabelString, cancelString);
  190. XtSetArg (args[2], XmNokLabelString, okString);
  191. XtSetArg (args[3], XmNhelpLabelString, helpString);
  192. XtSetArg (args[4], XmNuseAsyncGeometry, True);
  193. /* Search up to get the topmost shell */
  194. while (XtParent (w) != NULL && !(XtIsSubclass (w, shellWidgetClass)))
  195. w = XtParent (w);
  196. switch (dialogType)
  197. {
  198. case ERROR_DIALOG:
  199. message = XmCreateErrorDialog(w, title, args, 5);
  200. break;
  201. case WARNING_DIALOG:
  202. message = XmCreateWarningDialog(w, title, args, 5);
  203. break;
  204. case QUESTION_DIALOG:
  205. message = XmCreateQuestionDialog(w, title, args, 5);
  206. break;
  207. }
  208. if (XtWindow (w) != 0)
  209. XGetWindowAttributes(XtDisplay (w), XtWindow (w), &attributes);
  210. else
  211. attributes.map_state = IsUnmapped;
  212. /*
  213. * If parent widget isn't mapped, attach a callback
  214. * procedure that'll center the message dialog on screen.
  215. */
  216. if (attributes.map_state == IsUnmapped)
  217. XtAddCallback(XtParent(message),XmNpopupCallback,
  218. MessageDialogPopupCB,(XtPointer)w);
  219. /* Adjust the decorations and title for the dialog shell of the dialog */
  220. XtSetArg(args[0], XmNtitle, title);
  221. XtSetArg(args[1], XmNmwmFunctions, MWM_FUNC_MOVE);
  222. XtSetArg(args[2], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE);
  223. XtSetValues(XtParent (message), args, 3);
  224. widget = XmMessageBoxGetChild(message, XmDIALOG_CANCEL_BUTTON);
  225. if (!cancel_btn)
  226. XtUnmanageChild(widget);
  227. else if (cancel_callback)
  228. {
  229. XtAddCallback(widget, XmNactivateCallback, cancel_callback,
  230. (caddr_t) message);
  231. XtSetArg(args[0], XmNcancelButton, widget);
  232. XtSetValues(message, args, 1);
  233. }
  234. widget = XmMessageBoxGetChild(message, XmDIALOG_OK_BUTTON);
  235. XtSetArg(args[0], XmNmarginWidth, 10);
  236. XtSetArg(args[1], XmNmarginHeight, 2);
  237. XtSetValues(widget, args, 2);
  238. XtAddCallback(widget, XmNactivateCallback, ok_callback, (caddr_t) message);
  239. widget = XmMessageBoxGetChild(message, XmDIALOG_HELP_BUTTON);
  240. if (helpIdStr != NULL)
  241. {
  242. if (help_callback)
  243. {
  244. XtAddCallback(widget, XmNactivateCallback, help_callback,
  245. (caddr_t) helpIdStr);
  246. }
  247. XtSetValues(widget, args, 2);
  248. }
  249. else
  250. XtUnmanageChild(widget);
  251. widget = XmMessageBoxGetChild(message, XmDIALOG_MESSAGE_LABEL);
  252. message_string = XmStringCreateLocalized(message_text);
  253. XtSetArg(args[0], XmNlabelString, message_string);
  254. XtSetValues(widget, args, 1);
  255. XmStringFree(message_string);
  256. XtManageChild(message);
  257. if (deleteOnClose)
  258. {
  259. if (close_callback == NULL)
  260. close_callback = _DtMessageClose;
  261. XtAddEventHandler(XtParent (message), StructureNotifyMask, True,
  262. (XtEventHandler)close_callback, message);
  263. }
  264. XmStringFree(okString);
  265. XmStringFree(cancelString);
  266. XmStringFree(helpString);
  267. return(message);
  268. }
  269. /************************************************************************
  270. *
  271. * _DtMessageOK
  272. * Close the error message box.
  273. *
  274. ************************************************************************/
  275. /* ARGSUSED */
  276. void
  277. _DtMessageOK(
  278. Widget w,
  279. XtPointer client_data,
  280. XtPointer call_data )
  281. {
  282. XtUnmanageChild(client_data);
  283. }
  284. /************************************************************************
  285. *
  286. * _DtMessageClose
  287. * Close the error message box.
  288. *
  289. ************************************************************************/
  290. void
  291. _DtMessageClose(
  292. Widget w,
  293. XtPointer client_data,
  294. XEvent *event )
  295. {
  296. if (event->type == UnmapNotify)
  297. {
  298. XtRemoveEventHandler(XtParent(client_data), StructureNotifyMask,
  299. True, (XtEventHandler)_DtMessageClose, client_data);
  300. XtUnmanageChild(client_data);
  301. XtDestroyWidget(w);
  302. }
  303. }
  304. /*
  305. * Center a message dialog on screen once it is managed.
  306. * client_data is expected to contain the parent shell widget handle.
  307. */
  308. static void MessageDialogPopupCB(Widget w, XtPointer client_data,
  309. XtPointer call_data)
  310. {
  311. Position msg_x, msg_y;
  312. unsigned int scr_w, scr_h, off_x=0, off_y=0;
  313. Dimension msg_w=0, msg_h=0;
  314. Arg args[2];
  315. #ifdef USE_XINERAMA
  316. DtXineramaInfo_t *dt_xi;
  317. #endif
  318. msg_w=XtWidth(w);
  319. msg_h=XtHeight(w);
  320. scr_w=WidthOfScreen(XtScreen(w));
  321. scr_h=HeightOfScreen(XtScreen(w));
  322. #ifdef USE_XINERAMA
  323. /* determine xinerama screen number the parent shell resides on,
  324. * and override scr_w/scr_h and off_x/off_y on success */
  325. if((dt_xi=_DtXineramaInit(XtDisplay(w)))){
  326. int i;
  327. unsigned int pw_x=XtX((Widget)client_data);
  328. unsigned int pw_y=XtY((Widget)client_data);
  329. for(i=0; i<dt_xi->numscreens; i++){
  330. unsigned int sw,sh,sx,sy;
  331. _DtXineramaGetScreen(dt_xi,i,&sw,&sh,&sx,&sy);
  332. if(pw_x>=sx && pw_x<(sx+sw) && pw_y>=sy && pw_y<(sy+sh)){
  333. off_x=sx; off_y=sy;
  334. scr_w=sw; scr_h=sh;
  335. break;
  336. }
  337. }
  338. }
  339. #endif /* USE_XINERAMA */
  340. msg_x=off_x+(scr_w-msg_w)/2;
  341. msg_y=off_y+(scr_h-msg_h)/2;
  342. XtSetArg(args[0],XmNx,msg_x);
  343. XtSetArg(args[1],XmNy,msg_y);
  344. XtSetValues(w,args,2);
  345. XtRemoveCallback(w,XmNpopupCallback,MessageDialogPopupCB,client_data);
  346. }