ARB
AW_window.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : AW_window.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "aw_at.hxx"
12 #include "aw_nawar.hxx"
13 #include "aw_xfig.hxx"
14 #include "aw_Xm.hxx"
15 #include "aw_window.hxx"
16 #include "aw_window_Xm.hxx"
17 #include "aw_xkey.hxx"
18 #include "aw_select.hxx"
19 #include "aw_awar.hxx"
20 #include "aw_msg.hxx"
21 #include "aw_root.hxx"
22 #include "aw_xargs.hxx"
23 #include "aw_device_click.hxx"
24 #include "aw_localdef.hxx"
25 
26 #include <arbdbt.h>
27 #include <arb_file.h>
28 #include <arb_str.h>
29 #include <arb_strarray.h>
30 
31 #include <X11/Shell.h>
32 #include <Xm/AtomMgr.h>
33 #include <Xm/Frame.h>
34 #include <Xm/PushB.h>
35 #include <Xm/Protocols.h>
36 #include <Xm/RowColumn.h>
37 #include <Xm/DrawingA.h>
38 #include <Xm/Form.h>
39 #include <Xm/Separator.h>
40 #include <Xm/MainW.h>
41 #include <Xm/CascadeB.h>
42 #include <Xm/MenuShell.h>
43 #include <Xm/ScrollBar.h>
44 #include <Xm/MwmUtil.h>
45 
46 #include "aw_question.hxx"
47 
48 #include <cctype>
49 #include <map>
50 #include <string>
51 
52 void AW_POPDOWN(AW_window *window){
53  window->hide();
54 }
55 
61 #if defined(DEBUG)
62 // #define TRACE_WM_OFFSETS
63 #endif
64 
65 static AW_window *find_or_createAndRegisterWindow(CreateWindowCallback *windowMaker) {
66  typedef std::map<CreateWindowCallback, AW_window*> window_map;
67 
68  static window_map window; // previously popped up windows
69  CreateWindowCallback& maker = *windowMaker;
70 
71  if (window.find(maker) == window.end()) {
72  AW_window *made = maker(AW_root::SINGLETON);
73  if (!made) {
74 #if defined(DEBUG)
75  // the current (NDEBUG) code allows a windows creator method to return null.
76  // if triggered again, window creation will be tried again.
77  //
78  // i am not sure whether that behavior is intentional.
79  // it has been introduced during attempt to port arb to gtk.
80  //
81  // current DEBUG code triggers a runtime error, assuming it happens by mistake.
82  // if behavior is really intended, add an explicit callback type which allows returning NULp.
83  fputs("Bug(?): window factory did not create a window\n", stderr);
84  maker(NULp); // cause arb to crash inside the callback (otherwise debugger is required to detect callback)
85  arb_assert(0);
86 #endif
87  return NULp;
88  }
89 
90  window[maker] = made;
91  }
92  return window[maker];
93 }
94 
95 void AW_window::popper(AW_window *, CreateWindowCallback *windowMaker) {
96  AW_window *toPopup = find_or_createAndRegisterWindow(windowMaker);
97  if (toPopup) toPopup->activate();
98 }
99 void AW_window::replacer(AW_window *caller, CreateWindowCallback *windowMaker) {
100  AW_window *toPopup = find_or_createAndRegisterWindow(windowMaker);
101  if (toPopup) {
102  toPopup->activate();
103  caller->hide();
104  }
105 }
106 void AW_window::destroyCreateWindowCallback(CreateWindowCallback *windowMaker) {
107  delete windowMaker;
108 }
109 
110 
111 void AW_window::label(const char *_label) {
112  aw_assert(_label); // cannot clear label with this method (consider using unset_at_commands)
113  aw_assert(_label[0]); // empty labels not supported
114  aw_assert(_at->label_for_inputfield == NULp); // you are overwriting an existing label (probably by mistake or wrong design)
115  freedup(_at->label_for_inputfield, _label);
116 }
117 
118 void AW_window::get_window_size(int &width, int &height){
119  unsigned short hoffset = 0;
120  if (p_w->menu_bar[0]) XtVaGetValues(p_w->menu_bar[0], XmNheight, &hoffset, NULp);
121  width = _at->max_x_size;
122  height = hoffset + _at->max_y_size;
123 }
124 
125 void AW_window::help_text(const char *id) {
127  delete _at->helptext_for_next_button; // @@@ delete/free mismatch
128  _at->helptext_for_next_button = strdup(id);
129 }
130 
133  _at->highlight = true;
134 }
135 
138  aw_assert(legal_mask(mask));
139  _at->widget_mask = mask;
140 }
141 
142 void AW_window::callback(const WindowCallback& wcb) {
147  _callback = new AW_cb(this, wcb);
148 }
149 
150 void AW_window::d_callback(const WindowCallback& wcb) {
155  _d_callback = new AW_cb(this, wcb);
156 }
157 
158 // -------------------------------------------------------------
159 // code used by scalers
160 
161 static float apply_ScalerType(float val, AW_ScalerType scalerType, bool inverse) {
162  float res = 0.0;
163 
164  aw_assert(val>=0.0 && val<=1.0);
165 
166  switch (scalerType) {
167  case AW_SCALER_LINEAR:
168  res = val;
169  break;
170 
171  case AW_SCALER_EXP_LOWER:
172  if (inverse) res = pow(val, 1/3.0);
173  else res = pow(val, 3.0);
174  break;
175 
176  case AW_SCALER_EXP_UPPER:
177  res = 1.0-apply_ScalerType(1.0-val, AW_SCALER_EXP_LOWER, inverse);
178  break;
179 
181  inverse = !inverse;
182  // fall-through
183  case AW_SCALER_EXP_CENTER: {
185  if (val>0.5) res = (1+apply_ScalerType(2*val-1, subType, false))/2;
186  else if (val<0.5) res = (1-apply_ScalerType(1-2*val, subType, false))/2;
187  else res = val;
188  break;
189  }
190  }
191 
192  aw_assert(res>=0.0 && res<=1.0);
193 
194  return res;
195 }
196 
197 float AW_ScalerTransformer::scaler2awar(float scaler, AW_awar *awar) {
198  float amin = awar->get_min();
199  float amax = awar->get_max();
200  float modScaleRel = apply_ScalerType(scaler, type, false);
201  float aval = amin + modScaleRel*(amax-amin);
202 
203  return aval;
204 }
205 
207  float amin = awar->get_min();
208  float amax = awar->get_max();
209 
210  float awarRel = 0.0;
211  switch (awar->variable_type) {
212  case AW_FLOAT:
213  awarRel = (awar->read_float()-amin) / (amax-amin);
214  break;
215 
216  case AW_INT:
217  awarRel = (awar->read_int()-amin) / (amax-amin);
218  break;
219 
220  default:
221  GBK_terminatef("Unsupported awar type %i in calculate_scaler_value", int(awar->variable_type));
222  break;
223  }
224 
225  aw_assert(awarRel>=0.0 && awarRel<=1.0);
226 
227  return apply_ScalerType(awarRel, type, true);
228 }
229 
230 // -------------------------
231 // Hotkey Checking
232 
233 #if defined(DEBUG)
234 #define CHECK_DUPLICATED_MNEMONICS
235 #endif
236 
237 #ifdef CHECK_DUPLICATED_MNEMONICS
238 
239 inline char oppositeCase(char c) {
240  return isupper(c) ? tolower(c) : toupper(c);
241 }
242 static void strcpy_overlapping(char *dest, char *src) {
243  int src_len = strlen(src);
244  memmove(dest, src, src_len+1);
245 }
246 static const char *possible_mnemonics(const char *used_mnemonics, bool top_level, const char *topic_name) {
247  static char *unused;
248  for (int fromTopic = 1; fromTopic>=0; --fromTopic) {
249  freedup(unused, fromTopic ? topic_name : "abcdefghijklmnopqrstuvwxyz");
250 
251  for (int t = 0; unused[t]; ++t) {
252  bool remove = false;
253  if ((top_level && !isalpha(unused[t])) || !isalnum(unused[t])) { // remove useless chars
254  remove = true;
255  }
256  else {
257  char *dup = strchr(unused, unused[t]);
258  if (dup && (dup-unused)<t) { // remove duplicated chars
259  remove = true;
260  }
261  else {
262  dup = strchr(unused, oppositeCase(unused[t]));
263  if (dup && (dup-unused)<t) { // char is duplicated with opposite case
264  dup[0] = toupper(dup[0]); // prefer upper case
265  remove = true;
266  }
267  }
268  }
269  if (remove) {
270  strcpy_overlapping(unused+t, unused+t+1);
271  --t;
272  }
273  }
274 
275  for (int t = 0; used_mnemonics[t]; ++t) {
276  char c = used_mnemonics[t]; // upper case!
277  char *u = strchr(unused, c);
278  if (u) strcpy_overlapping(u, u+1); // remove char
279  u = strchr(unused, tolower(c));
280  if (u) strcpy_overlapping(u, u+1); // remove char
281  }
282 
283  if (unused[0]) {
284  if (!fromTopic) {
285  freeset(unused, GBS_global_string_copy("unused but not in topic: \"%s\"", unused));
286  }
287  break;
288  }
289  }
290  return unused;
291 }
292 
293 class MnemonicScope : virtual Noncopyable {
294  typedef std::map<char,std::string> Char2Topic;
295 
296  std::string name; // of menu or window
297  MnemonicScope *parent;
298  StrArray requested; // topics lacking sufficient mnemonic
299  Char2Topic accepted; // accepted mnemonics (key = uppercase hotkey, value=topic)
300 
301  void print_at_menu(FILE *out) {
302  if (parent) {
303  parent->print_at_menu(out);
304  fputc('|', out);
305  }
306  fputs(name.c_str(), out);
307  }
308  void print_at_location(FILE *out, const char *topic) {
309  fputs(" (", out);
310  print_at_menu(out);
311  fprintf(out, "|%s)\n", topic);
312  }
313 
314  void requestPossibilities(const char *topic_name) {
315  // will be shown delayed (when menu closes)
316  if (requested.index_of(topic_name) == -1) { // avoid duplicates
317  requested.put(strdup(topic_name));
318  }
319  }
320 
321  void showRequestedPossibilities() {
322  unsigned size = accepted.size();
323  char *used = new char[size+1];
324 
325  int i = 0;
326  for (Char2Topic::iterator a = accepted.begin(); a != accepted.end(); ++a) {
327  used[i++] = a->first;
328  }
329  used[size] = 0;
330 
331  for (i = 0; requested[i]; ++i) {
332  const char *possible = possible_mnemonics(used, !parent, requested[i]);
333  fprintf(stderr, "Warning: Possible mnemonics for '%s': '%s'\n", requested[i], possible);
334  }
335 
336  delete [] used;
337  }
338 
339  void warn_mnemonic(const char *topic_name, const char *mnemonic, const char *warning) {
340  fprintf(stderr, "Warning: mnemonic '%s' %s", mnemonic, warning);
341  print_at_location(stderr, topic_name);
342  }
343 
344 public:
345 
346  MnemonicScope(const char *name_, MnemonicScope *parent_)
347  : name(name_),
348  parent(parent_)
349  {}
350 
351  ~MnemonicScope() {
352  showRequestedPossibilities();
353  }
354 
355  void add(const char *topic_name, const char *mnemonic);
356 
357  MnemonicScope *get_parent() { return parent; }
358 };
359 
360 static MnemonicScope *current_mscope = NULp;
361 static MnemonicScope *help_mscope = NULp;
362 
363 void MnemonicScope::add(const char *topic_name, const char *mnemonic) {
364  if (mnemonic && mnemonic[0] != 0) {
365  if (mnemonic[1]) { // longer than 1 char -> wrong
366  warn_mnemonic(topic_name, mnemonic, "is too long; only 1 character allowed");
367  }
368 
369  if (AW_IS_IMAGEREF(topic_name)) {
370  if (mnemonic[0]) {
371  warn_mnemonic(topic_name, mnemonic, "is useless for graphical menu entry");
372  }
373  }
374  else if (!isalpha(mnemonic[0]) && !get_parent()) { // do not allow top-level numeric mnemonics
375  warn_mnemonic(topic_name, mnemonic, "is invalid (allowed: a-z)");
376  requestPossibilities(topic_name);
377  }
378  else if (!isalnum(mnemonic[0])) {
379  warn_mnemonic(topic_name, mnemonic, "is invalid (allowed: a-z and 0-9)");
380  requestPossibilities(topic_name);
381  }
382  else {
383  char *TOPIC_NAME = ARB_strupper(strdup(topic_name));
384  char HOTKEY = toupper(mnemonic[0]); // store hotkeys case-less (case does not matter when pressing the hotkey)
385 
386  if (strchr(TOPIC_NAME, HOTKEY)) { // occurs in menu text
387  Char2Topic::iterator found = accepted.find(HOTKEY);
388 
389  if (found != accepted.end()) {
390  warn_mnemonic(topic_name, mnemonic, "is used multiple times");
391  requestPossibilities(topic_name);
392  requestPossibilities(found->second.c_str()); // show possibilities for accepted duplicate
393  }
394  else {
395  accepted[HOTKEY] = topic_name;
396 
397  if (!strchr(topic_name, mnemonic[0])) {
398  char *warning = GBS_global_string_copy("has wrong case, use '%c'", HOTKEY == mnemonic[0] ? tolower(HOTKEY) : HOTKEY);
399  warn_mnemonic(topic_name, mnemonic, warning);
400  free(warning);
401  }
402  }
403  }
404  else {
405  warn_mnemonic(topic_name, mnemonic, "is useless; does not occur in text");
406  requestPossibilities(topic_name);
407  }
408  free(TOPIC_NAME);
409  }
410  }
411  else {
412  if (!AW_IS_IMAGEREF(topic_name)) {
413  fputs("Warning: mnemonic is missing", stderr);
414  print_at_location(stderr, topic_name);
415  requestPossibilities(topic_name);
416  }
417  }
418 }
419 
420 static void open_test_duplicate_mnemonics(const char *sub_menu_name, const char *mnemonic) {
421  aw_assert(current_mscope);
422  current_mscope->add(sub_menu_name, mnemonic);
423 
424  MnemonicScope *prev = current_mscope;
425  current_mscope = new MnemonicScope(sub_menu_name, prev);
426 }
427 
428 static void close_test_duplicate_mnemonics() {
429  MnemonicScope *prev = current_mscope->get_parent();
430  delete current_mscope;
431  current_mscope = prev;
432 }
433 
434 static void init_duplicate_mnemonic(const char *window_name) {
435  if (!current_mscope) {
436  current_mscope = new MnemonicScope(window_name, NULp);
437  help_mscope = new MnemonicScope("<HELP>", current_mscope);
438  }
439  else {
440  while (current_mscope->get_parent()) {
441  close_test_duplicate_mnemonics();
442  }
443  }
444 }
445 
446 static void test_duplicate_mnemonics(const char *topic_name, const char *mnemonic) {
447  aw_assert(current_mscope);
448  current_mscope->add(topic_name, mnemonic);
449 }
450 
451 static void exit_duplicate_mnemonic() {
452  delete help_mscope; help_mscope = NULp;
453  while (current_mscope) close_test_duplicate_mnemonics();
454 }
455 
456 
457 #endif
458 
459 void AW_window::create_menu(AW_label name, const char *mnemonic, AW_active mask) {
460  aw_assert(legal_mask(mask));
461  p_w->menu_deep = 0;
462 
463 #ifdef CHECK_DUPLICATED_MNEMONICS
464  init_duplicate_mnemonic(window_title);
465 #endif
466 
467 #if defined(DUMP_MENU_LIST)
468  dumpCloseAllSubMenus();
469 #endif // DUMP_MENU_LIST
470  insert_sub_menu(name, mnemonic, mask);
471 }
472 
478 #ifdef CHECK_DUPLICATED_MNEMONICS
479  close_test_duplicate_mnemonics();
480 #endif
481 #if defined(DUMP_MENU_LIST)
482  dumpCloseSubMenu();
483 #endif // DUMP_MENU_LIST
484  if (p_w->menu_deep>0)
485  p_w->menu_deep--;
486 }
487 
488 void AW_window::all_menus_created() const { // this is called by AW_window::show() (i.e. after all menus have been created)
489 #if defined(DEBUG)
490  if (p_w->menu_deep>0) { // window had menu
491  aw_assert(p_w->menu_deep == 1);
492 #ifdef CHECK_DUPLICATED_MNEMONICS
493  exit_duplicate_mnemonic(); // cleanup mnemonic check
494 #endif
495  }
496 #endif // DEBUG
497 }
498 
499 void AW_window::draw_line(int x1, int y1, int x2, int y2, int width, bool resize) {
500  aw_assert(xfig_data); // forgot to call load_xfig ?
501 
502  xfig_data->add_line(x1, y1, x2, y2, width);
503 
504  _at->max_x_size = std::max(_at->max_x_size, xfig_data->maxx - xfig_data->minx);
505  _at->max_y_size = std::max(_at->max_y_size, xfig_data->maxy - xfig_data->miny);
506 
507  if (resize) {
509  set_window_size(WIDER_THAN_SCREEN, HIGHER_THAN_SCREEN);
510  }
511 }
512 
513 AW_device_click *AW_window::get_click_device(AW_area area, int mousex, int mousey, int max_distance) {
514  AW_area_management *aram = MAP_ARAM(area);
515  AW_device_click *click_device = NULp;
516 
517  if (aram) {
518  click_device = aram->get_click_device();
519  click_device->init_click(AW::Position(mousex, mousey), max_distance, AW_ALL_DEVICES);
520  }
521  return click_device;
522 }
523 
524 AW_device *AW_window::get_device(AW_area area) { // @@@ rename to get_screen_device
525  AW_area_management *aram = MAP_ARAM(area);
526  arb_assert(aram);
527  return aram->get_screen_device();
528 }
529 
530 void AW_window::get_event(AW_event *eventi) const {
531  *eventi = event;
532 }
533 
534 AW_device_print *AW_window::get_print_device(AW_area area) {
535  AW_area_management *aram = MAP_ARAM(area);
536  return aram ? aram->get_print_device() : NULp;
537 }
538 
540  AW_area_management *aram = MAP_ARAM(area);
541  if (!aram) return NULp;
542 
543  AW_device_size *size_device = aram->get_size_device();
544  if (size_device) {
545  size_device->restart_tracking();
546  size_device->reset(); // @@@ hm
547  }
548  return size_device;
549 }
550 
552  AW_area_management *aram = MAP_ARAM(area);
553  return aram ? aram->get_common() : NULp;
554 }
555 
556 void AW_window::insert_help_topic(const char *labeli,
557  const char *mnemonic, const char *helpText,
558  AW_active mask, const WindowCallback& cb) {
559  aw_assert(legal_mask(mask));
560  Widget button;
561 
562 #ifdef CHECK_DUPLICATED_MNEMONICS
563  if (!current_mscope) init_duplicate_mnemonic(window_title);
564  MnemonicScope *tmp = current_mscope;
565  current_mscope = help_mscope;
566  test_duplicate_mnemonics(labeli, mnemonic);
567  current_mscope = tmp;
568 #endif
569 
570  // insert one help-sub-menu-entry
571  button = XtVaCreateManagedWidget("", xmPushButtonWidgetClass,
573  RES_CONVERT(XmNlabelString, labeli),
574  RES_CONVERT(XmNmnemonic, mnemonic), NULp);
575  XtAddCallback(button, XmNactivateCallback,
576  (XtCallbackProc) AW_server_callback,
577  (XtPointer) new AW_cb(this, cb, helpText));
578 
579  root->make_sensitive(button, mask);
580 }
581 
582 void AW_window::insert_menu_topic(const char *topic_id, const char *labeltext,
583  const char *mnemonic, const char *helpText,
584  AW_active mask, const WindowCallback& wcb) {
585  aw_assert(legal_mask(mask));
586  Widget button;
587 
588  TuneBackground(p_w->menu_bar[p_w->menu_deep], TUNE_MENUTOPIC); // set background color for normal menu topics
589 
590 #if defined(DUMP_MENU_LIST)
591  dumpMenuEntry(name);
592 #endif // DUMP_MENU_LIST
593 
594 #ifdef CHECK_DUPLICATED_MNEMONICS
595  test_duplicate_mnemonics(labeltext, mnemonic);
596 #endif
597 
598  Label topiclabel(labeltext, this);
599  if (mnemonic && *mnemonic && strchr(labeltext, mnemonic[0])) {
600  // create one sub-menu-point
601  button = XtVaCreateManagedWidget("", xmPushButtonWidgetClass,
603  RES_LABEL_CONVERT(topiclabel),
604  RES_CONVERT(XmNmnemonic, mnemonic),
605  XmNbackground, _at->background_color, NULp);
606  }
607  else {
608  button = XtVaCreateManagedWidget("",
609  xmPushButtonWidgetClass,
611  RES_LABEL_CONVERT(topiclabel),
612  XmNbackground, _at->background_color,
613  NULp);
614  }
615 
616  AW_label_in_awar_list(this, button, labeltext);
617  AW_cb *cbs = new AW_cb(this, wcb, helpText);
618  XtAddCallback(button, XmNactivateCallback,
619  (XtCallbackProc) AW_server_callback,
620  (XtPointer) cbs);
621 
622 #if defined(DEVEL_RALF) // wanted version
623  aw_assert(topic_id);
624 #else // !defined(DEVEL_RALF)
625  if (!topic_id) topic_id = labeltext;
626 #endif
627  cbs->id = strdup(topic_id);
629  root->make_sensitive(button, mask);
630 }
631 
632 void AW_window::insert_sub_menu(const char *labeli, const char *mnemonic, AW_active mask){
633  aw_assert(legal_mask(mask));
634  Widget shell, Label;
635 
636  TuneBackground(p_w->menu_bar[p_w->menu_deep], TUNE_SUBMENU); // set background color for submenus
637  // (Note: This must even be called if TUNE_SUBMENU is 0!
638  // Otherwise several submenus get the TUNE_MENUTOPIC color)
639 
640 #if defined(DUMP_MENU_LIST)
641  dumpOpenSubMenu(name);
642 #endif // DUMP_MENU_LIST
643 
644 #ifdef CHECK_DUPLICATED_MNEMONICS
645  open_test_duplicate_mnemonics(labeli, mnemonic);
646 #endif
647 
648  // create shell for Pull-Down
649  shell = XtVaCreatePopupShell("menu_shell", xmMenuShellWidgetClass,
651  XmNwidth, 1,
652  XmNheight, 1,
653  XmNallowShellResize, true,
654  XmNoverrideRedirect, true,
655  NULp);
656 
657  // create row column in Pull-Down shell
658 
659  p_w->menu_bar[p_w->menu_deep+1] = XtVaCreateWidget("menu_row_column",
660  xmRowColumnWidgetClass, shell,
661  XmNrowColumnType, XmMENU_PULLDOWN,
662  XmNtearOffModel, XmTEAR_OFF_ENABLED,
663  NULp);
664 
665  // create label in menu bar
666  if (mnemonic && *mnemonic && strchr(labeli, mnemonic[0])) {
667  // if mnemonic is "" -> Cannot convert string "" to type KeySym
668  Label = XtVaCreateManagedWidget("menu1_top_b1",
669  xmCascadeButtonWidgetClass, p_w->menu_bar[p_w->menu_deep],
670  RES_CONVERT(XmNlabelString, labeli),
671  RES_CONVERT(XmNmnemonic, mnemonic),
672  XmNsubMenuId, p_w->menu_bar[p_w->menu_deep+1],
673  XmNbackground, _at->background_color, NULp);
674  }
675  else {
676  Label = XtVaCreateManagedWidget("menu1_top_b1",
677  xmCascadeButtonWidgetClass,
679  RES_CONVERT(XmNlabelString, labeli),
680  XmNsubMenuId, p_w->menu_bar[p_w->menu_deep+1],
681  XmNbackground, _at->background_color,
682  NULp);
683  }
684 
686 
687  root->make_sensitive(Label, mask);
688 }
689 
690 static void AW_xfigCB_info_area(AW_window *aww, AW_xfig *xfig) {
691  AW_device *device = aww->get_device(AW_INFO_AREA);
692  device->reset();
693 
694  if (aww->get_root()->color_mode == 0) { // mono colr
695  device->clear(-1);
696  }
697  device->set_offset(AW::Vector(-xfig->minx, -xfig->miny));
698 
699  xfig->print(device);
700 }
701 
702 void AW_window::get_font_size(int& width, int& height) {
703  width = get_root()->font_width;
704  height = get_root()->font_height;
705 }
706 
707 void AW_window::load_xfig(const char *file, bool resize /*= true*/) {
708  int width, height;
709  get_font_size(width, height);
710 
711  if (file) xfig_data = new AW_xfig(file, width, height);
712  else xfig_data = new AW_xfig(width, height); // create an empty xfig
713 
714  xfig_data->create_gcs(get_device(AW_INFO_AREA), get_root()->color_mode ? 8 : 1);
715 
716  // @@@ move into AW_at::set_xfig
717  int xsize = xfig_data->maxx - xfig_data->minx;
718  int ysize = xfig_data->maxy - xfig_data->miny;
719  if (xsize>_at->max_x_size) _at->max_x_size = xsize;
720  if (ysize>_at->max_y_size) _at->max_y_size = ysize;
721 
722  if (resize) {
724  set_window_size(WIDER_THAN_SCREEN, HIGHER_THAN_SCREEN);
725  }
726 
727  set_expose_callback(AW_INFO_AREA, makeWindowCallback(AW_xfigCB_info_area, xfig_data));
728 }
729 
730 
731 char *AW_window::local_id_copy(const char *id) const {
736  return GBS_global_string_copy("%s/%s", get_window_id(), id);
737 }
738 const char *AW_window::local_id(const char *id) const {
743  static char *last_local_id = NULp;
744  freeset(last_local_id, local_id_copy(id));
745  return last_local_id;
746 }
747 
748 static const char *local_awarnamef(const char *format, AW_window *aww, const char *common_name) {
749  CONSTEXPR int MAXNAMELEN = 256;
750  static char buffer[MAXNAMELEN];
751  return GBS_global_string_to_buffer(buffer, MAXNAMELEN, format, aww->get_window_id(), common_name);
752 }
753 
754 const char *AW_window::local_awarname(const char *common_name, bool tmp) {
755  return local_awarnamef(tmp ? "tmp/window/%s/%s" : "window/%s/%s", this, common_name);
756 }
757 
758 AW_awar *AW_window::local_awar(const char *common_name, bool tmp) {
759  return get_root()->awar(local_awarname(common_name, tmp));
760 }
761 
762 
765  XtVaCreateManagedWidget("", xmSeparatorWidgetClass,
767  NULp);
768 }
769 
775 void AW_window::set_expose_callback(AW_area area, const WindowCallback& wcb) {
776  AW_area_management *aram = MAP_ARAM(area);
777  if (aram) aram->set_expose_callback(this, wcb);
778 }
779 
780 static void AW_focusCB(Widget /*wgt*/, XtPointer cl_aww, XEvent*, Boolean*) {
781  AW_window *aww = (AW_window*)cl_aww;
782  aww->run_focus_callback();
783 }
784 
788 void AW_window::set_focus_callback(const WindowCallback& wcb) {
789  if (!focus_cb) {
790  XtAddEventHandler(MIDDLE_WIDGET, EnterWindowMask, FALSE, AW_focusCB, (XtPointer) this);
791  }
792 
793  if (!is_focus_callback(AnyWinCB(wcb.callee()))) {
794  focus_cb = new AW_cb(this, wcb, NULp, focus_cb);
795  }
796 }
797 
802 void AW_window::set_popup_callback(const WindowCallback& wcb) {
803  p_w->popup_cb = new AW_cb(this, wcb, NULp, p_w->popup_cb);
804 }
805 
807  XtVaSetValues(INFO_WIDGET, XmNheight, h, NULp);
808  XtVaSetValues(p_w->frame, XmNtopOffset, h, NULp);
809 }
810 
812  XtVaSetValues(BOTTOM_WIDGET, XmNheight, h, NULp);
813  XtVaSetValues(p_w->scroll_bar_horizontal, XmNbottomOffset, (int)h, NULp);
814 }
815 
816 void AW_window::set_input_callback(AW_area area, const WindowCallback& wcb) {
817  AW_area_management *aram = MAP_ARAM(area);
818  if (aram) aram->set_input_callback(this, wcb);
819 }
820 
821 void AW_window::set_motion_callback(AW_area area, const WindowCallback& wcb) {
822  AW_area_management *aram = MAP_ARAM(area);
823  if (aram) aram->set_motion_callback(this, wcb);
824 }
825 
826 void AW_window::set_resize_callback(AW_area area, const WindowCallback& wcb) {
827  AW_area_management *aram = MAP_ARAM(area);
828  if (aram) aram->set_resize_callback(this, wcb);
829 }
830 
831 // SCROLL BAR STUFF
832 
834  picture->l = rectangle.l;
835  picture->r = rectangle.r;
836  picture->t = rectangle.t;
837  picture->b = rectangle.b;
838 }
839 
841  picture->l = (int)rectangle.l;
842  picture->r = (int)rectangle.r;
843  picture->t = (int)rectangle.t;
844  picture->b = (int)rectangle.b;
845 }
846 
848  return picture->r - picture->l;
849 }
850 
852  return picture->b - picture->t;
853 }
854 
856  picture->l = 0;
857  picture->r = 0;
858  picture->t = 0;
859  picture->b = 0;
860 }
861 
863  XtVaSetValues(p_w->scroll_bar_vertical, XmNtopOffset, (int)indent, NULp);
864  top_indent_of_vertical_scrollbar = indent;
865 }
866 
868  XtVaSetValues(p_w->scroll_bar_horizontal, XmNleftOffset, (int)indent, NULp);
869  left_indent_of_horizontal_scrollbar = indent;
870 }
871 
873  AW_area_management *aram = MAP_ARAM(area);
874  *square = aram->get_common()->get_screen();
875 }
876 
879  square->r -= left_indent_of_horizontal_scrollbar;
880  square->b -= top_indent_of_vertical_scrollbar;
881 }
882 
884  AW_screen_area scrollArea;
885  get_scrollarea_size(&scrollArea);
886 
887  // HORIZONTAL
888  {
889  int slider_max = (int)get_scrolled_picture_width();
890  if (slider_max <1) {
891  slider_max = 1;
892  XtVaSetValues(p_w->scroll_bar_horizontal, XmNsliderSize, 1, NULp);
893  }
894 
895  bool use_horizontal_bar = true;
896  int slider_size_horizontal = scrollArea.r;
897 
898  if (slider_size_horizontal < 1) slider_size_horizontal = 1; // ist der slider zu klein (<1) ?
899  if (slider_size_horizontal > slider_max) { // Schirm groesser als Bild
900  slider_size_horizontal = slider_max; // slider nimmt ganze laenge ein
901  XtVaSetValues(p_w->scroll_bar_horizontal, XmNvalue, 0, NULp); // slider ganz links setzen
902  use_horizontal_bar = false; // kein horizontaler slider mehr
903  }
904 
905  // check wether XmNValue is to big
906  int position_of_slider;
907  XtVaGetValues(p_w->scroll_bar_horizontal, XmNvalue, &position_of_slider, NULp);
908  if (position_of_slider > (slider_max-slider_size_horizontal)) { // steht der slider fuer slidergroesse zu rechts ?
909  position_of_slider = slider_max-slider_size_horizontal; // -1 ? vielleicht !
910  if (position_of_slider < 0) position_of_slider = 0;
911  XtVaSetValues(p_w->scroll_bar_horizontal, XmNvalue, position_of_slider, NULp);
912  }
913  // Anpassung fuer resize, wenn unbeschriebener Bereich vergroessert wird
914  int max_slider_pos = (int)(get_scrolled_picture_width() - scrollArea.r);
915  if (slider_pos_horizontal>max_slider_pos) {
916  slider_pos_horizontal = use_horizontal_bar ? max_slider_pos : 0;
917  }
918 
919  XtVaSetValues(p_w->scroll_bar_horizontal, XmNsliderSize, 1, NULp);
920  XtVaSetValues(p_w->scroll_bar_horizontal, XmNmaximum, slider_max, NULp);
921  XtVaSetValues(p_w->scroll_bar_horizontal, XmNsliderSize, slider_size_horizontal, NULp);
922 
924  }
925 
926  // VERTICAL
927  {
928  int slider_max = (int)get_scrolled_picture_height();
929  if (slider_max <1) {
930  slider_max = 1;
931  XtVaSetValues(p_w->scroll_bar_vertical, XmNsliderSize, 1, NULp);
932  }
933 
934  bool use_vertical_bar = true;
935  int slider_size_vertical = scrollArea.b;
936 
937  if (slider_size_vertical < 1) slider_size_vertical = 1;
938  if (slider_size_vertical > slider_max) {
939  slider_size_vertical = slider_max;
940  XtVaSetValues(p_w->scroll_bar_vertical, XmNvalue, 0, NULp);
941  use_vertical_bar = false;
942  }
943 
944  // check wether XmNValue is to big
945  int position_of_slider;
946  XtVaGetValues(p_w->scroll_bar_vertical, XmNvalue, &position_of_slider, NULp);
947  if (position_of_slider > (slider_max-slider_size_vertical)) {
948  position_of_slider = slider_max-slider_size_vertical; // -1 ? vielleicht !
949  if (position_of_slider < 0) position_of_slider = 0;
950  XtVaSetValues(p_w->scroll_bar_vertical, XmNvalue, position_of_slider, NULp);
951  }
952  // Anpassung fuer resize, wenn unbeschriebener Bereich vergroessert wird
953  int max_slider_pos = (int)(get_scrolled_picture_height() - scrollArea.b);
954  if (slider_pos_vertical>max_slider_pos) {
955  slider_pos_vertical = use_vertical_bar ? max_slider_pos : 0;
956  }
957 
958  XtVaSetValues(p_w->scroll_bar_vertical, XmNsliderSize, 1, NULp);
959  XtVaSetValues(p_w->scroll_bar_vertical, XmNmaximum, slider_max, NULp);
960  XtVaSetValues(p_w->scroll_bar_vertical, XmNsliderSize, slider_size_vertical, NULp);
961 
963  }
964 }
965 
968 }
969 
972 }
973 
975  RootCallback hor_src = makeRootCallback(horizontal_scrollbar_redefinition_cb, this);
976  RootCallback ver_src = makeRootCallback(vertical_scrollbar_redefinition_cb, this);
977 
978  get_root()->awar_int(local_awarname("horizontal_page_increment"), 50)->add_callback(hor_src);
979  get_root()->awar_int(local_awarname("vertical_page_increment"), 50)->add_callback(ver_src);
980  get_root()->awar_int(local_awarname("scroll_width_horizontal"), 9)->add_callback(hor_src);
981  get_root()->awar_int(local_awarname("scroll_width_vertical"), 20)->add_callback(ver_src);
982  get_root()->awar_int(local_awarname("scroll_delay_horizontal"), 20)->add_callback(hor_src);
983  get_root()->awar_int(local_awarname("scroll_delay_vertical"), 20)->add_callback(ver_src);
984 }
985 
987 #if defined(DEBUG) && 0
988  fprintf(stderr, "set_vertical_scrollbar_position to %i\n", position);
989 #endif
990  // @@@ test and constrain against limits
991  slider_pos_vertical = position;
992  XtVaSetValues(p_w->scroll_bar_vertical, XmNvalue, position, NULp);
993 }
994 
996 #if defined(DEBUG) && 0
997  fprintf(stderr, "set_horizontal_scrollbar_position to %i\n", position);
998 #endif
999  // @@@ test and constrain against limits
1000  slider_pos_horizontal = position;
1001  XtVaSetValues(p_w->scroll_bar_horizontal, XmNvalue, position, NULp);
1002 }
1003 
1004 static void value_changed_scroll_bar_vertical(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer call_data) {
1005  XmScrollBarCallbackStruct *sbcbs = (XmScrollBarCallbackStruct *)call_data;
1006  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1007  cbs->aw->slider_pos_vertical = sbcbs->value; // setzt Scrollwerte im AW_window
1008  cbs->run_callbacks();
1009 }
1010 static void value_changed_scroll_bar_horizontal(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer call_data) {
1011  XmScrollBarCallbackStruct *sbcbs = (XmScrollBarCallbackStruct *)call_data;
1012  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1013  (cbs->aw)->slider_pos_horizontal = sbcbs->value; // setzt Scrollwerte im AW_window
1014  cbs->run_callbacks();
1015 }
1016 
1017 static void drag_scroll_bar_vertical(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer call_data) {
1018  XmScrollBarCallbackStruct *sbcbs = (XmScrollBarCallbackStruct *)call_data;
1019  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1020  cbs->aw->slider_pos_vertical = sbcbs->value; // setzt Scrollwerte im AW_window
1021  cbs->run_callbacks();
1022 }
1023 static void drag_scroll_bar_horizontal(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer call_data) {
1024  XmScrollBarCallbackStruct *sbcbs = (XmScrollBarCallbackStruct *)call_data;
1025  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1026  (cbs->aw)->slider_pos_horizontal = sbcbs->value; // setzt Scrollwerte im AW_window
1027  cbs->run_callbacks();
1028 }
1029 
1030 void AW_window::set_vertical_change_callback(const WindowCallback& wcb) {
1031  XtAddCallback(p_w->scroll_bar_vertical, XmNvalueChangedCallback,
1032  (XtCallbackProc) value_changed_scroll_bar_vertical,
1033  (XtPointer) new AW_cb(this, wcb, ""));
1034  XtAddCallback(p_w->scroll_bar_vertical, XmNdragCallback,
1035  (XtCallbackProc) drag_scroll_bar_vertical,
1036  (XtPointer) new AW_cb(this, wcb, ""));
1037 
1038  XtAddCallback(p_w->scroll_bar_vertical, XmNpageIncrementCallback,
1039  (XtCallbackProc) drag_scroll_bar_vertical,
1040  (XtPointer) new AW_cb(this, wcb, ""));
1041  XtAddCallback(p_w->scroll_bar_vertical, XmNpageDecrementCallback,
1042  (XtCallbackProc) drag_scroll_bar_vertical,
1043  (XtPointer) new AW_cb(this, wcb, ""));
1044 }
1045 
1046 void AW_window::set_horizontal_change_callback(const WindowCallback& wcb) {
1047  XtAddCallback(p_w->scroll_bar_horizontal, XmNvalueChangedCallback,
1048  (XtCallbackProc) value_changed_scroll_bar_horizontal,
1049  (XtPointer) new AW_cb(this, wcb, ""));
1050  XtAddCallback(p_w->scroll_bar_horizontal, XmNdragCallback,
1051  (XtCallbackProc) drag_scroll_bar_horizontal,
1052  (XtPointer) new AW_cb(this, wcb, ""));
1053 }
1054 
1055 // END SCROLLBAR STUFF
1056 
1057 
1058 void AW_window::set_window_size(int width, int height) {
1059  XtVaSetValues(p_w->shell, XmNwidth, (int)width, XmNheight, (int)height, NULp);
1060 }
1061 
1063  XtVaSetValues(p_w->shell, XmNtitle, title, NULp);
1064  freedup(window_title, title);
1065 }
1066 
1067 const char* AW_window::get_window_title() const {
1068  return window_title;
1069 }
1070 
1071 void AW_window::shadow_width(int shadow_thickness) {
1072  _at->shadow_thickness = shadow_thickness;
1073 }
1074 
1075 void AW_window::button_height(int height) {
1076  _at->height_of_buttons = height>1 ? height : 0;
1077 }
1078 
1080  int width, height;
1081  get_window_size(width, height);
1082  set_window_size(width, height);
1083 }
1084 
1086  : recalc_size_at_show(AW_KEEP_SIZE),
1087  recalc_pos_at_show(AW_KEEP_POS),
1088  hide_cb(NULp),
1089  expose_callback_added(false),
1090  focus_cb(NULp),
1091  xfig_data(NULp),
1092  _at(new AW_at),
1093  left_indent_of_horizontal_scrollbar(0),
1094  top_indent_of_vertical_scrollbar(0),
1095  layout_reset_wanted(NULp),
1096  window_title(NULp),
1097  window_id(NULp),
1098  root(NULp),
1099  click_time(0),
1100  color_table_size(0),
1101  color_table(NULp),
1102  p_w(new AW_window_Motif),
1103  _callback(NULp),
1104  _d_callback(NULp),
1105  slider_pos_vertical(0),
1106  slider_pos_horizontal(0),
1107  window_is_shown(false),
1108  picture(new AW_screen_area)
1109 {
1111 }
1112 
1114  delete picture;
1115  delete p_w;
1116  delete hide_cb;
1117 }
1118 
1119 #if defined(DEBUG)
1120 // #define DUMP_MENU_LIST // this should NOT be defined normally (if defined, every window writes all menu-entries to stdout)
1121 #endif // DEBUG
1122 #if defined(DUMP_MENU_LIST)
1123 
1124 static char *window_name = 0;
1125 static char *sub_menu = 0;
1126 
1127 static void initMenuListing(const char *win_name) {
1128  aw_assert(win_name);
1129 
1130  freedup(window_name, win_name);
1131  freenull(sub_menu);
1132 
1133  printf("---------------------------------------- list of menus for '%s'\n", window_name);
1134 }
1135 
1136 static void dumpMenuEntry(const char *entry) {
1137  aw_assert(window_name);
1138  if (sub_menu) {
1139  printf("'%s/%s/%s'\n", window_name, sub_menu, entry);
1140  }
1141  else {
1142  printf("'%s/%s'\n", window_name, entry);
1143  }
1144 }
1145 
1146 static void dumpOpenSubMenu(const char *sub_name) {
1147  aw_assert(sub_name);
1148 
1149  dumpMenuEntry(sub_name); // dump the menu itself
1150 
1151  if (sub_menu) freeset(sub_menu, GBS_global_string_copy("%s/%s", sub_menu, sub_name));
1152  else sub_menu = strdup(sub_name);
1153 }
1154 
1155 static void dumpCloseSubMenu() {
1156  aw_assert(sub_menu);
1157  char *lslash = strrchr(sub_menu, '/');
1158  if (lslash) {
1159  lslash[0] = 0;
1160  }
1161  else freenull(sub_menu);
1162 }
1163 
1164 static void dumpCloseAllSubMenus() {
1165  freenull(sub_menu);
1166 }
1167 
1168 #endif // DUMP_MENU_LIST
1169 
1170 AW_window_menu_modes::AW_window_menu_modes() : AW_window_menu_modes_private(NULp) {}
1172 
1175 
1176 AW_window_simple::AW_window_simple() {}
1177 AW_window_simple::~AW_window_simple() {}
1178 
1181 
1184 
1185 #define LAYOUT_AWAR_ROOT "window/windows"
1186 
1187 static const char *local_layout_awarname(AW_window *aww, const char *sub_name) {
1188  return local_awarnamef(LAYOUT_AWAR_ROOT "/%s/%s", aww, sub_name);
1189 }
1190 
1191 #define local_posx_awarname(aww) local_layout_awarname((aww), "posx")
1192 #define local_posy_awarname(aww) local_layout_awarname((aww), "posy")
1193 #define local_width_awarname(aww) local_layout_awarname((aww), "width")
1194 #define local_height_awarname(aww) local_layout_awarname((aww), "height")
1195 #define local_reset_awarname(aww) local_layout_awarname((aww), "reset")
1196 
1197 void AW_window::create_user_geometry_awars(int posx, int posy, int width, int height) {
1198  get_root()->awar_int(local_posx_awarname(this), posx);
1199  get_root()->awar_int(local_posy_awarname(this), posy);
1200  get_root()->awar_int(local_width_awarname(this), width);
1201  get_root()->awar_int(local_height_awarname(this), height);
1202 
1203  if (layout_reset_wanted) {
1204  AW_awar *awar_reset = get_root()->awar_string(local_reset_awarname(this), "");
1205  const char *last_reset = awar_reset->read_char_pntr();
1206  int cmp = strcmp(last_reset, layout_reset_wanted);
1207  if (cmp) {
1208  awar_reset->write_string(layout_reset_wanted);
1209  reset_geometry_awars(); // (recalc_pos/size... calls would not be necessary here)
1210  }
1211  }
1212 }
1213 
1214 
1215 void AW_window::store_size_in_awars(int width, int height) {
1216  get_root()->awar(local_width_awarname(this))->write_int(width);
1217  get_root()->awar(local_height_awarname(this))->write_int(height);
1218 }
1219 
1220 void AW_window::get_size_from_awars(int& width, int& height) {
1221  width = get_root()->awar(local_width_awarname(this))->read_int();
1222  height = get_root()->awar(local_height_awarname(this))->read_int();
1223 }
1224 
1225 void AW_window::store_pos_in_awars(int posx, int posy) {
1226  get_root()->awar(local_posx_awarname(this))->write_int(posx);
1227  get_root()->awar(local_posy_awarname(this))->write_int(posy);
1228 }
1229 
1230 void AW_window::get_pos_from_awars(int& posx, int& posy) {
1231  posx = get_root()->awar(local_posx_awarname(this))->read_int();
1232  posy = get_root()->awar(local_posy_awarname(this))->read_int();
1233 }
1234 
1235 void AW_window::reset_geometry_awars() {
1236  AW_root *awr = get_root();
1237 
1242 
1245 }
1246 
1247 #undef local_posx_awarname
1248 #undef local_posy_awarname
1249 #undef local_width_awarname
1250 #undef local_height_awarname
1251 #undef local_reset_awarname
1252 
1253 static void aw_onExpose_calc_WM_offsets(AW_window *aww);
1255 
1257  AW_window_Motif *motif = p_aww(aww);
1258 
1259  int posx, posy; aww->get_window_content_pos(posx, posy);
1260 
1261  bool knows_window_position = posx != 0 || posy != 0;
1262 
1263  if (!knows_window_position) { // oops - motif has no idea where the window has been placed
1264  // assume positions stored in awars are correct and use them.
1265  // This works around problems with unclickable GUI-elements when running on 'Unity'
1266 
1267  int oposx, oposy; aww->get_pos_from_awars(oposx, oposy);
1268  aww->set_window_frame_pos(oposx, oposy);
1269 
1270  if (!motif->knows_WM_offset()) {
1271  aww->get_root()->add_timed_callback(100, makeTimedCallback(aw_calc_WM_offsets_delayed, aww));
1272  }
1273  }
1274  else if (!motif->knows_WM_offset()) {
1275  int oposx, oposy; aww->get_pos_from_awars(oposx, oposy);
1276 
1277  // calculate offset
1278  int left = posx-oposx;
1279  int top = posy-oposy;
1280 
1281  if (top == 0 || left == 0) { // invalid frame size
1282  if (motif->WM_left_offset == 0) {
1283  motif->WM_left_offset = 1; // hack: unused yet, use as flag to avoid endless repeats
1284 #if defined(TRACE_WM_OFFSETS)
1285  fprintf(stderr, "aw_onExpose_calc_WM_offsets: failed to detect framesize (shift window 1 pixel and retry)\n");
1286 #endif
1287  oposx = oposx>10 ? oposx-1 : oposx+1;
1288  oposy = oposy>10 ? oposy-1 : oposy+1;
1289 
1290  aww->set_window_frame_pos(oposx, oposy);
1291  aww->store_pos_in_awars(oposx, oposy);
1292 
1293  aww->get_root()->add_timed_callback(500, makeTimedCallback(aw_calc_WM_offsets_delayed, aww));
1294  return;
1295  }
1296  else {
1297  // use maximum seen frame size
1300 
1301  if (top == 0 || left == 0) { // still invalid -> retry later
1302  aww->get_root()->add_timed_callback(10000, makeTimedCallback(aw_calc_WM_offsets_delayed, aww));
1303  return;
1304  }
1305  }
1306  }
1307  motif->WM_top_offset = top;
1308  motif->WM_left_offset = left;
1309 
1310  // remember maximum seen offsets
1313 
1314 #if defined(TRACE_WM_OFFSETS)
1315  fprintf(stderr, "WM_top_offset=%i WM_left_offset=%i (pos from awar: %i/%i, content-pos: %i/%i)\n",
1316  motif->WM_top_offset, motif->WM_left_offset,
1317  oposx, oposy, posx, posy);
1318 #endif
1319  }
1320 }
1321 
1323  : last_widget(NULp),
1324  display(NULp),
1325  context(NULp),
1326  toplevel_widget(NULp),
1327  main_widget(NULp),
1328  main_aww(NULp),
1329  message_shell(NULp),
1330  foreground(0),
1331  background(0),
1332  fontlist(NULp),
1333  option_menu_list(NULp),
1334  last_option_menu(NULp),
1335  current_option_menu(NULp),
1336  toggle_field_list(NULp),
1337  last_toggle_field(NULp),
1338  selection_list(NULp),
1339  last_selection_list(NULp),
1340  screen_depth(0),
1341  color_table(NULp),
1342  colormap(0),
1343  help_active(0),
1344  clock_cursor(0),
1345  question_cursor(0),
1346  old_cursor_display(NULp),
1347  old_cursor_window(0),
1348  no_exit(false),
1349  action_hash(NULp)
1350 {}
1351 
1354  XmFontListFree(fontlist);
1355  free(color_table);
1356 }
1357 
1358 void AW_root_Motif::set_cursor(Display *d, Window w, Cursor c) {
1359  XSetWindowAttributes attrs;
1360  old_cursor_display = d;
1361  old_cursor_window = w;
1362 
1363  if (c)
1364  attrs.cursor = c;
1365  else
1366  attrs.cursor = None;
1367 
1368  if (d && w) {
1369  XChangeWindowAttributes(d, w, CWCursor, &attrs);
1370  }
1371  XChangeWindowAttributes(XtDisplay(main_widget), XtWindow(main_widget),
1372  CWCursor, &attrs);
1373  XFlush(XtDisplay(main_widget));
1374 }
1375 
1378 }
1379 
1380 void AW_server_callback(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer /*call_data*/) {
1381  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1382 
1383  AW_root *root = cbs->aw->get_root();
1384  if (p_global->help_active) {
1385  p_global->help_active = 0;
1386  p_global->normal_cursor();
1387 
1388  if (cbs->help_text && ((GBS_string_matches(cbs->help_text, "*.ps", GB_IGNORE_CASE)) ||
1389  (GBS_string_matches(cbs->help_text, "*.hlp", GB_IGNORE_CASE)) ||
1390  (GBS_string_matches(cbs->help_text, "*.help", GB_IGNORE_CASE))))
1391  {
1392  AW_help_popup(NULp, cbs->help_text);
1393  }
1394  else {
1395  aw_message("Sorry no help available");
1396  }
1397  return;
1398  }
1399 
1400  if (root->is_tracking()) root->track_action(cbs->id);
1401 
1402  p_global->set_cursor(XtDisplay(p_global->toplevel_widget),
1403  XtWindow(p_aww(cbs->aw)->shell),
1404  p_global->clock_cursor);
1405  cbs->run_callbacks();
1406 
1407  XEvent event; // destroy all old events !!!
1408  while (XCheckMaskEvent(XtDisplay(p_global->toplevel_widget),
1409  ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|
1410  KeyPressMask|KeyReleaseMask|PointerMotionMask, &event)) {
1411  }
1412 
1413  if (p_global->help_active) {
1414  p_global->set_cursor(XtDisplay(p_global->toplevel_widget),
1415  XtWindow(p_aww(cbs->aw)->shell),
1416  p_global->question_cursor);
1417  }
1418  else {
1419  p_global->set_cursor(XtDisplay(p_global->toplevel_widget),
1420  XtWindow(p_aww(cbs->aw)->shell),
1421  0);
1422  }
1423 }
1424 
1426  recalc_pos_at_show = pr;
1427 }
1428 
1430  return recalc_pos_at_show;
1431 }
1432 
1434  if (sr == AW_RESIZE_ANY) {
1435  sr = (recalc_size_at_show == AW_RESIZE_USER) ? AW_RESIZE_USER : AW_RESIZE_DEFAULT;
1436  }
1437  recalc_size_at_show = sr;
1438 }
1439 
1440 
1441 
1442 // --------------
1443 // focus
1444 
1445 
1447  if (focus_cb) focus_cb->run_callbacks();
1448 }
1449 
1451  return focus_cb && focus_cb->contains(f);
1452 }
1453 
1454 // ---------------
1455 // popup
1456 
1458  if (p_w->popup_cb) {
1460  }
1461 }
1462 
1463 // ---------------
1464 // expose
1465 
1467  if (expose_cb) expose_cb->run_callbacks();
1468 }
1469 
1470 static void AW_exposeCB(Widget /*wgt*/, XtPointer aw_cb_struct, XmDrawingAreaCallbackStruct *call_data) {
1471  XEvent *ev = call_data->event;
1472  AW_area_management *aram = (AW_area_management *) aw_cb_struct;
1473  if (ev->xexpose.count == 0) { // last expose cb
1474  aram->run_expose_callback();
1475  }
1476 }
1477 
1478 void AW_area_management::set_expose_callback(AW_window *aww, const WindowCallback& cb) {
1479  // insert expose callback for draw_area
1480  if (!expose_cb) {
1481  XtAddCallback(area, XmNexposeCallback, (XtCallbackProc) AW_exposeCB,
1482  (XtPointer) this);
1483  }
1484  expose_cb = new AW_cb(aww, cb, NULp, expose_cb);
1485 }
1486 
1488  return expose_cb && expose_cb->contains(f);
1489 }
1490 
1492  AW_area_management *aram = MAP_ARAM(area);
1493  return aram && aram->is_expose_callback(f);
1494 }
1495 
1497  XmDrawingAreaCallbackStruct da_struct;
1498 
1499  da_struct.reason = XmCR_EXPOSE;
1500  da_struct.event = NULp;
1501  da_struct.window = XtWindow(p_w->shell);
1502 
1503  XtCallCallbacks(p_w->shell, XmNexposeCallback, (XtPointer) &da_struct);
1504 }
1505 
1506 // ---------------
1507 // resize
1508 
1509 
1511  return resize_cb && resize_cb->contains(f);
1512 }
1513 
1515  AW_area_management *aram = MAP_ARAM(area);
1516  return aram && aram->is_resize_callback(f);
1517 }
1518 
1519 void AW_window::set_window_frame_pos(int x, int y) {
1520  // this will set the position of the frame around the client-area (see also WM_top_offset ..)
1521  XtVaSetValues(p_w->shell, XmNx, (int)x, XmNy, (int)y, NULp);
1522 }
1523 void AW_window::get_window_content_pos(int& xpos, int& ypos) {
1524  // this will report the position of the client-area (see also WM_top_offset ..)
1525  unsigned short x, y;
1526  XtVaGetValues(p_w->shell, XmNx, &x, XmNy, &y, NULp);
1527  xpos = x;
1528  ypos = y;
1529 }
1530 
1531 void AW_window::get_screen_size(int &width, int &height) {
1532  Screen *screen = XtScreen(p_w->shell);
1533 
1534  width = WidthOfScreen(screen);
1535  height = HeightOfScreen(screen);
1536 }
1537 
1538 bool AW_window::get_mouse_pos(int& x, int& y) {
1539  Display *d = XtDisplay(p_w->shell);
1540  Window w1 = XtWindow(p_w->shell);
1541  Window w2;
1542  Window w3;
1543  int rx, ry;
1544  int wx, wy;
1545  unsigned int mask;
1546 
1547  Bool ok = XQueryPointer(d, w1, &w2, &w3, &rx, &ry, &wx, &wy, &mask);
1548 
1549  if (ok) {
1550 #if defined(DEBUG) && 0
1551  printf("get_mouse_pos: rx/ry=%i/%i wx/wy=%i/%i\n", rx, ry, wx, wy);
1552 #endif // DEBUG
1553  x = rx;
1554  y = ry;
1555  }
1556  return ok;
1557 }
1558 
1559 static int is_resize_event(Display *display, XEvent *event, XPointer) {
1560  // Predicate function: checks, if the given event is a ResizeEvent
1561  if (event && (event->type == ResizeRequest || event->type
1562  == ConfigureNotify) && event->xany.display == display) {
1563  return 1;
1564  }
1565  return 0;
1566 }
1567 
1568 static void cleanupResizeEvents(Display *display) {
1569  // Removes redundant resize events from the x-event queue
1570  if (display) {
1571  XLockDisplay(display);
1572  XEvent event;
1573  if (XCheckIfEvent(display, &event, is_resize_event, NULp)) {
1574  // Some magic happens here... ;-) (removing redundant events from queue)
1575  while (XCheckIfEvent(display, &event, is_resize_event, NULp))
1576  ;
1577  // Keep last Event in queue
1578  XPutBackEvent(display, &event);
1579  }
1580  XUnlockDisplay(display);
1581  }
1582 }
1583 
1584 static void aw_window_avoid_destroy_cb(Widget, AW_window *, XmAnyCallbackStruct *) {
1585  aw_message("If YOU do not know what to answer, how should ARB know?\nPlease think again and answer the prompt!");
1586 }
1587 static void aw_window_noexit_destroy_cb(Widget, AW_window *aww, XmAnyCallbackStruct *) {
1588  if (aww->get_root()->is_tracking()) {
1589  aw_message("While recording a macro, you cannot use that [X] to hide this window.");
1590  }
1591  else {
1592  aww->hide();
1593  }
1594  // don't exit, when using destroy callback
1595 }
1596 static void aw_window_destroy_cb(Widget w, AW_window *aww, XmAnyCallbackStruct *) {
1597  AW_root *root = aww->get_root(); // used by p_global
1598  if ((p_global->main_aww == aww) || !p_global->main_aww->is_shown()) {
1599  if (root->is_tracking()) {
1600  aw_message("While recording a macro, you cannot use that [X] to quit.");
1601  }
1602  else {
1603 #ifdef NDEBUG
1604  if (!aw_ask_sure("quit_by_X", "Are you sure to quit?")) return;
1605 #endif
1606  exit(EXIT_SUCCESS);
1607  }
1608  }
1609  else {
1611  }
1612 }
1613 
1614 static void aw_set_delete_window_cb(AW_window *aww, Widget shell, bool allow_close) {
1615  Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(shell), (char*)"WM_DELETE_WINDOW", False);
1616 
1617  // remove any previous callbacks
1618  XmRemoveWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_avoid_destroy_cb, (caddr_t)aww);
1619  XmRemoveWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_noexit_destroy_cb, (caddr_t)aww);
1620  XmRemoveWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_destroy_cb, (caddr_t)aww);
1621 
1622  if (!allow_close) {
1623  XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_avoid_destroy_cb, (caddr_t)aww);
1624  }
1625  else {
1626  AW_root *root = aww->get_root();
1627  if (p_global->no_exit) {
1628  XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_noexit_destroy_cb, (caddr_t)aww);
1629  }
1630  else {
1631  XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc)aw_window_destroy_cb, (caddr_t)aww);
1632  }
1633  }
1634 }
1635 
1636 void AW_window::allow_delete_window(bool allow_close) {
1637  aw_set_delete_window_cb(this, p_w->shell, allow_close);
1638 }
1639 
1640 bool AW_window::is_shown() const {
1641  // return true if window is shown ( = not invisible and already created)
1642  // Note: does return TRUE!, if window is only minimized by WM
1643  return window_is_shown;
1644 }
1645 
1647  AW_window_Motif *motif = p_aww(aww);
1648 
1649  short posx, posy;
1650  unsigned short width, height, borderwidth;
1651  XtVaGetValues(motif->shell, // bad hack
1652  XmNborderWidth, &borderwidth,
1653  XmNwidth, &width,
1654  XmNheight, &height,
1655  XmNx, &posx,
1656  XmNy, &posy,
1657  NULp);
1658 
1659  if (motif->knows_WM_offset()) {
1660  posx -= motif->WM_left_offset;
1661  posy -= motif->WM_top_offset;
1662 
1663  if (posx<0) posx = 0;
1664  if (posy<0) posy = 0;
1665 
1666  aww->store_pos_in_awars(posx, posy);
1667  }
1668 #if defined(TRACE_WM_OFFSETS)
1669  else {
1670  fprintf(stderr, "Warning: WM_offsets unknown => did not update awars for window '%s'\n", aww->get_window_title());
1671  }
1672 #endif
1673  aww->store_size_in_awars(width, height);
1674 }
1675 
1677  bool was_shown = true;
1678  if (!window_is_shown) {
1679  all_menus_created();
1680  get_root()->window_show();
1681  window_is_shown = true;
1682  was_shown = false;
1683  }
1684 
1685  int width, height; // w/o window frame
1686  if (recalc_size_at_show != AW_KEEP_SIZE) {
1687  if (recalc_size_at_show == AW_RESIZE_DEFAULT) {
1688  // window ignores user-size (even if changed inside current session).
1689  // used for question boxes, user masks, ...
1690  window_fit();
1691  get_window_size(width, height);
1692  }
1693  else {
1694  aw_assert(recalc_size_at_show == AW_RESIZE_USER);
1695  // check whether user size is too small and increase to minimum window size
1696 
1697  int min_width, min_height; get_window_size(min_width, min_height);
1698  int user_width, user_height; get_size_from_awars(user_width, user_height);
1699 
1700  if (user_width <min_width) user_width = min_width;
1701  if (user_height<min_height) user_height = min_height;
1702 
1703  set_window_size(user_width, user_height); // restores user size
1704 
1705  width = user_width;
1706  height = user_height;
1707 
1708 #if defined(DEBUG)
1709  if (!was_shown) { // first popup
1710  // warn about too big default size
1711 #define LOWEST_SUPPORTED_SCREEN_X 1280 // @@@ this size is wrong when 'window/font' has changed (e.g. to "9x15bold")
1712 #define LOWEST_SUPPORTED_SCREEN_Y 800
1713 
1714  if (min_width>LOWEST_SUPPORTED_SCREEN_X || min_height>LOWEST_SUPPORTED_SCREEN_Y) {
1715  fprintf(stderr,
1716  "Warning: Window '%s' won't fit on %ix%i (win=%ix%i)\n",
1717  get_window_title(),
1718  LOWEST_SUPPORTED_SCREEN_X, LOWEST_SUPPORTED_SCREEN_Y,
1719  min_width, min_height);
1720 #if defined(DEVEL_RALF)
1721  aw_assert(0);
1722 #endif
1723  }
1724  }
1725 #endif
1726  }
1727  store_size_in_awars(width, height);
1728  recalc_size_at_show = AW_KEEP_SIZE;
1729  }
1730  else {
1731  get_window_size(width, height);
1732  }
1733 
1734  {
1735  int posx, posy;
1736  int swidth, sheight; get_screen_size(swidth, sheight);
1737  bool posIsFrame = false;
1738 
1739  switch (recalc_pos_at_show) {
1741  recalc_pos_at_show = AW_KEEP_POS;
1742  // fallthrough
1743  case AW_REPOS_TO_MOUSE: {
1744  int mx, my;
1745  if (!get_mouse_pos(mx, my)) goto FALLBACK_CENTER;
1746 
1747  posx = mx-width/2;
1748  posy = my-height/2;
1749  break;
1750  }
1751  case AW_REPOS_TO_CENTER:
1752  FALLBACK_CENTER:
1753  posx = (swidth-width)/2;
1754  posy = (sheight-height)/4;
1755  break;
1756 
1757  case AW_KEEP_POS:
1758  if (was_shown) {
1759  // user might have moved the window -> store (new) positions
1761  }
1762  get_pos_from_awars(posx, posy);
1763  get_size_from_awars(width, height);
1764  posIsFrame = true;
1765  break;
1766  }
1767 
1768  int frameWidth, frameHeight;
1769  if (p_w->knows_WM_offset()) {
1770  frameWidth = p_w->WM_left_offset;
1771  frameHeight = p_w->WM_top_offset;
1772  }
1773  else {
1774  // estimate
1775  frameWidth = AW_window_Motif::WM_max_left_offset + 1;
1776  frameHeight = AW_window_Motif::WM_max_top_offset + 1;
1777  }
1778 
1779  if (!posIsFrame) {
1780  posx -= frameWidth;
1781  posy -= frameHeight;
1782  posIsFrame = true;
1783  }
1784 
1785  // avoid windows outside of screen (or too near to screen-edges)
1786  {
1787  int maxx = swidth - 2*frameWidth - width;
1788  int maxy = sheight - frameWidth-frameHeight - height; // assumes lower border-width == frameWidth
1789 
1790  if (posx>maxx) posx = maxx;
1791  if (posy>maxy) posy = maxy;
1792 
1793  if (p_w->knows_WM_offset()) {
1794  if (posx<0) posx = 0;
1795  if (posy<0) posy = 0;
1796  }
1797  else {
1798  // workaround a bug leading to wrong WM-offsets (occurs when window-content is placed at screen-border)
1799  // shift window away from border
1800  if (posx<frameWidth) posx = frameWidth;
1801  if (posy<frameHeight) posy = frameHeight;
1802  }
1803  }
1804 
1805  aw_assert(implicated(p_w->knows_WM_offset(), posIsFrame));
1806 
1807  // store position and position window
1808  store_pos_in_awars(posx, posy);
1809  set_window_frame_pos(posx, posy);
1810  }
1811 
1812  XtPopup(p_w->shell, XtGrabNone);
1813  if (!was_shown) {
1815  }
1816  if (!expose_callback_added) {
1817  set_expose_callback(AW_INFO_AREA, aw_onExpose_calc_WM_offsets); // @@@ should be removed after it was called once
1818  expose_callback_added = true;
1819  }
1820 }
1821 
1824  get_root()->current_modal_window = this;
1825  activate();
1826 }
1827 
1829  if (window_is_shown) {
1831  if (hide_cb) (*hide_cb)(this);
1832  get_root()->window_hide(this);
1833  window_is_shown = false;
1834  }
1835  XtPopdown(p_w->shell);
1836 }
1837 
1839  if (error) aw_message(error);
1840  else hide();
1841 }
1842 
1843 void AW_window::on_hide(const WindowCallback& call_on_hide) {
1844  hide_cb = new WindowCallback(call_on_hide);
1845 }
1846 
1848  if (resize_cb) resize_cb->run_callbacks();
1849 }
1850 
1851 static void AW_resizeCB_draw_area(Widget /*wgt*/, XtPointer aw_cb_struct, XtPointer /*call_data*/) {
1852  AW_area_management *aram = (AW_area_management *) aw_cb_struct;
1854  aram->run_resize_callback();
1855 }
1856 
1857 void AW_area_management::set_resize_callback(AW_window *aww, const WindowCallback& cb) {
1858  // insert resize callback for draw_area
1859  if (!resize_cb) {
1860  XtAddCallback(area, XmNresizeCallback,
1861  (XtCallbackProc) AW_resizeCB_draw_area, (XtPointer) this);
1862  }
1863  resize_cb = new AW_cb(aww, cb, NULp, resize_cb);
1864 }
1865 
1866 // -------------------
1867 // user input
1868 
1869 
1870 static void AW_inputCB_draw_area(Widget wgt, XtPointer aw_cb_struct, XmDrawingAreaCallbackStruct *call_data) {
1871  XEvent *ev = call_data->event;
1872  AW_cb *cbs = (AW_cb *) aw_cb_struct;
1873  AW_window *aww = cbs->aw;
1874 
1875  bool run_callback = false;
1876  bool run_double_click_callback = false;
1877 
1878  AW_area_management *area = NULp;
1879  {
1880  int i;
1881  for (i=0; i<AW_MAX_AREA; i++) {
1882  if (p_aww(aww)->areas[i]->get_area() == wgt) {
1883  area = p_aww(aww)->areas[i];
1884  break;
1885  }
1886  }
1887  }
1888 
1889  if (ev->xbutton.type == ButtonPress || ev->xbutton.type == ButtonRelease) {
1890  AW_MouseButton currButton = AW_MouseButton(ev->xbutton.button);
1891 
1892  bool ignore_this_event = false;
1893  bool last_was_click_or_drag = aww->event.type == AW_Mouse_Press || aww->event.type == AW_Mouse_Drag;
1894 
1895  if (last_was_click_or_drag && aww->event.button == AW_BUTTON_MIDDLE) { // last event was drag with middle mouse button
1896  ignore_this_event = currButton != AW_BUTTON_MIDDLE; // then ignore all other mouse buttons until drag finished
1897  }
1898 
1899  if (!ignore_this_event) {
1900  aww->event.button = currButton;
1901  aww->event.x = ev->xbutton.x;
1902  aww->event.y = ev->xbutton.y;
1904  aww->event.keycode = AW_KEY_NONE;
1905  aww->event.character = '\0';
1906 
1907  if (ev->xbutton.type == ButtonPress) {
1908  aww->event.type = AW_Mouse_Press;
1909  if (area && area->get_double_click_cb()) {
1910  if ((ev->xbutton.time - area->get_click_time()) < 200) {
1911  run_double_click_callback = true;
1912  }
1913  else {
1914  run_callback = true;
1915  }
1916  area->set_click_time(ev->xbutton.time);
1917  }
1918  else {
1919  run_callback = true;
1920  }
1921  aww->event.time = ev->xbutton.time;
1922  }
1923  else if (ev->xbutton.type == ButtonRelease) {
1924  aww->event.type = AW_Mouse_Release;
1925  run_callback = true;
1926  // keep event.time set in ButtonPress-branch
1927  }
1928  }
1929  }
1930  else if (ev->xkey.type == KeyPress || ev->xkey.type == KeyRelease) {
1931  aww->event.time = ev->xbutton.time;
1932 
1933  const awXKeymap *mykey = aw_xkey_2_awkey(&(ev->xkey));
1934 
1935  aww->event.keycode = mykey->awkey;
1936  aww->event.keymodifier = mykey->awmod;
1937 
1938  if (mykey->awstr) {
1939  aww->event.character = mykey->awstr[0];
1940  }
1941  else {
1942  aww->event.character = 0;
1943  }
1944 
1945  if (ev->xkey.type == KeyPress) {
1946  aww->event.type = AW_Keyboard_Press;
1947  }
1948  else {
1950  }
1951  aww->event.button = AW_BUTTON_NONE;
1952  aww->event.x = ev->xbutton.x;
1953  aww->event.y = ev->xbutton.y;
1954 
1955  if (!mykey->awmod && mykey->awkey >= AW_KEY_F1 && mykey->awkey
1956  <= AW_KEY_F12 && p_aww(aww)->modes_f_callbacks && p_aww(aww)->modes_f_callbacks[mykey->awkey-AW_KEY_F1]
1957  && aww->event.type == AW_Keyboard_Press) {
1958  p_aww(aww)->modes_f_callbacks[mykey->awkey-AW_KEY_F1]->run_callbacks();
1959  }
1960  else {
1961  run_callback = true;
1962  }
1963  }
1964 
1965  if (run_double_click_callback) {
1966  if (cbs->help_text == (char*)1) {
1967  cbs->run_callbacks();
1968  }
1969  else {
1970  if (area)
1972  }
1973  }
1974 
1975  if (run_callback && !cbs->help_text) {
1976  cbs->run_callbacks();
1977  }
1978 }
1979 
1980 void AW_area_management::set_input_callback(AW_window *aww, const WindowCallback& wcb) {
1981  XtAddCallback(area, XmNinputCallback,
1982  (XtCallbackProc)AW_inputCB_draw_area,
1983  (XtPointer)new AW_cb(aww, wcb));
1984 }
1985 
1986 void AW_area_management::set_double_click_callback(AW_window *aww, const WindowCallback& wcb) {
1987  double_click_cb = new AW_cb(aww, wcb, NULp, double_click_cb);
1988 }
1989 
1990 void AW_window::set_double_click_callback(AW_area area, const WindowCallback& wcb) {
1991  AW_area_management *aram = MAP_ARAM(area);
1992  if (!aram)
1993  return;
1994  aram->set_double_click_callback(this, wcb);
1995 }
1996 
1997 // ---------------
1998 // motion
1999 
2000 static void AW_motionCB(Widget /*w*/, XtPointer aw_cb_struct, XEvent *ev, Boolean*) {
2001  AW_cb *cbs = (AW_cb *) aw_cb_struct;
2002 
2003  cbs->aw->event.type = AW_Mouse_Drag;
2004  cbs->aw->event.x = ev->xmotion.x;
2005  cbs->aw->event.y = ev->xmotion.y;
2006  cbs->aw->event.keycode = AW_KEY_NONE;
2007 
2008  cbs->run_callbacks();
2009 }
2010 void AW_area_management::set_motion_callback(AW_window *aww, const WindowCallback& wcb) {
2011  XtAddEventHandler(area, ButtonMotionMask, False,
2012  AW_motionCB, (XtPointer) new AW_cb(aww, wcb, ""));
2013 }
2014 static long destroy_awar(const char *, long val, void *) {
2015  AW_awar *awar = (AW_awar*)val;
2016  delete awar;
2017  return 0; // remove from hash
2018 }
2019 
2020 void AW_root::exit_variables() {
2025  }
2026 
2027  if (hash_for_windows) {
2030  }
2031 
2032  if (application_database) {
2033  GBDATA *prop_main = application_database;
2034  application_database = NULp;
2035  GB_close(prop_main);
2036  }
2037 }
2038 
2039 void AW_root::exit_root() {
2041 }
2042 
2044  AW_screen_area scrolled;
2045  get_scrollarea_size(&scrolled);
2046 
2047  if (orientation == AW_HORIZONTAL) {
2048  XtVaSetValues(p_w->scroll_bar_horizontal, XmNpageIncrement, (int)(scrolled.r*(local_awar("horizontal_page_increment")->read_int()*0.01)), NULp);
2049  XtVaSetValues(p_w->scroll_bar_horizontal, XmNincrement, (int)(local_awar("scroll_width_horizontal")->read_int()), NULp);
2050  XtVaSetValues(p_w->scroll_bar_horizontal, XmNrepeatDelay, (int)(local_awar("scroll_delay_horizontal")->read_int()), NULp);
2051  }
2052  else {
2053  XtVaSetValues(p_w->scroll_bar_vertical, XmNpageIncrement, (int)(scrolled.b*(local_awar("vertical_page_increment")->read_int()*0.01)), NULp);
2054  XtVaSetValues(p_w->scroll_bar_vertical, XmNincrement, (int)(local_awar("scroll_width_vertical")->read_int()), NULp);
2055  XtVaSetValues(p_w->scroll_bar_vertical, XmNrepeatDelay, (int)(local_awar("scroll_delay_vertical")->read_int()), NULp);
2056  }
2057 }
2058 
2060  AW_root *root = aww->get_root();
2061  common = new AW_common_Xm(XtDisplay(area), XtWindow(area), p_global->color_table, aww->color_table, aww->color_table_size, aww, ar);
2062 }
2063 
2064 AW_color_idx AW_window::alloc_named_data_color(int colnum, const char *colorname) {
2065  if (!color_table_size) {
2068  for (int i = 0; i<color_table_size; ++i) color_table[i] = AW_NO_COLOR;
2069  }
2070  else {
2071  if (colnum>=color_table_size) {
2072  long new_size = colnum+8;
2073  ARB_realloc(color_table, new_size);
2074  for (int i = color_table_size; i<new_size; ++i) {
2075  color_table[i] = AW_NO_COLOR;
2076  }
2077  color_table_size = new_size;
2078  }
2079  }
2080  XColor xcolor_returned, xcolor_exakt;
2081 
2082  if (p_global->screen_depth == 1) { // Black and White Monitor
2083  static int col = 1;
2084  if (colnum == AW_DATA_BG) {
2085  col = 1;
2086  if (strcmp(colorname, "white"))
2087  col *= -1;
2088  }
2089  if (col==1) {
2090  color_table[colnum] = WhitePixelOfScreen(XtScreen(p_global->toplevel_widget));
2091  }
2092  else {
2093  color_table[colnum] = BlackPixelOfScreen(XtScreen(p_global->toplevel_widget));
2094  }
2095  if (colnum == AW_DATA_BG)
2096  col *= -1;
2097  }
2098  else { // Color monitor
2099  if (color_table[colnum] != AW_NO_COLOR) {
2100  unsigned long color = color_table[colnum];
2101  XFreeColors(p_global->display, p_global->colormap, &color, 1, 0);
2102  }
2103  if (XAllocNamedColor(p_global->display, p_global->colormap, colorname, &xcolor_returned, &xcolor_exakt) == 0) {
2104  aw_message(GBS_global_string("XAllocColor failed: %s\n", colorname));
2105  color_table[colnum] = AW_NO_COLOR;
2106  }
2107  else {
2108  color_table[colnum] = xcolor_returned.pixel;
2109  }
2110  }
2111  if (colnum == AW_DATA_BG) {
2112  XtVaSetValues(p_w->areas[AW_MIDDLE_AREA]->get_area(), XmNbackground, color_table[colnum], NULp);
2113  }
2114  return (AW_color_idx)colnum;
2115 }
2116 
2118  unsigned long background_color;
2119  if (p_w->areas[AW_INFO_AREA]) {
2121  XtVaGetValues(p_w->areas[AW_INFO_AREA]->get_area(), XmNbackground, &background_color, NULp);
2122  p_global->color_table[AW_WINDOW_DRAG] = background_color ^ p_global->color_table[AW_WINDOW_FG];
2123  }
2124  if (p_w->areas[AW_MIDDLE_AREA]) {
2126  }
2127  if (p_w->areas[AW_BOTTOM_AREA]) {
2129  }
2130 }
2131 
2132 void aw_insert_default_help_entries(AW_window *aww) { // used externally from ../GL/glAW/AW_window_ogl.cxx
2133  aww->insert_help_topic("Click here and then on the questionable button/menu/...", "q", NULp, AWM_ALL, AW_help_entry_pressed);
2134 
2135  aww->insert_help_topic("How to use help", "H", "help.hlp", AWM_ALL, makeHelpCallback("help.hlp"));
2136  aww->insert_help_topic("ARB help", "A", "arb.hlp", AWM_ALL, makeHelpCallback("arb.hlp"));
2137 }
2138 
2139 inline char *strdup_getlen(const char *str, int& len) {
2140  len = strlen(str);
2141  return ARB_strduplen(str, len);
2142 }
2143 Label::Label(const char *labeltext, AW_window *aww) {
2144  imageref = AW_IS_IMAGEREF(labeltext);
2145  if (imageref) {
2146  label = strdup_getlen(AW_get_pixmapPath(labeltext+1), len);
2147  }
2148  else {
2149  AW_awar *is_awar = aww->get_root()->label_is_awar(labeltext);
2150 
2151  if (is_awar) { // for labels displaying awar values, insert dummy text here
2152  len = aww->get_at().length_of_buttons - 2;
2153  if (len < 1) len = 1;
2154 
2155  ARB_alloc(label, len+1);
2156  memset(label, 'y', len);
2157  label[len] = 0;
2158  }
2159  else {
2160  label = strdup_getlen(labeltext, len);
2161  }
2162  }
2163 }
2164 
2165 void AW_label_in_awar_list(AW_window *aww, Widget widget, const char *str) {
2166  AW_awar *is_awar = aww->get_root()->label_is_awar(str);
2167  if (is_awar) {
2168  char *display = is_awar->read_as_string();
2169 
2170  if (!display) {
2171  aw_assert(0); // awar not found
2172  freeset(display, GBS_global_string_copy("<undef AWAR: %s>", str));
2173  }
2174  if (!display[0]) freeset(display, strdup(" ")); // empty string causes wrong-sized buttons
2175 
2176  aww->update_label(widget, display);
2177  free(display);
2178 
2179  is_awar->tie_widget(0, widget, AW_WIDGET_LABEL_FIELD, aww);
2180  }
2181 }
2182 
2183 static void aw_loop_get_window_geometry(const char *, long val, void *) {
2185 }
2188 }
2189 
2190 static void aw_loop_forget_window_geometry(const char *, long val, void *) {
2191  ((AW_window*)val)->reset_geometry_awars();
2192 }
2194  AW_root *awr = aww->get_root();
2195  GBS_hash_do_const_loop(awr->hash_for_windows, aw_loop_forget_window_geometry, NULp); // reset geometry for used windows
2196 
2197  // reset geometry in stored, unused windows
2198  GBDATA *gb_props = awr->check_properties(NULp);
2199  GB_transaction ta(gb_props);
2200  GBDATA *gb_win = GB_search(gb_props, LAYOUT_AWAR_ROOT, GB_FIND);
2201  if (gb_win) {
2202  for (GBDATA *gbw = GB_child(gb_win); gbw; ) {
2203  const char *key = GB_read_key_pntr(gbw);
2204  long usedWin = GBS_read_hash(awr->hash_for_windows, key);
2205  GBDATA *gbnext = GB_nextChild(gbw);
2206 
2207  if (!usedWin) {
2208  GB_ERROR error = GB_delete(gbw);
2209  aw_message_if(error);
2210  }
2211  gbw = gbnext;
2212  }
2213  }
2214 }
2215 
2216 static const char *existingPixmap(const char *icon_relpath, const char *name) {
2217  const char *icon_relname = GBS_global_string("%s/%s.xpm", icon_relpath, name);
2218  const char *icon_fullname = AW_get_pixmapPath(icon_relname);
2219 
2220  if (!GB_is_regularfile(icon_fullname)) icon_fullname = NULp;
2221 
2222  return icon_fullname;
2223 }
2224 
2225 
2226 static Pixmap getIcon(Screen *screen, const char *iconName, Pixel foreground, Pixel background) {
2227  static SmartCustomPtr(GB_HASH, GBS_free_hash) icon_hash;
2228  if (icon_hash.isNull()) {
2229  icon_hash = GBS_create_hash(100, GB_MIND_CASE);
2230  }
2231 
2232  Pixmap pixmap = GBS_read_hash(&*icon_hash, iconName);
2233 
2234  if (!pixmap && iconName) {
2235  const char *iconFile = existingPixmap("icons", iconName);
2236 
2237  if (iconFile) {
2238  char *ico = strdup(iconFile);
2239  pixmap = XmGetPixmap(screen, ico, foreground, background);
2240  GBS_write_hash(&*icon_hash, iconName, pixmap);
2241  free(ico);
2242  }
2243  }
2244 
2245  return pixmap;
2246 }
2247 
2248 STATIC_ASSERT_ANNOTATED(CopyFromParent == 0, "value of CopyFromParent changed. Check use below");
2249 #define CopyFromParent_AsPtr NULp
2250 
2251 Widget aw_create_shell(AW_window *aww, bool allow_resize, bool allow_close, int width, int height, int posx, int posy) { // @@@ move into class AW_window?
2252  AW_root *root = aww->get_root();
2253  Widget shell;
2254 
2255  // set minimum window size to size provided by init
2256  if (width >aww->get_at().max_x_size) aww->get_at().max_x_size = width;
2257  if (height>aww->get_at().max_y_size) aww->get_at().max_y_size = height;
2258 
2259  bool has_user_geometry = false;
2260  if (!GBS_read_hash(root->hash_for_windows, aww->get_window_id())) {
2261  GBS_write_hash(root->hash_for_windows, aww->get_window_id(), (long)aww);
2262 
2263  aww->create_user_geometry_awars(posx, posy, width, height);
2264  }
2265  {
2266  int user_width, user_height; aww->get_size_from_awars(user_width, user_height);
2267  int user_posx, user_posy; aww->get_pos_from_awars(user_posx, user_posy);
2268 
2269  if (allow_resize) {
2270  if (width != user_width) { width = user_width; has_user_geometry = true; }
2271  if (height != user_height) { height = user_height; has_user_geometry = true; }
2272  }
2273 
2274  // @@@ FIXME: maximum should be set to current screen size minus some offset
2275  // to ensure that windows do not appear outside screen
2276  if (posx != user_posx) { posx = user_posx; has_user_geometry = true; }
2277  if (posy != user_posy) { posy = user_posy; has_user_geometry = true; }
2278 
2279  if (has_user_geometry) {
2280  aww->recalc_size_atShow(AW_RESIZE_USER); // keep user geometry (only if user size is smaller than default size, the latter is used)
2281  }
2282  else { // no geometry yet
2283  aww->recalc_pos_atShow(AW_REPOS_TO_MOUSE_ONCE); // popup the window at current mouse position
2284  }
2285  }
2286 
2287  if (allow_resize) {
2288  // create the window big enough to ensure that all widgets
2289  // are created in visible area (otherwise widget are crippled).
2290  // window will be resized later (on show)
2291 
2292  width = WIDER_THAN_SCREEN;
2293  height = HIGHER_THAN_SCREEN;
2294 
2296  }
2297 
2298  Widget father = p_global->toplevel_widget;
2299  Screen *screen = XtScreen(father);
2300  Pixmap icon_pixmap = getIcon(screen, aww->get_window_id(), p_global->foreground, p_global->background);
2301 
2302  if (!icon_pixmap) {
2303  icon_pixmap = getIcon(screen, root->program_name, p_global->foreground, p_global->background);
2304  }
2305 
2306  if (!icon_pixmap) {
2307  GBK_terminatef("Missing icon pixmap for window '%s'\n", aww->get_window_id());
2308  }
2309  else if (icon_pixmap == XmUNSPECIFIED_PIXMAP) {
2310  GBK_terminatef("Failed to load icon pixmap for window '%s'\n", aww->get_window_id());
2311  }
2312 
2313  int focusPolicy = root->focus_follows_mouse ? XmPOINTER : XmEXPLICIT;
2314 
2315  {
2316  aw_xargs args(9);
2317 
2318  args.add(XmNwidth, width);
2319  args.add(XmNheight, height);
2320  args.add(XmNx, posx);
2321  args.add(XmNy, posy);
2322  args.add(XmNtitle, (XtArgVal)aww->get_window_title());
2323  args.add(XmNiconName, (XtArgVal)aww->get_window_title());
2324  args.add(XmNkeyboardFocusPolicy, focusPolicy);
2325  args.add(XmNdeleteResponse, XmDO_NOTHING);
2326  args.add(XtNiconPixmap, icon_pixmap);
2327 
2328  if (!p_global->main_widget || !p_global->main_aww->is_shown()) {
2329  shell = XtCreatePopupShell("editor", applicationShellWidgetClass, father, args.list(), args.size());
2330  }
2331  else {
2332  shell = XtCreatePopupShell("transient", transientShellWidgetClass, father, args.list(), args.size());
2333  }
2334  }
2335 
2336  if (!p_global->main_widget) {
2337  p_global->main_widget = shell;
2338  p_global->main_aww = aww;
2339  }
2340  else {
2341  if (!p_global->main_aww->is_shown()) { // now i am the root window
2342  p_global->main_widget = shell;
2343  p_global->main_aww = aww;
2344  }
2345  }
2346 
2347  aw_set_delete_window_cb(aww, shell, allow_close);
2348 
2349  // set icon window (for window managers where iconified applications are dropped onto desktop or similar)
2350  {
2351  Window icon_window;
2352  XtVaGetValues(shell, XmNiconWindow, &icon_window, NULp);
2353 
2354  Display *dpy = XtDisplay(shell);
2355  if (!icon_window) {
2356  XSetWindowAttributes attr;
2357  attr.background_pixmap = icon_pixmap;
2358 
2359  int xpos, ypos;
2360  unsigned int xsize, ysize, borderwidth, depth;
2361  Window wroot;
2362 
2363  if (XGetGeometry(dpy, icon_pixmap, &wroot, &xpos, &ypos, &xsize, &ysize, &borderwidth, &depth)) {
2364  icon_window = XCreateWindow(dpy, wroot, 0, 0, xsize, ysize, 0, depth, CopyFromParent, CopyFromParent_AsPtr, CWBackPixmap, &attr);
2365  }
2366  }
2367  if (!icon_window) {
2368  XtVaSetValues(shell, XmNiconPixmap, icon_pixmap, NULp);
2369  }
2370  else {
2371  XtVaSetValues(shell, XmNiconWindow, icon_window, NULp);
2372  XSetWindowBackgroundPixmap(dpy, icon_window, icon_pixmap);
2373  XClearWindow(dpy, icon_window);
2374  }
2375  }
2376 
2377  return shell;
2378 }
2379 
2380 
2381 void aw_realize_widget(AW_window *aww) { // used externally from ../GL/glAW/AW_window_ogl.cxx
2382  if (p_aww(aww)->areas[AW_INFO_AREA] && p_aww(aww)->areas[AW_INFO_AREA]->get_form()) {
2383  XtManageChild(p_aww(aww)->areas[AW_INFO_AREA]->get_form());
2384  }
2385  if (p_aww(aww)->areas[AW_MIDDLE_AREA] && p_aww(aww)->areas[AW_MIDDLE_AREA]->get_form()) {
2386  XtManageChild(p_aww(aww)->areas[AW_MIDDLE_AREA]->get_form());
2387  }
2388  if (p_aww(aww)->areas[AW_BOTTOM_AREA] && p_aww(aww)->areas[AW_BOTTOM_AREA]->get_form()) {
2389  XtManageChild(p_aww(aww)->areas[AW_BOTTOM_AREA]->get_form());
2390  }
2391  XtRealizeWidget(p_aww(aww)->shell);
2392  p_aww(aww)->WM_top_offset = AW_CALC_OFFSET_ON_EXPOSE;
2393 }
2394 
2395 void AW_window::set_title_and_id(const char *title, const char *id) {
2396  window_title = strdup(title);
2397  window_id = GBS_string_2_key(id);
2398 }
2399 
2400 void AW_window_menu_modes::init(AW_root *root_in, const char *wid, const char *windowname, int width, int height) {
2401  Widget main_window;
2402  Widget help_popup;
2403  Widget help_label;
2404  Widget separator;
2405  Widget form1;
2406  Widget form2;
2407  const char *help_button = "HELP";
2408  const char *help_mnemonic = "H";
2409 
2410 #if defined(DUMP_MENU_LIST)
2411  initMenuListing(windowname);
2412 #endif // DUMP_MENU_LIST
2413  root = root_in; // for macro
2414  set_title_and_id(windowname, wid);
2415 
2416  int posx = 50;
2417  int posy = 50;
2418 
2419  p_w->shell = aw_create_shell(this, true, true, width, height, posx, posy);
2420 
2421  main_window = XtVaCreateManagedWidget("mainWindow1",
2422  xmMainWindowWidgetClass, p_w->shell,
2423  NULp);
2424 
2425  p_w->menu_bar[0] = XtVaCreateManagedWidget("menu1", xmRowColumnWidgetClass,
2426  main_window,
2427  XmNrowColumnType, XmMENU_BAR,
2428  NULp);
2429 
2430  // create shell for help-cascade
2431  help_popup = XtVaCreatePopupShell("menu_shell", xmMenuShellWidgetClass,
2432  p_w->menu_bar[0],
2433  XmNwidth, 1,
2434  XmNheight, 1,
2435  XmNallowShellResize, true,
2436  XmNoverrideRedirect, true,
2437  NULp);
2438 
2439  // create row column in Pull-Down shell
2440  p_w->help_pull_down = XtVaCreateWidget("menu_row_column",
2441  xmRowColumnWidgetClass, help_popup,
2442  XmNrowColumnType, XmMENU_PULLDOWN,
2443  NULp);
2444 
2445  // create HELP-label in menu bar
2446  help_label = XtVaCreateManagedWidget("menu1_top_b1",
2447  xmCascadeButtonWidgetClass, p_w->menu_bar[0],
2448  RES_CONVERT(XmNlabelString, help_button),
2449  RES_CONVERT(XmNmnemonic, help_mnemonic),
2450  XmNsubMenuId, p_w->help_pull_down, NULp);
2451  XtVaSetValues(p_w->menu_bar[0], XmNmenuHelpWidget, help_label, NULp);
2452  root->make_sensitive(help_label, AWM_ALL);
2453 
2454  form1 = XtVaCreateManagedWidget("form1",
2455  xmFormWidgetClass,
2456  main_window,
2457  // XmNwidth, width,
2458  // XmNheight, height,
2459  XmNresizePolicy, XmRESIZE_NONE,
2460  // XmNx, 0,
2461  // XmNy, 0,
2462  NULp);
2463 
2464  p_w->mode_area = XtVaCreateManagedWidget("mode area",
2465  xmDrawingAreaWidgetClass,
2466  form1,
2467  XmNresizePolicy, XmRESIZE_NONE,
2468  XmNwidth, 38,
2469  XmNheight, height,
2470  XmNx, 0,
2471  XmNy, 0,
2472  XmNleftOffset, 0,
2473  XmNtopOffset, 0,
2474  XmNbottomAttachment, XmATTACH_FORM,
2475  XmNleftAttachment, XmATTACH_POSITION,
2476  XmNtopAttachment, XmATTACH_POSITION,
2477  XmNmarginHeight, 2,
2478  XmNmarginWidth, 1,
2479  NULp);
2480 
2481  separator = XtVaCreateManagedWidget("separator",
2482  xmSeparatorWidgetClass,
2483  form1,
2484  XmNx, 37,
2485  XmNshadowThickness, 4,
2486  XmNorientation, XmVERTICAL,
2487  XmNbottomAttachment, XmATTACH_FORM,
2488  XmNtopAttachment, XmATTACH_FORM,
2489  XmNleftAttachment, XmATTACH_NONE,
2490  XmNleftWidget, NULp,
2491  XmNrightAttachment, XmATTACH_NONE,
2492  XmNleftOffset, 70,
2493  XmNleftPosition, 0,
2494  NULp);
2495 
2496  form2 = XtVaCreateManagedWidget("form2",
2497  xmFormWidgetClass,
2498  form1,
2499  XmNwidth, width,
2500  XmNheight, height,
2501  XmNtopOffset, 0,
2502  XmNbottomOffset, 0,
2503  XmNleftOffset, 0,
2504  XmNrightOffset, 0,
2505  XmNrightAttachment, XmATTACH_FORM,
2506  XmNbottomAttachment, XmATTACH_FORM,
2507  XmNleftAttachment, XmATTACH_WIDGET,
2508  XmNleftWidget, separator,
2509  XmNtopAttachment, XmATTACH_POSITION,
2510  XmNresizePolicy, XmRESIZE_NONE,
2511  XmNx, 0,
2512  XmNy, 0,
2513  NULp);
2514  p_w->areas[AW_INFO_AREA] =
2515  new AW_area_management(form2, XtVaCreateManagedWidget("info_area",
2516  xmDrawingAreaWidgetClass,
2517  form2,
2518  XmNheight, 0,
2519  XmNbottomAttachment, XmATTACH_NONE,
2520  XmNtopAttachment, XmATTACH_FORM,
2521  XmNleftAttachment, XmATTACH_FORM,
2522  XmNrightAttachment, XmATTACH_FORM,
2523  XmNmarginHeight, 2,
2524  XmNmarginWidth, 2,
2525  NULp));
2526 
2528  new AW_area_management(form2, XtVaCreateManagedWidget("bottom_area",
2529  xmDrawingAreaWidgetClass,
2530  form2,
2531  XmNheight, 0,
2532  XmNbottomAttachment, XmATTACH_FORM,
2533  XmNtopAttachment, XmATTACH_NONE,
2534  XmNleftAttachment, XmATTACH_FORM,
2535  XmNrightAttachment, XmATTACH_FORM,
2536  NULp));
2537 
2538  p_w->scroll_bar_horizontal = XtVaCreateManagedWidget("scroll_bar_horizontal",
2539  xmScrollBarWidgetClass,
2540  form2,
2541  XmNheight, 15,
2542  XmNminimum, 0,
2543  XmNmaximum, AW_SCROLL_MAX,
2544  XmNincrement, 10,
2545  XmNsliderSize, AW_SCROLL_MAX,
2546  XmNrightAttachment, XmATTACH_FORM,
2547  XmNbottomAttachment, XmATTACH_FORM,
2548  XmNbottomOffset, 0,
2549  XmNleftAttachment, XmATTACH_FORM,
2550  XmNtopAttachment, XmATTACH_NONE,
2551  XmNorientation, XmHORIZONTAL,
2552  XmNrightOffset, 18,
2553  NULp);
2554 
2555  p_w->scroll_bar_vertical = XtVaCreateManagedWidget("scroll_bar_vertical",
2556  xmScrollBarWidgetClass,
2557  form2,
2558  XmNwidth, 15,
2559  XmNminimum, 0,
2560  XmNmaximum, AW_SCROLL_MAX,
2561  XmNincrement, 10,
2562  XmNsliderSize, AW_SCROLL_MAX,
2563  XmNrightAttachment, XmATTACH_FORM,
2564  XmNbottomAttachment, XmATTACH_WIDGET,
2565  XmNbottomWidget, p_w->scroll_bar_horizontal,
2566  XmNbottomOffset, 3,
2567  XmNleftOffset, 3,
2568  XmNrightOffset, 3,
2569  XmNleftAttachment, XmATTACH_NONE,
2570  XmNtopAttachment, XmATTACH_WIDGET,
2571  XmNtopWidget, INFO_WIDGET,
2572  NULp);
2573 
2574  p_w->frame = XtVaCreateManagedWidget("draw_area",
2575  xmFrameWidgetClass,
2576  form2,
2577  XmNshadowType, XmSHADOW_IN,
2578  XmNshadowThickness, 2,
2579  XmNleftOffset, 3,
2580  XmNtopOffset, 3,
2581  XmNbottomOffset, 3,
2582  XmNrightOffset, 3,
2583  XmNbottomAttachment, XmATTACH_WIDGET,
2584  XmNbottomWidget, p_w->scroll_bar_horizontal,
2585  XmNtopAttachment, XmATTACH_FORM,
2586  XmNtopOffset, 0,
2587  XmNleftAttachment, XmATTACH_FORM,
2588  XmNrightAttachment, XmATTACH_WIDGET,
2589  XmNrightWidget, p_w->scroll_bar_vertical,
2590  NULp);
2591 
2593  new AW_area_management(p_w->frame, XtVaCreateManagedWidget("draw area",
2594  xmDrawingAreaWidgetClass,
2595  p_w->frame,
2596  XmNmarginHeight, 0,
2597  XmNmarginWidth, 0,
2598  NULp));
2599 
2600  XmMainWindowSetAreas(main_window, p_w->menu_bar[0], Widget(NULp), Widget(NULp), Widget(NULp), form1);
2601 
2602  aw_realize_widget(this);
2603 
2604  create_devices();
2607 }
2608 
2609 void AW_window_menu::init(AW_root *root_in, const char *wid, const char *windowname, int width, int height) {
2610  Widget main_window;
2611  Widget help_popup;
2612  Widget help_label;
2613  Widget separator;
2614  Widget form1;
2615  Widget form2;
2616  const char *help_button = "HELP";
2617  const char *help_mnemonic = "H";
2618 
2619 #if defined(DUMP_MENU_LIST)
2620  initMenuListing(windowname);
2621 #endif // DUMP_MENU_LIST
2622  root = root_in; // for macro
2623  set_title_and_id(windowname, wid);
2624 
2625  int posx = 50;
2626  int posy = 50;
2627 
2628  p_w->shell = aw_create_shell(this, true, true, width, height, posx, posy);
2629 
2630  main_window = XtVaCreateManagedWidget("mainWindow1",
2631  xmMainWindowWidgetClass, p_w->shell,
2632  NULp);
2633 
2634  p_w->menu_bar[0] = XtVaCreateManagedWidget("menu1", xmRowColumnWidgetClass,
2635  main_window,
2636  XmNrowColumnType, XmMENU_BAR,
2637  NULp);
2638 
2639  // create shell for help-cascade
2640  help_popup = XtVaCreatePopupShell("menu_shell", xmMenuShellWidgetClass,
2641  p_w->menu_bar[0],
2642  XmNwidth, 1,
2643  XmNheight, 1,
2644  XmNallowShellResize, true,
2645  XmNoverrideRedirect, true,
2646  NULp);
2647 
2648  // create row column in Pull-Down shell
2649  p_w->help_pull_down = XtVaCreateWidget("menu_row_column",
2650  xmRowColumnWidgetClass, help_popup,
2651  XmNrowColumnType, XmMENU_PULLDOWN,
2652  NULp);
2653 
2654  // create HELP-label in menu bar
2655  help_label = XtVaCreateManagedWidget("menu1_top_b1",
2656  xmCascadeButtonWidgetClass, p_w->menu_bar[0],
2657  RES_CONVERT(XmNlabelString, help_button),
2658  RES_CONVERT(XmNmnemonic, help_mnemonic),
2659  XmNsubMenuId, p_w->help_pull_down, NULp);
2660  XtVaSetValues(p_w->menu_bar[0], XmNmenuHelpWidget, help_label, NULp);
2661  root->make_sensitive(help_label, AWM_ALL);
2662 
2663  form1 = XtVaCreateManagedWidget("form1",
2664  xmFormWidgetClass,
2665  main_window,
2666  // XmNwidth, width,
2667  // XmNheight, height,
2668  XmNresizePolicy, XmRESIZE_NONE,
2669  // XmNx, 0,
2670  // XmNy, 0,
2671  NULp);
2672 
2673  p_w->mode_area = XtVaCreateManagedWidget("mode area",
2674  xmDrawingAreaWidgetClass,
2675  form1,
2676  XmNresizePolicy, XmRESIZE_NONE,
2677  XmNwidth, 17,
2678  XmNheight, height,
2679  XmNx, 0,
2680  XmNy, 0,
2681  XmNleftOffset, 0,
2682  XmNtopOffset, 0,
2683  XmNbottomAttachment, XmATTACH_FORM,
2684  XmNleftAttachment, XmATTACH_POSITION,
2685  XmNtopAttachment, XmATTACH_POSITION,
2686  XmNmarginHeight, 2,
2687  XmNmarginWidth, 1,
2688  NULp);
2689 
2690  separator = p_w->mode_area;
2691 
2692  form2 = XtVaCreateManagedWidget("form2",
2693  xmFormWidgetClass,
2694  form1,
2695  XmNwidth, width,
2696  XmNheight, height,
2697  XmNtopOffset, 0,
2698  XmNbottomOffset, 0,
2699  XmNleftOffset, 0,
2700  XmNrightOffset, 0,
2701  XmNrightAttachment, XmATTACH_FORM,
2702  XmNbottomAttachment, XmATTACH_FORM,
2703  XmNleftAttachment, XmATTACH_WIDGET,
2704  XmNleftWidget, separator,
2705  XmNtopAttachment, XmATTACH_POSITION,
2706  XmNresizePolicy, XmRESIZE_NONE,
2707  XmNx, 0,
2708  XmNy, 0,
2709  NULp);
2710  p_w->areas[AW_INFO_AREA] =
2711  new AW_area_management(form2, XtVaCreateManagedWidget("info_area",
2712  xmDrawingAreaWidgetClass,
2713  form2,
2714  XmNheight, 0,
2715  XmNbottomAttachment, XmATTACH_NONE,
2716  XmNtopAttachment, XmATTACH_FORM,
2717  XmNleftAttachment, XmATTACH_FORM,
2718  XmNrightAttachment, XmATTACH_FORM,
2719  XmNmarginHeight, 2,
2720  XmNmarginWidth, 2,
2721  NULp));
2722 
2724  new AW_area_management(form2, XtVaCreateManagedWidget("bottom_area",
2725  xmDrawingAreaWidgetClass,
2726  form2,
2727  XmNheight, 0,
2728  XmNbottomAttachment, XmATTACH_FORM,
2729  XmNtopAttachment, XmATTACH_NONE,
2730  XmNleftAttachment, XmATTACH_FORM,
2731  XmNrightAttachment, XmATTACH_FORM,
2732  NULp));
2733 
2734  p_w->scroll_bar_horizontal = XtVaCreateManagedWidget("scroll_bar_horizontal",
2735  xmScrollBarWidgetClass,
2736  form2,
2737  XmNheight, 15,
2738  XmNminimum, 0,
2739  XmNmaximum, AW_SCROLL_MAX,
2740  XmNincrement, 10,
2741  XmNsliderSize, AW_SCROLL_MAX,
2742  XmNrightAttachment, XmATTACH_FORM,
2743  XmNbottomAttachment, XmATTACH_FORM,
2744  XmNbottomOffset, 0,
2745  XmNleftAttachment, XmATTACH_FORM,
2746  XmNtopAttachment, XmATTACH_NONE,
2747  XmNorientation, XmHORIZONTAL,
2748  XmNrightOffset, 18,
2749  NULp);
2750 
2751  p_w->scroll_bar_vertical = XtVaCreateManagedWidget("scroll_bar_vertical",
2752  xmScrollBarWidgetClass,
2753  form2,
2754  XmNwidth, 15,
2755  XmNminimum, 0,
2756  XmNmaximum, AW_SCROLL_MAX,
2757  XmNincrement, 10,
2758  XmNsliderSize, AW_SCROLL_MAX,
2759  XmNrightAttachment, XmATTACH_FORM,
2760  XmNbottomAttachment, XmATTACH_WIDGET,
2761  XmNbottomWidget, p_w->scroll_bar_horizontal,
2762  XmNbottomOffset, 3,
2763  XmNleftOffset, 3,
2764  XmNrightOffset, 3,
2765  XmNleftAttachment, XmATTACH_NONE,
2766  XmNtopAttachment, XmATTACH_WIDGET,
2767  XmNtopWidget, INFO_WIDGET,
2768  NULp);
2769 
2770  p_w->frame = XtVaCreateManagedWidget("draw_area",
2771  xmFrameWidgetClass,
2772  form2,
2773  XmNshadowType, XmSHADOW_IN,
2774  XmNshadowThickness, 2,
2775  XmNleftOffset, 3,
2776  XmNtopOffset, 3,
2777  XmNbottomOffset, 3,
2778  XmNrightOffset, 3,
2779  XmNbottomAttachment, XmATTACH_WIDGET,
2780  XmNbottomWidget, p_w->scroll_bar_horizontal,
2781  XmNtopAttachment, XmATTACH_FORM,
2782  XmNtopOffset, 0,
2783  XmNleftAttachment, XmATTACH_FORM,
2784  XmNrightAttachment, XmATTACH_WIDGET,
2785  XmNrightWidget, p_w->scroll_bar_vertical,
2786  NULp);
2787 
2789  new AW_area_management(p_w->frame, XtVaCreateManagedWidget("draw area",
2790  xmDrawingAreaWidgetClass,
2791  p_w->frame,
2792  XmNmarginHeight, 0,
2793  XmNmarginWidth, 0,
2794  NULp));
2795 
2796  XmMainWindowSetAreas(main_window, p_w->menu_bar[0], Widget(NULp), Widget(NULp), Widget(NULp), form1);
2797 
2798  aw_realize_widget(this);
2799 
2800  create_devices();
2803 }
2804 
2805 void AW_window_simple::init(AW_root *root_in, const char *wid, const char *windowname) {
2806  root = root_in; // for macro
2807 
2808  int width = 100; // this is only the minimum size!
2809  int height = 100;
2810  int posx = 50;
2811  int posy = 50;
2812 
2813  set_title_and_id(windowname, wid);
2814 
2815  p_w->shell = aw_create_shell(this, true, true, width, height, posx, posy);
2816 
2817  // add this to disable resize or maximize in simple dialogs (avoids broken layouts)
2818  // XtVaSetValues(p_w->shell, XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE, NULp);
2819 
2820  Widget form1 = XtVaCreateManagedWidget("forms", xmFormWidgetClass,
2821  p_w->shell,
2822  NULp);
2823 
2824  p_w->areas[AW_INFO_AREA] =
2825  new AW_area_management(form1, XtVaCreateManagedWidget("info_area",
2826  xmDrawingAreaWidgetClass,
2827  form1,
2828  XmNbottomAttachment, XmATTACH_FORM,
2829  XmNtopAttachment, XmATTACH_FORM,
2830  XmNleftAttachment, XmATTACH_FORM,
2831  XmNrightAttachment, XmATTACH_FORM,
2832  XmNmarginHeight, 2,
2833  XmNmarginWidth, 2,
2834  NULp));
2835 
2836  aw_realize_widget(this);
2837  create_devices();
2838 }
2839 
2840 void AW_window_simple_menu::init(AW_root *root_in, const char *wid, const char *windowname) {
2841  root = root_in; // for macro
2842 
2843  const char *help_button = "HELP";
2844  const char *help_mnemonic = "H";
2845 
2846  set_title_and_id(windowname, wid);
2847 
2848  int width = 100;
2849  int height = 100;
2850  int posx = 50;
2851  int posy = 50;
2852 
2853  p_w->shell = aw_create_shell(this, true, true, width, height, posx, posy);
2854 
2855  Widget main_window;
2856  Widget help_popup;
2857  Widget help_label;
2858  Widget form1;
2859 
2860  main_window = XtVaCreateManagedWidget("mainWindow1",
2861  xmMainWindowWidgetClass, p_w->shell,
2862  NULp);
2863 
2864  p_w->menu_bar[0] = XtVaCreateManagedWidget("menu1", xmRowColumnWidgetClass,
2865  main_window,
2866  XmNrowColumnType, XmMENU_BAR,
2867  NULp);
2868 
2869  // create shell for help-cascade
2870  help_popup = XtVaCreatePopupShell("menu_shell", xmMenuShellWidgetClass,
2871  p_w->menu_bar[0],
2872  XmNwidth, 1,
2873  XmNheight, 1,
2874  XmNallowShellResize, true,
2875  XmNoverrideRedirect, true,
2876  NULp);
2877 
2878  // create row column in Pull-Down shell
2879  p_w->help_pull_down = XtVaCreateWidget("menu_row_column",
2880  xmRowColumnWidgetClass, help_popup,
2881  XmNrowColumnType, XmMENU_PULLDOWN,
2882  NULp);
2883 
2884  // create HELP-label in menu bar
2885  help_label = XtVaCreateManagedWidget("menu1_top_b1",
2886  xmCascadeButtonWidgetClass, p_w->menu_bar[0],
2887  RES_CONVERT(XmNlabelString, help_button),
2888  RES_CONVERT(XmNmnemonic, help_mnemonic),
2889  XmNsubMenuId, p_w->help_pull_down, NULp);
2890  XtVaSetValues(p_w->menu_bar[0], XmNmenuHelpWidget, help_label, NULp);
2891  root->make_sensitive(help_label, AWM_ALL);
2892 
2893  form1 = XtVaCreateManagedWidget("form1",
2894  xmFormWidgetClass,
2895  main_window,
2896  XmNtopOffset, 10,
2897  XmNresizePolicy, XmRESIZE_NONE,
2898  NULp);
2899 
2900  p_w->areas[AW_INFO_AREA] =
2901  new AW_area_management(form1, XtVaCreateManagedWidget("info_area",
2902  xmDrawingAreaWidgetClass,
2903  form1,
2904  XmNbottomAttachment, XmATTACH_FORM,
2905  XmNtopAttachment, XmATTACH_FORM,
2906  XmNleftAttachment, XmATTACH_FORM,
2907  XmNrightAttachment, XmATTACH_FORM,
2908  XmNmarginHeight, 2,
2909  XmNmarginWidth, 2,
2910  NULp));
2911 
2912  aw_realize_widget(this);
2913 
2915  create_devices();
2916 }
2917 
2918 void AW_window_message::init(AW_root *root_in, const char *wid, const char *windowname, bool allow_close) {
2919  root = root_in; // for macro
2920 
2921  int width = 100;
2922  int height = 100;
2923  int posx = 50;
2924  int posy = 50;
2925 
2926  set_title_and_id(windowname, wid);
2927 
2928  // create shell for message box
2929  p_w->shell = aw_create_shell(this, true, allow_close, width, height, posx, posy);
2930 
2931  // disable resize or maximize in simple dialogs (avoids broken layouts)
2932  XtVaSetValues(p_w->shell, XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE,
2933  NULp);
2934 
2935  p_w->areas[AW_INFO_AREA] =
2936  new AW_area_management(p_w->shell, XtVaCreateManagedWidget("info_area",
2937  xmDrawingAreaWidgetClass,
2938  p_w->shell,
2939  XmNheight, 0,
2940  XmNbottomAttachment, XmATTACH_NONE,
2941  XmNtopAttachment, XmATTACH_FORM,
2942  XmNleftAttachment, XmATTACH_FORM,
2943  XmNrightAttachment, XmATTACH_FORM,
2944  NULp));
2945 
2946  aw_realize_widget(this);
2947 }
2948 void AW_window_message::init(AW_root *root_in, const char *windowname, bool allow_close) {
2949  char *wid = GBS_string_2_key(windowname);
2950  init(root_in, wid, windowname, allow_close);
2951  free(wid);
2952 }
2953 
2954 void AW_window::set_focus_policy(bool follow_mouse) {
2955  int focusPolicy = follow_mouse ? XmPOINTER : XmEXPLICIT;
2956  XtVaSetValues(p_w->shell, XmNkeyboardFocusPolicy, focusPolicy, NULp);
2957 }
2958 
2959 void AW_window::select_mode(int mode) {
2960  if (mode >= p_w->number_of_modes)
2961  return;
2962 
2963  Widget oldwidget = p_w->modes_widgets[p_w->selected_mode];
2964  p_w->selected_mode = mode;
2966  XtVaSetValues(oldwidget, XmNbackground, p_global->background, NULp);
2967  XtVaSetValues(widget, XmNbackground, p_global->foreground, NULp);
2968 }
2969 
2970 static void aw_mode_callback(AW_window *aww, short mode, AW_cb *cbs) {
2971  aww->select_mode(mode);
2972  cbs->run_callbacks();
2973 }
2974 
2975 #define MODE_BUTTON_OFFSET 34
2976 inline int yoffset_for_mode_button(int button_number) {
2977  return button_number*MODE_BUTTON_OFFSET + (button_number/4)*8 + 2;
2978 }
2979 
2980 int AW_window::create_mode(const char *pixmap, const char *helpText, AW_active mask, const WindowCallback& cb) {
2981  aw_assert(legal_mask(mask));
2982  Widget button;
2983 
2984  TuneBackground(p_w->mode_area, TUNE_BUTTON); // set background color for mode-buttons
2985 
2986  const char *path = AW_get_pixmapPath(pixmap);
2987 
2989  button = XtVaCreateManagedWidget("", xmPushButtonWidgetClass, p_w->mode_area,
2990  XmNx, 0,
2991  XmNy, y,
2992  XmNlabelType, XmPIXMAP,
2993  XmNshadowThickness, 1,
2994  XmNbackground, _at->background_color,
2995  NULp);
2996  XtVaSetValues(button, RES_CONVERT(XmNlabelPixmap, path), NULp);
2997  XtVaGetValues(button, XmNforeground, &p_global->foreground, NULp);
2998 
2999  AW_cb *cbs = new AW_cb(this, cb, NULp);
3000  AW_cb *cb2 = new AW_cb(this, makeWindowCallback(aw_mode_callback, p_w->number_of_modes, cbs), helpText, cbs);
3001  XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)AW_server_callback, (XtPointer)cb2);
3002 
3003  if (!p_w->modes_f_callbacks) ARB_calloc(p_w->modes_f_callbacks, AW_NUMBER_OF_F_KEYS); // valgrinders : never freed because AW_window never is freed
3005 
3008  p_w->modes_widgets[p_w->number_of_modes] = button;
3009  }
3010 
3011  root->make_sensitive(button, mask);
3012  p_w->number_of_modes++;
3013 
3015  if (ynext> _at->max_y_size) _at->max_y_size = ynext;
3016 
3017  return p_w->number_of_modes;
3018 }
3019 
3021  memset((char *)this, 0, sizeof(AW_area_management));
3022  form = formi;
3023  area = widget;
3024 }
3025 
3027  if (!device) device = new AW_device_Xm(common);
3028  return device;
3029 }
3030 
3032  if (!size_device) size_device = new AW_device_size(common);
3033  return size_device;
3034 }
3035 
3037  if (!print_device) print_device = new AW_device_print(common);
3038  return print_device;
3039 }
3040 
3042  if (!click_device) click_device = new AW_device_click(common);
3043  return click_device;
3044 }
3045 
3047  {
3048  Boolean iconic = False;
3049  XtVaGetValues(p_w->shell, XmNiconic, &iconic, NULp);
3050 
3051  if (iconic == True) {
3052  XtVaSetValues(p_w->shell, XmNiconic, False, NULp);
3053 
3054  XtMapWidget(p_w->shell);
3055  XRaiseWindow(XtDisplay(p_w->shell), XtWindow(p_w->shell));
3056  }
3057  }
3058 
3059  {
3060  Display *xdpy = XtDisplay(p_w->shell);
3061  Window window = XtWindow(p_w->shell);
3062  Atom netactivewindow = XInternAtom(xdpy, "_NET_ACTIVE_WINDOW", False);
3063 
3064  if (netactivewindow) {
3065 
3066  XClientMessageEvent ce;
3067  ce.type = ClientMessage;
3068  ce.display = xdpy;
3069  ce.window = window;
3070  ce.message_type = netactivewindow;
3071  ce.format = 32;
3072  ce.data.l[0] = 2;
3073  ce.data.l[1] = None;
3074  ce.data.l[2] = Above;
3075  ce.data.l[3] = 0;
3076  ce.data.l[4] = 0;
3077 
3078 #if defined(DEBUG)
3079  Status ret =
3080 #endif // DEBUG
3081  XSendEvent(xdpy, XDefaultRootWindow(xdpy),
3082  False,
3083  SubstructureRedirectMask | SubstructureNotifyMask,
3084  (XEvent *) &ce);
3085 
3086 #if defined(DEBUG)
3087  if (!ret) { fprintf(stderr, "Failed to send _NET_ACTIVE_WINDOW to WM (XSendEvent returns %i)\n", ret); }
3088 #endif // DEBUG
3089  XSync(xdpy, False);
3090  }
3091 #if defined(DEBUG)
3092  else {
3093  fputs("No such atom '_NET_ACTIVE_WINDOW'\n", stderr);
3094  }
3095 #endif // DEBUG
3096  }
3097 }
3098 
3100  if (_callback && (long)_callback != 1) {
3104  }
3105 
3106  XtAddCallback((Widget) widget, XmNactivateCallback,
3107  (XtCallbackProc) AW_server_callback, (XtPointer) _callback);
3108  }
3109  _callback = NULp;
3110 }
3111 
3112 
3113 void AW_window::set_background(const char *colorname, Widget parentWidget) {
3114  bool colorSet = false;
3115 
3116  if (colorname) {
3117  XColor unused, color;
3118 
3119  if (XAllocNamedColor(p_global->display, p_global->colormap, colorname, &color, &unused)
3120  == 0) {
3121  fprintf(stderr, "XAllocColor failed: %s\n", colorname);
3122  }
3123  else {
3124  _at->background_color = color.pixel;
3125  colorSet = true;
3126  }
3127  }
3128 
3129  if (!colorSet) {
3130  XtVaGetValues(parentWidget, XmNbackground, &(_at->background_color),
3131  NULp); // fallback to background color
3132  }
3133 }
3134 
3135 void AW_window::TuneOrSetBackground(Widget w, const char *color, int modStrength) {
3136  // Sets the background for the next created widget.
3137  //
3138  // If 'color' is specified, it may contain one of the following values:
3139  // "+" means: slightly increase color of parent widget 'w'
3140  // "-" means: slightly decrease color of parent widget 'w'
3141  // otherwise it contains a specific color ('name' or '#RGB')
3142  //
3143  // If color is not specified, the color of the parent widget 'w' is modified
3144  // by 'modStrength' (increased if positive, decreased if negative)
3145  //
3146  // If it's not possible to modify the color (e.g. we cannot increase 'white'),
3147  // the color will be modified in the opposite direction. For details see TuneBackground()
3148 
3149  if (color) {
3150  switch (color[0]) {
3151  case '+':
3153  break;
3154  case '-':
3156  break;
3157  default:
3158  set_background(color, w); // use explicit color
3159  }
3160  }
3161  else {
3162  TuneBackground(w, modStrength);
3163  }
3164 }
3165 
3166 void AW_window::TuneBackground(Widget w, int modStrength) {
3167  // Gets the Background Color, modifies the rgb values slightly and sets new background color
3168  // Intended to give buttons a nicer 3D-look.
3169  //
3170  // possible values for modStrength:
3171  //
3172  // 0 = do not modify (i.e. set to background color of parent widget)
3173  // 1 .. 127 = increase if background is bright, decrease if background is dark
3174  // -1 ..-127 = opposite behavior than above
3175  // 256 .. 383 = always increase
3176  // -256 ..-383 = always decrease
3177  //
3178  // if it's impossible to decrease or increase -> opposite direction is used.
3179 
3180  int col[3];
3181  {
3182  Pixel bg;
3183  XtVaGetValues(w, XmNbackground, &bg, NULp);
3184 
3185  XColor xc;
3186  xc.pixel = bg;
3187  XQueryColor(XtDisplay(w), p_global->colormap, &xc);
3188 
3189  col[0] = xc.red >> 8; // take MSB
3190  col[1] = xc.green >> 8;
3191  col[2] = xc.blue >> 8;
3192  }
3193 
3194  int mod = modStrength;
3195  int preferredDir = 0;
3196  bool invertedMod = false;
3197 
3198  if (modStrength>0) {
3199  if (modStrength>255) {
3200  mod -= 256;
3201  preferredDir = 1; // increase preferred
3202  }
3203  }
3204  else {
3205  if (modStrength<-255) {
3206  mod = -modStrength-256;
3207  preferredDir = -1; // decrease preferred
3208  }
3209  else {
3210  invertedMod = true;
3211  mod = -mod;
3212  }
3213  }
3214 
3215  aw_assert(mod >= 0 && mod < 128);
3216  // illegal modification
3217 
3218  bool incPossible[3]; // increment possible for color
3219  bool decPossible[3]; // decrement possible for color
3220  int incs = 0; // count possible increments
3221  int decs = 0; // count possible decrements
3222 
3223  for (int i = 0; i<3; ++i) {
3224  if ((incPossible[i] = ((col[i]+mod) <= 255)))
3225  incs++;
3226  if ((decPossible[i] = ((col[i]-mod) >= 0)))
3227  decs++;
3228  }
3229 
3230  aw_assert(incs||decs);
3231 
3232  switch (preferredDir) {
3233  case 0: // no direction preferred yet, need to decide
3234  if (invertedMod)
3235  preferredDir = decs ? -1 : 1;
3236  else
3237  preferredDir = incs ? 1 : -1;
3238  break;
3239  case 1:
3240  if (!incs)
3241  preferredDir = -1;
3242  break;
3243  case -1:
3244  if (!decs)
3245  preferredDir = 1;
3246  break;
3247  }
3248 
3249  aw_assert(preferredDir == 1 || preferredDir == -1); // no direction chosen above
3250 
3251  if (preferredDir == 1) {
3252  for (int i=0; i<3; ++i) col[i] += (incPossible[i] ? mod : 0);
3253  }
3254  else if (preferredDir == -1) {
3255  for (int i=0; i<3; ++i) col[i] -= (decPossible[i] ? mod : 0);
3256  }
3257 
3258 
3259  char hex_color[50];
3260  sprintf(hex_color, "#%2.2X%2.2X%2.2X", col[0], col[1], col[2]);
3261  aw_assert(strlen(hex_color) == 7);
3262  // otherwise some value overflowed
3263  set_background(hex_color, w);
3264 }
3265 
3266 void AW_window::reset_layout(const char *YYYYMMDD) {
3267  aw_assert(!layout_reset_wanted); // do not use twice!
3268  aw_assert(!root); // has to be called BEFORE init!
3269 
3270  layout_reset_wanted = YYYYMMDD; // we only store the ptr. make sure to pass static data (e.g. a literal)!
3271 }
3272 
3273 void AW_window::alias_remote_command(const char *action_alias, const char *registered_action) {
3279  char *registered_localAction = local_id_copy(registered_action);
3280  const char *localAction_alias = local_id(action_alias);
3281 
3282  get_root()->alias_remote_command(localAction_alias, registered_localAction);
3283  free(registered_localAction);
3284 }
3285 
3287  // Don't call make_sensitive directly!
3288  //
3289  // Simply set sens_mask(AWM_EXP) and after creating the expert-mode-only widgets,
3290  // set it back using sens_mask(AWM_ALL)
3291 
3292  aw_assert(w);
3293  aw_assert(legal_mask(mask));
3294 
3295  prvt->set_last_widget(w);
3296 
3297  if (mask != AWM_ALL) { // no need to make widget sensitive, if its shown unconditionally
3298  button_sens_list = new AW_buttons_struct(mask, w, button_sens_list);
3299  if (!(mask & global_mask)) XtSetSensitive(w, False); // disable widget if mask doesn't match
3300  }
3301 }
3302 
3303 void AW_root::set_active(Widget w, bool active) {
3304  // only use for widgets NOT used with make_sensitive!
3305  // allows local control over widget
3306 
3307  XtSetSensitive(w, active);
3308 }
3309 
3311  aw_assert(w);
3312  aw_assert(legal_mask(maski));
3313 
3314  mask = maski;
3315  button = w;
3316  next = prev_button;
3317 }
3318 
3320  delete next;
3321 }
3322 
3324  bool removed = false;
3325  if (button_sens_list) {
3326  AW_buttons_struct *prev = NULp;
3327  AW_buttons_struct *bl = button_sens_list;
3328 
3329  while (bl) {
3330  if (bl->button == button) break; // found wanted widget
3331  prev = bl;
3332  bl = bl->next;
3333  }
3334 
3335  if (bl) {
3336  // remove from list
3337  if (prev) prev->next = bl->next;
3338  else button_sens_list = bl->next;
3339 
3340  bl->next = NULp;
3341  removed = true;
3342 
3343  delete bl;
3344  }
3345  }
3346  return removed;
3347 }
3348 
3349 AW_option_menu_struct::AW_option_menu_struct(int numberi, const char *variable_namei,
3350  AW_VARIABLE_TYPE variable_typei, Widget label_widgeti,
3351  Widget menu_widgeti, AW_pos xi, AW_pos yi, int correct) {
3352  option_menu_number = numberi;
3353  variable_name = strdup(variable_namei);
3354  variable_type = variable_typei;
3355  label_widget = label_widgeti;
3356  menu_widget = menu_widgeti;
3357  first_choice = NULp;
3358  last_choice = NULp;
3359  default_choice = NULp;
3360  next = NULp;
3361  x = xi;
3362  y = yi;
3363 
3364  correct_for_at_center_intern = correct;
3365 }
3366 
3368  const char *variable_namei, AW_VARIABLE_TYPE variable_typei,
3369  Widget label_widgeti, int correct) {
3370 
3371  toggle_field_number = toggle_field_numberi;
3372  variable_name = strdup(variable_namei);
3373  variable_type = variable_typei;
3374  label_widget = label_widgeti;
3375  first_toggle = NULp;
3376  last_toggle = NULp;
3377  default_toggle = NULp;
3378  next = NULp;
3379  correct_for_at_center_intern = correct;
3380 }
3381 
3383  : shell(NULp),
3384  scroll_bar_vertical(NULp),
3385  scroll_bar_horizontal(NULp),
3386  menu_deep(0),
3387  help_pull_down(NULp),
3388  mode_area(NULp),
3389  number_of_modes(0),
3390  modes_f_callbacks(NULp),
3391  modes_widgets(NULp),
3392  selected_mode(0),
3393  popup_cb(NULp),
3394  frame(NULp),
3395  toggle_field(NULp),
3396  toggle_label(NULp),
3397  toggle_field_var_name(NULp),
3398  toggle_field_var_type(AW_NONE),
3399  keymodifier(AW_KEYMODE_NONE),
3400  WM_top_offset(0),
3401  WM_left_offset(0)
3402 {
3403  for (int i = 0; i<AW_MAX_MENU_DEEP; ++i) {
3404  menu_bar[i] = NULp;
3405  }
3406  for (int i = 0; i<AW_MAX_AREA; ++i) {
3407  areas[i] = NULp;
3408  }
3409 }
3410 
void TuneBackground(Widget w, int modStrength)
Definition: AW_window.cxx:3166
void aw_realize_widget(AW_window *aww)
Definition: AW_window.cxx:2381
AW_widget_value_pair * first_toggle
#define arb_assert(cond)
Definition: arb_assert.h:245
GB_HASH * action_hash
static void horizontal_scrollbar_redefinition_cb(AW_root *, AW_window *aw)
Definition: AW_window.cxx:966
bool is_resize_callback(AW_area area, AnyWinCB f)
Definition: AW_window.cxx:1514
enum AW_root::@65 color_mode
void set_input_callback(AW_window *aww, const WindowCallback &wcb)
Definition: AW_window.cxx:1980
virtual void clear(AW_bitset filteri)
Definition: AW_device.cxx:313
void update_scrollbar_settings_from_awars(AW_orientation orientation)
Definition: AW_window.cxx:2043
AW_device_print * get_print_device(AW_area area)
Definition: AW_window.cxx:534
AW_cb * _callback
Definition: aw_window.hxx:292
const char * GB_ERROR
Definition: arb_core.h:25
AW_bitset AW_active
Definition: aw_base.hxx:45
#define TUNE_BUTTON
Definition: aw_window.hxx:39
Arg * list()
Definition: aw_xargs.hxx:36
void set_resize_callback(AW_area area, const WindowCallback &wcb)
Definition: AW_window.cxx:826
#define AW_CALC_OFFSET_ON_EXPOSE
AW_cb * get_double_click_cb()
AW_active global_mask
Definition: aw_root.hxx:108
#define TUNE_SUBMENU
Definition: aw_window.hxx:41
void set_last_widget(Widget w)
void define_remote_command(class AW_cb *cbs)
Definition: AW_root.cxx:229
#define LAYOUT_AWAR_ROOT
Definition: AW_window.cxx:1185
static void aw_loop_forget_window_geometry(const char *, long val, void *)
Definition: AW_window.cxx:2190
static const char * local_layout_awarname(AW_window *aww, const char *sub_name)
Definition: AW_window.cxx:1187
bool is_tracking() const
Definition: aw_root.hxx:179
AliDataPtr format(AliDataPtr data, const size_t wanted_len, GB_ERROR &error)
Definition: insdel.cxx:615
#define TUNE_DARK
Definition: aw_window.hxx:44
AW_key_mod awmod
Definition: aw_xkey.hxx:12
AW_pos get_scrolled_picture_height() const
Definition: AW_window.cxx:851
void d_callback(const WindowCallback &cb)
Definition: AW_window.cxx:150
void sens_mask(AW_active mask)
Definition: AW_window.cxx:136
AW_device * get_device(AW_area area)
Definition: AW_window.cxx:524
static AW_window * find_or_createAndRegisterWindow(CreateWindowCallback *windowMaker)
Definition: AW_window.cxx:65
GBDATA * GB_child(GBDATA *father)
Definition: adquery.cxx:322
#define implicated(hypothesis, conclusion)
Definition: arb_assert.h:289
const AW_screen_area & get_screen() const
Definition: aw_common.hxx:241
static void AW_exposeCB(Widget, XtPointer aw_cb_struct, XmDrawingAreaCallbackStruct *call_data)
Definition: AW_window.cxx:1470
static char * y[maxsp+1]
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
Definition: adhash.cxx:454
STATIC_ASSERT_ANNOTATED(CopyFromParent==0,"value of CopyFromParent changed. Check use below")
return string(buffer, length)
AW_option_menu_struct * next
bool is_resize_callback(AnyWinCB f)
Definition: AW_window.cxx:1510
Widget menu_bar[AW_MAX_MENU_DEEP]
AW_widget_value_pair * default_choice
void insert_menu_topic(const char *id, const char *name, const char *mnemonic, const char *help_text_, AW_active mask, const WindowCallback &wcb)
Definition: AW_window.cxx:582
GB_HASH * hash_for_windows
Definition: aw_root.hxx:125
bool remove_button_from_sens_list(Widget button)
Definition: AW_window.cxx:3323
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:707
AW_awar * label_is_awar(const char *label)
Definition: AW_root.cxx:219
const char * get_window_id() const
Definition: aw_window.hxx:377
#define TUNE_BRIGHT
Definition: aw_window.hxx:43
void set_popup_callback(const WindowCallback &wcb)
Definition: AW_window.cxx:802
void update_label(Widget widget, const char *var_value)
Definition: AW_button.cxx:740
#define ASSERT_NO_ERROR(errorExpr)
Definition: arb_assert.h:360
static void drag_scroll_bar_horizontal(Widget, XtPointer aw_cb_struct, XtPointer call_data)
Definition: AW_window.cxx:1023
const char * GBS_global_string_to_buffer(char *buffer, size_t bufsize, const char *templat,...)
Definition: arb_msg.cxx:178
void reset_scrolled_picture_size()
Definition: AW_window.cxx:855
void run_expose_callback()
Definition: AW_window.cxx:1466
virtual ~AW_window()
Definition: AW_window.cxx:1113
void on_hide(const WindowCallback &call_on_hide)
Definition: AW_window.cxx:1843
void set_vertical_scrollbar_top_indent(int indent)
Definition: AW_window.cxx:862
void _set_activate_callback(void *widget)
Definition: AW_window.cxx:3099
#define FALSE
Definition: defs.h:21
int max_y_size
Definition: aw_at.hxx:36
#define WIDER_THAN_SCREEN
Definition: aw_at.hxx:11
long
Definition: AW_awar.cxx:152
AW_ScalerType
Definition: aw_window.hxx:228
static void aw_loop_get_window_geometry(const char *, long val, void *)
Definition: AW_window.cxx:2183
static long destroy_awar(const char *, long val, void *)
Definition: AW_window.cxx:2014
static int WM_max_left_offset
#define MAP_ARAM(ar)
void add(int v)
Definition: ClustalV.cxx:461
AW_window * current_modal_window
Definition: aw_root.hxx:115
AW_VARIABLE_TYPE variable_type
Definition: aw_awar.hxx:102
AW_window * aw
Definition: aw_window.hxx:133
int maxx
Definition: aw_xfig.hxx:86
short shadow_thickness
Definition: aw_at.hxx:20
long read_int() const
Definition: AW_awar.cxx:184
AW_screen_area * picture
Definition: aw_window.hxx:357
long color_table_size
Definition: aw_window.hxx:289
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
void warning(int warning_num, const char *warning_message)
Definition: util.cxx:61
AW_SizeRecalc
Definition: aw_window.hxx:214
const char * title
Definition: readseq.c:22
void get_scrollarea_size(AW_screen_area *square)
Definition: AW_window.cxx:877
void GBK_terminatef(const char *templat,...)
Definition: arb_msg.cxx:523
void set_background(const char *colorname, Widget w)
Definition: AW_window.cxx:3113
void init(AW_root *root_in, const char *wid, const char *windowname, bool allow_close)
Definition: AW_window.cxx:2918
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
void allow_delete_window(bool allow_close)
Definition: AW_window.cxx:1636
char * id
Definition: aw_window.hxx:135
AW_root_Motif * prvt
Definition: aw_root.hxx:104
AW_area_management(Widget form, Widget widget)
Definition: AW_window.cxx:3020
void GBS_free_hash(GB_HASH *hs)
Definition: adhash.cxx:538
AW_color_idx
Definition: aw_base.hxx:83
Definition: aw_at.hxx:18
char * GBS_string_2_key(const char *str)
Definition: adstring.cxx:52
#define TUNE_MENUTOPIC
Definition: aw_window.hxx:42
void reset_layout(const char *YYYYMMDD)
Definition: AW_window.cxx:3266
void add_timed_callback(int ms, const TimedCallback &tcb)
Definition: AW_root.cxx:590
void _get_area_size(AW_area area, AW_screen_area *square)
Definition: AW_window.cxx:872
AW_pos get_scrolled_picture_width() const
Definition: AW_window.cxx:847
void wm_activate()
Definition: AW_window.cxx:3046
void set_offset(const AW::Vector &off)
Definition: aw_device.hxx:130
const AW_bitset AW_ALL_DEVICES
Definition: aw_device.hxx:44
#define EXIT_SUCCESS
Definition: arb_a2ps.c:154
int slider_pos_horizontal
current position of the vertical slider
Definition: aw_window.hxx:353
#define BOTTOM_WIDGET
short height_of_buttons
Definition: aw_at.hxx:22
static void aw_window_avoid_destroy_cb(Widget, AW_window *, XmAnyCallbackStruct *)
Definition: AW_window.cxx:1584
void set_window_title(const char *title)
Definition: AW_window.cxx:1062
char * program_name
Definition: aw_root.hxx:113
static Pixmap getIcon(Screen *screen, const char *iconName, Pixel foreground, Pixel background)
Definition: AW_window.cxx:2226
const char * AW_get_pixmapPath(const char *pixmapName)
Definition: AW_button.cxx:266
unsigned long time
Definition: aw_window.hxx:82
bool is_focus_callback(AnyWinCB f)
Definition: AW_window.cxx:1450
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
static void AW_xfigCB_info_area(AW_window *aww, AW_xfig *xfig)
Definition: AW_window.cxx:690
void activate()
Definition: aw_window.hxx:368
XmFontList fontlist
#define cb(action)
char character
Definition: aw_window.hxx:91
const char * local_awarname(const char *common_name, bool tmp=true)
Definition: AW_window.cxx:754
void set_motion_callback(AW_area area, const WindowCallback &wcb)
Definition: AW_window.cxx:821
AW_device_size * get_size_device(AW_area area)
Definition: AW_window.cxx:539
AW_widget_value_pair * first_choice
AW_common * get_common(AW_area area)
Definition: AW_window.cxx:551
#define MAXNAMELEN
AW_area
Definition: aw_base.hxx:76
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
GB_ERROR GB_delete(GBDATA *&source)
Definition: arbdb.cxx:1916
static void AW_inputCB_draw_area(Widget wgt, XtPointer aw_cb_struct, XmDrawingAreaCallbackStruct *call_data)
Definition: AW_window.cxx:1870
void create_window_variables()
Definition: AW_window.cxx:974
bool AW_IS_IMAGEREF(const char *label)
Definition: aw_localdef.hxx:13
POS_TREE1 * father
Definition: probe_tree.h:39
static void value_changed_scroll_bar_vertical(Widget, XtPointer aw_cb_struct, XtPointer call_data)
Definition: AW_window.cxx:1004
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
#define SmartCustomPtr(type, deallocator)
Definition: smartptr.h:46
GB_HASH * hash_table_for_variables
Definition: aw_root.hxx:110
int create_mode(const char *pixmap, const char *help_text_, AW_active mask, const WindowCallback &cb)
Definition: AW_window.cxx:2980
static AW_root * SINGLETON
Definition: aw_root.hxx:102
void show()
Definition: AW_window.cxx:1676
double AW_pos
Definition: aw_base.hxx:29
AW_buttons_struct(AW_active maski, Widget w, AW_buttons_struct *next)
Definition: AW_window.cxx:3310
const char * help_text
Definition: aw_window.hxx:134
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
Widget get_area() const
char * ARB_strduplen(const char *p, unsigned len)
Definition: arb_string.h:33
static int WM_max_top_offset
#define p_aww(aww)
bool contains(AnyWinCB g)
short font_height
Definition: aw_root.hxx:123
TYPE * ARB_alloc(size_t nelem)
Definition: arb_mem.h:56
bool highlight
Definition: aw_at.hxx:24
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
Definition: arbdb.cxx:1656
bool is_expose_callback(AW_area area, AnyWinCB f)
Definition: AW_window.cxx:1491
Widget scroll_bar_horizontal
AW_VARIABLE_TYPE
Definition: aw_base.hxx:53
int miny
Definition: aw_xfig.hxx:85
AW_pos l
Definition: aw_base.hxx:32
void create_devices()
Definition: AW_window.cxx:2117
#define RES_LABEL_CONVERT(label)
void get_event(AW_event *eventi) const
Definition: AW_window.cxx:530
AW_MouseButton
Definition: aw_window.hxx:70
void set_double_click_callback(AW_area area, const WindowCallback &wcb)
Definition: AW_window.cxx:1990
void recalc_size_atShow(enum AW_SizeRecalc sr)
Definition: AW_window.cxx:1433
float scaler2awar(float scaler, AW_awar *awar)
Definition: AW_window.cxx:197
AW_default check_properties(AW_default aw_props)
Definition: aw_root.hxx:162
void GBS_hash_do_const_loop(const GB_HASH *hs, gb_hash_const_loop_type func, void *client_data)
Definition: adhash.cxx:559
void force_expose()
Definition: AW_window.cxx:1496
void create_devices(AW_window *aww, AW_area ar)
Definition: AW_window.cxx:2059
AW_cb * _d_callback
Definition: aw_window.hxx:293
void set_double_click_callback(AW_window *aww, const WindowCallback &wcb)
Definition: AW_window.cxx:1986
AW_cb ** modes_f_callbacks
Display * get_display() const
static unsigned aw_calc_WM_offsets_delayed(AW_root *, AW_window *aww)
Definition: AW_window.cxx:1254
void calculate_scrollbars()
Definition: AW_window.cxx:883
#define MIDDLE_WIDGET
#define aw_assert(bed)
Definition: aw_position.hxx:29
AW_device_click * get_click_device(AW_area area, int mousex, int mousey, int max_distance)
Definition: AW_window.cxx:513
#define false
Definition: ureadseq.h:13
static void aw_window_destroy_cb(Widget w, AW_window *aww, XmAnyCallbackStruct *)
Definition: AW_window.cxx:1596
char * helptext_for_next_button
Definition: aw_at.hxx:26
float get_max() const
Definition: AW_awar.cxx:555
void show_modal()
Definition: AW_window.cxx:1822
const char * get_window_title() const
Definition: AW_window.cxx:1067
AW_root * root
Definition: aw_window.hxx:275
#define legal_mask(m)
Definition: aw_root.hxx:25
static double xi
void set_expose_callback(AW_area area, const WindowCallback &wcb)
Definition: AW_window.cxx:775
void create_menu(const char *name, const char *mnemonic, AW_active mask=AWM_ALL)
Definition: AW_window.cxx:459
#define local_posx_awarname(aww)
Definition: AW_window.cxx:1191
int yoffset_for_mode_button(int button_number)
Definition: AW_window.cxx:2976
void help_text(const char *id)
Definition: AW_window.cxx:125
AW_buttons_struct * next
static void error(const char *msg)
Definition: mkptypes.cxx:96
AW_event event
Definition: aw_window.hxx:287
void init(AW_root *root, const char *wid, const char *windowname, int width, int height)
Definition: AW_window.cxx:2400
void set_active(Widget w, bool active)
Definition: AW_window.cxx:3303
void set_title_and_id(const char *title, const char *id)
Definition: AW_window.cxx:2395
const char * mnemonic
fputc('\n', stderr)
AW_device_click * get_click_device()
Definition: AW_window.cxx:3041
AW_toggle_field_struct * next
bool knows_WM_offset() const
AW_area_management * areas[AW_MAX_AREA]
static void vertical_scrollbar_redefinition_cb(AW_root *, AW_window *aw)
Definition: AW_window.cxx:970
void label(const char *label)
Definition: AW_window.cxx:111
void insert_help_topic(const char *labeli, const char *mnemonic, const char *helpText, AW_active mask, const WindowCallback &cb)
Definition: AW_window.cxx:556
static void value_changed_scroll_bar_horizontal(Widget, XtPointer aw_cb_struct, XtPointer call_data)
Definition: AW_window.cxx:1010
short font_width
Definition: aw_root.hxx:122
char * read_as_string() const
AW_VARIABLE_TYPE variable_type
void window_show()
Definition: AW_root.cxx:538
bool focus_follows_mouse
Definition: aw_root.hxx:109
bool window_is_shown
current position of the horizontal slider
Definition: aw_window.hxx:355
void TuneOrSetBackground(Widget w, const char *color, int modStrength)
Definition: AW_window.cxx:3135
GB_ERROR reset_to_default()
Definition: AW_awar.cxx:214
#define INFO_WIDGET
int max_x_size
Definition: aw_at.hxx:35
#define HIGHER_THAN_SCREEN
Definition: aw_at.hxx:12
#define cmp(h1, h2)
Definition: admap.cxx:50
Widget scroll_bar_vertical
AW_device_Xm * get_screen_device()
Definition: AW_window.cxx:3026
class AW_awar * local_awar(const char *common_name, bool tmp=true)
Definition: AW_window.cxx:758
static Display * dpy
Label(const char *labeltext, AW_window *aww)
Definition: AW_window.cxx:2143
AW_orientation
Definition: aw_window.hxx:51
float awar2scaler(AW_awar *awar)
Definition: AW_window.cxx:206
const awXKeymap * aw_xkey_2_awkey(XKeyEvent *xkeyevent)
Definition: AW_xkey.cxx:196
static void aw_onExpose_calc_WM_offsets(AW_window *aww)
Definition: AW_window.cxx:1256
AW_pos r
Definition: aw_base.hxx:32
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:606
const int AW_NUMBER_OF_F_KEYS
void insert_sub_menu(const char *name, const char *mnemonic, AW_active mask=AWM_ALL)
Definition: AW_window.cxx:632
AW_key_code keycode
Definition: aw_window.hxx:90
void window_fit()
Definition: AW_window.cxx:1079
AW_key_mod keymodifier
Definition: aw_window.hxx:83
Definition: arbdb.h:86
float get_min() const
Definition: AW_awar.cxx:544
void button_height(int height)
Definition: AW_window.cxx:1075
char * ARB_strupper(char *s)
Definition: arb_str.h:63
static void AW_motionCB(Widget, XtPointer aw_cb_struct, XEvent *ev, Boolean *)
Definition: AW_window.cxx:2000
static void aw_window_noexit_destroy_cb(Widget, AW_window *aww, XmAnyCallbackStruct *)
Definition: AW_window.cxx:1587
void create_user_geometry_awars(int posx, int posy, int width, int height)
Definition: AW_window.cxx:1197
void GBS_hash_do_loop(GB_HASH *hs, gb_hash_loop_type func, void *client_data)
Definition: adhash.cxx:545
void set_horizontal_scrollbar_left_indent(int indent)
Definition: AW_window.cxx:867
float read_float() const
Definition: AW_awar.cxx:177
AW_active widget_mask
Definition: aw_at.hxx:27
static const char * existingPixmap(const char *icon_relpath, const char *name)
Definition: AW_window.cxx:2216
int maxy
Definition: aw_xfig.hxx:86
AW_rgb * color_table
AW_pos b
Definition: aw_base.hxx:32
Widget aw_create_shell(AW_window *aww, bool allow_resize, bool allow_close, int width, int height, int posx, int posy)
Definition: AW_window.cxx:2251
WindowCallbackSimple AnyWinCB
Definition: aw_window.hxx:120
#define RES_CONVERT(res_name, res_value)
bool is_expose_callback(AnyWinCB f)
Definition: AW_window.cxx:1487
AW_PosRecalc
Definition: aw_window.hxx:221
void set_click_time(long click_time_)
void tell_scrolled_picture_size(AW_screen_area rectangle)
Definition: AW_window.cxx:833
bool aw_ask_sure(const char *unique_id, const char *msg)
static void set_focus_policy(const char *, long cl_aww, void *)
Definition: AW_root.cxx:303
void normal_cursor()
Definition: AW_window.cxx:1376
Widget * modes_widgets
#define local_width_awarname(aww)
Definition: AW_window.cxx:1193
void set_info_area_height(int height)
Definition: AW_window.cxx:806
AW_widget_value_pair * last_toggle
#define p_global
fputs(TRACE_PREFIX, stderr)
AW_rgb * color_table
Definition: aw_window.hxx:290
void create_gcs(AW_device *device, int screen_depth)
Definition: AW_xfig.cxx:504
AW_event_type type
Definition: aw_window.hxx:81
unsigned long int background_color
Definition: aw_at.hxx:29
void set_bottom_area_height(int height)
Definition: AW_window.cxx:811
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:632
AW_window_Motif * p_w
Definition: aw_window.hxx:291
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
void draw_line(int x1, int y1, int x2, int y2, int width, bool resize)
Definition: AW_window.cxx:499
static void drag_scroll_bar_vertical(Widget, XtPointer aw_cb_struct, XtPointer call_data)
Definition: AW_window.cxx:1017
void AW_help_entry_pressed(AW_window *aww)
Definition: AW_root.cxx:38
void set_focus_callback(const WindowCallback &wcb)
Definition: AW_window.cxx:788
void AW_forget_all_window_geometry(AW_window *aww)
Definition: AW_window.cxx:2193
AW_option_menu_struct(int numberi, const char *variable_namei, AW_VARIABLE_TYPE variable_typei, Widget label_widgeti, Widget menu_widgeti, AW_pos xi, AW_pos yi, int correct)
Definition: AW_window.cxx:3349
AW_device_size * get_size_device()
Definition: AW_window.cxx:3031
Definition: output.h:122
static float apply_ScalerType(float val, AW_ScalerType scalerType, bool inverse)
Definition: AW_window.cxx:161
AW_pos t
Definition: aw_base.hxx:32
void set_resize_callback(AW_window *aww, const WindowCallback &cb)
Definition: AW_window.cxx:1857
AW_MouseButton button
Definition: aw_window.hxx:86
#define local_height_awarname(aww)
Definition: AW_window.cxx:1194
void run_resize_callback()
Definition: AW_window.cxx:1847
#define AW_SCROLL_MAX
void ARB_realloc(TYPE *&tgt, size_t nelem)
Definition: arb_mem.h:43
void make_sensitive(Widget w, AW_active mask)
Definition: AW_window.cxx:3286
void recalc_pos_atShow(AW_PosRecalc pr)
Definition: AW_window.cxx:1425
void set_horizontal_scrollbar_position(int position)
Definition: AW_window.cxx:995
void reset()
Definition: AW_device.cxx:280
char * strdup_getlen(const char *str, int &len)
Definition: AW_window.cxx:2139
void close_sub_menu()
Definition: AW_window.cxx:473
static ARB_init_perl_interface init
Definition: ARB_ext.c:101
bool is_shown() const
Definition: AW_window.cxx:1640
static void AW_resizeCB_draw_area(Widget, XtPointer aw_cb_struct, XtPointer)
Definition: AW_window.cxx:1851
AW_device_print * get_print_device()
Definition: AW_window.cxx:3036
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
static const char * local_awarnamef(const char *format, AW_window *aww, const char *common_name)
Definition: AW_window.cxx:748
void hide()
Definition: AW_window.cxx:1828
void select_mode(int mode)
Definition: AW_window.cxx:2959
void highlight()
Definition: AW_window.cxx:131
AW_root * get_root()
Definition: aw_window.hxx:362
AW_common_Xm * get_common() const
Display * old_cursor_display
long get_click_time() const
void add_line(int x1, int y1, int x2, int y2, int width)
Definition: AW_xfig.cxx:533
static int is_resize_event(Display *display, XEvent *event, XPointer)
Definition: AW_window.cxx:1559
#define NULp
Definition: cxxforward.h:116
bool GB_is_regularfile(const char *path)
Definition: arb_file.cxx:76
AW_key_mod
Definition: aw_keysym.hxx:46
char * label_for_inputfield
Definition: aw_at.hxx:31
static void aw_mode_callback(AW_window *aww, short mode, AW_cb *cbs)
Definition: AW_window.cxx:2970
int size()
Definition: aw_xargs.hxx:37
Window old_cursor_window
void init(AW_root *root, const char *wid, const char *windowname, int width, int height)
Definition: AW_window.cxx:2609
void AW_help_popup(UNFIXED, const char *help_file)
Definition: AW_help.cxx:642
GB_ERROR write_string(const char *aw_string)
AW_VARIABLE_TYPE variable_type
void run_focus_callback()
Definition: AW_window.cxx:1446
void sep______________()
Definition: AW_window.cxx:763
void aw_uninstall_xkeys()
Definition: AW_xkey.cxx:178
void set_vertical_scrollbar_position(int position)
Definition: AW_window.cxx:986
AW_toggle_field_struct(int toggle_field_numberi, const char *variable_namei, AW_VARIABLE_TYPE variable_typei, Widget label_widgeti, int correct)
Definition: AW_window.cxx:3367
void AW_label_in_awar_list(AW_window *aww, Widget widget, const char *str)
Definition: AW_window.cxx:2165
const char * local_id(const char *id) const
Definition: AW_window.cxx:738
void set_cursor(Display *d, Window w, Cursor c)
Definition: AW_window.cxx:1358
#define AW_NO_COLOR
Definition: aw_base.hxx:50
void AW_server_callback(Widget, XtPointer aw_cb_struct, XtPointer)
Definition: AW_window.cxx:1380
GBDATA * GB_nextChild(GBDATA *child)
Definition: adquery.cxx:326
#define AW_MAX_MENU_DEEP
AW_PosRecalc get_recalc_pos_atShow() const
Definition: AW_window.cxx:1429
GB_transaction ta(gb_var)
void run_callbacks()
void callback(const WindowCallback &cb)
Definition: AW_window.cxx:142
void set_horizontal_change_callback(const WindowCallback &wcb)
Definition: AW_window.cxx:1046
void set_vertical_change_callback(const WindowCallback &wcb)
Definition: AW_window.cxx:1030
static void aw_update_window_geometry_awars(AW_window *aww)
Definition: AW_window.cxx:1646
void run_popup_callbacks()
Definition: AW_window.cxx:1457
void aw_insert_default_help_entries(AW_window *aww)
Definition: AW_window.cxx:2132
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:622
void print(AW_device *device)
Definition: AW_xfig.cxx:461
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
Definition: admatch.cxx:193
#define MODE_BUTTON_OFFSET
Definition: AW_window.cxx:2975
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
void hide_or_notify(const char *error)
Definition: AW_window.cxx:1838
void shadow_width(int shadow_thickness)
Definition: AW_window.cxx:1071
void alias_remote_command(const char *action_alias, const char *registered_action)
Definition: AW_root.cxx:270
void set_expose_callback(AW_window *aww, const WindowCallback &cb)
Definition: AW_window.cxx:1478
char * local_id_copy(const char *id) const
Definition: AW_window.cxx:731
static void aw_set_delete_window_cb(AW_window *aww, Widget shell, bool allow_close)
Definition: AW_window.cxx:1614
int slider_pos_vertical
Definition: aw_window.hxx:352
void add(String name, XtArgVal value)
Definition: aw_xargs.hxx:39
static void cleanupResizeEvents(Display *display)
Definition: AW_window.cxx:1568
void set_motion_callback(AW_window *aww, const WindowCallback &wcb)
Definition: AW_window.cxx:2010
int minx
Definition: aw_xfig.hxx:85
AW_key_code awkey
Definition: aw_xkey.hxx:13
#define CopyFromParent_AsPtr
Definition: AW_window.cxx:2249
#define CONSTEXPR
Definition: cxxforward.h:108
void aw_update_all_window_geometry_awars(AW_root *awr)
Definition: AW_window.cxx:2186
static void AW_focusCB(Widget, XtPointer cl_aww, XEvent *, Boolean *)
Definition: AW_window.cxx:780
void set_input_callback(AW_area area, const WindowCallback &wcb)
Definition: AW_window.cxx:816
#define local_reset_awarname(aww)
Definition: AW_window.cxx:1195
GB_ERROR write_int(long aw_int)
char * awstr
Definition: aw_xkey.hxx:14
struct _WidgetRec * Widget
Definition: aw_base.hxx:48
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:392
AW_color_idx alloc_named_data_color(int colnum, const char *colorname)
Definition: AW_window.cxx:2064
void window_hide(AW_window *aww)
Definition: AW_root.cxx:529
void get_window_size(int &width, int &height)
Definition: AW_window.cxx:118
void init(AW_root *root, const char *wid, const char *windowname)
Definition: AW_window.cxx:2840
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
#define local_posy_awarname(aww)
Definition: AW_window.cxx:1192
void GB_close(GBDATA *gbd)
Definition: arbdb.cxx:655
void alias_remote_command(const char *action_alias, const char *registered_action)
Definition: AW_window.cxx:3273
void tie_widget(AW_CL cd1, Widget widget, AW_widget_type type, AW_window *aww)
Definition: AW_awar.cxx:257
AW_widget_value_pair * default_toggle
void track_action(const char *action_id)
Definition: aw_root.hxx:176
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
Definition: adhash.cxx:253
AW_widget_value_pair * last_choice
#define max(a, b)
Definition: f2c.h:154