Link with C++ linker
[oweals/cde.git] / cde / programs / dtfile / ToolTalk.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 librararies 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 /* $TOG: ToolTalk.c /main/6 1999/09/16 13:41:16 mgreess $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           ToolTalk.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    Contains routines to handle tooltalk messages.
32  *
33  *   FUNCTIONS: FileCallback
34  *              FinalizeToolTalkSession
35  *              InitializeToolTalkProcid
36  *              InitializeToolTalkSession
37  *              MediaCallback
38  *              SessionCallback
39  *              ToolTalkError
40  *
41  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
42  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
43  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
44  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
45  *
46  ****************************************************************************
47  ************************************<+>*************************************/
48
49 #include <Xm/XmP.h>
50 #include <Xm/DrawingA.h>
51 #include <Xm/DrawingAP.h>
52 #include <Xm/MessageB.h>
53 #include <Xm/RowColumn.h>
54 #include <Xm/MwmUtil.h>
55
56 #include <Dt/Icon.h>
57 #include <Dt/IconP.h>
58 #include <Dt/IconFile.h>
59
60 #include <Dt/HelpDialog.h>
61
62 #ifdef SHAPE
63 #include <X11/extensions/shape.h>
64 #endif
65
66 #include <X11/Shell.h>
67 #include <X11/Xatom.h>
68 #include <Xm/Protocols.h>
69 #include <X11/keysymdef.h>
70
71 #include <Dt/Session.h>
72 #include <Dt/DtP.h>
73 #include <Dt/Connect.h>
74 #include <Dt/FileM.h>
75 #include <Dt/Indicator.h>
76 #include <Dt/Lock.h>
77 #include <Dt/UserMsg.h>
78 #include <Dt/Wsm.h>
79 #include <Dt/WsmP.h>
80 #include <Dt/DtNlUtils.h>
81 #include <Dt/CommandM.h>
82 #include <Dt/EnvControlP.h>
83
84 #include <Tt/tttk.h>
85
86 #include "Encaps.h"
87 #include "SharedProcs.h"
88 #include "FileMgr.h"
89 #include "Desktop.h"
90 #include "Main.h"
91
92 /* ToolTalk messages */
93 #define FM_TT_MSG_QUIT        "Quit"
94 #define FM_TT_MSG_PAUSE       "Pause"
95 #define FM_TT_MSG_RESUME      "Resume"
96 #define FM_TT_MSG_GET_STAT    "Get_Status"
97 #define FM_TT_MSG_DO_CMD      "Do_Command"
98
99 #define VENDOR                "CDE"
100 #define VERSION               "1.0"
101
102 static char* RESTRICTED_HEADER = "-restricted";
103
104 static Tt_pattern * FileManagerToolTalkPattern = NULL;
105 static Boolean sendStopped = False;
106 XtInputId ProcessToolTalkInputId = 0;
107
108
109 Tt_message
110 FileCallback(
111         Tt_message msg,
112         Tttk_op op,
113         char * file,
114         void * clientdata,
115         int trust,
116         int self)
117 {
118   View *view = clientdata;
119   char local_host[MAXHOSTNAMELEN];
120   extern char home_host_name[];
121
122   switch (op) {
123           char *to_file;
124           DialogData *dialog_data;
125           int i;
126       default:
127           break;
128       case TTDT_MOVED:
129           if (view == 0) {
130                   break;
131           }
132           to_file = tt_message_arg_val(msg, 1);
133           strcpy(local_host, home_host_name);
134           dialog_data = (DialogData *)view->dialog_data;
135           ShowNewDirectory( (FileMgrData *)dialog_data->data,
136                             local_host, to_file);
137
138           /* Quit the old file, join the new */
139           ttdt_file_quit( view->pats, 0 );
140           view->pats = ttdt_file_join( to_file, TT_SESSION,
141                                        0, FileCallback, view );
142           if (tt_is_err( tt_ptr_error( view->pats ))) {
143               view->pats = 0;
144           }
145           tt_free( to_file );
146           tttk_message_destroy( msg );
147           msg = 0;
148   }
149   tt_free( file );
150   return msg;
151 }
152
153
154 void
155 FinalizeToolTalkSession( )
156 {
157   Tt_status ttRc;
158   int i;
159
160   for (i = 0; i < view_count; i++)
161   {
162       if (view_set[i]->msg != 0) {
163          if (view_set[i]->pats != 0) {
164             ttdt_file_quit( view_set[i]->pats, 0 );
165             view_set[i]->pats = 0;
166          }
167          tt_message_reply( view_set[i]->msg );
168          tttk_message_destroy( view_set[i]->msg );
169          view_set[i]->msg = 0;
170       }
171   }
172
173   if( FileManagerToolTalkPattern &&
174       tt_ptr_error( FileManagerToolTalkPattern ) == TT_OK )
175   {
176     ttRc = ttdt_session_quit( NULL,
177                               FileManagerToolTalkPattern,
178                               1 );
179     if( ProcessToolTalkInputId )
180       XtRemoveInput( ProcessToolTalkInputId );
181   }
182   ttRc = ttdt_close( NULL, NULL, sendStopped );
183 }
184
185 void
186 ToolTalkError( char * procName, Tt_status errId )
187 {
188   if( tt_is_err( errId ) )
189   {
190     switch( errId )
191     {
192       case TT_ERR_NOMP:
193          XtRemoveInput( ProcessToolTalkInputId );
194          break;
195       default:
196          break;
197     }
198   }
199 }
200
201 Tt_message
202 SessionCallback( Tt_message msg, void * client_data, Tt_message contract )
203 {
204   View *view = client_data;
205   char *opString = tt_message_op( msg );
206   Tttk_op op = tttk_string_op( opString );
207   tt_free( opString );
208
209   switch (op) {
210           int i;
211       default:
212           break;
213       case TTDT_QUIT:
214           if (contract == 0) {
215                   tt_message_reply( msg );
216                   FinalizeToolTalkSession( );
217                   exit( 0 );
218           }
219           /*
220            * Instead of quitting the whole process, we are to just
221            * quit the view associated with contract.
222            */
223           if (view == 0) {
224                   tttk_message_fail( msg, TT_DESKTOP_EINVAL, 0, 1 );
225                   return 0;
226           }
227           CloseView( (DialogData *)view->dialog_data );
228           tt_message_reply( msg );
229           tttk_message_destroy( msg );
230           return 0;
231   }
232   return msg;
233 }
234
235 Tt_message
236 MediaCallback( Tt_message msg,
237                void * client_data,
238                Tttk_op op,
239                Tt_status diag,
240                unsigned char * contents,
241                int len,
242                char * file,
243                char * docname )
244 {
245         char *ceiling;
246         Boolean restricted = False;
247
248         tt_free( docname );
249         if (diag != TT_OK) {
250                 return msg;
251         }
252         if (file == 0) {
253                 if (contents == 0) {
254                         tttk_message_fail( msg, TT_DESKTOP_ENODATA, 0, 1 );
255                         return 0;
256                 } else {
257                         /* Buffers and files are the same to dtfile */
258                         /* ToolTalk buffers are always null-terminated */
259                         tt_free( file );
260                         file = (char *)contents;
261                 }
262         }
263         /* Old libtt SEGVs if you ask for a context that is not there */
264         if (tt_message_contexts_count( msg ) > 0) {
265                 ceiling = tt_message_context_val( msg, "restricted" );
266                 if (! tt_is_err( tt_ptr_error( ceiling ))) {
267                         if ((ceiling == 0) || (strcmp( ceiling, "." ) != 0)) {
268                                 tttk_message_fail( msg,
269                                                    TT_DESKTOP_ENOTSUP, 0, 1 );
270                                 return 0;
271                         }
272                         restricted = True;
273                 }
274         }
275         switch ( op ) {
276             default:
277                 break;
278             case TTME_DISPLAY:
279             case TTME_EDIT:
280                 /*
281                  * Create a display of the given directory tree
282                  */
283                 ViewDirectoryProc( file, restricted, msg );
284                 msg = 0;
285                 break;
286         }
287         tt_free( file );
288         tt_free( (caddr_t)contents );
289         return msg;
290 }
291
292 Tt_status
293 InitializeToolTalkProcid( int *ttFd, Widget topLevel, Boolean sendStarted )
294 {
295   char * procId;
296   Tt_status ttstat;
297
298 #ifdef DT_PERFORMANCE
299    printf("  InitializeToolTalkProcid\n");
300    gettimeofday(&update_time_s, NULL);
301 #endif
302   sendStopped = sendStarted;
303   procId = ttdt_open( ttFd,
304                       DTFILE_CLASS_NAME,
305                       VENDOR,
306                       VERSION,
307                       sendStarted );
308
309 #ifdef DT_PERFORMANCE
310    gettimeofday(&update_time_f, NULL);
311    if (update_time_s.tv_usec > update_time_f.tv_usec) {
312       update_time_f.tv_usec += 1000000;
313       update_time_f.tv_sec--;
314    }
315    printf("    done InitializeToolTalkProcid, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
316 #endif
317
318   if( (ttstat = tt_ptr_error( procId )) == TT_OK )
319   {
320     ProcessToolTalkInputId =
321             XtAppAddInput( XtWidgetToApplicationContext( toplevel ),
322                            *ttFd, (XtPointer)XtInputReadMask,
323                            tttk_Xt_input_handler, procId );
324     return( TT_OK );
325   }
326   else
327   {
328     ttdt_close( NULL, NULL, sendStopped );
329     return( ttstat );
330   }
331 }
332
333
334 int
335 InitializeToolTalkSession( Widget topLevel, int ttFd )
336 {
337   Tt_status ttstat;
338
339   ttstat = ttmedia_ptype_declare( "DT_File_Manager",
340                                   0,
341                                   MediaCallback,
342                                   (void *) 0,
343                                   0);
344   if (ttstat == TT_OK)
345     ttstat = ttmedia_ptype_declare( "DT_File_Manager",
346                                     1000,
347                                     MediaCallback,
348                                     (void *) 0,
349                                     1);
350   tt_ptype_opnum_callback_add( "DT_File_Manager", 0, HandleTtRequest );
351   if (ttstat == TT_OK)
352   {
353     /*
354      * If we were started by a message, the following call to
355      * tttk_Xt_input_handler will process it.  Otherwise,
356      * tttk_Xt_input_handler will just return.
357      */
358     tttk_Xt_input_handler( NULL, 0, 0 );
359
360     FileManagerToolTalkPattern = ttdt_session_join( tt_default_session( ),
361                                                     SessionCallback,
362                                                     topLevel,
363                                                     NULL,
364                                                     1 );
365     if( tt_is_err( tt_ptr_error( FileManagerToolTalkPattern )))
366     {
367       ttdt_close( NULL, NULL, sendStopped );
368       return( 0 );
369     }
370   }
371   else
372   {
373     ttdt_close( NULL, NULL, sendStopped );
374     return( 0 );
375   }
376   return( TT_OK );
377 }