2 * Copyright 2022 Olaf Wintermann
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
35 #include <ucx/buffer.h>
36 #include <ucx/utils.h>
38 static XtAppContext app;
39 static Display *display;
40 static Widget toplevel_window;
42 static char *open_file_arg;
44 static int event_pipe[2];
46 static String fallback[] = {
48 "*rt*fontType: FONT_IS_XFT",
52 "*pbbutton.shadowThickness: 1",
53 "*pbbutton.highlightThickness: 1",
55 "*XmText.baseTranslations: #override\\n" \
56 "Ctrl~Alt~Meta<KeyPress>v: paste-clipboard()\\n" \
57 "Ctrl~Alt~Meta<KeyPress>c: copy-clipboard()\\n" \
58 "Ctrl~Alt~Meta<KeyPress>x: cut-clipboard()\\n" \
59 "Ctrl~Alt~Meta<KeyPress>u: delete-to-start-of-line()\\n",
60 "*XmTextField.baseTranslations: #override\\n" \
61 "Ctrl~Alt~Meta<KeyPress>v: paste-clipboard()\\n" \
62 "Ctrl~Alt~Meta<KeyPress>c: copy-clipboard()\\n" \
63 "Ctrl~Alt~Meta<KeyPress>x: cut-clipboard()\\n" \
64 "Ctrl~Alt~Meta<KeyPress>u: delete-to-start-of-line()\\n",
68 static String langProc(Display *dp, String xnl, XtPointer closure) {
69 setlocale(LC_ALL, xnl);
70 setlocale(LC_NUMERIC, "C");
71 return setlocale(LC_ALL, NULL);
74 typedef struct EventLoopCB {
79 static void input_proc(XtPointer data, int *source, XtInputId *iid) {
81 ssize_t r = read(event_pipe[0], cb, sizeof(EventLoopCB)*16);
82 size_t n = r / sizeof(EventLoopCB);
83 for(int i=0;i<n;i++) {
84 cb[i].proc(cb[i].data);
88 int main(int argc, char** argv) {
89 // disable stdout buffering, because the netbeans's internal terminal
90 // has a bug on freebsd and doesn't flush the output after a newline
91 setvbuf(stdout, NULL, _IONBF, 0);
93 // init event pipe for xt event loop
94 if(pipe(event_pipe)) {
100 XtToolkitInitialize();
101 XtSetLanguageProc(NULL, langProc, NULL);
102 app = XtCreateApplicationContext();
103 XtAppSetFallbackResources(app, fallback);
105 display = XtOpenDisplay(app, NULL, APP_NAME, APP_CLASS, NULL, 0, &argc, argv);
109 if(stat(argv[1], &s)) {
110 fprintf(stderr, "Cannot open file: %s\n", argv[1]);
114 open_file_arg = argv[1];
120 (XtPointer)XtInputReadMask,
129 MainWindow *window = WindowCreate(display);
130 toplevel_window = window->window;
132 // random numbers only used for creating tmp dirs
141 XtAppContext* GetAppContext(void) {
145 void ApplicationExit(void) {
146 XtAppSetExitFlag(app);
149 void AppExecProc(XtWorkProc proc, XtPointer data) {
153 write(event_pipe[1], &cb, sizeof(cb));
156 char* GetOpenFileArg(void) {
157 return open_file_arg;
160 void CleanOpenFileArg(void) {
161 open_file_arg = NULL;
164 static Window app_player_window = 0;
166 void SetPlayerWindow(Window w) {
167 app_player_window = w;
171 * Extended Xt main loop, that also handles external window events
173 void AppMainLoop(XtAppContext app) {
174 while(!XtAppGetExitFlag(app)) {
176 XtAppNextEvent(app, &event);
178 if(app_player_window != 0 && event.xany.window == app_player_window) {
179 WindowHandlePlayerEvent(GetMainWindow(), &event);
181 XtDispatchEvent(&event);