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 //%% $TOG: tttk.C /main/5 1999/09/14 13:00:44 mgreess $
29 # include <sys/poll.h>
36 #include "api/c/tt_c.h"
37 #include "util/tt_gettext.h"
38 #include "util/tt_Xlib.h"
39 #include "util/tt_port.h"
40 #include "tttk/tttk.h"
41 #include "tttk/tttk2free.h"
42 #include "tttk/tttkutils.h"
43 #include "tttk/tttkpattern.h"
44 #include "tttk/ttdtprocid.h"
45 #include "tttk/ttdesktop.h"
47 extern Tt_status _tt_errno_status( int err_no );
49 const char *Tttk_integer = "integer";
50 const char *Tttk_string = "string";
51 const char *Tttk_boolean = "boolean";
52 const char *Tttk_file = "File";
53 const char *Tttk_message_id = "messageID";
54 const char *Tttk_title = "title";
55 const char *Tttk_width = "width";
56 const char *Tttk_height = "height";
57 const char *Tttk_xoffset = "xOffset";
58 const char *Tttk_yoffset = "yOffset";
60 _TtDtProcid *_ttdtme = 0;
73 _ttdtme = new _TtDtProcid( toolName, vendor, version );
75 return (char *)tt_error_pointer( TT_ERR_NOMEM );
77 char *procID = tt_open();
78 Tt_status status = tt_ptr_error( procID );
79 if (status != TT_OK) {
83 status = tt_int_error( *ttFD );
84 if (status != TT_OK) {
87 return (char *)tt_error_pointer( status );
90 ttdt_Started( 0, toolName, vendor, version, 1 );
96 // A callback used internally to pick geometry info out of
97 // a Get_Geometry reply and stuff it into (DisplayInfo *)clientData.
110 DisplayInfo *info = (DisplayInfo *)clientData;
112 info->repliesOutStanding--;
114 info->height = height;
115 info->xOffset = xOffset;
116 info->yOffset = yOffset;
118 tttk_message_destroy( msg );
123 // A TtDtGetXInfoMsgCB used internally to pick X11 info out of
124 // a Get_XInfo reply and stuff it into (DisplayInfo *)clientData.
136 DisplayInfo *info = (DisplayInfo *)clientData;
138 info->repliesOutStanding--;
139 info->display = display;
141 tttk_message_destroy( msg );
146 ttdt_sender_imprint_on(
148 Tt_message commission,
154 XtAppContext app2run,
161 info.repliesOutStanding = 0;
164 info.xOffset = INT_MAX;
165 info.yOffset = INT_MAX;
167 if ((width != 0) || (height != 0) || (xOffset != 0) || (yOffset != 0)){
168 msg = ttdt_Get_Geometry( handler, commission,
169 _ttDtApplyGeom, &info, 1 );
170 status = tt_ptr_error( msg );
171 if (status == TT_OK) {
172 info.repliesOutStanding++;
175 // XXX sending XInfo before Geometry causes segv in handler!? Saberize.
176 msg = ttdt_Get_XInfo( handler, commission,
177 _ttDtApplyXInfo, &info, 1);
178 status = tt_ptr_error( msg );
179 if (status == TT_OK) {
180 info.repliesOutStanding++;
182 msg = ttdt_Get_Locale( handler, commission, 0, &info, 0, 1 );
183 status = tt_ptr_error( msg );
184 if (status == TT_OK) {
185 info.repliesOutStanding++;
187 msg = ttdt_Get_Situation( handler, commission, 0, &info, 1 );
188 status = tt_ptr_error( msg );
189 if (status == TT_OK) {
190 info.repliesOutStanding++;
192 if (info.repliesOutStanding == 0) {
195 status = tttk_block_while( app2run,
196 &info.repliesOutStanding, msTimeOut );
198 if (info.display != 0) {
199 _tt_putenv( "DISPLAY", info.display );
201 tt_free( info.display );
203 *pDisplay = info.display;
209 *height = info.height;
212 *xOffset = info.xOffset;
215 *yOffset = info.yOffset;
223 const char *newProcid,
229 status = tt_default_procid_set( procid );
230 if (status != TT_OK) {
235 ttdt_Stopped( 0, _ttdtme->toolname(), _ttdtme->vendor(),
236 _ttdtme->version(), 1 );
239 if (status != TT_OK) {
242 if (newProcid != 0) {
243 status = tt_default_procid_set( newProcid );
244 if (status != TT_OK) {
261 _TttkItem2Free item2free;
263 sessid = tt_default_session();
264 status = tt_ptr_error( sessid );
265 if (status != TT_OK) {
266 return (Tt_pattern *)tt_error_pointer( status );
268 item2free = (char *)sessid;
270 Tt_pattern *pats = _ttdtme->pats_create( 0, cb, shell, clientdata );
272 status = tt_session_join( sessid );
273 if (status != TT_OK) {
274 return (Tt_pattern *)tt_error_pointer( status );
288 _TttkItem2Free item2free;
290 sessid = tt_default_session();
291 status = tt_ptr_error( sessid );
292 if (status != TT_OK) {
295 item2free = (char *)sessid;
297 status = _tttk_patterns_destroy( pats );
298 if (status != TT_OK) {
302 status = tt_session_quit( sessid );
303 if (status != TT_OK) {
322 status = tt_message_accept( contract );
323 if (status != TT_OK) {
327 Tt_pattern *pats = _ttdtme->pats_create( contract, cb, shell,
329 status = tt_ptr_error( pats );
330 if (status == TT_OK) {
331 tt_message_user_set( contract, _TttkContractKey, pats );
334 ttdt_Status( contract, contract,
335 catgets( _ttcatd, 1, 24, "Accepting request" ),
336 _ttdtme->toolname(), _ttdtme->vendor(),
337 _ttdtme->version(), 1 );
343 ttdt_subcontract_manage(
344 Tt_message subcontract,
350 const int numPats = 4;
351 Tt_pattern *pats = (Tt_pattern *)malloc(numPats * sizeof(Tt_pattern));
353 return (Tt_pattern *)tt_error_pointer( TT_ERR_NOMEM );
357 pats[0] = ttdt_Get_Geometry_pat( TT_HANDLE, subcontract,
358 _ttdt_do_GSet_Geometry, shell, 1 );
359 pats[1] = ttdt_Get_XInfo_pat( TT_HANDLE, subcontract,
360 _ttdt_do_Get_XInfo, shell, 1 );
362 pats[0] = ttdt_Get_Geometry_pat( TT_HANDLE, subcontract,
363 (Ttdt_Geometry_out_cb)cb, clientData, 1 );
364 pats[1] = ttdt_Get_XInfo_pat( TT_HANDLE, subcontract,
365 (Ttdt_XInfo_out_cb)cb, clientData, 1 );
367 pats[2] = _ttdt_pat( TTDT_STATUS, _ttdt_contract_cb, TT_OBSERVE,
368 subcontract, cb, clientData, 1 );
369 pats[ numPats - 1 ] = 0;
370 for (int i = 0; i < numPats; i++) {
371 Tt_status status = tt_ptr_error( pats[ i ] );
372 if (status != TT_OK) {
373 _tttk_patterns_destroy( pats );
375 return (Tt_pattern *)tt_error_pointer( status );
378 tt_message_user_set( subcontract, _TttkSubContractKey, pats );
383 tttk_Xt_input_handler(
389 static const char *here = "ttdt_Xt_input_handler()";
391 Tt_message msg = _tttk_message_receive( (char *)procid );
392 Tt_status status = tt_ptr_error( msg );
393 if (status != TT_OK) {
394 _ttDtPrintStatus( here, "tttk_message_receive()", status);
395 if (status == TT_ERR_NOMP) {
396 ttdt_close( (const char *)procid, 0, 0 );
397 if (! _tt_load_xt()) {
401 CALLXT(XtRemoveInput)( *id );
409 status = tttk_message_abandon( msg );
410 if (status != TT_OK) {
411 _ttDtPrintStatus( here, "tttk_message_abandon()", status );
416 _tttk_block_procid_while(
422 Tt_status status = tt_int_error( fd );
423 if (status != TT_OK) {
426 while ((blocked == 0) || (*blocked > 0)) {
427 struct pollfd fds[ 1 ];
429 fds[0].events = POLLIN;
430 int activeFDs = poll( fds, 1, msTimeOut );
431 if (activeFDs == 0) {
432 return TT_DESKTOP_ETIMEDOUT;
433 } else if (activeFDs < 0) {
434 if ((blocked != 0) && (*blocked)) {
435 _ttDtPError( "_tttk_block_procid_while()",
437 return _tt_errno_status( errno );
440 if (fds[ 0 ].revents != 0) {
442 // AIX has fd in struct pollfd as a long, not
443 // an int, and complains (justifiably) when
444 // long* is passed when int* is needed. So use
445 // call-by-value-return instead of
446 // call-by-reference. Hey,
447 // tttk_Xt_input_handler doesn\'t use the
452 tttk_Xt_input_handler( 0, &fd_temp, 0 );
455 if (msTimeOut == 0) {
458 if (msTimeOut == 0) {
467 XtPointer p_timed_out,
471 *(int *)p_timed_out = 1;
475 _tttk_block_app_while(
476 XtAppContext app2run,
481 XtIntervalId alarm = 0;
482 if ((blocked != 0) && (*blocked <= 0)) return TT_OK;
483 int timed_out = (msTimeOut == 0);
484 if ((! _tt_load_xt()) || (! _tt_load_xlib())) {
485 return TT_ERR_ACCESS; // i.e. ELIBACC
487 if ((timed_out) && (! CALLXT(XtAppPending)( app2run ))) {
489 // We are non-blocking and no input is available,
492 return TT_DESKTOP_ETIMEDOUT;
495 alarm = CALLXT(XtAppAddTimeOut)( app2run,
496 (unsigned long)msTimeOut,
497 (XtTimerCallbackProc)_tttk_timed_out,
501 CALLXT(XtAppProcessEvent)( app2run, XtIMAll );
502 } while ((! timed_out) && ((blocked == 0) || (*blocked > 0)));
504 CALLXT(XtRemoveTimeOut)( alarm );
506 if (timed_out && (msTimeOut > 0)) {
507 return TT_DESKTOP_ETIMEDOUT;
514 XtAppContext app2run,
520 return _tttk_block_procid_while( blocked, msTimeOut );
522 return _tttk_block_app_while( app2run, blocked, msTimeOut );