source: tags/ms_r16q2/PHYLO/PH_main.cxx

Last change on this file was 14940, checked in by westram, 6 years ago
  • AW_manage_GC: changed trigger for color-groups (bool → definition string)
    • allows to specify the position of color_groups in GC-list managed by AW_gc_manager
    • Fixed: if a color-range was specified ⇒ fonts of color-group-GCs were undefined (bug was triggered by [14936])
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : PH_main.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "phylo.hxx"
12#include "phwin.hxx"
13#include "PH_display.hxx"
14
15#include <awt_sel_boxes.hxx>
16#include <aw_preset.hxx>
17#include <aw_awar.hxx>
18#include <aw_msg.hxx>
19#include <awt.hxx>
20#include <aw_root.hxx>
21#include <arbdbt.h>
22#include <arb_strarray.h>
23
24#include <macros.hxx>
25#include <aw_question.hxx>
26
27AW_HEADER_MAIN
28
29const char *filter_text[FILTER_MODES] = {
30    "don't count (ignore)                       ", // DONT_COUNT
31    "if occurs most often => forget whole column", // SKIP_COLUMN_IF_MAX
32    "if occurs => forget whole column           ", // SKIP_COLUMN_IF_OCCUR
33    "count, but do NOT use as maximum           ", // COUNT_DONT_USE_MAX
34    "treat as uppercase character               ", // TREAT_AS_UPPERCASE
35    "treat as regular character                 ", // TREAT_AS_REGULAR
36};
37
38static bool valid_alignment_selected(AW_root *aw_root, GBDATA *gb_main) {
39    GB_transaction  ta(gb_main);
40    const char     *aliname = aw_root->awar(AWAR_PHYLO_ALIGNMENT)->read_char_pntr();
41    if (GBT_get_alignment_len(gb_main, aliname)<1) {
42        GB_clear_error();
43        return false;
44    }
45    return true;
46}
47
48static void startup_sequence_cb(AW_window *alisel_window, AW_window *main_window, PH_root *ph_root) {
49    AW_root *aw_root = main_window->get_root();
50    GBDATA  *gb_main = ph_root->get_gb_main();
51    if (valid_alignment_selected(aw_root, gb_main)) {
52        if (alisel_window) alisel_window->hide();
53
54        char   *use = aw_root->awar(AWAR_PHYLO_ALIGNMENT)->read_string();
55        PHDATA *phd = new PHDATA(aw_root, ph_root);
56
57        GB_set_cache_size(gb_main, PH_DB_CACHE_SIZE);
58        phd->load(use);
59        phd->ROOT = phd;
60
61        long len = PHDATA::ROOT->get_seq_len(); // @@@ off by one?
62        aw_root->awar(AWAR_PHYLO_FILTER_STOPCOL)->write_int(len);
63        aw_root->awar(AWAR_PHYLO_FILTER_STARTCOL)->set_minmax(0, len);
64        aw_root->awar(AWAR_PHYLO_FILTER_STOPCOL)->set_minmax(0, len);
65
66        main_window->activate();
67        ph_view_species_cb();
68    }
69    else {
70        if (alisel_window) {
71            aw_message("Please select a valid alignment");
72        }
73        else {
74            GBK_terminate("Expected to have a valid alignment");
75        }
76    }
77}
78
79__ATTR__NORETURN static void ph_exit(AW_window *aw_window, PH_root *ph_root) {
80    AW_root *aw_root = aw_window->get_root();
81    shutdown_macro_recording(aw_root);
82
83    GBDATA *gb_main = ph_root->get_gb_main();
84    if (gb_main) {
85        aw_root->unlink_awars_from_DB(gb_main);
86#if defined(DEBUG)
87        AWT_browser_forget_db(gb_main);
88#endif // DEBUG
89        GB_close(gb_main);
90    }
91
92    exit(EXIT_SUCCESS);
93}
94
95
96void expose_cb() {
97    if (PH_display::ph_display && PH_display::ph_display->displayed()!=DISP_NONE) {
98        PH_display::ph_display->clear_window();
99        PH_display::ph_display->display();
100    }
101}
102
103static void resize_cb() {
104    if (PH_display::ph_display) {
105        PH_display::ph_display->resized();
106        PH_display::ph_display->display();
107    }
108}
109
110static void gc_changed_cb(GcChange whatChanged) {
111    switch (whatChanged) {
112        case GC_COLOR_GROUP_USE_CHANGED:
113            ph_assert(0); // not used atm -> fall-through
114        case GC_COLOR_CHANGED:
115            expose_cb();
116            break;
117        case GC_FONT_CHANGED:
118            resize_cb();
119            break;
120    }
121}
122
123static GB_ERROR PH_create_ml_multiline_SAI(GB_CSTR sai_name, int nr, GBDATA **gb_sai_ptr, PH_root *ph_root) {
124    GBDATA   *gb_sai = GBT_find_or_create_SAI(ph_root->get_gb_main(), sai_name);
125    GBDATA   *gbd, *gb2;
126    GB_ERROR  error  = ph_check_initialized();
127
128    if (!error) {
129        for (gbd = GB_child(gb_sai); gbd; gbd = gb2) {
130            gb2 = GB_nextChild(gbd);
131
132            const char *key = GB_read_key_pntr(gbd);
133            if (!strcmp(key, "name")) continue;
134            if (!strncmp(key, "ali_", 4)) continue;
135
136            error = GB_delete(gbd);
137            if (error) break;
138        }
139    }
140
141    if (!error) {
142        GBDATA *gb_ali = GB_search(gb_sai, PHDATA::ROOT->use, GB_FIND);
143        if (gb_ali) {
144            for (gbd = GB_child(gb_ali); gbd; gbd = gb2) {
145                gb2 = GB_nextChild(gbd);
146
147                const char *key = GB_read_key_pntr(gbd);
148                if (!strcmp(key, "data")) continue;
149                if (!strcmp(key, "_TYPE")) continue;
150
151                error = GB_delete(gbd);
152                if (error) break;
153            }
154        }
155    }
156
157    GBDATA *gb_data = 0, *gb_TYPE = 0;
158
159    if (!error) {
160        gb_data             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "data", GB_STRING);
161        if (!gb_data) error = GB_await_error();
162    }
163
164    if (!error) {
165        gb_TYPE             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "_TYPE", GB_STRING);
166        if (!gb_TYPE) error = GB_await_error();
167    }
168
169    if (!error && !PHDATA::ROOT->markerline) {
170        error = "Nothing calculated yet";
171    }
172
173    if (!error) {
174        char *full_save_name = 0;
175        FILE *saveResults    = 0;
176        if (nr == 2) {
177            char *save_name = GB_unique_filename("conservationProfile", "gnu");
178            saveResults     = GB_fopen_tempfile(save_name, "w+", &full_save_name);
179            GB_remove_on_exit(full_save_name);
180            free(save_name);
181
182            if (!saveResults) error = GB_await_error();
183        }
184
185        if (!error) {
186            AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
187            long       minhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int();
188            long       maxhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int();
189            long       startcol   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int();
190            long       stopcol    = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int();
191            float     *markerline = PHDATA::ROOT->markerline;
192            long       len        = PHDATA::ROOT->get_seq_len();
193
194            char *data = (char *)calloc(sizeof(char), (int)len+1);
195            int   cnt  = 0;
196
197
198            for (int x=0; x<len; x++) {
199                char c;
200
201                if (x<startcol || x>stopcol) {
202                    c = '.';
203                }
204                else {
205                    float ml = markerline[x];
206                    if (nr==2 && ml>0.0) {
207                        ph_assert(saveResults);
208                        fprintf(saveResults, "%i\t%.2f\n", cnt, ml);
209                        cnt++;
210                    }
211
212                    if (ml>=0.0 && ml>=minhom && ml<=maxhom) {
213                        int digit = -1;
214                        switch (nr) {
215                            case 0: // hundred
216                                if (ml>=100.0) digit = 1;
217                                break;
218                            case 1: // ten
219                                if (ml>=10.0) digit = int(ml/10);
220                                break;
221                            case 2: // one
222                                digit = int(ml);
223                                break;
224                            default:
225                                ph_assert(0);
226                                break;
227                        }
228
229                        if (digit<0) c = '-';
230                        else         c = '0' + digit%10;
231                    }
232                    else {
233                        c = '-';
234                    }
235                }
236
237                data[x] = c;
238            }
239            data[len] = 0;
240
241            if (saveResults) {
242                fclose(saveResults);
243                fprintf(stderr, "Note: Frequencies as well saved to '%s'\n", full_save_name);
244            }
245
246            error = GB_write_string(gb_data, data);
247            if (!error) {
248                const char *buffer = GBS_global_string("FMX: Filter by Maximum Frequency: "
249                                                       "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
250                                                       startcol, stopcol, minhom, maxhom);
251                error = GB_write_string(gb_TYPE, buffer);
252            }
253            free(data);
254        }
255        free(full_save_name);
256    }
257
258    if (!error) *gb_sai_ptr = gb_sai;
259    return error;
260}
261
262static void PH_save_ml_multiline_cb(AW_window *aww, PH_root *ph_root) {
263    GB_transaction ta(ph_root->get_gb_main());
264
265    GB_ERROR  error     = 0;
266    char     *fname     = aww->get_root()->awar(AWAR_PHYLO_MARKERLINENAME)->read_string();
267    int       fname_len = strlen(fname);
268    {
269        char *digit_appended = (char*)malloc(fname_len+2);
270        memcpy(digit_appended, fname, fname_len);
271        strcpy(digit_appended+fname_len, "0");
272
273        freeset(fname, digit_appended);
274    }
275    GBDATA *gb_sai[3];
276    int i;
277    for (i=0; !error && i<3; i++) {
278        fname[fname_len] = '0'+i;
279        error = PH_create_ml_multiline_SAI(fname, i, &gb_sai[i], ph_root);
280    }
281
282    delete fname;
283
284    aw_message_if(ta.close(error));
285}
286
287static void PH_save_ml_cb(AW_window *aww, PH_root *ph_root) {
288    GBDATA  *gb_main = ph_root->get_gb_main();
289    GB_transaction ta(gb_main);
290
291    char   *fname  = aww->get_root()->awar(AWAR_PHYLO_MARKERLINENAME)->read_string();
292    GBDATA *gb_sai = GBT_find_or_create_SAI(gb_main, fname);
293
294    GB_ERROR error = ph_check_initialized();
295
296    if (!error) {
297        for (GBDATA *gbd = GB_child(gb_sai), *gbnext; gbd; gbd = gbnext) {
298            gbnext = GB_nextChild(gbd);
299
300            const char *key = GB_read_key_pntr(gbd);
301            if (!strcmp(key, "name")) continue;
302            if (!strncmp(key, "ali_", 4)) continue;
303
304            error = GB_delete(gbd);
305            if (error) break;
306        }
307    }
308
309    if (!error) {
310        GBDATA *gb_ali = GB_search(gb_sai, PHDATA::ROOT->use, GB_FIND);
311        if (gb_ali) {
312            for (GBDATA *gbd = GB_child(gb_ali), *gbnext; gbd; gbd = gbnext) {
313                gbnext = GB_nextChild(gbd);
314
315                const char *key = GB_read_key_pntr(gbd);
316                if (!strcmp(key, "bits")) continue;
317                if (!strcmp(key, "_TYPE")) continue;
318
319                error = GB_delete(gbd);
320                if (error) break;
321            }
322        }
323    }
324
325    GBDATA *gb_bits = 0, *gb_TYPE = 0;
326
327    if (!error) {
328        gb_bits             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "bits", GB_BITS);
329        if (!gb_bits) error = GB_await_error();
330    }
331
332    if (!error) {
333        gb_TYPE             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "_TYPE", GB_STRING);
334        if (!gb_TYPE) error = GB_await_error();
335    }
336
337    if (!error && !PHDATA::ROOT->markerline) {
338        error = "Nothing calculated yet";
339    }
340
341    if (!error) {
342        AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
343        long       minhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int();
344        long       maxhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int();
345        long       startcol   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int();
346        long       stopcol    = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int();
347        long       len        = PHDATA::ROOT->get_seq_len();
348        char      *bits       = (char *)calloc(sizeof(char), (int)len+1);
349        int        x;
350        float     *markerline = PHDATA::ROOT->markerline;
351
352        for (x=0; x<len; x++) {
353            int bit;
354
355            if (x < startcol || x>stopcol) {
356                bit = 0;
357            }
358            else {
359                float ml = markerline[x];
360
361                if (ml>=0.0 && ml>=minhom && ml<=maxhom) bit = 1;
362                else                     bit = 0;
363
364            }
365            bits[x] = '0'+bit;
366        }
367
368        GB_write_bits(gb_bits, bits, len, "0");
369        char buffer[1024];
370        sprintf(buffer, "FMX: Filter by Maximum Frequency: "
371                "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
372                startcol, stopcol, minhom, maxhom);
373
374        GB_write_string(gb_TYPE, buffer);
375
376        free(bits);
377    }
378    free(fname);
379    aw_message_if(ta.close(error));
380}
381
382
383static AW_window *PH_save_markerline(AW_root *root, PH_root *ph_root, int multi_line) {
384    // multi_line ==1 -> save three SAI's usable as column percentage
385
386    root->awar_string(AWAR_PHYLO_MARKERLINENAME, "markerline", AW_ROOT_DEFAULT);
387
388    AW_window_simple *aws = new AW_window_simple;
389
390    if (multi_line) {
391        aws->init(root, "EXPORT_FREQUENCY_LINES", "Export Frequency Lines");
392    }
393    else {
394        aws->init(root, "EXPORT_MARKER_LINE", "Export Marker Line");
395    }
396
397    aws->load_xfig("phylo/save_markerline.fig");
398
399    aws->callback(AW_POPDOWN);
400    aws->at("close");
401    aws->create_button("CLOSE", "CLOSE", "C");
402
403    aws->callback(makeHelpCallback("ph_export_markerline.hlp"));
404    aws->at("help");
405    aws->create_button("HELP", "HELP", "H");
406
407    aws->at("name");
408    aws->create_input_field(AWAR_PHYLO_MARKERLINENAME);
409
410    aws->at("box");
411    awt_create_SAI_selection_list(ph_root->get_gb_main(), aws, AWAR_PHYLO_MARKERLINENAME, false);
412
413    aws->at("save");
414    if (multi_line) aws->callback(makeWindowCallback(PH_save_ml_multiline_cb, ph_root));
415    else            aws->callback(makeWindowCallback(PH_save_ml_cb, ph_root));
416    aws->create_button("EXPORT", "EXPORT", "E");
417
418    return aws;
419}
420
421static AW_window *create_phyl_main_window(AW_root *aw_root, PH_root *ph_root) {
422    AW_window_menu_modes *awm = new AW_window_menu_modes;
423    awm->init(aw_root, "ARB_PHYLO", "ARB_PHYLO", 830, 630);
424
425    // create menus and menu inserts with callbacks
426
427    const GcChangedCallback gcChangedCb = makeGcChangedCallback(gc_changed_cb);
428
429    AW_gc_manager *gcmiddle =
430        AW_manage_GC(awm,
431                     awm->get_window_id(),
432                     awm->get_device(AW_MIDDLE_AREA),
433                     PH_GC_SEQUENCE, PH_GC_DRAG, AW_GCM_DATA_AREA,
434                     gcChangedCb,
435                     "#C4B6D0",
436                     "#SEQUENCE$#000000",
437                     "#MARKER$#E0F570",
438                     "NOT_MARKER$#A270C0",
439                     NULL);
440
441    AW_manage_GC(awm,
442                 "ARB_PHYLO_BOTTOM",
443                 awm->get_device(AW_BOTTOM_AREA),
444                 PH_GC_BOTTOM_TEXT, PH_GC_BOTTOM_DRAG, AW_GCM_WINDOW_AREA,
445                 gcChangedCb,
446                 "lightgrey",
447                 "#FOOTER",
448                 NULL);
449
450
451#if defined(DEBUG)
452    AWT_create_debug_menu(awm);
453#endif // DEBUG
454
455    // File menu
456    awm->create_menu("File", "F");
457    awm->insert_menu_topic("export_filter", "Export Filter",      "E", "ph_export_markerline.hlp", AWM_ALL, makeCreateWindowCallback(PH_save_markerline, ph_root, 0));
458    awm->insert_menu_topic("export_freq",   "Export Frequencies", "F", "ph_export_markerline.hlp", AWM_ALL, makeCreateWindowCallback(PH_save_markerline, ph_root, 1));
459    insert_macro_menu_entry(awm, false);
460
461    awm->insert_menu_topic("quit", "Quit", "Q", "quit.hlp", AWM_ALL, makeWindowCallback(ph_exit, ph_root));
462
463    // Calculate menu
464    awm->create_menu("Calculate", "C");
465    awm->insert_menu_topic("calc_column_filter", "Column Filter", "F", "no help", AWM_ALL, makeWindowCallback(ph_calc_filter_cb));
466
467    // Config menu
468    awm->create_menu("Config", "o");
469    awm->insert_menu_topic("config_column_filter", "Column Filter", "F", "no help", AWM_ALL, PH_create_filter_window);
470
471    // Properties menu
472    awm->create_menu("Properties", "P");
473#if defined(ARB_MOTIF)
474    awm->insert_menu_topic("props_menu", "Frame settings ...",   "F", "props_frame.hlp", AWM_ALL, AW_preset_window);
475#endif
476    awm->insert_menu_topic("props_data", "Colors and Fonts ...", "C", "color_props.hlp", AWM_ALL, makeCreateWindowCallback(AW_create_gc_window, gcmiddle));
477    awm->sep______________();
478    AW_insert_common_property_menu_entries(awm);
479    awm->sep______________();
480    awm->insert_menu_topic("save_props", "Save Properties (phylo.arb)", "S", "savedef.hlp", AWM_ALL, AW_save_properties);
481
482
483    // set window areas
484    awm->set_info_area_height(30);
485    awm->at(5, 2);
486    awm->auto_space(5, -2);
487
488    awm->callback(makeWindowCallback(ph_exit, ph_root));
489    awm->button_length(0);
490    awm->help_text("quit.hlp");
491    awm->create_button("QUIT", "QUIT");
492#if defined(ARB_GTK)
493    awm->set_close_action("QUIT");
494#endif
495
496    awm->callback(makeHelpCallback("phylo.hlp"));
497    awm->button_length(0);
498    awm->create_button("HELP", "HELP", "H");
499
500
501    awm->set_bottom_area_height(120);
502
503    awm->set_expose_callback(AW_MIDDLE_AREA, makeWindowCallback(expose_cb));
504    awm->set_resize_callback(AW_MIDDLE_AREA, makeWindowCallback(resize_cb));
505    awm->set_expose_callback(AW_BOTTOM_AREA, makeWindowCallback(display_status_cb));
506    awm->set_resize_callback(AW_BOTTOM_AREA, makeWindowCallback(display_status_cb));
507
508    return awm;
509}
510
511
512static AW_window *create_select_alignment_window(AW_root *aw_root, AW_window *main_window, PH_root *ph_root) {
513    AW_window_simple *aws = new AW_window_simple;
514
515    aws->init(aw_root, "SELECT_ALIGNMENT", "ARB_PHYLO: Select alignment");
516    aws->load_xfig("phylo/select_ali.fig");
517    aws->button_length(10);
518
519    aws->at("which_alignment");
520    awt_create_ALI_selection_list(ph_root->get_gb_main(), (AW_window *)aws, AWAR_PHYLO_ALIGNMENT, "*=");
521
522    aws->auto_space(10, 10);
523
524    aws->at("ok");
525    aws->callback(makeWindowCallback(startup_sequence_cb, main_window, ph_root));
526    aws->create_button("OK", "Ok", "D");
527
528    aws->callback(makeWindowCallback(ph_exit, ph_root));
529    aws->create_button("ABORT", "Abort", "D");
530
531#if defined(ARB_GTK)
532    aws->set_close_action("ABORT");
533#endif
534
535    return aws;
536}
537
538
539
540PH_used_windows::PH_used_windows()
541{
542    memset((char *) this, 0, sizeof(PH_used_windows));
543}
544
545// initialize 'globals'
546PH_used_windows *PH_used_windows::windowList = 0;
547PH_display *PH_display::ph_display=0;
548PHDATA *PHDATA::ROOT = 0;
549
550static void create_variables(AW_root *aw_root, AW_default def, GBDATA *gb_main) {
551    aw_root->awar_string(AWAR_PHYLO_ALIGNMENT,     "", def);
552    aw_root->awar_string(AWAR_PHYLO_FILTER_FILTER, "", def);
553    PH_create_filter_variables(aw_root, def, gb_main);
554}
555
556int ARB_main(int argc, char *argv[]) {
557    aw_initstatus();
558
559    GB_shell shell;
560    AW_root  *aw_root = AWT_create_root("phylo.arb", "ARB_PHYLO", need_macro_ability(), &argc, &argv);
561
562    int exitcode = EXIT_SUCCESS;
563    if (argc > 2 || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
564        fprintf(stderr, "Usage: arb_phylo [database]\n");
565        exitcode = EXIT_FAILURE;
566    }
567    else {
568        const char *db_server = (argc == 2 ? argv[1] : ":");
569
570        PH_used_windows *puw = new PH_used_windows;
571        PH_display      *phd = new PH_display;
572
573        PH_root  *ph_root = new PH_root;
574        GB_ERROR  error   = ph_root->open(db_server);
575
576        if (!error) error = configure_macro_recording(aw_root, "ARB_PHYLO", ph_root->get_gb_main());
577        if (!error) {
578            GBDATA *gb_main = ph_root->get_gb_main();
579
580            // create arb_phylo awars :
581            create_variables(aw_root, AW_ROOT_DEFAULT, gb_main);
582            ARB_init_global_awars(aw_root, AW_ROOT_DEFAULT, gb_main);
583#if defined(DEBUG)
584            AWT_create_db_browser_awars(aw_root, AW_ROOT_DEFAULT);
585#endif // DEBUG
586
587#if defined(DEBUG)
588            AWT_announce_db_to_browser(gb_main, GBS_global_string("ARB-database (%s)", db_server));
589#endif // DEBUG
590
591            // create main window :
592
593            puw->phylo_main_window = create_phyl_main_window(aw_root, ph_root);
594            puw->windowList        = puw;
595
596            phd->ph_display = phd;
597
598            // loading database
599            GB_push_transaction(gb_main);
600
601            ConstStrArray alignment_names;
602            GBT_get_alignment_names(alignment_names, gb_main);
603
604            int num_alignments;
605            for (num_alignments = 0; alignment_names[num_alignments] != 0; num_alignments++) {}
606
607            if (num_alignments > 1) {
608                char *defaultAli = GBT_get_default_alignment(gb_main);
609                aw_root->awar(AWAR_PHYLO_ALIGNMENT)->write_string(defaultAli);
610                create_select_alignment_window(aw_root, puw->phylo_main_window, ph_root)->show();
611                free(defaultAli);
612            }
613            else {
614                aw_root->awar(AWAR_PHYLO_ALIGNMENT)->write_string(alignment_names[0]);
615                startup_sequence_cb(NULL, puw->phylo_main_window, ph_root);
616            }
617            GB_pop_transaction(gb_main);
618
619            AWT_install_cb_guards();
620            aw_root->main_loop();
621        }
622
623        if (error) {
624            aw_popup_exit(error);
625            exitcode = EXIT_FAILURE;
626        }
627    }
628
629    delete aw_root;
630    return exitcode;
631}
632
Note: See TracBrowser for help on using the repository browser.