1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: filesel.c 2730 2007-12-16 15:54:33Z roms $ */
3
4 /* TiEmu - Tiemu Is an EMUlator
5 *
6 * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin
7 * Copyright (c) 2001-2003, Romain Lievin
8 * Copyright (c) 2003, Julien Blache
9 * Copyright (c) 2004, Romain Li�vin
10 * Copyright (c) 2005-2007, Romain Li�vin, Kevin Kofler
11 *
12 * Carbon file dialog code lifted from Systool (LGPL):
13 * Copyright (c) 2006 Asger Ottar Alstrup, Nicolas Cannasse, Edwin van Rijkom
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details. *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27
28 /*
29 Some informations about these file selectors: starting at tifiles2-v0.0.6, we
30 use the 'glib filename encoding' scheme for charset encoding of filenames:
31 - UTF-8 charset on Windows,
32 - locale charset on Linux (usually UTF-8 but this is not always true).
33
34 GTK+ always uses UTF-8 for widgets (label, file selectors, ...) thus some conversions
35 may be needed.
36 */
37
38 #ifdef HAVE_CONFIG_H
39 # include <config.h>
40 #endif /* */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <gtk/gtk.h>
45 #include <string.h>
46
47 #ifdef __WIN32__
48 #include <windows.h>
49 #include <wchar.h>
50 #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
51 typedef OPENFILENAME OPENFILENAME_MAYALIAS __attribute__((may_alias));
52 #else
53 typedef OPENFILENAME OPENFILENAME_MAYALIAS;
54 #endif
55 #endif
56
57 #ifdef HAVE_CARBON_CARBON_H
58 #include <Carbon/Carbon.h>
59 #endif
60
61 #if WITH_KDE
62 #include "kde.h"
63 #endif
64
65 #include "intl.h"
66 #include "filesel.h"
67 #include "refresh.h"
68 #include "struct.h"
69
70 /* In case some header happens to define this... */
71 #undef HAVE_CARBON_CARBON_H
72
73 #ifdef HAVE_CARBON_CARBON_H
74 /* Helpers */
75 #define PATH_SIZE 2048
76
GetFSRefFromAEDesc(FSRef * fsRef,AEDesc * theItem)77 static OSStatus GetFSRefFromAEDesc( FSRef *fsRef, AEDesc* theItem ) {
78 OSStatus err = noErr;
79 AEDesc coerceDesc= { 0, NULL };
80 if ( theItem->descriptorType != typeFSRef ) {
81 err = AECoerceDesc( theItem, typeFSRef, &coerceDesc );
82 if ( err == noErr )
83 theItem = &coerceDesc;
84 }
85 if ( err == noErr )
86 err = AEGetDescData( theItem, fsRef, sizeof(*fsRef) );
87 AEDisposeDesc( &coerceDesc );
88
89 if ( err != noErr ) {
90 FSSpec fsSpec;
91 AEDesc coerceDesc2 = {0, NULL};
92 if ( theItem->descriptorType != typeFSS ) {
93 err = AECoerceDesc( theItem, typeFSS, &coerceDesc2 );
94 theItem = &coerceDesc2;
95 }
96 if ( err == noErr )
97 err = AEGetDescData( theItem, &fsSpec, sizeof(fsSpec) );
98 AEDisposeDesc( &coerceDesc2 );
99 if ( err == noErr )
100 err = FSpMakeFSRef( &fsSpec, fsRef );
101 }
102 return(err);
103 }
104
filterProc(AEDesc * theItem,void * info,void * callBackUD,NavFilterModes filterMode)105 static Boolean filterProc(AEDesc * theItem, void * info, void * callBackUD, NavFilterModes filterMode) {
106 const gchar **filters = (const gchar **) callBackUD;
107 if (!filters)
108 return 1;
109
110 NavFileOrFolderInfo *i = (NavFileOrFolderInfo*) info;
111 if (i->isFolder)
112 return 1;
113
114 if (theItem->descriptorType==typeFSRef) {
115 FSRef f;
116 UInt8 path[PATH_SIZE];
117
118 GetFSRefFromAEDesc(&f,theItem);
119 if (FSRefMakePath (&f,path,PATH_SIZE)==noErr) {
120 char *ext = NULL;
121 char *next = (char*) path;
122 while(next) {
123 next = strchr(next,'.');
124 if (next)
125 ext = ++next;
126 }
127 if(ext) {
128 while(*filters) {
129 const gchar *filter=*(filters++);
130 if (*(filter++)=='*' && *filter=='.') {
131 next = ext;
132 while (*(++filter)) {
133 if (!*next) break;
134 if (*filter=='?') {
135 next++;
136 } else if (*filter!=*(next++)) break;
137 }
138 if (!*filter && !*next)
139 return 1;
140 }
141 }
142 }
143 }
144 return 0;
145 }
146 return 1;
147 }
148 #endif
149
150 /* Single file selectors */
151
152 static gchar *fname = NULL;
153 static gint action = 0;
154
155 // GTK >= 2.4
create_fsel_2(gchar * dirname,gchar * filename,gchar * ext,gboolean save)156 static const gchar* create_fsel_2(gchar *dirname, gchar *filename, gchar *ext, gboolean save)
157 {
158 GtkWidget *dialog;
159 GtkFileFilter *filter;
160 gchar *path, *tmp;
161 gchar **sarray;
162 gint i;
163 gchar *sfilename, *sext;
164
165 // gtk_file_chooser_set_current_name and gtk_file_filter_add_pattern ALWAYS want UTF-8.
166 sfilename = filename ? g_filename_to_utf8(filename,-1,NULL,NULL,NULL) : NULL;
167 sext = ext ? g_filename_to_utf8(ext,-1,NULL,NULL,NULL) : NULL;
168
169 // create box
170 dialog = gtk_file_chooser_dialog_new (
171 save ? "Save File" : "Open File",
172 NULL,
173 save ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN,
174 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
175 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
176 NULL);
177
178 // set default folder
179 tmp = g_strconcat(dirname, G_DIR_SEPARATOR_S, NULL); // add trailing '/' otherwise get_dirname is confused
180 path = g_path_get_dirname(tmp);
181 g_free(tmp);
182
183 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
184 g_free(path);
185
186 // set default name
187 if(filename)
188 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), sfilename);
189
190 // set wildcards
191 filter = gtk_file_filter_new();
192 sarray = g_strsplit(sext, ";", -1);
193 for(i = 0; sarray[i] != NULL; i++)
194 gtk_file_filter_add_pattern (filter, sarray[i]);
195 g_strfreev(sarray);
196 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
197
198 // get result
199 g_free(fname);
200 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
201 fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
202 else
203 fname = NULL;
204 gtk_widget_destroy (dialog);
205
206 g_free(sfilename);
207 g_free(sext);
208
209 return fname;
210 }
211
212 // WIN32
create_fsel_3(gchar * dirname,gchar * filename,gchar * ext,gboolean save)213 static const gchar* create_fsel_3(gchar *dirname, gchar *filename, gchar *ext, gboolean save)
214 {
215 #if defined(__WIN32__)
216 OPENFILENAME_MAYALIAS o;
217 char lpstrFile[2048] = "\0";
218 char lpstrFilter[512];
219 char *p;
220 gchar **sarray;
221 int i, n;
222 int have_widechar = G_WIN32_HAVE_WIDECHAR_API();
223 void *sdirname;
224
225 // clear structure
226 memset (&o, 0, sizeof(OPENFILENAME));
227
228 // set default filename
229 if(filename)
230 {
231 void *temp;
232 if (have_widechar)
233 {
234 temp = g_utf8_to_utf16(filename,-1,NULL,NULL,NULL);
235 if(!temp) return NULL;
236 wcsncpy((wchar_t *)lpstrFile, temp, sizeof(lpstrFile)>>1);
237 }
238 else
239 {
240 temp = g_locale_from_utf8(filename,-1,NULL,NULL,NULL);
241 if(!temp) return NULL;
242 strncpy(lpstrFile, temp, sizeof(lpstrFile));
243 }
244 g_free(temp);
245 }
246
247 // format filter
248 sarray = g_strsplit(ext, "|", -1);
249 for(n = 0; sarray[n] != NULL; n++);
250
251 for(i = 0, p = lpstrFilter; i < n; i++)
252 {
253 void *temp;
254 if (have_widechar)
255 {
256 temp = g_utf8_to_utf16(sarray[i],-1,NULL,NULL,NULL);
257 wcscpy((wchar_t *)p,temp);
258 p += (wcslen(temp)<<1);
259 *p++ = '\0';
260 *p++ = '\0';
261 wcscpy((wchar_t *)p,temp);
262 p += (wcslen(temp)<<1);
263 *p++ = '\0';
264 *p++ = '\0';
265 }
266 else
267 {
268 temp = g_locale_from_utf8(sarray[i],-1,NULL,NULL,NULL);
269 strcpy(p,temp);
270 p += strlen(temp);
271 *p++ = '\0';
272 strcpy(p,temp);
273 p += strlen(temp);
274 *p++ = '\0';
275 }
276 g_free(temp);
277 }
278 *p++ = '\0';
279 if (have_widechar)
280 *p++ = '\0';
281 g_strfreev(sarray);
282
283 // set structure
284 o.lStructSize = sizeof (o);
285 o.lpstrFilter = lpstrFilter; //"All\0*.*\0Text\0*.TXT\0";
286 o.lpstrFile = lpstrFile;
287 if (have_widechar)
288 {
289 o.nMaxFile = sizeof(lpstrFile) >> 1;
290 sdirname = g_utf8_to_utf16(dirname,-1,NULL,NULL,NULL);
291 }
292 else
293 {
294 o.nMaxFile = sizeof(lpstrFile);
295 sdirname = g_locale_from_utf8(dirname,-1,NULL,NULL,NULL);
296 }
297 o.lpstrInitialDir = sdirname;
298 o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
299 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON;
300
301 // open/close
302 if(save)
303 {
304 if(!(have_widechar ? GetSaveFileNameW((OPENFILENAMEW *)&o) : GetSaveFileName((OPENFILENAME *)&o)))
305 {
306 g_free(sdirname);
307 return fname = NULL;
308 }
309 }
310 else
311 {
312 if(!(have_widechar ? GetOpenFileNameW((OPENFILENAMEW *)&o) : GetOpenFileName((OPENFILENAME *)&o)))
313 {
314 g_free(sdirname);
315 return fname = NULL;
316 }
317 }
318
319 g_free(sdirname);
320
321 if (have_widechar)
322 fname = g_utf16_to_utf8((wchar_t *)lpstrFile,-1,NULL,NULL,NULL);
323 else
324 fname = g_locale_to_utf8(lpstrFile,-1,NULL,NULL,NULL);
325 return fname;
326 #elif defined(HAVE_CARBON_CARBON_H)
327 NavDialogRef ref;
328 NavDialogCreationOptions opt;
329 OSStatus ret;
330 gchar **sarray=NULL;
331
332 fname = NULL;
333 NavGetDefaultDialogCreationOptions(&opt);
334 opt.clientName = CFSTR("TiEmu");
335 opt.modality = kWindowModalityAppModal;
336 opt.optionFlags = kNavDefaultNavDlogOptions | kNavAllFilesInPopup;
337
338 if (save) {
339 ret = NavCreatePutFileDialog(&opt,0,kNavGenericSignature,NULL,NULL,&ref);
340 } else {
341 sarray = g_strsplit(ext, ";", -1);
342 ret = NavCreateChooseFileDialog(&opt,NULL,NULL,NULL,filterProc,sarray,&ref);
343 }
344 if (ret == noErr) {
345 if (NavDialogRun(ref) == noErr) {
346 if (NavDialogGetUserAction(ref) == save?kNavUserActionSaveAs:kNavUserActionChoose) {
347 NavReplyRecord reply;
348 if (NavDialogGetReply(ref,&reply) == kNavNormalState) {
349 FSRef fsref;
350 AEGetNthPtr(&reply.selection,1,typeFSRef,0,0,&fsref,sizeof(FSRef),0);
351 fname = g_malloc(PATH_SIZE);
352 memset(fname,0,PATH_SIZE);
353 if (FSRefMakePath (&fsref,(UInt8*)fname,PATH_SIZE-(save?1:0))==noErr) {
354 if (save) {
355 strcat(fname,"/");
356 CFStringGetCString(reply.saveFileName,fname+strlen(fname),PATH_SIZE-strlen(fname),kCFStringEncodingUTF8);
357 }
358 } else {
359 g_free(fname);
360 fname = NULL;
361 }
362 NavDisposeReply(&reply);
363 }
364 }
365 }
366 NavDialogDispose(ref);
367 }
368 if (!save) g_strfreev(sarray);
369 return fname;
370 #endif
371
372 return NULL;
373 }
374
375 // KDE
create_fsel_4(gchar * dirname,gchar * filename,gchar * ext,gboolean save)376 static const gchar* create_fsel_4(gchar *dirname, gchar *filename, gchar *ext, gboolean save)
377 {
378 #if WITH_KDE
379 gchar *p;
380 gchar *extspaces = g_strdup(ext);
381
382 p = extspaces;
383 while ((p = strchr(p, ';'))) *p = ' ';
384
385 if(save)
386 {
387 if (filename)
388 dirname = g_strconcat(dirname, "/", filename, NULL);
389 fname = sp_kde_get_write_filename(dirname, extspaces, _("Save file"));
390 }
391 else
392 fname = sp_kde_get_open_filename(dirname, extspaces, _("Open file"));
393
394 g_free(extspaces);
395 return fname;
396 #endif
397
398 return NULL;
399 }
400
401 // Front-end
create_fsel(gchar * dirname,gchar * filename,gchar * ext,gboolean save)402 const gchar *create_fsel(gchar *dirname, gchar *filename, gchar *ext, gboolean save)
403 {
404 #if !defined(__WIN32__) && !defined(HAVE_CARBON_CARBON_H)
405 if(options.fs_type == 2)
406 {
407 #if WITH_KDE
408 const char *p = getenv("KDE_FULL_SESSION");
409 if (p && *p) // KDE is running
410 options.fs_type = 3;
411 else
412 #endif
413 options.fs_type = 1;
414 }
415 #endif
416 #if !WITH_KDE
417 if(options.fs_type == 3)
418 options.fs_type = 1;
419 #endif
420 //printf("%i: <%s> <%s> <%s> %i\n", options.fs_type, dirname, filename, ext, save);
421
422 switch(options.fs_type)
423 {
424 case 0:
425 case 1: return create_fsel_2(dirname, filename, ext, save);
426 case 2: return create_fsel_3(dirname, filename, ext, save);
427 case 3: return create_fsel_4(dirname, filename, ext, save);
428 default: return NULL;
429 }
430
431 return NULL;
432 }
433
434 /* Multiple files selectors */
435
436 static gchar** filenames = NULL;
437 static gint actions = 0;
438
439 // GTK >= 2.4
create_fsels_2(gchar * dirname,gchar * filename,gchar * ext)440 static gchar** create_fsels_2(gchar *dirname, gchar *filename, gchar *ext)
441 {
442 GtkWidget *dialog;
443 GtkFileFilter *filter;
444 gchar *path, *tmp;
445 gchar **sarray;
446 gint i;
447 gchar *sfilename, *sext;
448
449 // gtk_file_chooser_set_current_name and gtk_file_filter_add_pattern ALWAYS want UTF-8.
450 sfilename = filename ? g_filename_to_utf8(filename,-1,NULL,NULL,NULL) : NULL;
451 sext = ext ? g_filename_to_utf8(ext,-1,NULL,NULL,NULL) : NULL;
452
453 // create box
454 dialog = gtk_file_chooser_dialog_new ("Open File",
455 NULL,
456 GTK_FILE_CHOOSER_ACTION_OPEN,
457 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
458 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
459 NULL);
460
461 // set default folder
462 tmp = g_strconcat(dirname, G_DIR_SEPARATOR_S, NULL); // add trailing '/' otherwise get_dirname is confused
463 path = g_path_get_dirname(tmp);
464 g_free(tmp);
465
466 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
467 g_free(path);
468
469 // set multiple selection
470 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
471
472 // set default name
473 if(filename)
474 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), sfilename);
475
476 // set wildcards
477 filter = gtk_file_filter_new();
478 sarray = g_strsplit(sext, ";", -1);
479 for(i = 0; sarray[i] != NULL; i++)
480 gtk_file_filter_add_pattern (filter, sarray[i]);
481 g_strfreev(sarray);
482 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
483
484 // get result
485 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
486 {
487 GSList *list, *p;
488 gchar **q;
489
490 // convert list into string array
491 list=gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (dialog));
492
493 filenames = (gchar **)g_malloc0((g_slist_length(list)+1) *
494 sizeof(gchar *));
495 for(p = list, q = filenames; p; p = g_slist_next(p), q++)
496 *q = p->data;
497 *q = NULL;
498
499 g_slist_free(list);
500 }
501 else
502 filenames = NULL;
503 gtk_widget_destroy (dialog);
504
505 g_free(sfilename);
506 g_free(sext);
507
508 return filenames;
509 }
510
511 // WIN32
create_fsels_3(gchar * dirname,gchar * filename,gchar * ext)512 static gchar** create_fsels_3(gchar *dirname, gchar *filename, gchar *ext)
513 {
514 #if defined(__WIN32__)
515 OPENFILENAME_MAYALIAS o;
516 char lpstrFile[2048] = "\0";
517 char lpstrFilter[512];
518 char *p;
519 gchar **sarray;
520 int i, n;
521 int have_widechar = G_WIN32_HAVE_WIDECHAR_API();
522 void *sdirname;
523 gchar *temp1;
524
525 // clear structure
526 memset (&o, 0, sizeof(OPENFILENAME));
527
528 // set default filename
529 if(filename)
530 {
531 void *temp;
532 if (have_widechar)
533 {
534 temp = g_utf8_to_utf16(filename,-1,NULL,NULL,NULL);
535 if(!temp) return NULL;
536 wcsncpy((wchar_t *)lpstrFile, temp, sizeof(lpstrFile)>>1);
537 }
538 else
539 {
540 temp = g_locale_from_utf8(filename,-1,NULL,NULL,NULL);
541 if(!temp) return NULL;
542 strncpy(lpstrFile, temp, sizeof(lpstrFile));
543 }
544 g_free(temp);
545 }
546
547 // format filter
548 sarray = g_strsplit(ext, "|", -1);
549 for(n = 0; sarray[n] != NULL; n++);
550
551 for(i = 0, p = lpstrFilter; i < n; i++)
552 {
553 void *temp;
554 if (have_widechar)
555 {
556 temp = g_utf8_to_utf16(sarray[i],-1,NULL,NULL,NULL);
557 wcscpy((wchar_t *)p,temp);
558 p += (wcslen(temp)<<1);
559 *p++ = '\0';
560 *p++ = '\0';
561 wcscpy((wchar_t *)p,temp);
562 p += (wcslen(temp)<<1);
563 *p++ = '\0';
564 *p++ = '\0';
565 }
566 else
567 {
568 temp = g_locale_from_utf8(sarray[i],-1,NULL,NULL,NULL);
569 strcpy(p,temp);
570 p += strlen(temp);
571 *p++ = '\0';
572 strcpy(p,temp);
573 p += strlen(temp);
574 *p++ = '\0';
575 }
576 g_free(temp);
577 }
578 *p++ = '\0';
579 if (have_widechar)
580 *p++ = '\0';
581 g_strfreev(sarray);
582
583 // set structure
584 o.lStructSize = sizeof (o);
585 o.lpstrFilter = lpstrFilter; //"All\0*.*\0Text\0*.TXT\0";
586 o.lpstrFile = lpstrFile; //"C:\msvc\tilp\0foo.txt\0bar.txt"
587 if (have_widechar)
588 {
589 o.nMaxFile = sizeof(lpstrFile) >> 1;
590 sdirname = g_utf8_to_utf16(dirname,-1,NULL,NULL,NULL);
591 }
592 else
593 {
594 o.nMaxFile = sizeof(lpstrFile);
595 sdirname = g_locale_from_utf8(dirname,-1,NULL,NULL,NULL);
596 }
597 o.lpstrInitialDir = sdirname;
598 o.Flags = 0x02000000 | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
599 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_LONGNAMES | OFN_NONETWORKBUTTON |
600 OFN_ALLOWMULTISELECT;
601
602 // open selector
603 if(!(have_widechar ? GetOpenFileNameW((OPENFILENAMEW *)&o) : GetOpenFileName((OPENFILENAME *)&o)))
604 {
605 g_free(sdirname);
606 return NULL;
607 }
608 filenames = NULL;
609
610 // converts resulting string
611 if (have_widechar)
612 temp1 = g_utf16_to_utf8((wchar_t *)lpstrFile,-1,NULL,NULL,NULL);
613 else
614 temp1 = g_locale_to_utf8(lpstrFile,-1,NULL,NULL,NULL);
615 for(p = lpstrFile, i=0; *p;
616 p += have_widechar?((wcslen((wchar_t *)p)+1)<<1):(strlen(p)+1), i++)
617 {
618 if(i) // skip directory
619 {
620 gchar *temp;
621 filenames = g_realloc(filenames, (i+1) * sizeof(gchar *));
622 if (have_widechar)
623 temp = g_utf16_to_utf8((wchar_t *)p,-1,NULL,NULL,NULL);
624 else
625 temp = g_locale_to_utf8(p,-1,NULL,NULL,NULL);
626 filenames[i-1] = g_strconcat(temp1, G_DIR_SEPARATOR_S, temp, NULL);
627 g_free(temp);
628 }
629 }
630 g_free(temp1);
631
632 // one file selected ?
633 if(i == 1)
634 {
635 filenames = g_malloc(2 * sizeof(gchar *));
636 if (have_widechar)
637 filenames[0] = g_utf16_to_utf8((wchar_t *)lpstrFile,-1,NULL,NULL,NULL);
638 else
639 filenames[0] = g_locale_to_utf8(lpstrFile,-1,NULL,NULL,NULL);
640 filenames[1] = NULL;
641 }
642 else
643 filenames[i-1] = NULL;
644
645 g_free(sdirname);
646
647 return filenames;
648 #elif defined(HAVE_CARBON_CARBON_H)
649 NavDialogRef ref;
650 NavDialogCreationOptions opt;
651 gchar **sarray;
652
653 filenames = NULL;
654 NavGetDefaultDialogCreationOptions(&opt);
655 opt.clientName = CFSTR("TiEmu");
656 opt.modality = kWindowModalityAppModal;
657 opt.optionFlags = kNavDefaultNavDlogOptions | kNavAllFilesInPopup;
658
659 sarray = g_strsplit(ext, ";", -1);
660 if (NavCreateGetFileDialog(&opt,NULL,NULL,NULL,filterProc,sarray,&ref) == noErr) {
661
662 if (NavDialogRun(ref) == noErr) {
663 if (NavDialogGetUserAction(ref)==kNavUserActionOpen) {
664 NavReplyRecord reply;
665 if (NavDialogGetReply(ref,&reply) == kNavNormalState) {
666 long count;
667 AECountItems(&reply.selection, &count);
668 if (count) {
669 filenames = (gchar **) g_malloc0((count+1)*sizeof(gchar*));
670 while(count>0) {
671 FSRef fsref;
672 AEGetNthPtr(&reply.selection,count--,typeFSRef,0,0,&fsref,sizeof(FSRef),0);
673 filenames[count] = g_malloc(PATH_SIZE);
674 memset(filenames[count],0,PATH_SIZE);
675 if (FSRefMakePath (&fsref,(UInt8*)filenames[count],PATH_SIZE)!=noErr) {
676 g_strfreev(filenames);
677 filenames = NULL;
678 }
679 }
680 }
681 NavDisposeReply(&reply);
682 }
683 }
684 }
685 NavDialogDispose(ref);
686 }
687 g_strfreev(sarray);
688 return filenames;
689 #endif
690
691 return NULL;
692 }
693
create_fsels_4(gchar * dirname,gchar * filename,gchar * ext)694 static gchar** create_fsels_4(gchar *dirname, gchar *filename, gchar *ext)
695 {
696 #if WITH_KDE
697 gchar *p;
698 gchar *extspaces = g_strdup(ext);
699 p = extspaces;
700 while ((p = strchr(p, ';'))) *p = ' ';
701 filenames = sp_kde_get_open_filenames(dirname, extspaces, _("Open file"));
702 g_free(extspaces);
703 return filenames;
704 #endif
705
706 return NULL;
707 }
708
709 // Front-end
create_fsels(gchar * dirname,gchar * filename,gchar * ext)710 gchar** create_fsels(gchar *dirname, gchar *filename, gchar *ext)
711 {
712 #if !defined(__WIN32__) && !defined(HAVE_CARBON_CARBON_H)
713 if(options.fs_type == 2)
714 {
715 #if WITH_KDE
716 const char *p = getenv("KDE_FULL_SESSION");
717 if (p && *p) // KDE is running
718 options.fs_type = 3;
719 else
720 #endif
721 options.fs_type = 1;
722 }
723 #endif
724 #if !WITH_KDE
725 if(options.fs_type == 3)
726 options.fs_type = 1;
727 #endif
728 //printf("%i: <%s> <%s> <%s>\n", options.fs_type, dirname, filename, ext);
729
730 switch(options.fs_type)
731 {
732 case 0:
733 case 1: return create_fsels_2(dirname, filename, ext);
734 case 2: return create_fsels_3(dirname, filename, ext);
735 case 3: return create_fsels_4(dirname, filename, ext);
736 default: return NULL;
737 }
738
739 return NULL;
740 }
741
742
743