1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2014 Olaf Wintermann. All rights reserved. |
4 * Copyright 2024 Olaf Wintermann. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
31 #include <unistd.h> |
31 #include <unistd.h> |
32 #include <pthread.h> |
32 #include <pthread.h> |
33 |
33 |
34 #include "toolkit.h" |
34 #include "toolkit.h" |
35 #include "toolbar.h" |
35 #include "toolbar.h" |
|
36 #include "container.h" |
36 #include "stock.h" |
37 #include "stock.h" |
|
38 #include "../common/menu.h" |
|
39 #include "../common/toolbar.h" |
37 #include "../common/document.h" |
40 #include "../common/document.h" |
38 #include "../common/properties.h" |
41 #include "../common/properties.h" |
39 #include <cx/buffer.h> |
42 #include <cx/buffer.h> |
40 |
43 |
|
44 #include <X11/Intrinsic.h> |
|
45 #include <Xm/CutPaste.h> |
|
46 |
41 static XtAppContext app; |
47 static XtAppContext app; |
42 static Display *display; |
48 static Display *display; |
43 static Widget active_window; |
49 static Widget active_window; |
44 static char *application_name; |
50 static const char *application_name; |
45 |
51 |
46 static ui_callback startup_func; |
52 static ui_callback startup_func; |
47 static void *startup_data; |
53 static void *startup_data; |
48 static ui_callback open_func; |
54 static ui_callback open_func; |
49 void *open_data; |
55 void *open_data; |
66 "*f1*fontSize: 11", |
72 "*f1*fontSize: 11", |
67 "*renderTable: rt", |
73 "*renderTable: rt", |
68 "*rt*fontType: FONT_IS_XFT", |
74 "*rt*fontType: FONT_IS_XFT", |
69 "*rt*fontName: Sans", |
75 "*rt*fontName: Sans", |
70 "*rt*fontSize: 11", |
76 "*rt*fontSize: 11", |
|
77 |
|
78 "*window_frame.shadowType: SHADOW_ETCHED_OUT", |
|
79 "*window_frame.shadowThickness: 1", |
|
80 "*togglebutton.shadowThickness: 1", |
|
81 "*togglebutton.highlightThickness: 2", |
71 NULL |
82 NULL |
72 }; |
83 }; |
73 |
84 |
74 void input_proc(XtPointer data, int *source, XtInputId *iid) { |
85 void input_proc(XtPointer data, int *source, XtInputId *iid) { |
75 void *ptr; |
86 void *ptr; |
76 read(event_pipe[0], &ptr, sizeof(void*)); |
87 read(event_pipe[0], &ptr, sizeof(void*)); |
77 } |
88 } |
78 |
89 |
79 void ui_init(char *appname, int argc, char **argv) { |
90 void ui_init(const char *appname, int argc, char **argv) { |
80 application_name = appname; |
91 application_name = appname; |
|
92 uic_init_global_context(); |
81 |
93 |
82 XtToolkitInitialize(); |
94 XtToolkitInitialize(); |
83 XtSetLanguageProc(NULL, NULL, NULL); |
95 XtSetLanguageProc(NULL, NULL, NULL); |
84 app = XtCreateApplicationContext(); |
96 app = XtCreateApplicationContext(); |
85 XtAppSetFallbackResources(app, fallback); |
97 XtAppSetFallbackResources(app, fallback); |
86 |
98 |
87 display = XtOpenDisplay(app, NULL, appname, appname, NULL, 0, &argc, argv); |
99 display = XtOpenDisplay(app, NULL, appname, appname, NULL, 0, &argc, argv); |
88 char **missing = NULL; |
|
89 int nm = 0; |
|
90 char *def = NULL; |
|
91 XCreateFontSet(display, "-dt-interface system-medium-r-normal-s*utf*", &missing, &nm, &def); |
|
92 |
100 |
93 uic_docmgr_init(); |
101 uic_docmgr_init(); |
94 ui_toolbar_init(); |
102 uic_menu_init(); |
95 ui_stock_init(); |
103 uic_toolbar_init(); |
96 |
|
97 uic_load_app_properties(); |
104 uic_load_app_properties(); |
98 |
105 |
99 if(pipe(event_pipe)) { |
106 if(pipe(event_pipe)) { |
100 fprintf(stderr, "UiError: Cannot create event pipe\n"); |
107 fprintf(stderr, "UiError: Cannot create event pipe\n"); |
101 exit(-1); |
108 exit(-1); |
155 } |
162 } |
156 |
163 |
157 void ui_show(UiObject *obj) { |
164 void ui_show(UiObject *obj) { |
158 uic_check_group_widgets(obj->ctx); |
165 uic_check_group_widgets(obj->ctx); |
159 XtRealizeWidget(obj->widget); |
166 XtRealizeWidget(obj->widget); |
160 ui_window_dark_theme(XtDisplay(obj->widget), XtWindow(obj->widget)); // TODO: if |
167 } |
161 } |
168 |
162 |
169 void ui_close(UiObject *obj) { |
163 // implemented in window.c |
170 |
164 //void ui_close(UiObject *obj) |
171 } |
|
172 |
165 |
173 |
166 void ui_set_enabled(UIWIDGET widget, int enabled) { |
174 void ui_set_enabled(UIWIDGET widget, int enabled) { |
167 XtSetSensitive(widget, enabled); |
175 XtSetSensitive(widget, enabled); |
168 } |
176 } |
169 |
177 |
180 XtUnmanageChild(widget); |
188 XtUnmanageChild(widget); |
181 } |
189 } |
182 } |
190 } |
183 |
191 |
184 static Boolean ui_job_finished(void *data) { |
192 static Boolean ui_job_finished(void *data) { |
185 printf("WorkProc\n"); |
|
186 UiJob *job = data; |
193 UiJob *job = data; |
187 |
194 if(job->finish_callback) { |
188 UiEvent event; |
195 UiEvent event; |
189 event.obj = job->obj; |
196 event.obj = job->obj; |
190 event.window = job->obj->window; |
197 event.window = job->obj->window; |
191 event.document = job->obj->ctx->document; |
198 event.document = job->obj->ctx->document; |
192 event.intval = 0; |
199 event.intval = 0; |
193 event.eventdata = NULL; |
200 event.eventdata = NULL; |
194 |
201 job->finish_callback(&event, job->finish_data); |
195 job->finish_callback(&event, job->finish_data); |
202 } |
196 free(job); |
203 free(job); |
197 return TRUE; |
204 return TRUE; |
198 } |
205 } |
199 |
206 |
200 static void* ui_jobthread(void *data) { |
207 static void* ui_jobthread(void *data) { |
201 UiJob *job = data; |
208 UiJob *job = data; |
202 int result = job->job_func(job->job_data); |
209 int result = job->job_func(job->job_data); |
203 if(!result) { |
210 if(!result) { |
204 printf("XtAppAddWorkProc\n"); |
|
205 write(event_pipe[1], &job, sizeof(void*)); // hack |
211 write(event_pipe[1], &job, sizeof(void*)); // hack |
206 XtAppAddWorkProc(app, ui_job_finished, job); |
212 XtAppAddWorkProc(app, ui_job_finished, job); |
207 |
213 |
208 } |
214 } |
209 return NULL; |
215 return NULL; |
219 pthread_t pid; |
225 pthread_t pid; |
220 pthread_create(&pid, NULL, ui_jobthread, job); |
226 pthread_create(&pid, NULL, ui_jobthread, job); |
221 } |
227 } |
222 |
228 |
223 void ui_clipboard_set(char *str) { |
229 void ui_clipboard_set(char *str) { |
224 printf("copy: {%s}\n", str); |
|
225 int length = strlen(str) + 1; |
230 int length = strlen(str) + 1; |
226 |
231 |
227 Display *dp = XtDisplayOfObject(active_window); |
232 Display *dp = XtDisplayOfObject(active_window); |
228 Window window = XtWindowOfObject(active_window); |
233 Window window = XtWindowOfObject(active_window); |
229 |
234 |
285 |
290 |
286 Widget ui_get_active_window() { |
291 Widget ui_get_active_window() { |
287 return active_window; |
292 return active_window; |
288 } |
293 } |
289 |
294 |
|
295 /* |
|
296 * doesn't work with gnome anymore |
|
297 */ |
290 void ui_window_dark_theme(Display *dp, Window window) { |
298 void ui_window_dark_theme(Display *dp, Window window) { |
291 Atom atom = XInternAtom(dp, "_GTK_THEME_VARIANT", False); |
299 Atom atom = XInternAtom(dp, "_GTK_THEME_VARIANT", False); |
292 Atom type = XInternAtom(dp, "UTF8_STRING", False); |
300 Atom type = XInternAtom(dp, "UTF8_STRING", False); |
293 XChangeProperty( |
301 XChangeProperty( |
294 dp, |
302 dp, |
298 8, |
306 8, |
299 PropModeReplace, |
307 PropModeReplace, |
300 (const unsigned char*)"dark", |
308 (const unsigned char*)"dark", |
301 4); |
309 4); |
302 } |
310 } |
|
311 |
|
312 void ui_destroy_eventdata(Widget w, XtPointer *data, XtPointer d) { |
|
313 free(data); |
|
314 } |
|
315 |
|
316 void ui_set_widget_groups(UiContext *ctx, Widget widget, const int *groups) { |
|
317 if(!groups) { |
|
318 return; |
|
319 } |
|
320 size_t ngroups = uic_group_array_size(groups); |
|
321 ui_set_widget_ngroups(ctx, widget, groups, ngroups); |
|
322 } |
|
323 |
|
324 void ui_set_widget_ngroups(UiContext *ctx, Widget widget, const int *groups, size_t ngroups) { |
|
325 if(ngroups > 0) { |
|
326 uic_add_group_widget_i(ctx, widget, (ui_enablefunc)ui_set_enabled, groups, ngroups); |
|
327 ui_set_enabled(widget, FALSE); |
|
328 } |
|
329 } |
|
330 |