ui/motif/window.c

changeset 115
e57ca2747782
parent 108
77254bd6dccb
equal deleted inserted replaced
114:3da24640513a 115:e57ca2747782
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <unistd.h>
34
35 #include "window.h"
31 36
32 #include "toolkit.h" 37 #include "toolkit.h"
33 #include "menu.h" 38 #include "menu.h"
34 #include "toolbar.h" 39 #include "toolbar.h"
35 #include "container.h" 40 #include "container.h"
36 #include "../ui/window.h" 41 #include "pathbar.h"
37 #include "../common/context.h" 42 #include "../common/context.h"
43 #include "../common/utils.h"
38 44
39 #include "Grid.h" 45 #include "Grid.h"
46 #include "Fsb.h"
40 47
41 #include <cx/mempool.h> 48 #include <cx/mempool.h>
42 49
43 static int nwindows = 0; 50 static int nwindows = 0;
44 51
48 void ui_window_widget_destroy(UiObject *obj) { 55 void ui_window_widget_destroy(UiObject *obj) {
49 XtDestroyWidget(obj->widget); 56 XtDestroyWidget(obj->widget);
50 uic_object_destroy(obj); 57 uic_object_destroy(obj);
51 nwindows--; 58 nwindows--;
52 if(nwindows == 0) { 59 if(nwindows == 0) {
53 ui_exit_mainloop(); 60 ui_app_quit();
54 } 61 }
55 } 62 }
56 63
57 static void window_close_handler(Widget window, void *udata, void *cdata) { 64 static void window_close_handler(Widget window, void *udata, void *cdata) {
58 UiObject *obj = udata; 65 UiObject *obj = udata;
65 ui_window_widget_destroy(obj); 72 ui_window_widget_destroy(obj);
66 } 73 }
67 } 74 }
68 75
69 76
70 static UiObject* create_window(const char *title, void *window_data, Boolean simple) { 77 static UiObject* create_window(const char *title, Boolean simple) {
71 CxMempool *mp = cxMempoolCreateSimple(256); 78 CxMempool *mp = cxMempoolCreateSimple(256);
72 const CxAllocator *a = mp->allocator; 79 const CxAllocator *a = mp->allocator;
73 UiObject *obj = uic_object_new_toplevel(); 80 UiObject *obj = uic_object_new_toplevel();
74 obj->window = window_data;
75 obj->destroy = ui_window_widget_destroy; 81 obj->destroy = ui_window_widget_destroy;
82
83 int window_width = window_default_width;
84 int window_height = window_default_height;
85 if(!simple) {
86 ui_get_window_default_width(&window_width, &window_height);
87 }
88
89 UiMotifAppWindow *appwindow = cxZalloc(a, sizeof(UiMotifAppWindow));
90 ui_object_set(obj, "ui_motif_app_window", appwindow);
76 91
77 Arg args[16]; 92 Arg args[16];
78 int n = 0; 93 int n = 0;
79 XtSetArg(args[n], XmNtitle, title); n++; 94 XtSetArg(args[n], XmNtitle, title); n++;
80 XtSetArg(args[n], XmNminWidth, 100); n++; 95 XtSetArg(args[n], XmNminWidth, 100); n++;
81 XtSetArg(args[n], XmNminHeight, 50); n++; 96 XtSetArg(args[n], XmNminHeight, 50); n++;
82 XtSetArg(args[n], XmNwidth, window_default_width); n++; 97 XtSetArg(args[n], XmNwidth, window_width); n++;
83 XtSetArg(args[n], XmNheight, window_default_height); n++; 98 XtSetArg(args[n], XmNheight, window_height); n++;
84 99
85 Widget toplevel = XtAppCreateShell( 100 Widget toplevel = XtAppCreateShell(
86 ui_appname(), 101 ui_appname(),
87 "mainwindow", 102 "mainwindow",
88 //applicationShellWidgetClass, 103 //applicationShellWidgetClass,
108 toplevel, 123 toplevel,
109 NULL); 124 NULL);
110 125
111 // menu 126 // menu
112 if(!simple) { 127 if(!simple) {
113 ui_create_menubar(obj, window); 128 appwindow->menubar = ui_create_menubar(obj, window);
114 } 129 }
115 130
116 // content frame 131 // content frame
117 n = 0; 132 n = 0;
118 Widget frame = XmCreateFrame(window, "window_frame", args, n); 133 Widget frame = XmCreateFrame(window, "window_frame", args, n);
133 obj->widget = toplevel; 148 obj->widget = toplevel;
134 nwindows++; 149 nwindows++;
135 return obj; 150 return obj;
136 } 151 }
137 152
138 UiObject* ui_window(const char *title, void *window_data) { 153 UiObject* ui_window(const char *title) {
139 return create_window(title, window_data, FALSE); 154 return create_window(title, FALSE);
140 } 155 }
141 156
142 UiObject* ui_simple_window(const char *title, void *window_data) { 157 UiObject* ui_simple_window(const char *title) {
143 return create_window(title, window_data, TRUE); 158 return create_window(title, TRUE);
144 } 159 }
160
161 void ui_window_size(UiObject *obj, int width, int height) {
162 XtVaSetValues(obj->widget, XmNwidth, width, XmNheight, height, NULL);
163 }
164
165 void ui_window_default_size(int width, int height) {
166 window_default_width = width;
167 window_default_height = height;
168 }
169
170 void ui_window_menubar_set_visible(UiObject *obj, UiBool visible) {
171 UiMotifAppWindow *window = ui_object_get(obj, "ui_motif_app_window");
172 if(window) {
173 if(window->menubar) {
174 ui_set_visible(window->menubar, visible);
175 }
176 } else {
177 fprintf(stderr, "Error: obj is not an application window\n");
178 }
179 }
180
181 static Atom net_wm_state;
182 static Atom net_wm_state_fullscreen;
183 static int net_wm_atoms_initialized = 0;
184
185 void ui_window_fullscreen(UiObject *obj, UiBool fullscreen) {
186 Display *dpy = XtDisplay(obj->widget);
187
188 // init net_wm_state atoms
189 if(!net_wm_atoms_initialized) {
190 net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
191 net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
192 net_wm_atoms_initialized = 1;
193 }
194
195 XEvent ev;
196 memset(&ev, 0, sizeof(XEvent));
197 ev.type = ClientMessage;
198 ev.xclient.window = XtWindow(obj->widget);
199 ev.xclient.message_type = net_wm_state;
200 ev.xclient.format = 32;
201 ev.xclient.data.l[0] = fullscreen ? 1 : 0;
202 ev.xclient.data.l[1] = net_wm_state_fullscreen;
203 ev.xclient.data.l[2] = 0;
204 XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask | SubstructureRedirectMask, &ev);
205 }
206
207 static void filedialog_event(UiEventData *event, int result, UiFileList flist) {
208 UiEvent evt;
209 evt.obj = event->obj;
210 evt.document = evt.obj->ctx->document;
211 evt.window = evt.obj->window;
212 evt.intval = result;
213
214 evt.eventdata = &flist;
215 evt.eventdatatype = UI_EVENT_DATA_FILE_LIST;
216
217 if(event->callback) {
218 event->callback(&evt, event->userdata);
219 }
220 }
221
222 static void filedialog_select(
223 Widget widget,
224 UiEventData *data,
225 XmFileSelectionBoxCallbackStruct *selection)
226 {
227 UiFileList flist;
228
229 char *value = NULL;
230 XmStringGetLtoR(selection->value, XmSTRING_DEFAULT_CHARSET, &value);
231 flist.files = &value;
232 flist.nfiles = 1;
233
234 filedialog_event(data, 1, flist);
235
236 XtFree(value);
237
238 XtUnmanageChild(widget);
239 XtDestroyWidget(widget);
240 }
241
242 static void filedialog_cancel(
243 Widget widget,
244 UiEventData *data,
245 XmFileSelectionBoxCallbackStruct *selection)
246 {
247 UiFileList flist;
248 flist.files = NULL;
249 flist.nfiles = 0;
250 filedialog_event(data, 0, flist);
251
252 XtUnmanageChild(widget);
253 XtDestroyWidget(widget);
254 }
255
256 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) {
257 Widget dialog = XnCreateFileSelectionDialog(obj->widget, "dialog", NULL, 0);
258
259 UiEventData *data = malloc(sizeof(UiEventData));
260 memset(data, 0, sizeof(UiEventData));
261 data->obj = obj;
262 data->callback = file_selected_callback;
263 data->userdata = cbdata;
264
265 XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, data);
266 XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, data);
267 //XtAddCallback(dialog, XmNhelpCallback, (XtCallbackProc)filedialog_help, wd);
268
269 XtManageChild(dialog);
270 }
271
272 void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) {
273 Arg args[16];
274 int n = 0;
275
276 // Save File Dialog needs this parameter
277 XtSetArg(args[n], XnNfsbType, FILEDIALOG_SAVE); n++;
278 char *selectedpath = (char*)name;
279 if(name) {
280 if(name[0] != '/') {
281 char cwd[PATH_MAX];
282 if(getcwd(cwd, PATH_MAX)) {
283 pathbar_concat_path(cwd, name);
284 } else {
285 fprintf(stderr, "Error: getcwd failed: %s\n", strerror(errno));
286 selectedpath = NULL;
287 }
288 }
289 if(selectedpath) {
290 XtSetArg(args[n], XnNselectedPath, selectedpath); n++;
291 }
292 }
293 Widget dialog = XnCreateFileSelectionDialog(obj->widget, "dialog", args, n);
294
295 UiEventData *data = malloc(sizeof(UiEventData));
296 memset(data, 0, sizeof(UiEventData));
297 data->obj = obj;
298 data->callback = file_selected_callback;
299 data->userdata = cbdata;
300
301 XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, data);
302 XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, data);
303 //XtAddCallback(dialog, XmNhelpCallback, (XtCallbackProc)filedialog_help, wd);
304
305 XtManageChild(dialog);
306
307 if(selectedpath != name) {
308 free(selectedpath);
309 }
310 }

mercurial