Geant4  10.03
G4UIXm.cc
Go to the documentation of this file.
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 // $Id: G4UIXm.cc 97174 2016-05-27 12:41:02Z gcosmo $
28 //
29 // G.Barrand
30 
31 //#define DEBUG
32 
33 #ifdef G4UI_BUILD_XM_SESSION
34 
35 #include "G4Types.hh"
36 
37 #include <string.h>
38 
39 #include <X11/Intrinsic.h>
40 #include <X11/Shell.h>
41 #include <X11/keysym.h>
42 
43 #include <Xm/Xm.h>
44 #include <Xm/Command.h>
45 #include <Xm/RowColumn.h>
46 #include <Xm/Form.h>
47 #include <Xm/PushB.h>
48 #include <Xm/CascadeB.h>
49 #include <Xm/Text.h>
50 
51 #include "G4UIXm.hh"
52 #include "G4UImanager.hh"
53 #include "G4StateManager.hh"
54 #include "G4UIcommandTree.hh"
55 #include "G4UIcommandStatus.hh"
56 
57 #include "G4Xt.hh"
58 
59 #include <stdlib.h>
60 
61 static void XmTextAppendString (Widget,char*);
62 
63 static void clearButtonCallback (Widget,XtPointer,XtPointer);
64 
65 static char* XmConvertCompoundStringToString (XmString,int);
66 static G4bool ConvertStringToInt(const char*,int&);
67 static void ExecuteChangeSizeFunction(Widget);
68 
69 static G4bool exitSession = true;
70 static G4bool exitPause = true;
71 static G4bool exitHelp = true;
72 /***************************************************************************/
73 G4UIXm::G4UIXm (
74  int argc
75 ,char** argv
76 )
77 :shell(NULL)
78 ,command(NULL)
79 ,menuBar(NULL)
80 ,text(NULL)
81 ,fHelp(false)
82 ,fHelpChoice(0)
83 /***************************************************************************/
85 {
87  if(UI!=NULL) UI->SetSession(this);
88 
89  G4Xt* interactorManager = G4Xt::getInstance (argc,argv,(char*)"Xm");
90 
91  Widget top = (Widget)interactorManager->GetMainInteractor();
92 
93  if(getenv("XENVIRONMENT")==NULL) {
94  XrmDatabase database = XrmGetDatabase(XtDisplay(top));
95  if(database!=NULL) {
96  XrmPutLineResource(&database,"*topShadowColor:white");
97  XrmPutLineResource(&database,"*bottomShadowColor:black");
98  XrmPutLineResource(&database,"*foreground:black");
99  XrmPutLineResource(&database,"*background:lightgrey");
100  XrmPutLineResource(&database,"*borderColor:lightgrey");
101  XrmPutLineResource(&database,"*fontList:-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1");
102  XrmPutLineResource(&database,"*text.background:white");
103  XrmPutLineResource(&database,"*text.fontList:*courier*-r-*--14-*");
104  XrmPutLineResource(&database,"*text.maxLength:8000");
105  }
106  }
107 
108  Arg args[9];
109  XtSetArg(args[0],XmNkeyboardFocusPolicy,XmPOINTER); // For completion.
110  shell = XtAppCreateShell ("G4UIXm","G4UIXm",
111  topLevelShellWidgetClass,XtDisplay(top),
112  args,1);
113  form = XmCreateForm (shell,(char*)"form",NULL,0);
114  XtManageChild (form);
115 
116  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
117  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
118  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
119  menuBar = XmCreateMenuBar (form,(char*)"menuBar",args,3);
120 
121  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
122  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
123  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
124  XtSetArg(args[3],XmNbottomAttachment ,XmATTACH_FORM);
125  command = XmCreateCommand (form,(char*)"command",args,4);
126  XtManageChild (command);
127 
128  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_NONE);
129  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
130  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
131  XtSetArg(args[3],XmNbottomAttachment,XmATTACH_WIDGET);
132  XtSetArg(args[4],XmNbottomWidget ,command);
133  XmString cps = XmStringLtoRCreate((char*)"Clear",(char*)XmSTRING_DEFAULT_CHARSET);
134  XtSetArg (args[5],XmNlabelString,cps);
135  Widget clearButton = XmCreatePushButton(form,(char*)"clearButton",args,6);
136  XmStringFree (cps);
137  XtManageChild (clearButton);
138 
139  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_WIDGET);
140  XtSetArg(args[1],XmNtopWidget ,menuBar);
141  XtSetArg(args[2],XmNleftAttachment ,XmATTACH_FORM);
142  XtSetArg(args[3],XmNrightAttachment ,XmATTACH_FORM);
143  XtSetArg(args[4],XmNbottomAttachment,XmATTACH_WIDGET);
144  XtSetArg(args[5],XmNbottomWidget ,clearButton);
145  XtSetArg(args[6],XmNeditMode ,XmMULTI_LINE_EDIT);
146  XtSetArg(args[7],XmNrows ,12);
147  XtSetArg(args[8],XmNcolumns ,80);
148  text = XmCreateScrolledText (form,(char*)"text",args,9);
149  XtManageChild (text);
150 
151  XtAddCallback(clearButton,XmNactivateCallback,
152  clearButtonCallback,(XtPointer)text);
153  XtAddCallback(command,XmNcommandEnteredCallback,
154  CommandEnteredCallback,(XtPointer)this);
155 
156  Widget commandText = XmCommandGetChild(command,XmDIALOG_COMMAND_TEXT);
157  XtAddEventHandler(commandText,KeyPressMask,False,keyHandler,(XtPointer)this);
158 
159  XtRealizeWidget(shell);
160  XtMapWidget(shell);
161 
162  if(UI!=NULL) UI->SetCoutDestination(this);
163 }
164 /***************************************************************************/
165 G4UIXm::~G4UIXm(
166 )
167 /***************************************************************************/
169 {
171  if(UI!=NULL) {
172  UI->SetSession(NULL);
173  UI->SetCoutDestination(NULL);
174  }
175  XtDestroyWidget(shell);
176 }
177 /***************************************************************************/
178 G4UIsession* G4UIXm::SessionStart (
179 )
180 /***************************************************************************/
182 {
183  G4Xt* interactorManager = G4Xt::getInstance ();
184  Prompt("session");
185  exitSession = false;
186  interactorManager->DisableSecondaryLoop ();
187  void* event;
188  while((event = interactorManager->GetEvent())!=NULL) {
189  interactorManager->DispatchEvent(event);
190  if(exitSession==true) break;
191  }
192  interactorManager->EnableSecondaryLoop ();
193  return this;
194 }
195 /***************************************************************************/
196 void G4UIXm::Prompt (
197  G4String aPrompt
198 )
199 /***************************************************************************/
201 {
202  Arg args[1];
203  char* str = (char*)XtNewString(aPrompt.data());
204  XmString cps = XmStringLtoRCreate(str,(char*)XmSTRING_DEFAULT_CHARSET);
205  XtFree(str);
206  XtSetArg(args[0],XmNpromptString,cps);
207  XtSetValues(command,args,1);
208  XmStringFree(cps);
209 }
210 /***************************************************************************/
211 void G4UIXm::SessionTerminate (
212 )
213 /***************************************************************************/
215 {
216 }
217 /***************************************************************************/
218 void G4UIXm::PauseSessionStart (
219  const G4String& a_state
220 )
221 /***************************************************************************/
223 {
224  if(a_state=="G4_pause> ") {
225  SecondaryLoop ("Pause, type continue to exit this state");
226  }
227 
228  if(a_state=="EndOfEvent") {
229  // Picking with feed back in event data Done here !!!
230  SecondaryLoop ("End of event, type continue to exit this state");
231  }
232 }
233 /***************************************************************************/
234 void G4UIXm::SecondaryLoop (
235  G4String a_prompt
236 )
237 /***************************************************************************/
239 {
240  G4Xt* interactorManager = G4Xt::getInstance ();
241  Prompt(a_prompt);
242  exitPause = false;
243  void* event;
244  while((event = interactorManager->GetEvent())!=NULL) {
245  interactorManager->DispatchEvent(event);
246  if(exitPause==true) break;
247  }
248  Prompt("session");
249 }
250 /***************************************************************************/
251 G4int G4UIXm::ReceiveG4cout (
252  const G4String& a_string
253 )
254 /***************************************************************************/
256 {
257  XmTextAppendString(text,(char*)a_string.data());
258  return 0;
259 }
260 /***************************************************************************/
261 G4int G4UIXm::ReceiveG4cerr (
262  const G4String& a_string
263 )
264 /***************************************************************************/
266 {
267  XmTextAppendString(text,(char*)a_string.data());
268  return 0;
269 }
270 /***************************************************************************/
271 G4bool G4UIXm::GetHelpChoice(
272  G4int& aInt
273 )
274 /***************************************************************************/
276 {
277  fHelp = true;
278  // SecondaryLoop :
279  G4Xt* interactorManager = G4Xt::getInstance ();
280  Prompt("Help");
281  exitHelp = false;
282  void* event;
283  while((event = interactorManager->GetEvent())!=NULL) {
284  interactorManager->DispatchEvent(event);
285  if(exitHelp==true) break;
286  }
287  Prompt("session");
288  //
289  if(fHelp==false) return false;
290  aInt = fHelpChoice;
291  fHelp = false;
292  return true;
293 }
294 /***************************************************************************/
295 void G4UIXm::ExitHelp(
296 ) const
297 /***************************************************************************/
299 {
300 }
301 /***************************************************************************/
302 void G4UIXm::AddMenu (
303  const char* a_name
304 ,const char* a_label
305 )
306 /***************************************************************************/
308 {
309  if(menuBar==NULL) return;
310  if(a_name==NULL) return;
311  if(a_label==NULL) return;
312  XtManageChild (menuBar);
313  // Pulldown menu :
314  Widget widget;
315  widget = XmCreatePulldownMenu (menuBar,(char*)a_name,NULL,0);
316  AddInteractor (a_name,(G4Interactor)widget);
317  // Cascade button :
318  Arg args[2];
319  XmString cps = XmStringLtoRCreate((char*)a_label,(char*)XmSTRING_DEFAULT_CHARSET);
320  XtSetArg (args[0],XmNlabelString,cps);
321  XtSetArg (args[1],XmNsubMenuId,widget);
322  widget = XmCreateCascadeButton (menuBar,(char*)a_name,args,2);
323  XmStringFree (cps);
324  XtManageChild (widget);
325  ExecuteChangeSizeFunction(form);
326 }
327 /***************************************************************************/
328 void G4UIXm::AddButton (
329  const char* a_menu
330 ,const char* a_label
331 ,const char* a_command
332 )
333 /***************************************************************************/
335 {
336  if(a_menu==NULL) return;
337  if(a_label==NULL) return;
338  if(a_command==NULL) return;
339  Widget parent = (Widget)GetInteractor(a_menu);
340  if(parent==NULL) return;
341  Widget widget = XmCreatePushButton(parent,(char*)a_label,NULL,0);
342  XtManageChild (widget);
343  XtAddCallback (widget,XmNactivateCallback,ButtonCallback,(XtPointer)this);
344  commands[widget] = a_command;
345 }
346 /***************************************************************************/
347 G4String G4UIXm::GetCommand (
348  Widget a_widget
349 )
350 /***************************************************************************/
352 {
353  return commands[a_widget];
354 }
355 /***************************************************************************/
356 /***************************************************************************/
357 /***************************************************************************/
358 void G4UIXm::CommandEnteredCallback (
359  Widget
360 ,XtPointer a_tag
361 ,XtPointer a_data
362 )
363 /***************************************************************************/
365 {
366  G4UIXm* This = (G4UIXm*)a_tag;
367 
368  XmString cps = ((XmCommandCallbackStruct*)a_data)->value;
369  char* ss = XmConvertCompoundStringToString(cps,0);
370  G4String command (ss);
371  XtFree (ss);
372 
373  if(This->fHelp==true) {
374  exitHelp = true;
375  This->fHelp = ConvertStringToInt(command.data(),This->fHelpChoice);
376  } else {
377  This->ApplyShellCommand (command,exitSession,exitPause);
378  }
379 
380  //a_widget = NULL; Not used (1st argument). Comment out to avoid compiler warnings. (JA)
381  a_tag = NULL;
382 }
383 /***************************************************************************/
384 void G4UIXm::keyHandler (
385  Widget a_widget
386 ,XtPointer a_tag
387 ,XEvent* a_event
388 ,Boolean*
389 )
390 /***************************************************************************/
392 {
393  KeySym keySym;
394  XLookupString(&(a_event->xkey),NULL,0,&keySym,NULL);
395  if(keySym!=XK_Tab) return;
396  G4UIXm* This = (G4UIXm*)a_tag;
397  char* s = XmTextGetString(a_widget);
398  G4String ss = This->Complete(s);
399  XmTextSetString(a_widget,(char*)ss.data());
400  XtFree(s);
401  XmTextSetInsertionPosition(a_widget,XmTextGetLastPosition(a_widget));
402 }
403 /***************************************************************************/
404 void clearButtonCallback (
405  Widget
406 ,XtPointer a_tag
407 ,XtPointer
408 )
409 /***************************************************************************/
411 {
412  XmTextSetString((Widget)a_tag,(char*)"");
413 }
414 /***************************************************************************/
415 void G4UIXm::ButtonCallback (
416  Widget a_widget
417 ,XtPointer a_tag
418 ,XtPointer
419 )
420 /***************************************************************************/
422 {
423  G4UIXm* This = (G4UIXm*)a_tag;
424  if(This->fHelp==true) return; // Disabled when in help.
425  G4String ss = This->GetCommand (a_widget);
426  This->ApplyShellCommand(ss,exitSession,exitPause);
427 }
428 /***************************************************************************/
429 /***************************************************************************/
430 /***************************************************************************/
431 char* XmConvertCompoundStringToString (
432  XmString a_cps
433 ,int a_number
434 )
435 /***************************************************************************/
437 {
438  if(a_cps==NULL) return NULL;
439  char* ss = NULL;
440  XmStringContext context;
441  XmStringInitContext(&context,a_cps);
442  int icount = 0;
443  Boolean Done = False;
444  while(Done==False) {
445  char* text = NULL;
446  XmStringCharSet charset = NULL;
447  XmStringDirection direct;
448  Boolean sep;
449  if(XmStringGetNextSegment(context,&text,&charset,&direct,&sep)==True) {
450  XtFree(charset);
451  if(sep==True) Done = True;
452  if(icount==a_number) {
453  ss = text;
454  break;
455  }
456  icount++;
457  XtFree(text);
458  }
459  else
460  Done = True;
461  }
462  XmStringFreeContext(context);
463  return ss;
464 }
465 /***************************************************************************/
466 void XmTextAppendString (
467  Widget This
468 ,char* a_string
469 )
470 /***************************************************************************/
472 {
473  if(This==NULL) return;
474  if(!XtIsSubclass(This,xmTextWidgetClass)) return;
475  if(a_string==NULL) return;
476  XmTextPosition lastpos = XmTextGetLastPosition(This);
477  XmTextReplace(This,lastpos,lastpos,a_string);
478  XmTextSetInsertionPosition(This,XmTextGetLastPosition(This));
479 }
481 G4bool ConvertStringToInt(
482  const char* aString
483 ,int& aInt
484 )
487 {
488  aInt = 0;
489  if(aString==NULL) return false;
490  char* s;
491  long value = strtol(aString,&s,10);
492  if(s==aString) return false;
493  aInt = value;
494  return true;
495 }
496 #include <X11/IntrinsicP.h>
498 void ExecuteChangeSizeFunction (
499  Widget aWidget
500 )
503 {
504  if(aWidget==NULL) return;
505  if(aWidget->core.widget_class->core_class.resize==NULL) return;
506  (aWidget->core.widget_class->core_class.resize)(aWidget);
507 }
508 
509 
510 #endif
static constexpr double s
Definition: G4SIunits.hh:169
void SetSession(G4UIsession *const value)
Definition: G4UImanager.hh:213
int G4int
Definition: G4Types.hh:78
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:58
void * G4Interactor
bool G4bool
Definition: G4Types.hh:79
const char * data() const
void SetCoutDestination(G4UIsession *const value)
Definition: G4UImanager.cc:618
G4UImanager * UI
Definition: G4UIterminal.hh:73
G4VUIshell * shell
Definition: G4UIterminal.hh:75