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