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