ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4UIXm.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4UIXm.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 // G.Barrand
29 
30 //#define DEBUG
31 
32 #ifdef G4UI_BUILD_XM_SESSION
33 
34 #include "G4Types.hh"
35 
36 #include <string.h>
37 
38 #include <X11/Intrinsic.h>
39 #include <X11/Shell.h>
40 #include <X11/keysym.h>
41 
42 #include <Xm/Xm.h>
43 #include <Xm/Command.h>
44 #include <Xm/RowColumn.h>
45 #include <Xm/Form.h>
46 #include <Xm/PushB.h>
47 #include <Xm/CascadeB.h>
48 #include <Xm/Text.h>
49 
50 #include "G4UIXm.hh"
51 #include "G4UImanager.hh"
52 #include "G4StateManager.hh"
53 #include "G4UIcommandTree.hh"
54 #include "G4UIcommandStatus.hh"
55 
56 #include "G4Xt.hh"
57 
58 #include <stdlib.h>
59 
60 static void XmTextAppendString (Widget,char*);
61 
62 static void clearButtonCallback (Widget,XtPointer,XtPointer);
63 
64 static char* XmConvertCompoundStringToString (XmString,int);
65 static G4bool ConvertStringToInt(const char*,int&);
66 static void ExecuteChangeSizeFunction(Widget);
67 
68 static G4bool exitSession = true;
69 static G4bool exitPause = true;
70 static G4bool exitHelp = true;
71 /***************************************************************************/
72 G4UIXm::G4UIXm (
73  int argc
74 ,char** argv
75 )
76 :shell(NULL)
77 ,command(NULL)
78 ,menuBar(NULL)
79 ,text(NULL)
80 ,fHelp(false)
81 ,fHelpChoice(0)
82 /***************************************************************************/
84 {
86  if(UI!=NULL) UI->SetSession(this);
87 
88  G4Xt* interactorManager = G4Xt::getInstance (argc,argv,(char*)"Xm");
89 
90  Widget top = (Widget)interactorManager->GetMainInteractor();
91 
92  if(std::getenv("XENVIRONMENT")==NULL) {
93  XrmDatabase database = XrmGetDatabase(XtDisplay(top));
94  if(database!=NULL) {
95  XrmPutLineResource(&database,"*topShadowColor:white");
96  XrmPutLineResource(&database,"*bottomShadowColor:black");
97  XrmPutLineResource(&database,"*foreground:black");
98  XrmPutLineResource(&database,"*background:lightgrey");
99  XrmPutLineResource(&database,"*borderColor:lightgrey");
100  XrmPutLineResource(&database,"*fontList:-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1");
101  XrmPutLineResource(&database,"*text.background:white");
102  XrmPutLineResource(&database,"*text.fontList:*courier*-r-*--14-*");
103  XrmPutLineResource(&database,"*text.maxLength:8000");
104  }
105  }
106 
107  Arg args[9];
108  XtSetArg(args[0],XmNkeyboardFocusPolicy,XmPOINTER); // For completion.
109  shell = XtAppCreateShell ("G4UIXm","G4UIXm",
110  topLevelShellWidgetClass,XtDisplay(top),
111  args,1);
112  form = XmCreateForm (shell,(char*)"form",NULL,0);
113  XtManageChild (form);
114 
115  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
116  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
117  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
118  menuBar = XmCreateMenuBar (form,(char*)"menuBar",args,3);
119 
120  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
121  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
122  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
123  XtSetArg(args[3],XmNbottomAttachment ,XmATTACH_FORM);
124  command = XmCreateCommand (form,(char*)"command",args,4);
125  XtManageChild (command);
126 
127  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
128  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
129  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
130  XtSetArg(args[3],XmNbottomAttachment,XmATTACH_WIDGET);
131  XtSetArg(args[4],XmNbottomWidget ,command);
132  XmString cps = XmStringLtoRCreate((char*)"Clear",(char*)XmSTRING_DEFAULT_CHARSET);
133  XtSetArg (args[5],XmNlabelString,cps);
134  Widget clearButton = XmCreatePushButton(form,(char*)"clearButton",args,6);
135  XmStringFree (cps);
136  XtManageChild (clearButton);
137 
138  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_WIDGET);
139  XtSetArg(args[1],XmNtopWidget ,menuBar);
140  XtSetArg(args[2],XmNleftAttachment ,XmATTACH_FORM);
141  XtSetArg(args[3],XmNrightAttachment ,XmATTACH_FORM);
142  XtSetArg(args[4],XmNbottomAttachment,XmATTACH_WIDGET);
143  XtSetArg(args[5],XmNbottomWidget ,clearButton);
144  XtSetArg(args[6],XmNeditMode ,XmMULTI_LINE_EDIT);
145  XtSetArg(args[7],XmNrows ,12);
146  XtSetArg(args[8],XmNcolumns ,80);
147  text = XmCreateScrolledText (form,(char*)"text",args,9);
148  XtManageChild (text);
149 
150  XtAddCallback(clearButton,XmNactivateCallback,
151  clearButtonCallback,(XtPointer)text);
152  XtAddCallback(command,XmNcommandEnteredCallback,
153  CommandEnteredCallback,(XtPointer)this);
154 
155  Widget commandText = XmCommandGetChild(command,XmDIALOG_COMMAND_TEXT);
156  XtAddEventHandler(commandText,KeyPressMask,False,keyHandler,(XtPointer)this);
157 
158  XtRealizeWidget(shell);
159  XtMapWidget(shell);
160 
161  if(UI!=NULL) UI->SetCoutDestination(this);
162 }
163 /***************************************************************************/
164 G4UIXm::~G4UIXm(
165 )
166 /***************************************************************************/
168 {
170  if(UI!=NULL) {
171  UI->SetSession(NULL);
172  UI->SetCoutDestination(NULL);
173  }
174  XtDestroyWidget(shell);
175 }
176 /***************************************************************************/
177 G4UIsession* G4UIXm::SessionStart (
178 )
179 /***************************************************************************/
181 {
182  G4Xt* interactorManager = G4Xt::getInstance ();
183  Prompt("session");
184  exitSession = false;
185  interactorManager->DisableSecondaryLoop ();
186  void* event;
187  while((event = interactorManager->GetEvent())!=NULL) {
188  interactorManager->DispatchEvent(event);
189  if(exitSession==true) break;
190  }
191  interactorManager->EnableSecondaryLoop ();
192  return this;
193 }
194 /***************************************************************************/
195 void G4UIXm::Prompt (
196  G4String aPrompt
197 )
198 /***************************************************************************/
200 {
201  Arg args[1];
202  char* str = (char*)XtNewString(aPrompt.data());
203  XmString cps = XmStringLtoRCreate(str,(char*)XmSTRING_DEFAULT_CHARSET);
204  XtFree(str);
205  XtSetArg(args[0],XmNpromptString,cps);
206  XtSetValues(command,args,1);
207  XmStringFree(cps);
208 }
209 /***************************************************************************/
210 void G4UIXm::SessionTerminate (
211 )
212 /***************************************************************************/
214 {
215 }
216 /***************************************************************************/
217 void G4UIXm::PauseSessionStart (
218  const G4String& a_state
219 )
220 /***************************************************************************/
222 {
223  if(a_state=="G4_pause> ") {
224  SecondaryLoop ("Pause, type continue to exit this state");
225  }
226 
227  if(a_state=="EndOfEvent") {
228  // Picking with feed back in event data Done here !!!
229  SecondaryLoop ("End of event, type continue to exit this state");
230  }
231 }
232 /***************************************************************************/
233 void G4UIXm::SecondaryLoop (
234  G4String a_prompt
235 )
236 /***************************************************************************/
238 {
239  G4Xt* interactorManager = G4Xt::getInstance ();
240  Prompt(a_prompt);
241  exitPause = false;
242  void* event;
243  while((event = interactorManager->GetEvent())!=NULL) {
244  interactorManager->DispatchEvent(event);
245  if(exitPause==true) break;
246  }
247  Prompt("session");
248 }
249 /***************************************************************************/
250 G4int G4UIXm::ReceiveG4cout (
251  const G4String& a_string
252 )
253 /***************************************************************************/
255 {
256  XmTextAppendString(text,(char*)a_string.data());
257  return 0;
258 }
259 /***************************************************************************/
260 G4int G4UIXm::ReceiveG4cerr (
261  const G4String& a_string
262 )
263 /***************************************************************************/
265 {
266  XmTextAppendString(text,(char*)a_string.data());
267  return 0;
268 }
269 /***************************************************************************/
270 G4bool G4UIXm::GetHelpChoice(
271  G4int& aInt
272 )
273 /***************************************************************************/
275 {
276  fHelp = true;
277  // SecondaryLoop :
278  G4Xt* interactorManager = G4Xt::getInstance ();
279  Prompt("Help");
280  exitHelp = false;
281  void* event;
282  while((event = interactorManager->GetEvent())!=NULL) {
283  interactorManager->DispatchEvent(event);
284  if(exitHelp==true) break;
285  }
286  Prompt("session");
287  //
288  if(fHelp==false) return false;
289  aInt = fHelpChoice;
290  fHelp = false;
291  return true;
292 }
293 /***************************************************************************/
294 void G4UIXm::ExitHelp(
295 ) const
296 /***************************************************************************/
298 {
299 }
300 /***************************************************************************/
301 void G4UIXm::AddMenu (
302  const char* a_name
303 ,const char* a_label
304 )
305 /***************************************************************************/
307 {
308  if(menuBar==NULL) return;
309  if(a_name==NULL) return;
310  if(a_label==NULL) return;
311  XtManageChild (menuBar);
312  // Pulldown menu :
313  Widget widget;
314  widget = XmCreatePulldownMenu (menuBar,(char*)a_name,NULL,0);
315  AddInteractor (a_name,(G4Interactor)widget);
316  // Cascade button :
317  Arg args[2];
318  XmString cps = XmStringLtoRCreate((char*)a_label,(char*)XmSTRING_DEFAULT_CHARSET);
319  XtSetArg (args[0],XmNlabelString,cps);
320  XtSetArg (args[1],XmNsubMenuId,widget);
321  widget = XmCreateCascadeButton (menuBar,(char*)a_name,args,2);
322  XmStringFree (cps);
323  XtManageChild (widget);
324  ExecuteChangeSizeFunction(form);
325 }
326 /***************************************************************************/
327 void G4UIXm::AddButton (
328  const char* a_menu
329 ,const char* a_label
330 ,const char* a_command
331 )
332 /***************************************************************************/
334 {
335  if(a_menu==NULL) return;
336  if(a_label==NULL) return;
337  if(a_command==NULL) return;
338  Widget parent = (Widget)GetInteractor(a_menu);
339  if(parent==NULL) return;
340  Widget widget = XmCreatePushButton(parent,(char*)a_label,NULL,0);
341  XtManageChild (widget);
342  XtAddCallback (widget,XmNactivateCallback,ButtonCallback,(XtPointer)this);
343  commands[widget] = a_command;
344 }
345 /***************************************************************************/
346 G4String G4UIXm::GetCommand (
347  Widget a_widget
348 )
349 /***************************************************************************/
351 {
352  return commands[a_widget];
353 }
354 /***************************************************************************/
355 /***************************************************************************/
356 /***************************************************************************/
357 void G4UIXm::CommandEnteredCallback (
358  Widget
359 ,XtPointer a_tag
360 ,XtPointer a_data
361 )
362 /***************************************************************************/
364 {
365  G4UIXm* This = (G4UIXm*)a_tag;
366 
367  XmString cps = ((XmCommandCallbackStruct*)a_data)->value;
368  char* ss = XmConvertCompoundStringToString(cps,0);
369  G4String command (ss);
370  XtFree (ss);
371 
372  if(This->fHelp==true) {
373  exitHelp = true;
374  This->fHelp = ConvertStringToInt(command.data(),This->fHelpChoice);
375  } else {
376  This->ApplyShellCommand (command,exitSession,exitPause);
377  }
378 
379  //a_widget = NULL; Not used (1st argument). Comment out to avoid compiler warnings. (JA)
380  a_tag = NULL;
381 }
382 /***************************************************************************/
383 void G4UIXm::keyHandler (
384  Widget a_widget
385 ,XtPointer a_tag
386 ,XEvent* a_event
387 ,Boolean*
388 )
389 /***************************************************************************/
391 {
392  KeySym keySym;
393  XLookupString(&(a_event->xkey),NULL,0,&keySym,NULL);
394  if(keySym!=XK_Tab) return;
395  G4UIXm* This = (G4UIXm*)a_tag;
396  char* s = XmTextGetString(a_widget);
397  G4String ss = This->Complete(s);
398  XmTextSetString(a_widget,(char*)ss.data());
399  XtFree(s);
400  XmTextSetInsertionPosition(a_widget,XmTextGetLastPosition(a_widget));
401 }
402 /***************************************************************************/
403 void clearButtonCallback (
404  Widget
405 ,XtPointer a_tag
406 ,XtPointer
407 )
408 /***************************************************************************/
410 {
411  XmTextSetString((Widget)a_tag,(char*)"");
412 }
413 /***************************************************************************/
414 void G4UIXm::ButtonCallback (
415  Widget a_widget
416 ,XtPointer a_tag
417 ,XtPointer
418 )
419 /***************************************************************************/
421 {
422  G4UIXm* This = (G4UIXm*)a_tag;
423  if(This->fHelp==true) return; // Disabled when in help.
424  G4String ss = This->GetCommand (a_widget);
425  This->ApplyShellCommand(ss,exitSession,exitPause);
426 }
427 /***************************************************************************/
428 /***************************************************************************/
429 /***************************************************************************/
430 char* XmConvertCompoundStringToString (
431  XmString a_cps
432 ,int a_number
433 )
434 /***************************************************************************/
436 {
437  if(a_cps==NULL) return NULL;
438  char* ss = NULL;
439  XmStringContext context;
440  XmStringInitContext(&context,a_cps);
441  int icount = 0;
442  Boolean Done = False;
443  while(Done==False) {
444  char* text = NULL;
445  XmStringCharSet charset = NULL;
446  XmStringDirection direct;
447  Boolean sep;
448  if(XmStringGetNextSegment(context,&text,&charset,&direct,&sep)==True) {
449  XtFree(charset);
450  if(sep==True) Done = True;
451  if(icount==a_number) {
452  ss = text;
453  break;
454  }
455  icount++;
456  XtFree(text);
457  }
458  else
459  Done = True;
460  }
461  XmStringFreeContext(context);
462  return ss;
463 }
464 /***************************************************************************/
465 void XmTextAppendString (
466  Widget This
467 ,char* a_string
468 )
469 /***************************************************************************/
471 {
472  if(This==NULL) return;
473  if(!XtIsSubclass(This,xmTextWidgetClass)) return;
474  if(a_string==NULL) return;
475  XmTextPosition lastpos = XmTextGetLastPosition(This);
476  XmTextReplace(This,lastpos,lastpos,a_string);
477  XmTextSetInsertionPosition(This,XmTextGetLastPosition(This));
478 }
480 G4bool ConvertStringToInt(
481  const char* aString
482 ,int& aInt
483 )
486 {
487  aInt = 0;
488  if(aString==NULL) return false;
489  char* s;
490  long value = strtol(aString,&s,10);
491  if(s==aString) return false;
492  aInt = value;
493  return true;
494 }
495 #include <X11/IntrinsicP.h>
497 void ExecuteChangeSizeFunction (
498  Widget aWidget
499 )
502 {
503  if(aWidget==NULL) return;
504  if(aWidget->core.widget_class->core_class.resize==NULL) return;
505  (aWidget->core.widget_class->core_class.resize)(aWidget);
506 }
507 
508 
509 #endif