00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef G4UI_BUILD_XM_SESSION
00035
00036 #include "G4Types.hh"
00037
00038 #include <string.h>
00039
00040 #include <X11/Intrinsic.h>
00041 #include <X11/Shell.h>
00042 #include <X11/keysym.h>
00043
00044 #include <Xm/Xm.h>
00045 #include <Xm/Command.h>
00046 #include <Xm/RowColumn.h>
00047 #include <Xm/Form.h>
00048 #include <Xm/PushB.h>
00049 #include <Xm/CascadeB.h>
00050 #include <Xm/Text.h>
00051
00052 #include "G4UIXm.hh"
00053 #include "G4UImanager.hh"
00054 #include "G4StateManager.hh"
00055 #include "G4UIcommandTree.hh"
00056 #include "G4UIcommandStatus.hh"
00057
00058 #include "G4Xt.hh"
00059
00060 #include <stdlib.h>
00061
00062 static void XmTextAppendString (Widget,char*);
00063
00064 static void clearButtonCallback (Widget,XtPointer,XtPointer);
00065
00066 static char* XmConvertCompoundStringToString (XmString,int);
00067 static G4bool ConvertStringToInt(const char*,int&);
00068 static void ExecuteChangeSizeFunction(Widget);
00069
00070 static G4bool exitSession = true;
00071 static G4bool exitPause = true;
00072 static G4bool exitHelp = true;
00073
00074 G4UIXm::G4UIXm (
00075 int argc
00076 ,char** argv
00077 )
00078 :shell(NULL)
00079 ,command(NULL)
00080 ,menuBar(NULL)
00081 ,text(NULL)
00082 ,fHelp(false)
00083 ,fHelpChoice(0)
00084
00086 {
00087 G4UImanager* UI = G4UImanager::GetUIpointer();
00088 if(UI!=NULL) UI->SetSession(this);
00089
00090 G4Xt* interactorManager = G4Xt::getInstance (argc,argv,(char*)"Xm");
00091
00092 Widget top = (Widget)interactorManager->GetMainInteractor();
00093
00094 if(getenv("XENVIRONMENT")==NULL) {
00095 XrmDatabase database = XrmGetDatabase(XtDisplay(top));
00096 if(database!=NULL) {
00097 XrmPutLineResource(&database,"*topShadowColor:white");
00098 XrmPutLineResource(&database,"*bottomShadowColor:black");
00099 XrmPutLineResource(&database,"*foreground:black");
00100 XrmPutLineResource(&database,"*background:lightgrey");
00101 XrmPutLineResource(&database,"*borderColor:lightgrey");
00102 XrmPutLineResource(&database,"*fontList:-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1");
00103 XrmPutLineResource(&database,"*text.background:white");
00104 XrmPutLineResource(&database,"*text.fontList:*courier*-r-*--14-*");
00105 XrmPutLineResource(&database,"*text.maxLength:8000");
00106 }
00107 }
00108
00109 Arg args[9];
00110 XtSetArg(args[0],XmNkeyboardFocusPolicy,XmPOINTER);
00111 shell = XtAppCreateShell ("G4UIXm","G4UIXm",
00112 topLevelShellWidgetClass,XtDisplay(top),
00113 args,1);
00114 form = XmCreateForm (shell,(char*)"form",NULL,0);
00115 XtManageChild (form);
00116
00117 XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
00118 XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
00119 XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
00120 menuBar = XmCreateMenuBar (form,(char*)"menuBar",args,3);
00121
00122 XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
00123 XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
00124 XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
00125 XtSetArg(args[3],XmNbottomAttachment ,XmATTACH_FORM);
00126 command = XmCreateCommand (form,(char*)"command",args,4);
00127 XtManageChild (command);
00128
00129 XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
00130 XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
00131 XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
00132 XtSetArg(args[3],XmNbottomAttachment,XmATTACH_WIDGET);
00133 XtSetArg(args[4],XmNbottomWidget ,command);
00134 XmString cps = XmStringLtoRCreate((char*)"Clear",XmSTRING_DEFAULT_CHARSET);
00135 XtSetArg (args[5],XmNlabelString,cps);
00136 Widget clearButton = XmCreatePushButton(form,(char*)"clearButton",args,6);
00137 XmStringFree (cps);
00138 XtManageChild (clearButton);
00139
00140 XtSetArg(args[0],XmNtopAttachment ,XmATTACH_WIDGET);
00141 XtSetArg(args[1],XmNtopWidget ,menuBar);
00142 XtSetArg(args[2],XmNleftAttachment ,XmATTACH_FORM);
00143 XtSetArg(args[3],XmNrightAttachment ,XmATTACH_FORM);
00144 XtSetArg(args[4],XmNbottomAttachment,XmATTACH_WIDGET);
00145 XtSetArg(args[5],XmNbottomWidget ,clearButton);
00146 XtSetArg(args[6],XmNeditMode ,XmMULTI_LINE_EDIT);
00147 XtSetArg(args[7],XmNrows ,12);
00148 XtSetArg(args[8],XmNcolumns ,80);
00149 text = XmCreateScrolledText (form,(char*)"text",args,9);
00150 XtManageChild (text);
00151
00152 XtAddCallback(clearButton,XmNactivateCallback,
00153 clearButtonCallback,(XtPointer)text);
00154 XtAddCallback(command,XmNcommandEnteredCallback,
00155 commandEnteredCallback,(XtPointer)this);
00156
00157 Widget commandText = XmCommandGetChild(command,XmDIALOG_COMMAND_TEXT);
00158 XtAddEventHandler(commandText,KeyPressMask,False,keyHandler,(XtPointer)this);
00159
00160 XtRealizeWidget(shell);
00161 XtMapWidget(shell);
00162
00163 if(UI!=NULL) UI->SetCoutDestination(this);
00164 }
00165
00166 G4UIXm::~G4UIXm(
00167 )
00168
00170 {
00171 G4UImanager* UI = G4UImanager::GetUIpointer();
00172 if(UI!=NULL) {
00173 UI->SetSession(NULL);
00174 UI->SetCoutDestination(NULL);
00175 }
00176 XtDestroyWidget(shell);
00177 }
00178
00179 G4UIsession* G4UIXm::SessionStart (
00180 )
00181
00183 {
00184 G4Xt* interactorManager = G4Xt::getInstance ();
00185 Prompt("session");
00186 exitSession = false;
00187 interactorManager->DisableSecondaryLoop ();
00188 void* event;
00189 while((event = interactorManager->GetEvent())!=NULL) {
00190 interactorManager->DispatchEvent(event);
00191 if(exitSession==true) break;
00192 }
00193 interactorManager->EnableSecondaryLoop ();
00194 return this;
00195 }
00196
00197 void G4UIXm::Prompt (
00198 G4String aPrompt
00199 )
00200
00202 {
00203 Arg args[1];
00204 char* str = (char*)XtNewString(aPrompt.data());
00205 XmString cps = XmStringLtoRCreate(str,XmSTRING_DEFAULT_CHARSET);
00206 XtFree(str);
00207 XtSetArg(args[0],XmNpromptString,cps);
00208 XtSetValues(command,args,1);
00209 XmStringFree(cps);
00210 }
00211
00212 void G4UIXm::SessionTerminate (
00213 )
00214
00216 {
00217 }
00218
00219 void G4UIXm::PauseSessionStart (
00220 G4String a_state
00221 )
00222
00224 {
00225 if(a_state=="G4_pause> ") {
00226 SecondaryLoop ("Pause, type continue to exit this state");
00227 }
00228
00229 if(a_state=="EndOfEvent") {
00230
00231 SecondaryLoop ("End of event, type continue to exit this state");
00232 }
00233 }
00234
00235 void G4UIXm::SecondaryLoop (
00236 G4String a_prompt
00237 )
00238
00240 {
00241 G4Xt* interactorManager = G4Xt::getInstance ();
00242 Prompt(a_prompt);
00243 exitPause = false;
00244 void* event;
00245 while((event = interactorManager->GetEvent())!=NULL) {
00246 interactorManager->DispatchEvent(event);
00247 if(exitPause==true) break;
00248 }
00249 Prompt("session");
00250 }
00251
00252 G4int G4UIXm::ReceiveG4cout (
00253 G4String a_string
00254 )
00255
00257 {
00258 XmTextAppendString(text,(char*)a_string.data());
00259 return 0;
00260 }
00261
00262 G4int G4UIXm::ReceiveG4cerr (
00263 G4String a_string
00264 )
00265
00267 {
00268 XmTextAppendString(text,(char*)a_string.data());
00269 return 0;
00270 }
00271
00272 G4bool G4UIXm::GetHelpChoice(
00273 G4int& aInt
00274 )
00275
00277 {
00278 fHelp = true;
00279
00280 G4Xt* interactorManager = G4Xt::getInstance ();
00281 Prompt("Help");
00282 exitHelp = false;
00283 void* event;
00284 while((event = interactorManager->GetEvent())!=NULL) {
00285 interactorManager->DispatchEvent(event);
00286 if(exitHelp==true) break;
00287 }
00288 Prompt("session");
00289
00290 if(fHelp==false) return false;
00291 aInt = fHelpChoice;
00292 fHelp = false;
00293 return true;
00294 }
00295
00296 void G4UIXm::ExitHelp(
00297 )
00298
00300 {
00301 }
00302
00303 void G4UIXm::AddMenu (
00304 const char* a_name
00305 ,const char* a_label
00306 )
00307
00309 {
00310 if(menuBar==NULL) return;
00311 if(a_name==NULL) return;
00312 if(a_label==NULL) return;
00313 XtManageChild (menuBar);
00314
00315 Widget widget;
00316 widget = XmCreatePulldownMenu (menuBar,(char*)a_name,NULL,0);
00317 AddInteractor (a_name,(G4Interactor)widget);
00318
00319 Arg args[2];
00320 XmString cps = XmStringLtoRCreate((char*)a_label,XmSTRING_DEFAULT_CHARSET);
00321 XtSetArg (args[0],XmNlabelString,cps);
00322 XtSetArg (args[1],XmNsubMenuId,widget);
00323 widget = XmCreateCascadeButton (menuBar,(char*)a_name,args,2);
00324 XmStringFree (cps);
00325 XtManageChild (widget);
00326 ExecuteChangeSizeFunction(form);
00327 }
00328
00329 void G4UIXm::AddButton (
00330 const char* a_menu
00331 ,const char* a_label
00332 ,const char* a_command
00333 )
00334
00336 {
00337 if(a_menu==NULL) return;
00338 if(a_label==NULL) return;
00339 if(a_command==NULL) return;
00340 Widget parent = (Widget)GetInteractor(a_menu);
00341 if(parent==NULL) return;
00342 Widget widget = XmCreatePushButton(parent,(char*)a_label,NULL,0);
00343 XtManageChild (widget);
00344 XtAddCallback (widget,XmNactivateCallback,ButtonCallback,(XtPointer)this);
00345 commands[widget] = a_command;
00346 }
00347
00348 G4String G4UIXm::GetCommand (
00349 Widget a_widget
00350 )
00351
00353 {
00354 return commands[a_widget];
00355 }
00356
00357
00358
00359 void G4UIXm::commandEnteredCallback (
00360 Widget a_widget
00361 ,XtPointer a_tag
00362 ,XtPointer a_data
00363 )
00364
00366 {
00367 G4UIXm* This = (G4UIXm*)a_tag;
00368
00369 XmString cps = ((XmCommandCallbackStruct*)a_data)->value;
00370 char* ss = XmConvertCompoundStringToString(cps,0);
00371 G4String command (ss);
00372 XtFree (ss);
00373
00374 if(This->fHelp==true) {
00375 exitHelp = true;
00376 This->fHelp = ConvertStringToInt(command.data(),This->fHelpChoice);
00377 } else {
00378 This->ApplyShellCommand (command,exitSession,exitPause);
00379 }
00380
00381 a_widget = NULL;
00382 a_tag = NULL;
00383 }
00384
00385 void G4UIXm::keyHandler (
00386 Widget a_widget
00387 ,XtPointer a_tag
00388 ,XEvent* a_event
00389 ,Boolean*
00390 )
00391
00393 {
00394 KeySym keySym;
00395 XLookupString(&(a_event->xkey),NULL,0,&keySym,NULL);
00396 if(keySym!=XK_Tab) return;
00397 G4UIXm* This = (G4UIXm*)a_tag;
00398 char* s = XmTextGetString(a_widget);
00399 G4String ss = This->Complete(s);
00400 XmTextSetString(a_widget,(char*)ss.data());
00401 XtFree(s);
00402 XmTextSetInsertionPosition(a_widget,XmTextGetLastPosition(a_widget));
00403 }
00404
00405 void clearButtonCallback (
00406 Widget
00407 ,XtPointer a_tag
00408 ,XtPointer
00409 )
00410
00412 {
00413 XmTextSetString((Widget)a_tag,(char*)"");
00414 }
00415
00416 void G4UIXm::ButtonCallback (
00417 Widget a_widget
00418 ,XtPointer a_tag
00419 ,XtPointer
00420 )
00421
00423 {
00424 G4UIXm* This = (G4UIXm*)a_tag;
00425 if(This->fHelp==true) return;
00426 G4String ss = This->GetCommand (a_widget);
00427
00428 This->ApplyShellCommand(ss,exitSession,exitPause);
00429 }
00430
00431
00432
00433 char* XmConvertCompoundStringToString (
00434 XmString a_cps
00435 ,int a_number
00436 )
00437
00439 {
00440 if(a_cps==NULL) return NULL;
00441 char* ss = NULL;
00442 XmStringContext context;
00443 XmStringInitContext(&context,a_cps);
00444 int icount = 0;
00445 Boolean Done = False;
00446 while(Done==False) {
00447 char* text = NULL;
00448 XmStringCharSet charset = NULL;
00449 XmStringDirection direct;
00450 Boolean sep;
00451 if(XmStringGetNextSegment(context,&text,&charset,&direct,&sep)==True) {
00452 XtFree(charset);
00453 if(sep==True) Done = True;
00454 if(icount==a_number) {
00455 ss = text;
00456 break;
00457 }
00458 icount++;
00459 XtFree(text);
00460 }
00461 else
00462 Done = True;
00463 }
00464 XmStringFreeContext(context);
00465 return ss;
00466 }
00467
00468 void XmTextAppendString (
00469 Widget This
00470 ,char* a_string
00471 )
00472
00474 {
00475 if(This==NULL) return;
00476 if(!XtIsSubclass(This,xmTextWidgetClass)) return;
00477 if(a_string==NULL) return;
00478 XmTextPosition lastpos = XmTextGetLastPosition(This);
00479 XmTextReplace(This,lastpos,lastpos,a_string);
00480 XmTextSetInsertionPosition(This,XmTextGetLastPosition(This));
00481 }
00483 G4bool ConvertStringToInt(
00484 const char* aString
00485 ,int& aInt
00486 )
00489 {
00490 aInt = 0;
00491 if(aString==NULL) return false;
00492 char* s;
00493 long value = strtol(aString,&s,10);
00494 if(s==aString) return false;
00495 aInt = value;
00496 return true;
00497 }
00498 #include <X11/IntrinsicP.h>
00500 void ExecuteChangeSizeFunction (
00501 Widget aWidget
00502 )
00505 {
00506 if(aWidget==NULL) return;
00507 if(aWidget->core.widget_class->core_class.resize==NULL) return;
00508 (aWidget->core.widget_class->core_class.resize)(aWidget);
00509 }
00510
00511
00512 #endif