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 librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $XConsortium: ttmedia.C /main/3 1995/10/23 10:32:41 rswiston $
28 #include "api/c/tt_c.h"
29 #include "util/tt_gettext.h"
30 #include "tttk/tttk.h"
31 #include "tttk/ttdesktop.h"
32 #include "tttk/tttkmessage.h"
33 #include "tttk/tttkpattern.h"
34 #include "tttk/tttkutils.h"
35 #include "tttk/tttk2free.h"
37 Tt_status _tt_ptype_opnum_user_set(const char *ptype, int opnum,
39 void * _tt_ptype_opnum_user(const char *ptype, int opnum);
41 class _Ttmedia_ptype_info: public _Tt_allocated {
44 Ttmedia_load_pat_cb loadCB,
48 Ttmedia_load_pat_cb _loadCB;
52 _Ttmedia_ptype_info::_Ttmedia_ptype_info(
53 Ttmedia_load_pat_cb loadCB,
57 _clientData = clientData;
64 Ttmedia_load_pat_cb callback,
67 int counterfoilArg = -1,
71 static const char here[] = "ttMediaLoadPatCB()";
72 unsigned char *contents = 0;
76 Tt_status diagnosis = TT_OK;
77 const char *diagnosisStr= 0;
78 char *counterfoil = 0;
84 status = tt_message_arg_bval( msg, 0, &contents, &len );
85 if (status != TT_OK) {
87 diagnosisStr = "tt_message_arg_bval( msg, 0 )";
88 } else if (len == 0) {
90 // contents arg empty; contents are in named file
92 file = tt_message_file( msg );
93 status = tt_ptr_error( file );
94 if (status != TT_OK) {
97 diagnosisStr = "tt_message_file()";
98 } else if ( (file == 0)
99 && (tt_message_arg_mode( msg, 0 ) != TT_OUT)
100 && (op != TTME_INSTANTIATE))
102 diagnosis = TT_DESKTOP_ENODATA;
103 diagnosisStr = catgets( _ttcatd, 1, 25,
104 "empty document and no file" );
107 if (counterfoilArg >= 0) {
108 counterfoil = tt_message_arg_val( msg, counterfoilArg );
109 status = tt_ptr_error( counterfoil );
110 if (status != TT_OK) {
111 _ttDtPrintStatus( here,
112 catgets( _ttcatd, 1, 26,
113 "cannot get messageID; "
114 "operation may not be "
115 "cancel-able, because "
116 "tt_message_arg_val()"),
118 counterfoil = 0; // charge ahead
121 if (docNameArg > 0) {
122 docName = tt_message_arg_val( msg, docNameArg );
123 status = tt_ptr_error( docName );
124 if (status != TT_OK) {
125 _ttDtPrintStatus( here,
126 catgets( _ttcatd, 1, 27,
127 "cannot get title; document "
128 "will be untitled because "
129 "tt_message_arg_val()" ),
131 docName = 0; // charge ahead
134 msg = (*callback)( msg, clientData, op, diagnosis, contents,
135 len, file, docName );
136 status = tt_ptr_error( msg );
137 if ((status == TT_OK) && (msg != 0) && (diagnosis != TT_OK)) {
138 tttk_message_fail( msg, diagnosis, diagnosisStr, 1 );
139 return (Tt_message)tt_error_pointer( diagnosis );
151 static const char here[] = "_ttMeOpnumCB()";
153 if ( (tt_message_state( msg ) != TT_SENT)
154 || (tt_message_class( msg ) != TT_REQUEST )
155 || (! _tttk_message_am_handling( msg )))
157 return TT_CALLBACK_CONTINUE;
159 int opnum = tt_message_opnum( msg );
160 Tt_status status = tt_int_error( opnum );
161 if ((status != TT_OK) && (opnum != -1)) {
162 return TT_CALLBACK_PROCESSED;
164 int base = opnum - (opnum % 1000);
165 int offset = opnum - base;
166 char *ptype = tt_message_handler_ptype( msg );
167 _Ttmedia_ptype_info *i = (_Ttmedia_ptype_info *)
168 _tt_ptype_opnum_user( ptype, base );
170 status = tt_ptr_error( i );
171 if ((status != TT_OK) || (i == 0)) {
172 return TT_CALLBACK_PROCESSED;
176 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
180 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
184 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
185 TTME_DISPLAY, -1, 1 );
188 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
189 TTME_DISPLAY, 1, 2 );
192 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
196 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
200 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
204 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
208 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
212 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
216 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
217 TTME_COMPOSE, -1, 1 );
220 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
221 TTME_COMPOSE, 1, 2 );
224 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
228 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
232 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
233 TTME_MAIL_EDIT, -1, 1 );
236 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
240 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
241 TTME_MAIL_COMPOSE, -1, 1 );
244 msg = ttMediaLoadPatCB( msg, pat, i->_loadCB, i->_clientData,
247 // Add any new offsets to ttmedia_ptype_declare()
250 catgets(_ttcatd, 1, 28, "unknown opnum offset"),
252 return TT_CALLBACK_CONTINUE;
254 return _ttDtCallbackAction( msg );
258 ttmedia_ptype_declare(
261 Ttmedia_load_pat_cb loadCB,
269 * XXX Join default contexts of current default procid.
271 for (int i = 0; i <= 200; i += 100) {
272 for (int j = 1; j <= 4; j++) {
273 status = tt_ptype_opnum_callback_add( ptype,
274 i + j + baseOpnum, _ttMeOpnumCB );
275 if (status != TT_OK) {
280 status = tt_ptype_opnum_callback_add( ptype, 301, _ttMeOpnumCB );
281 if (status != TT_OK) return status;
282 status = tt_ptype_opnum_callback_add( ptype, 311, _ttMeOpnumCB );
283 if (status != TT_OK) return status;
284 status = tt_ptype_opnum_callback_add( ptype, 313, _ttMeOpnumCB );
285 if (status != TT_OK) return status;
286 status = tt_ptype_opnum_callback_add( ptype, 321, _ttMeOpnumCB );
287 if (status != TT_OK) return status;
288 status = tt_ptype_opnum_callback_add( ptype, 323, _ttMeOpnumCB );
289 if (status != TT_OK) return status;
290 status = tt_ptype_opnum_callback_add( ptype, 401, _ttMeOpnumCB );
291 if (status != TT_OK) return status;
293 // Like opnum callbacks themselves, this memory lives as long
296 _Ttmedia_ptype_info *info =
297 new _Ttmedia_ptype_info( loadCB, clientData );
298 status = _tt_ptype_opnum_user_set( ptype, baseOpnum, info );
299 if (status != TT_OK) {
303 status = tt_ptype_declare( ptype );
304 if (status != TT_OK) {
312 // Parse Display/Edit/Compose reply, or Deposit request, and pass to
323 char *opname = tt_message_op( msg );
324 Tttk_op op = tttk_string_op( opname );
326 int final = _tttk_message_in_final_state( msg );
327 switch (tt_message_state( msg )) {
332 if (op != TTME_DEPOSIT) {
333 // This address space is handler, but is not
334 // through handling, so continue.
339 Tt_pattern depositPat = 0;
342 (Tt_pattern)tt_message_user( msg, _TttkDepositPatKey );
344 Ttmedia_load_msg_cb _cb = (Ttmedia_load_msg_cb)clientCB;
346 _TttkItem2Free fuse = msg;
347 unsigned char *contents = 0;
350 status = tt_message_arg_bval( msg, 0, &contents, &len );
351 if (status != TT_OK) {
352 return (Tt_message)tt_error_pointer( status );
354 char *file = tt_message_file( msg );
355 if (tt_ptr_error( file ) != TT_OK) {
359 msg = (*_cb)( msg, clientData, op, contents, len, file );
363 // The reply has now come in, so there can be no
364 // more Deposit requests on this buffer.
366 tt_pattern_destroy( depositPat );
373 Tt_category category,
374 const char *media_type,
375 Tt_message commission,
376 const char *buffer_id,
377 Ttmedia_load_msg_cb clientcb,
382 Tt_pattern pat = _ttDtPatternCreate( category, TT_SESSION,
383 register_it, 0, TTME_DEPOSIT,
384 _ttMediaLoadMsgCB, (void *)clientcb,
386 Tt_status status = tt_ptr_error( pat );
387 if (status != TT_OK) {
390 _TttkItem2Free fuse = pat;
391 status = tt_pattern_arg_add( pat, TT_IN, media_type, 0 );
392 if (status != TT_OK) {
393 return (Tt_pattern)tt_error_pointer( status );
395 if (buffer_id != 0) {
396 status = tt_pattern_arg_add( pat, TT_IN, "bufferID",
398 if (status != TT_OK) {
399 return (Tt_pattern)tt_error_pointer( status );
403 return _ttDesktopPatternFinish( pat, commission, register_it );
409 Ttmedia_load_msg_cb cb,
412 const char *mediaType,
413 const unsigned char *contents,
420 Tt_message msg = _ttDtPMessageCreate( context, TT_REQUEST, TT_SESSION,
421 0, op, _ttMediaLoadMsgCB, (void *)cb, clientData );
422 Tt_status status = tt_ptr_error( msg );
423 if (status != TT_OK) {
426 _TttkItem2Free fuse = msg;
431 case TTME_INSTANTIATE:
435 case TTME_MAIL_COMPOSE:
442 status = tt_message_barg_add( msg, mode, mediaType, contents, len );
443 if (status != TT_OK) {
444 return (Tt_message)tt_error_pointer( status );
447 status = tt_message_file_set( msg, file );
448 if (status != TT_OK) {
449 return (Tt_message)tt_error_pointer( status );
453 status = tt_message_arg_add( msg, TT_IN, Tttk_title, docname );
454 if (status != TT_OK) {
455 return (Tt_message)tt_error_pointer( status );
458 Tt_pattern pat = ttmedia_Deposit_pat( TT_HANDLE, mediaType,
459 msg, 0, cb, clientData, 1 );
460 status = tt_ptr_error( pat );
461 if (status == TT_OK) {
462 // Save the pattern so we can destroy it when
463 // the message reaches a final state.
464 tt_message_user_set( msg, _TttkDepositPatKey, pat );
467 status = tt_message_send( msg );
468 if (status != TT_OK) {
469 return (Tt_message)tt_error_pointer( status );
479 const unsigned char *newContents,
481 int reply_and_destroy
484 Tt_status status = TT_OK;
485 status = tt_message_arg_bval_set( contract, 0, newContents, newLen );
486 if (status != TT_OK) {
489 if (reply_and_destroy) {
490 status = tt_message_reply( contract );
491 if (status != TT_OK) {
494 tttk_message_destroy( contract );
502 const char *buffer_id,
503 const char *media_type,
504 const unsigned char *new_contents,
507 XtAppContext app2run,
513 if (buffer_id == 0) {
514 handler = tt_message_sender( contract );
515 status = tt_ptr_error( handler );
516 if (status != TT_OK) {
521 Tt_message msg = _ttDtPMessageCreate( contract, TT_REQUEST, TT_SESSION,
522 handler, TTME_DEPOSIT, _ttTkNoteReplyStatus,
525 status = tt_ptr_error( msg );
526 if (status != TT_OK) {
529 _TttkItem2Free fuse = msg;
530 const char *_media_type = media_type;
531 if (media_type == 0) {
532 _media_type = tt_message_arg_type( contract, 0 );
534 status = tt_message_barg_add( msg, TT_IN, _media_type, new_contents,
536 if (media_type == 0) {
537 tt_free( (caddr_t)_media_type );
539 if (status != TT_OK) {
543 status = tt_message_file_set( msg, file );
544 if (status != TT_OK) {
548 msg = _ttDesktopMessageFinish( msg, contract, 1 );
549 status = tt_ptr_error( msg );
550 if (status != TT_OK) {
554 status = tttk_block_while( app2run, &replyStatus, ms_timeout );
555 if (status == TT_DESKTOP_ETIMEDOUT) {
556 // See comment in ttdt_Get_Modified()
557 tttk_message_destroy( msg );
560 return (Tt_status)-replyStatus;