1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: xitMsgWin 4 -- 5 -- Project: xit - X Internal Toolkit 6 -- System: <> 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- Window for general messages. The messages displayed are numbered and 12 -- they can be viewed and a file log can be created. 13 -- 14 -- Filename: xitMsgWin.c 15 -- 16 -- Authors: Roger Larsson, Ulrika Bornetun 17 -- Creation date: 1992-06-16 18 -- 19 -- 20 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 21 -- All rights reserved 22 -- 23 -- Permission to use, copy, modify, and distribute this software and its 24 -- documentation for any purpose and without fee is hereby granted, 25 -- provided that the above copyright notice appear in all copies. Ulrika 26 -- Bornetun and Roger Larsson make no representations about the usability 27 -- of this software for any purpose. It is provided "as is" without express 28 -- or implied warranty. 29 ----------------------------------------------------------------------------*/ 30 31 /* SCCS module identifier. */ 32 static char SCCSID[] = "@(#) Module: xitMsgWin.c, Version: 1.1, Date: 95/02/18 15:10:42"; 33 34 35 /*---------------------------------------------------------------------------- 36 -- Include files 37 ----------------------------------------------------------------------------*/ 38 39 #include <string.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 43 #include <X11/Intrinsic.h> 44 #include <X11/Shell.h> 45 46 #include <Xm/Protocols.h> 47 48 #include <Xm/Xm.h> 49 #include <Xm/RowColumn.h> 50 #include <Xm/Text.h> 51 52 #include "System.h" 53 #include "TimDate.h" 54 55 #include "xitTools.h" 56 #include "xitMsgWin.h" 57 58 59 /*---------------------------------------------------------------------------- 60 -- Macro definitions 61 ----------------------------------------------------------------------------*/ 62 63 /* Local widgets in the show window. */ 64 #define msgWinLa dataLocalW[ 0 ] 65 #define msgWinRc dataLocalW[ 1 ] 66 #define msgWinTx dataLocalW[ 2 ] 67 68 69 /*---------------------------------------------------------------------------- 70 -- Type declarations 71 ----------------------------------------------------------------------------*/ 72 73 /* Record for internal data. */ 74 typedef struct { 75 76 /* Max messages to display in the message window. */ 77 int max_msg; 78 79 /* Number of messages in the window. */ 80 int no_msg; 81 82 /* Selected message. */ 83 int selected_msg; 84 85 /* File name for error log file. */ 86 char *log_file; 87 88 /* Parent window. */ 89 Widget parentW; 90 91 /* Message window. */ 92 Widget msgWinW; 93 94 } MSG_REC, *MSG_REC_REF; 95 96 97 /*---------------------------------------------------------------------------- 98 -- Global definitions 99 ----------------------------------------------------------------------------*/ 100 101 102 /*---------------------------------------------------------------------------- 103 -- Function prototypes 104 ----------------------------------------------------------------------------*/ 105 106 static Widget 107 createMsgWindow( MSG_REC_REF msg_win_ref, 108 XIT_MSW_LABEL_REC *labels ); 109 110 static void 111 clearCB( Widget widget, 112 MSG_REC_REF msg_win_ref, 113 XtPointer call_data ); 114 115 static void 116 closeCB( Widget widget, 117 MSG_REC_REF msg_win_ref, 118 XtPointer call_data ); 119 120 static void 121 destroyCB( Widget widget, 122 MSG_REC_REF msg_win_ref, 123 XtPointer call_data ); 124 125 126 127 /*---------------------------------------------------------------------------- 128 -- Functions 129 ----------------------------------------------------------------------------*/ 130 131 XIT_MSW_HANDLE xitCreateMsgWindow(Widget parent,int max_messages,char * log_file,XIT_MSW_LABEL_REC * labels)132 xitCreateMsgWindow( Widget parent, 133 int max_messages, 134 char *log_file, 135 XIT_MSW_LABEL_REC *labels ) 136 { 137 138 /* Variables. */ 139 MSG_REC_REF msg_win_ref; 140 141 142 /* Code. */ 143 144 /* Create and initialize our private data. */ 145 msg_win_ref = SysNew( MSG_REC ); 146 if( msg_win_ref == NULL ) 147 return( NULL ); 148 149 msg_win_ref -> parentW = parent; 150 msg_win_ref -> log_file = NULL; 151 msg_win_ref -> max_msg = max_messages; 152 msg_win_ref -> no_msg = 0; 153 msg_win_ref -> selected_msg = 0; 154 155 /* Any log file? */ 156 if( log_file != NULL && *log_file != '\0' ) { 157 msg_win_ref -> log_file = SysNewString( log_file ); 158 } 159 160 /* Create the message window. */ 161 msg_win_ref -> msgWinW = createMsgWindow( msg_win_ref, labels ); 162 163 164 return( (XIT_MSW_HANDLE) msg_win_ref ); 165 166 } /* xitCreateMsgWindow */ 167 168 169 /*----------------------------------------------------------------------*/ 170 171 void xitMsgWinClearWindow(XIT_MSW_HANDLE msg_win_handle)172 xitMsgWinClearWindow( XIT_MSW_HANDLE msg_win_handle ) 173 { 174 175 /* Variables. */ 176 MSG_REC_REF msg_win_ref; 177 178 179 /* Code. */ 180 181 if( msg_win_handle == NULL ) 182 return; 183 184 /* Our private data. */ 185 msg_win_ref = (MSG_REC_REF) msg_win_handle; 186 187 188 /* Clear the window. */ 189 clearCB( NULL, msg_win_ref, NULL ); 190 191 192 return; 193 194 } /* xitMsgWinClearWindow */ 195 196 197 /*----------------------------------------------------------------------*/ 198 199 void xitMsgWinDestroy(XIT_MSW_HANDLE msg_win_handle)200 xitMsgWinDestroy( XIT_MSW_HANDLE msg_win_handle ) 201 { 202 203 /* Variables. */ 204 MSG_REC_REF msg_win_ref; 205 206 207 /* Code. */ 208 209 if( msg_win_handle == NULL ) 210 return; 211 212 /* Our private data. */ 213 msg_win_ref = (MSG_REC_REF) msg_win_handle; 214 215 216 /* Destroy the window. */ 217 XtDestroyWidget( msg_win_ref -> msgWinW ); 218 219 220 return; 221 222 } /* xitMsgWinDestroy */ 223 224 225 /*----------------------------------------------------------------------*/ 226 227 void xitMsgWinDisplayMessage(XIT_MSW_HANDLE msg_win_handle,char * msg,int msg_id)228 xitMsgWinDisplayMessage( XIT_MSW_HANDLE msg_win_handle, 229 char *msg, 230 int msg_id ) 231 { 232 233 /* Variables. */ 234 char *char_ref; 235 char *text_ref; 236 char buffer[ 50 ]; 237 char msg_buf[ 1000 ]; 238 Widget mainW; 239 Widget tempW; 240 XmTextPosition position; 241 MSG_REC_REF msg_win_ref; 242 TIM_TIME_REF now; 243 244 245 /* Code. */ 246 247 if( msg_win_handle == NULL ) 248 return; 249 250 /* Our private data. */ 251 msg_win_ref = (MSG_REC_REF) msg_win_handle; 252 253 254 now = TimLocalTime( TimMakeTimeNow() ); 255 mainW = XtNameToWidget( msg_win_ref -> msgWinW, 256 "SysMsgWinTlBase.SysMsgWinTlFo" ); 257 258 259 /* Build the message. */ 260 msg_buf[ 0 ] = '\0'; 261 262 if( msg_id > 0 ) { 263 sprintf( buffer, "%2.2d ", msg_id ); 264 strcat( msg_buf, buffer ); 265 } 266 267 TimFormatDate( now, buffer, sizeof( buffer ) ); 268 strcat( msg_buf, buffer ); 269 strcat( msg_buf, " " ); 270 271 TimFormatTime( now, buffer, sizeof( buffer ) ); 272 strcat( msg_buf, buffer ); 273 strcat( msg_buf, "\n" ); 274 275 strcat( msg_buf, msg ); 276 277 if( msg_buf[ strlen( msg_buf ) - 1 ] != '\n' ) 278 strcat( msg_buf, "\n" ); 279 strcat( msg_buf, ">>\n" ); 280 281 282 /* Write the message in the message window. */ 283 tempW = XtNameToWidget( mainW, "MsgWinTxSW.MsgWinTx" ); 284 285 /* Remove the top message? */ 286 if( msg_win_ref -> no_msg >= msg_win_ref -> max_msg ) { 287 text_ref = xitStringGetText( tempW ); 288 289 char_ref = strstr( text_ref, "\n>>\n" ); 290 if( char_ref != NULL ) { 291 position = (XmTextPosition) (char_ref - text_ref + 3); 292 XmTextReplace( tempW, 0, position, "" ); 293 294 SysFree( text_ref ); 295 } 296 } 297 298 /* Add the new message. */ 299 msg_win_ref -> no_msg++; 300 301 text_ref = xitStringGetText( tempW ); 302 position = (XmTextPosition) strlen( text_ref ); 303 SysFree( text_ref ); 304 305 XmTextReplace( tempW, position, position, msg_buf ); 306 307 position = position + (XmTextPosition) strlen( msg_buf ); 308 XmTextShowPosition( tempW, position ); 309 310 311 /* Make sure the window is displayed. */ 312 XtPopup( msg_win_ref -> msgWinW, XtGrabNone ); 313 314 XRaiseWindow( XtDisplay( msg_win_ref -> msgWinW ), 315 XtWindow( msg_win_ref -> msgWinW ) ); 316 317 XtMapWidget( msg_win_ref -> msgWinW ); 318 319 320 return; 321 322 } /* xitMsgWinDisplayMessage */ 323 324 325 /*----------------------------------------------------------------------*/ 326 327 static Widget createMsgWindow(MSG_REC_REF msg_win_ref,XIT_MSW_LABEL_REC * labels)328 createMsgWindow( MSG_REC_REF msg_win_ref, 329 XIT_MSW_LABEL_REC *labels ) 330 { 331 332 /* Variables. */ 333 Boolean default_geometry = False; 334 int index; 335 char *char_ref; 336 Arg args[ 10 ]; 337 Cardinal n; 338 Widget controlBu[ 1 ]; 339 Widget dataLocalW[ 3 ]; 340 Widget sysMsgWinTl; 341 Widget toplevel; 342 Widget workFo; 343 344 static XIT_PUSH_STRUCT control_def[] = { 345 { "ClosePb", "", "", True, NULL }, 346 }; 347 348 static XIT_TEXT_STRUCT text_buffer_def[] = { 349 { "MsgWinTx", NULL, 2, True }, 350 }; 351 352 static XIT_ACTION_AREA_ITEM action_buttons[] = { 353 { NULL, NULL, NULL }, 354 { "", closeCB, NULL }, 355 { NULL, NULL, NULL }, 356 }; 357 358 359 /* Code. */ 360 361 /* Set message strings. */ 362 action_buttons[ 1 ].label = labels -> close_button; 363 action_buttons[ 1 ].data = msg_win_ref; 364 365 control_def[ 0 ].title = labels -> clear_button; 366 367 368 /* Create a form dialog with buttons. */ 369 toplevel = xitGetToplevelWidget( msg_win_ref -> parentW ); 370 371 sysMsgWinTl = xitCreateToplevelDialog( toplevel, "SysMsgWinTl", 372 2, 0, 373 action_buttons, 374 XtNumber( action_buttons ) ); 375 376 n = 0; 377 XtSetArg( args[ n ], XmNtitle, labels -> title ); n++; 378 XtSetArg( args[ n ], XmNiconName, labels -> title ); n++; 379 XtSetValues( sysMsgWinTl, args, n ); 380 381 382 /* If no geometry defined, position in the middle of the screen. */ 383 n = 0; 384 XtSetArg( args[ n ], XmNgeometry, &char_ref ); n++; 385 XtGetValues( sysMsgWinTl, args, n ); 386 387 if( char_ref != NULL && strpbrk( char_ref, "+-" ) != NULL ) 388 default_geometry = False; 389 390 if( default_geometry ) { 391 n = 0; 392 XtSetArg( args[ n ], XmNx, 393 WidthOfScreen( XtScreen( sysMsgWinTl ) ) / 2 ); n++; 394 XtSetArg( args[ n ], XmNy, 395 HeightOfScreen( XtScreen( sysMsgWinTl ) ) / 2 ); n++; 396 XtSetValues( sysMsgWinTl, args, n ); 397 } 398 399 400 /* Pop down if this window is deleted. */ 401 { 402 Atom wm_delete_window; 403 404 wm_delete_window = XmInternAtom( XtDisplay( sysMsgWinTl ), 405 "WM_DELETE_WINDOW", False ); 406 407 XmAddWMProtocols( sysMsgWinTl, &wm_delete_window, 1 ); 408 XmAddWMProtocolCallback( sysMsgWinTl, wm_delete_window, 409 (XtCallbackProc) closeCB, 410 (XtPointer) msg_win_ref ); 411 } /* block */ 412 413 XtAddCallback( sysMsgWinTl, XmNdestroyCallback, 414 (XtCallbackProc) destroyCB, (XtPointer) msg_win_ref ); 415 416 417 /* Container for the contents of the window. */ 418 workFo = XtNameToWidget( sysMsgWinTl, "SysMsgWinTlBase.SysMsgWinTlFo" ); 419 420 421 /* Label for the message list. */ 422 msgWinLa = xitCreateLabel( workFo, "MsgWinLa", 423 labels -> list_label, XmALIGNMENT_BEGINNING ); 424 425 /* Text window with messages.. */ 426 msgWinTx = xitCreateTextScrolled( workFo, &text_buffer_def[ 0 ] ); 427 428 n = 0; 429 XtSetArg( args[ n ], XmNeditable, False ); n++; 430 XtSetArg( args[ n ], XmNcursorPositionVisible, False ); n++; 431 XtSetValues( msgWinTx, args, n ); 432 433 434 /* Control buttons. */ 435 n = 0; 436 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 437 XtSetArg( args[ n ], XmNspacing, 10 ); n++; 438 XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++; 439 msgWinRc = XmCreateRowColumn( workFo, "MsgWinRc", args, n ); 440 441 for( index = 0; index < XtNumber( controlBu ); index++ ) 442 controlBu[ index ] = xitCreatePushButton( msgWinRc, 443 &control_def[ index ] ); 444 445 XtAddCallback( controlBu[ 0 ], XmNactivateCallback, 446 (XtCallbackProc) clearCB, (XtPointer) msg_win_ref ); 447 448 /* Put the elements together. */ 449 xitAttachWidget( msgWinLa, 450 XmATTACH_FORM, NULL, XmATTACH_FORM, NULL, 451 XmATTACH_NONE, NULL, XmATTACH_NONE, NULL ); 452 xitAttachWidget( XtParent( msgWinTx ), 453 XmATTACH_WIDGET, msgWinLa, XmATTACH_FORM, NULL, 454 XmATTACH_NONE, NULL, XmATTACH_NONE, NULL ); 455 xitAttachWidget( msgWinRc, 456 XmATTACH_WIDGET, XtParent( msgWinTx ), XmATTACH_FORM, NULL, 457 XmATTACH_NONE, NULL, XmATTACH_NONE, NULL ); 458 459 460 /* Make sure there is enough space between the children. */ 461 n = 0; 462 XtSetArg( args[ n ], XmNtopOffset, 5 ); n++; 463 XtSetArg( args[ n ], XmNleftOffset, 5 ); n++; 464 XtSetArg( args[ n ], XmNrightOffset, 5 ); n++; 465 XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++; 466 XtSetValues( msgWinLa, args, n ); 467 XtSetValues( XtParent( msgWinTx ), args, n ); 468 XtSetValues( msgWinRc, args, n ); 469 470 /* Manage the widgets. */ 471 XtManageChildren( controlBu, XtNumber( controlBu ) ); 472 473 xitManageChildren( dataLocalW, XtNumber( dataLocalW ) ); 474 475 476 /* Set the size of the window. */ 477 xitSetSizeToplevelDialog( sysMsgWinTl, True ); 478 479 /* Make the final attachments. */ 480 xitAttachWidget( msgWinRc, 481 XmATTACH_NONE, NULL, XmATTACH_FORM, NULL, 482 XmATTACH_NONE, NULL, XmATTACH_FORM, NULL ); 483 xitAttachWidget( XtParent( msgWinTx ), 484 XmATTACH_WIDGET, msgWinLa, XmATTACH_FORM, NULL, 485 XmATTACH_FORM, NULL, XmATTACH_WIDGET, msgWinRc ); 486 487 488 return( sysMsgWinTl ); 489 490 } /* createMsgWindow */ 491 492 493 /*----------------------------------------------------------------------*/ 494 495 static void clearCB(Widget widget,MSG_REC_REF msg_win_ref,XtPointer call_data)496 clearCB( Widget widget, 497 MSG_REC_REF msg_win_ref, 498 XtPointer call_data ) 499 { 500 501 /* Variables. */ 502 Widget mainW; 503 Widget tempW; 504 505 506 /* Code. */ 507 508 mainW = XtNameToWidget( msg_win_ref -> msgWinW, 509 "SysMsgWinTlBase.SysMsgWinTlFo" ); 510 511 /* Clear the message window (but leave the log file). */ 512 tempW = XtNameToWidget( mainW, "MsgWinTxSW.MsgWinTx" ); 513 514 XmTextSetString( tempW, "" ); 515 516 msg_win_ref -> no_msg = 0; 517 518 519 return; 520 521 } /* clearCB */ 522 523 524 /*----------------------------------------------------------------------*/ 525 526 static void closeCB(Widget widget,MSG_REC_REF msg_win_ref,XtPointer call_data)527 closeCB( Widget widget, 528 MSG_REC_REF msg_win_ref, 529 XtPointer call_data ) 530 { 531 532 /* Code. */ 533 534 XtPopdown( msg_win_ref -> msgWinW ); 535 536 537 return; 538 539 } /* closeCB */ 540 541 542 /*----------------------------------------------------------------------*/ 543 544 static void destroyCB(Widget widget,MSG_REC_REF msg_win_ref,XtPointer call_data)545 destroyCB( Widget widget, 546 MSG_REC_REF msg_win_ref, 547 XtPointer call_data ) 548 { 549 550 /* Code. */ 551 552 if( msg_win_ref -> log_file != NULL ) 553 SysFree( msg_win_ref -> log_file ); 554 555 SysFree( msg_win_ref ); 556 557 558 return; 559 560 } /* destroyCB */ 561