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