1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmTools
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Miscellaneous tools for the Xdiary modules.
12 --
13 --  Filename:         xtmTools.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1990-12-16
17 --
18 --
19 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
20 --      All rights reserved
21 --
22 --  Permission to use, copy, modify, and distribute this software and its
23 --  documentation for any purpose and without fee is hereby granted,
24 --  provided that the above copyright notice appear in all copies. Ulrika
25 --  Bornetun and Roger Larsson make no representations about the usability
26 --  of this software for any purpose. It is provided "as is" without express
27 --  or implied warranty.
28 ----------------------------------------------------------------------------*/
29 
30 /* SCCS module identifier. */
31 static char SCCSID[] = "@(#) Module: xtmTools.c, Version: 1.1, Date: 95/02/18 15:52:54";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/signal.h>
44 
45 #include <X11/Intrinsic.h>
46 
47 #include <Xm/Protocols.h>
48 
49 #if ! defined( XD_HAS_NO_NLS ) && XtSpecificationRelease > 4
50 #  include <X11/Xlocale.h>
51 #endif
52 
53 #include <Xm/Xm.h>
54 
55 #include "System.h"
56 #include "Message.h"
57 #include "SigHandler.h"
58 
59 #include "msgXdiary.h"
60 #include "xitError.h"
61 #include "xitTools.h"
62 #include "xmubCustUtil.h"
63 #include "xtmTools.h"
64 #include "xitTune.h"
65 
66 /*----------------------------------------------------------------------------
67 --  Macro definitions
68 ----------------------------------------------------------------------------*/
69 
70 #define  WM_STATE_ELEMENTS   1
71 
72 
73 /*----------------------------------------------------------------------------
74 --  Type declarations
75 ----------------------------------------------------------------------------*/
76 
77 
78 /*----------------------------------------------------------------------------
79 --  Global definitions
80 ----------------------------------------------------------------------------*/
81 
82 /* Name of module. */
83 static char  *module_name = "xtmTools";
84 
85 
86 /*----------------------------------------------------------------------------
87 --  Function prototypes
88 ----------------------------------------------------------------------------*/
89 
90 static unsigned long
91 checkWindowState( Display  *display,
92                   Window   window );
93 
94 static void
95 saveSessionCB( Widget     widget,
96                Widget     toplevelW,
97                XtPointer  call_data );
98 
99 
100 
101 /*----------------------------------------------------------------------------
102 --  Functions
103 ----------------------------------------------------------------------------*/
104 
105 void
xtmToInitializeResourceMapping(unsigned int argc,char ** argv,Display * display)106 xtmToInitializeResourceMapping( unsigned int  argc,
107                                 char**        argv,
108                                 Display*      display )
109 {
110 
111   String       app_class;
112   String       app_name;
113   XrmDatabase  display_db = XtDatabase( display );
114 
115   xmubResourceMappingInfoRef  res_info = NULL;
116 
117   XtGetApplicationNameAndClass( display, &app_name, &app_class );
118 
119   XrmParseCommand( &display_db,
120                    xmub_options, xmub_num_options,
121                    app_name, (int*) &argc, argv );
122 
123   xmubInitResourceMapping( display,
124                            xmub_resource_sets, xmub_num_resource_sets,
125                            &res_info );
126 
127   if( res_info == NULL )
128     xitErMessage( NULL, XIT_ER_FATAL,
129                   "", "main",
130                   "Cannot find resource mapping file.\n"
131                   "Please check the XDiary installation." );
132 
133   xmubResFreeInfo( res_info );
134 
135 
136   return;
137 
138 } /* xtmToInitializeResourceMapping */
139 
140 
141 /*----------------------------------------------------------------------*/
142 
143 void
xtmToPlayMelody(Widget parentW,char * tune_player,char * tune_player_param,char * tune_file,int volume,int duration_delta)144 xtmToPlayMelody( Widget  parentW,
145                  char    *tune_player,
146                  char    *tune_player_param,
147                  char    *tune_file,
148                  int     volume,
149                  int     duration_delta )
150 {
151 
152   /* Code. */
153 
154   /* Anything to play? */
155   if( tune_file == NULL || *tune_file == '\0' ) {
156     XBell( XtDisplay( parentW ), 100 );
157 
158     return;
159   }
160 
161   /* Do we have our own tune player? */
162   if( tune_player != NULL && *tune_player != '\0' ) {
163 
164     int   index;
165     char  *process_args[ 10 ];
166 
167     /* Process arguments. */
168     index = 0;
169     process_args[ index++ ] = tune_player;
170 
171     if( tune_player_param != NULL && *tune_player_param != '\0' )
172       process_args[ index++ ] = tune_player_param;
173 
174     process_args[ index++ ] = tune_file;
175     process_args[ index++ ] = NULL;
176 
177     (void) xtmToStartProcess( NULL, True, NULL, process_args );
178 
179     return;
180   }
181 
182   /* Use the built-in speaker. */
183   xitTuPlayTuneFromFile( XtDisplay( parentW ),
184                          XtWidgetToApplicationContext( parentW ),
185                          tune_file, volume, duration_delta );
186 
187   return;
188 
189 } /* xtmToPlayMelody */
190 
191 
192 /*----------------------------------------------------------------------*/
193 
194 void
xtmToSessionMgmt(Widget shellW,unsigned int argc,char ** argv)195 xtmToSessionMgmt( Widget        shellW,
196                   unsigned int  argc,
197                   char**        argv )
198 {
199 
200   /* Variables. */
201   Atom      wm_save_yourself;
202   Display   *display;
203 
204 
205   /* Code. */
206 
207   display = XtDisplay( shellW );
208 
209   /* Set command parameters on the window. */
210   if( argv != NULL )
211     XSetCommand( XtDisplay( shellW ), XtWindow( shellW ), argv, (int) argc );
212 
213 
214   /* Save session callback. */
215   wm_save_yourself = XmInternAtom( display, "WM_SAVE_YOURSELF", False );
216 
217   XmAddWMProtocols( shellW, &wm_save_yourself, 1 );
218   XmAddWMProtocolCallback( shellW, wm_save_yourself,
219                            (XtCallbackProc) saveSessionCB,
220                            (XtPointer) shellW );
221 
222 
223   return;
224 
225 } /* xtmToSessionMgmt */
226 
227 
228 /*----------------------------------------------------------------------*/
229 
230 void
xtmToSetLocale(char * program_name)231 xtmToSetLocale( char  *program_name )
232 {
233 
234   /* Code. */
235 
236   /* Only for release >X11R5. */
237 #if ! defined( XD_HAS_NO_NLS ) && XtSpecificationRelease > 4
238 
239   if( setlocale( LC_ALL, "" ) == NULL ) {
240     if( setlocale( LC_ALL, "C" ) == NULL ) {
241       fprintf( stderr, "%s: Cannot set locale.\n", program_name );
242       exit( 1 );
243     }
244   }
245 
246   if( ! XSupportsLocale() ) {
247     fprintf( stderr, "%s: X does not support locale.\n", program_name );
248     exit( 1 );
249   }
250 
251   if( XSetLocaleModifiers( "" ) == NULL ) {
252     fprintf( stderr, "%s: X cannot set locale modifiers.\n", program_name );
253   }
254 
255 #endif
256 
257 
258   return;
259 
260 } /* xtmToSetLocale */
261 
262 
263 /*----------------------------------------------------------------------*/
264 
265 int
xtmToStartProcess(Widget parent,Boolean remove_message,char * starting_message,char * process_args[])266 xtmToStartProcess( Widget   parent,
267                    Boolean  remove_message,
268                    char     *starting_message,
269                    char     *process_args[] )
270 {
271 
272   /* Variables. */
273   int      pid;
274   Display  *display = NULL;
275   Widget   tempW;
276 
277 
278   /* Code. */
279 
280   if( parent != NULL )
281     display = XtDisplay( parent );
282 
283   /* Start the process. */
284   pid = fork();
285 
286   switch( pid ) {
287 
288     /* Child running. */
289     case 0:
290       if( display != NULL )
291         close( ConnectionNumber( display ) );
292 
293 
294       /* Start the process. */
295       execvp( process_args[ 0 ], process_args );
296 
297       {
298         char  buffer[ 200 ];
299 
300         sprintf( buffer,
301                  msgGetText( MXDI_ERRMSG_EXECUTE_PROCESS ),
302                  process_args[ 0 ] );
303 
304         xitErMessage( NULL, XIT_ER_ERROR,
305                       module_name, "startProcess",
306                       buffer );
307       } /* block */
308 
309       exit( 1 );
310 
311     /* Error in fork. */
312     case -1:
313       xitErMessage( parent, XIT_ER_ERROR,
314                     module_name, "xtmToStartProcess",
315                     msgGetText( MXDI_PROCESS_CANNOT_FORK ) );
316       return( 0 );
317 
318     /* Parent */
319     default:
320       break;
321 
322   } /* switch */
323 
324 
325   /* Tell the user what we are doing since this might take time. */
326   if( starting_message != NULL ) {
327     tempW = xitCreateInformationDialog(
328               parent, "InformationDialog",
329               msgGetText( MXDI_INFORMATION_LABEL ),
330               starting_message,
331               NULL, NULL );
332 
333     if( remove_message )
334       xitInformationDialogTimeout( tempW, 4 );
335   }
336 
337   /* Catch this process when we return. */
338   (void) SigRegister( SIGCHLD, pid, NULL, NULL );
339 
340 
341   return( pid );
342 
343 } /* xtmToStartProcess */
344 
345 
346 /*----------------------------------------------------------------------*/
347 
348 static unsigned long
checkWindowState(Display * display,Window window)349 checkWindowState( Display  *display,
350                   Window   window )
351 {
352 
353   /* Variables. */
354   int            actual_format;
355   int            status;
356   unsigned long  *property = NULL;
357   unsigned long  nitems;
358   unsigned long  leftover;
359   Atom           actual_type;
360   Atom           wm_state;
361 
362 
363   /* Code. */
364 
365   wm_state = XInternAtom( display, "WM_STATE", False );
366 
367   status = XGetWindowProperty( display, window,
368                                wm_state, 0L, WM_STATE_ELEMENTS, False,
369                                wm_state,
370                                &actual_type, &actual_format, &nitems,
371                                &leftover, (unsigned char **) &property );
372 
373   if( ! ((status == Success) &&
374          (actual_type = wm_state) &&
375          (nitems == WM_STATE_ELEMENTS)) ) {
376     if( property ) {
377       XFree( (char *) property );
378       return( 0L );
379     }
380   }
381 
382   if( property == NULL )
383     return( 0 );
384   else
385     return( *property );
386 
387 } /* checkWindowState */
388 
389 
390 /*----------------------------------------------------------------------*/
391 
392 static void
saveSessionCB(Widget widget,Widget toplevelW,XtPointer call_data)393 saveSessionCB( Widget     widget,
394                Widget     toplevelW,
395                XtPointer  call_data )
396 {
397 
398   /* Variables. */
399   int     argc;
400   char**  argv;
401 
402 
403   /* Code. */
404 
405   /* Just "touch" the WM_COMMAND property. */
406   if( XGetCommand( XtDisplay( toplevelW ), XtWindow( toplevelW  ),
407                    &argv, &argc ) != 0 ) {
408     XSetCommand( XtDisplay( toplevelW ), XtWindow( toplevelW ), argv, argc );
409 
410     XFreeStringList( argv );
411   }
412 
413 
414   return;
415 
416 } /* saveSessionCB */
417 
418 
419