]> git.draconx.ca Git - rrace.git/blob - src/motif.c
96d8e086666633428bb0d9c54aba5629c9b6f185
[rrace.git] / src / motif.c
1 /*
2  * X11 GUI for slide puzzle game
3  * Copyright © 2022 Nick Bowler
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <getopt.h>
23
24 #include <Xm/XmAll.h>
25
26 #include "help.h"
27 #include "motif.h"
28 #include "options.h"
29 #include "game.h"
30
31 #define PROGNAME "rrace"
32 static const char *progname = PROGNAME;
33 static const struct option lopts[] = { LOPTS_INITIALIZER, {0} };
34
35 static char * const default_resources[] = {
36         PROGNAME "*game.height: 371", // 365 + 2*shadowThickness
37         PROGNAME "*game.width: 498",
38
39         PROGNAME "*game.XmFrame.shadowThickness: 3",
40         PROGNAME "*game.XmFrame.shadowType: shadow_in",
41         PROGNAME "*goalArea.leftOffset: 1",
42         PROGNAME "*gameCanvas.background: #404040",
43
44         NULL
45 };
46
47 static void print_version(void)
48 {
49         printf("%s %s\n", PROGNAME, PACKAGE_VERSION);
50         printf("Copyright (C) 2022 Nick Bowler\n");
51         puts("License GPLv3+: GNU GPL version 3 or any later version");
52         puts("This is free software: you are free to change and redistribute it.");
53         puts("There is NO WARRANTY, to the extent permitted by law.");
54 }
55
56 static void print_usage(FILE *f)
57 {
58         fprintf(f, "Usage: %s [options]\n", progname);
59         if (f != stdout)
60                 fprintf(f, "Try %s --help for more information.\n", progname);
61 }
62
63 static void print_help(void)
64 {
65         const struct option *opt;
66
67         print_usage(stdout);
68
69         putchar('\n');
70         puts("Options:");
71         for (opt = lopts; opt->name; opt++) {
72                 struct lopt_help help;
73                 int w;
74
75                 if (!lopt_get_help(opt, &help))
76                         continue;
77                 help_print_option(opt, help.arg, help.desc, 20);
78         }
79         putchar('\n');
80
81         printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
82 }
83
84 static Widget early_setup(XtAppContext *app, int argc, char **argv)
85 {
86         Widget shell;
87         int opt;
88
89         /* Check for --help/--version early (before X connection) */
90         opterr = 0;
91         while ((opt = getopt_long_only(argc, argv, "", lopts, NULL)) != -1) {
92                 switch (opt) {
93                 case LOPT_VERSION:
94                         print_version();
95                         exit(EXIT_SUCCESS);
96                 case LOPT_HELP:
97                         print_help();
98                         exit(EXIT_SUCCESS);
99                 }
100         }
101
102         shell = XtOpenApplication(app, PROGNAME, NULL, 0,
103                                   &argc, argv, (String *)default_resources,
104                                   sessionShellWidgetClass, NULL, 0);
105
106         opterr = optind = 1;
107         while ((opt = getopt_long_only(argc, argv, "", lopts, NULL)) != -1) {
108                 switch (opt) {
109                 default:
110                         print_usage(stderr);
111                         exit(EXIT_FAILURE);
112                 }
113         }
114
115         if (argv[optind]) {
116                 fprintf(stderr, "%s: excess command-line arguments.\n",
117                                 progname);
118                 print_usage(stderr);
119                 exit(EXIT_FAILURE);
120         }
121
122         return shell;
123 }
124
125 static XtAppContext app_initialize(int argc, char **argv)
126 {
127         static struct app_state state;
128         XtAppContext app;
129         Widget shell;
130
131         if (argc > 0)
132                 progname = argv[0];
133
134         shell = early_setup(&app, argc, argv);
135         ui_initialize(&state, shell);
136         x11_initialize(&state, XtScreen(shell));
137         game_reset(&state.board);
138         XtRealizeWidget(shell);
139
140         return app;
141 }
142
143 int main(int argc, char **argv)
144 {
145         XtAppMainLoop(app_initialize(argc, argv));
146         return 0;
147 }