UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2017 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <stdbool.h> 33 34 #include "toolkit.h" 35 #include "toolbar.h" 36 #include "model.h" 37 #include "image.h" 38 #include "../common/document.h" 39 #include "../common/properties.h" 40 41 #include <ucx/utils.h> 42 43 #include <pthread.h> 44 45 #ifndef UI_GTK2 46 static GtkApplication *app; 47 #endif 48 49 static char *application_name; 50 51 static ui_callback startup_func; 52 static void *startup_data; 53 static ui_callback open_func; 54 void *open_data; 55 static ui_callback exit_func; 56 void *exit_data; 57 58 static ui_callback appclose_fnc; 59 static void *appclose_udata; 60 61 static UiObject *active_window; 62 63 static int scale_factor = 1; 64 65 void ui_init(char *appname, int argc, char **argv) { 66 uic_init_global_context(); 67 68 gtk_init(&argc, &argv); 69 application_name = appname; 70 71 uic_docmgr_init(); 72 ui_toolbar_init(); 73 74 // init custom types 75 ui_list_init(); 76 77 ui_image_init(); 78 79 uic_load_app_properties(); 80 81 #ifdef UI_SUPPORTS_SCALE 82 scale_factor = gdk_monitor_get_scale_factor( 83 gdk_display_get_primary_monitor(gdk_display_get_default())); 84 #endif 85 } 86 87 char* ui_appname() { 88 return application_name; 89 } 90 91 void ui_onstartup(ui_callback f, void *userdata) { 92 startup_func = f; 93 startup_data = userdata; 94 } 95 96 void ui_onopen(ui_callback f, void *userdata) { 97 open_func = f; 98 open_data = userdata; 99 } 100 101 void ui_onexit(ui_callback f, void *userdata) { 102 exit_func = f; 103 exit_data = userdata; 104 } 105 106 107 #ifndef UI_GTK2 108 static void app_startup(GtkApplication* app, gpointer userdata) { 109 if(startup_func) { 110 startup_func(NULL, startup_data); 111 } 112 } 113 114 static void app_activate(GtkApplication* app, gpointer userdata) { 115 printf("activate\n"); 116 } 117 #endif 118 119 void ui_main() { 120 #ifndef UI_GTK2 121 sstr_t appid = ucx_sprintf( 122 "ui.%s", 123 application_name ? application_name : "application1"); 124 125 app = gtk_application_new( 126 appid.ptr, 127 G_APPLICATION_FLAGS_NONE); 128 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL); 129 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL); 130 g_application_run(G_APPLICATION (app), 0, NULL); 131 g_object_unref (app); 132 133 free(appid.ptr); 134 #else 135 if(startup_func) { 136 startup_func(NULL, startup_data); 137 } 138 gtk_main(); 139 #endif 140 if(exit_func) { 141 exit_func(NULL, exit_data); 142 } 143 uic_store_app_properties(); 144 } 145 146 #ifndef UI_GTK2 147 void ui_app_quit() { 148 g_application_quit(G_APPLICATION(app)); 149 } 150 151 GtkApplication* ui_get_application() { 152 return app; 153 } 154 #endif 155 156 void ui_show(UiObject *obj) { 157 uic_check_group_widgets(obj->ctx); 158 gtk_widget_show_all(obj->widget); 159 } 160 161 void ui_close(UiObject *obj) { 162 gtk_widget_destroy(obj->widget); 163 } 164 165 166 static gboolean ui_job_finished(void *data) { 167 UiJob *job = data; 168 169 UiEvent event; 170 event.obj = job->obj; 171 event.window = job->obj->window; 172 event.document = job->obj->ctx->document; 173 event.intval = 0; 174 event.eventdata = NULL; 175 176 job->finish_callback(&event, job->finish_data); 177 free(job); 178 return FALSE; 179 } 180 181 static void* ui_jobthread(void *data) { 182 UiJob *job = data; 183 int result = job->job_func(job->job_data); 184 if(!result) { 185 g_idle_add(ui_job_finished, job); 186 } 187 return NULL; 188 } 189 190 void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd) { 191 UiJob *job = malloc(sizeof(UiJob)); 192 job->obj = obj; 193 job->job_func = tf; 194 job->job_data = td; 195 job->finish_callback = f; 196 job->finish_data = fd; 197 pthread_t pid; 198 pthread_create(&pid, NULL, ui_jobthread, job); 199 } 200 201 void ui_set_enabled(UIWIDGET widget, int enabled) { 202 gtk_widget_set_sensitive(widget, enabled); 203 } 204 205 void ui_set_show_all(UIWIDGET widget, int value) { 206 gtk_widget_set_no_show_all(widget, !value); 207 } 208 209 void ui_set_visible(UIWIDGET widget, int visible) { 210 if(visible) { 211 gtk_widget_set_no_show_all(widget, FALSE); 212 gtk_widget_show_all(widget); 213 } else { 214 gtk_widget_hide(widget); 215 } 216 } 217 218 void ui_clipboard_set(char *str) { 219 GtkClipboard *cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 220 gtk_clipboard_set_text(cb, str, strlen(str)); 221 } 222 223 char* ui_clipboard_get() { 224 GtkClipboard *cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 225 char *str = gtk_clipboard_wait_for_text(cb); 226 if(str) { 227 char *copy = strdup(str); 228 g_free(str); 229 return copy; 230 } else { 231 return NULL; 232 } 233 } 234 235 int ui_get_scalefactor() { 236 return scale_factor; 237 } 238 239 void ui_destroy_userdata(GtkWidget *object, void *userdata) { 240 free(userdata); 241 } 242 243 void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data) { 244 ui_destroy_boundvar(data->obj->ctx, data->var); 245 free(data); 246 } 247 248 void ui_destroy_boundvar(UiContext *ctx, UiVar *var) { 249 if(var->type == UI_VAR_SPECIAL) { 250 free(var); 251 } else { 252 uic_remove_bound_var(ctx, var); 253 } 254 } 255 256 void ui_set_active_window(UiObject *obj) { 257 active_window = obj; 258 } 259 260 UiObject *ui_get_active_window() { 261 return active_window; 262 } 263 264 265