Skip to content

Commit 382697f

Browse files
authored
Merge pull request #3 from Eyap53/bugfix/linux
Bugfix/linux
2 parents c9b7dad + 5cd4d5a commit 382697f

File tree

9 files changed

+345
-209
lines changed

9 files changed

+345
-209
lines changed

Packages/com.maellacour.sfb/Runtime/Plugins/StandaloneFileBrowser.jslib

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,7 @@ var StandaloneFileBrowserWebGLPlugin = {
4848
}
4949
document.body.appendChild(fileInput);
5050

51-
document.onmouseup = function() {
52-
fileInput.click();
53-
document.onmouseup = null;
54-
}
51+
fileInput.click();
5552
},
5653

5754
// Save file
@@ -87,4 +84,4 @@ var StandaloneFileBrowserWebGLPlugin = {
8784
}
8885
};
8986

90-
mergeInto(LibraryManager.library, StandaloneFileBrowserWebGLPlugin);
87+
mergeInto(LibraryManager.library, StandaloneFileBrowserWebGLPlugin);

Packages/com.maellacour.sfb/Runtime/StandaloneFileBrowserWindows.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private static string GetFilterFromFileExtensionList(ExtensionFilter[] extension
9090
if (extensions == null) return "";
9191
var filterString = "";
9292
foreach (var filter in extensions) {
93-
filterString += filter.Name + "(";
93+
filterString += filter.Name + " (";
9494

9595
foreach (var ext in filter.Extensions) {
9696
filterString += "*." + ext + ",";
@@ -111,4 +111,4 @@ private static string GetFilterFromFileExtensionList(ExtensionFilter[] extension
111111
}
112112
}
113113

114-
#endif
114+
#endif
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.idea
2-
cmake-build-debug
2+
cmake-build-debug
3+
build

Plugins/Linux/StandaloneFileBrowser/CMakeLists.txt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.12)
22
project(StandaloneFileBrowser C)
33

44
set(CMAKE_C_STANDARD 11)
5+
set(CMAKE_C_FLAGS "-Wall")
6+
set(CMAKE_C_FLAGS_DEBUG "-g")
7+
set(CMAKE_C_FLAGS_RELEASE "-O2")
58

69
# Use the package PkgConfig to detect GTK+ headers/library files
710
FIND_PACKAGE(PkgConfig REQUIRED)
@@ -15,10 +18,6 @@ LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
1518
# Add other flags to the compiler
1619
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER})
1720

18-
add_library(${PROJECT_NAME} SHARED library.c library.h)
21+
add_executable(dialog dialog.c)
1922

20-
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GTK3_LIBRARIES})
21-
22-
add_executable(${PROJECT_NAME}_EXE main.c)
23-
24-
TARGET_LINK_LIBRARIES(${PROJECT_NAME}_EXE ${PROJECT_NAME} ${GTK3_LIBRARIES})
23+
TARGET_LINK_LIBRARIES(dialog ${GTK3_LIBRARIES})
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
LD = ld
2+
CC = gcc
3+
COPTS = -O2 -Wall -Wextra
4+
5+
.PHONY: all
6+
all: build/main build/libStandaloneFileBrowser.so
7+
8+
build/dialog: dialog.c
9+
mkdir -p build
10+
cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make
11+
build/dialog.bin.o: build/dialog
12+
$(LD) -r -b binary -o build/dialog.bin.o build/dialog
13+
build/library.o: library.c library.h
14+
$(CC) $(COPTS) -o build/library.o -c library.c -fPIC
15+
build/libStandaloneFileBrowser.so: build/dialog.bin.o build/library.o
16+
$(CC) $(COPTS) -o build/libStandaloneFileBrowser.so build/library.o build/dialog.bin.o -shared
17+
build/main: build/libStandaloneFileBrowser.so main.c library.h
18+
$(CC) $(COPTS) -o build/main main.c build/libStandaloneFileBrowser.so
19+
20+
.PHONY: clean
21+
clean:
22+
rm -rf build
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
#include <stddef.h>
2+
#include <gtk/gtk.h>
3+
#include <string.h>
4+
#include <malloc.h>
5+
#include <stdbool.h>
6+
#include <unistd.h>
7+
8+
char* strcat_realloc(char* str1, const char* str2) {
9+
char* new_str;
10+
size_t length;
11+
size_t str1length;
12+
13+
if (str2 == NULL)
14+
return str1;
15+
str1length = 0;
16+
if (str1 != NULL)
17+
str1length = strlen(str1);
18+
length = strlen(str2) + str1length;
19+
new_str = (char*) realloc(str1, (1 + length) * sizeof(char));
20+
if (new_str == NULL)
21+
return str1;
22+
new_str[str1length] = '\0';
23+
24+
strcat(new_str, str2);
25+
26+
return new_str;
27+
}
28+
29+
// Rewrite strcpy() to avoid linking with memcpy function of high version (2.14) glibc ABI
30+
char *strcpy_menci(char* dst, const char* src) {
31+
char *p = dst;
32+
do *p++ = *src; while (*src++);
33+
return dst;
34+
}
35+
36+
void DialogInit() {
37+
gtk_init(0, NULL);
38+
}
39+
40+
const char*
41+
GTKOpenPanel(const char* title, const char* directory, const char* extension, bool multiselect,
42+
GtkFileChooserAction action);
43+
44+
const char*
45+
GTKSavePanel(const char* title, const char* directory, const char* defaultName, const char* filters);
46+
47+
void GTKSetFilters(const char* extension, GtkWidget* dialog);
48+
49+
const char* DialogOpenFilePanel(const char* title, const char* directory, const char* extension,
50+
bool multiselect) {
51+
return GTKOpenPanel(title, directory, extension, multiselect,
52+
GTK_FILE_CHOOSER_ACTION_OPEN);
53+
}
54+
55+
const char* DialogOpenFolderPanel(const char* title, const char* directory, bool multiselect) {
56+
return GTKOpenPanel(title, directory, "", multiselect,
57+
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
58+
}
59+
60+
const char* DialogSaveFilePanel(const char* title, const char* directory, const char* defaultName,
61+
const char* filters) {
62+
return GTKSavePanel(title, directory, defaultName, filters);
63+
}
64+
65+
const char*
66+
GTKOpenPanel(const char* title, const char* directory, const char* extensions, bool multiselect,
67+
GtkFileChooserAction action) {
68+
char* filename = NULL;
69+
GtkWidget* dialog;
70+
gint res;
71+
72+
dialog = gtk_file_chooser_dialog_new(title,
73+
NULL,
74+
action,
75+
("_Cancel"),
76+
GTK_RESPONSE_CANCEL,
77+
("_Open"),
78+
GTK_RESPONSE_ACCEPT,
79+
NULL);
80+
gtk_file_chooser_set_select_multiple((GtkFileChooser*) dialog, multiselect);
81+
gtk_file_chooser_set_current_folder((GtkFileChooser*) dialog, directory);
82+
83+
GTKSetFilters(extensions, dialog);
84+
85+
res = gtk_dialog_run(GTK_DIALOG (dialog));
86+
if (res == GTK_RESPONSE_ACCEPT) {
87+
GtkFileChooser* chooser = GTK_FILE_CHOOSER (dialog);
88+
89+
if (multiselect) {
90+
GSList* filenamepus = gtk_file_chooser_get_filenames(chooser);
91+
92+
int nIndex;
93+
GSList* node;
94+
95+
char split[] = {(char)28, 0};
96+
for (nIndex = 0; (node = g_slist_nth(filenamepus, (guint) nIndex)); nIndex++) {
97+
if (nIndex == 0) {
98+
filename = malloc((strlen(node->data) + 1) * sizeof(char));
99+
strcpy_menci(filename, node->data);
100+
continue;
101+
}
102+
filename = strcat_realloc(filename, split);
103+
filename = strcat_realloc(filename, node->data);
104+
105+
g_free(node->data);
106+
}
107+
g_slist_free(filenamepus);
108+
} else {
109+
char* name = gtk_file_chooser_get_filename(chooser);
110+
filename = malloc(strlen(name) * sizeof(char) + 1);
111+
strcpy_menci(filename, name);
112+
g_free(name);
113+
}
114+
} else { // if (res == GTK_RESPONSE_CANCEL) {
115+
filename = malloc(sizeof(char));
116+
filename[0] = '\0';
117+
}
118+
119+
gtk_widget_destroy(dialog);
120+
121+
while (gtk_events_pending ())
122+
gtk_main_iteration ();
123+
return filename;
124+
}
125+
126+
const char*
127+
GTKSavePanel(const char* title, const char* directory, const char* defaultName, const char* filters) {
128+
char* filename = NULL;
129+
GtkWidget *dialog;
130+
GtkFileChooser *chooser;
131+
gint res;
132+
133+
dialog = gtk_file_chooser_dialog_new ("Save File",
134+
NULL,
135+
GTK_FILE_CHOOSER_ACTION_SAVE,
136+
("_Cancel"),
137+
GTK_RESPONSE_CANCEL,
138+
("_Save"),
139+
GTK_RESPONSE_ACCEPT,
140+
NULL);
141+
chooser = GTK_FILE_CHOOSER (dialog);
142+
143+
gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
144+
gtk_file_chooser_set_current_name(chooser, defaultName);
145+
gtk_file_chooser_set_current_folder(chooser, directory);
146+
147+
GTKSetFilters(filters, dialog);
148+
149+
res = gtk_dialog_run (GTK_DIALOG (dialog));
150+
if (res == GTK_RESPONSE_ACCEPT)
151+
{
152+
char* name = gtk_file_chooser_get_filename(chooser);
153+
filename = malloc(strlen(name) * sizeof(char) + 1);
154+
strcpy_menci(filename, name);
155+
g_free(name);
156+
}
157+
else if (res == GTK_RESPONSE_CANCEL) {
158+
filename = malloc(sizeof(char));
159+
filename[0] = '\0';
160+
}
161+
162+
gtk_widget_destroy (dialog);
163+
164+
while (gtk_events_pending ())
165+
gtk_main_iteration ();
166+
return filename;
167+
}
168+
169+
void GTKSetFilters(const char* extensions, GtkWidget* dialog) {
170+
if (extensions == NULL || strlen(extensions) == 0) {
171+
return;
172+
}
173+
174+
// Image Files;png,jpg,jpeg|Sound Files;mp3,wav|All Files;*
175+
char* extensions_tok = malloc(sizeof(char) * (1+ strlen(extensions)));
176+
extensions_tok = strcpy_menci(extensions_tok, extensions);
177+
char* extensions_tok_beginning = extensions_tok;
178+
179+
char *extension_filters;
180+
char *name_or_filters;
181+
char *ext;
182+
while ((extension_filters = strtok_r(extensions_tok, "|", &extensions_tok))) {
183+
puts(extension_filters);
184+
int i = 0;
185+
GtkFileFilter* filter = gtk_file_filter_new();
186+
if (extension_filters[0] == ';') { // no filter name
187+
++i;
188+
}
189+
while ((name_or_filters = strtok_r(extension_filters, ";", &extension_filters))) {
190+
puts(name_or_filters);
191+
if (i == 0) {
192+
// Filter Name
193+
gtk_file_filter_set_name(filter, name_or_filters);
194+
} else {
195+
// Filter extentions
196+
while ((ext = strtok_r(name_or_filters, ",", &name_or_filters))) {
197+
puts(ext);
198+
if (ext[0] == '*') {
199+
gtk_file_filter_add_pattern(filter, ext);
200+
} else {
201+
char* ext_s;// = "*.";
202+
ext_s = malloc(3 * sizeof(char));
203+
ext_s = strcpy_menci(ext_s, "*.");
204+
ext_s = strcat_realloc(ext_s, ext);
205+
gtk_file_filter_add_pattern(filter, ext_s);
206+
free(ext_s);
207+
}
208+
}
209+
}
210+
++i;
211+
}
212+
gtk_file_chooser_add_filter((GtkFileChooser*) dialog, filter);
213+
}
214+
215+
free(extensions_tok_beginning);
216+
}
217+
218+
int main(int argc, char *argv[]) {
219+
DialogInit();
220+
221+
// fprintf(stderr, "operation = %s\n", argv[1]);
222+
223+
const char *result = NULL;
224+
if (strcmp(argv[1], "DialogOpenFolderPanel") == 0) {
225+
result = DialogOpenFolderPanel(argv[2], argv[3], argv[4][0] == '1');
226+
} else if (strcmp(argv[1], "DialogOpenFilePanel") == 0) {
227+
result = DialogOpenFilePanel(argv[2], argv[3], argv[4], argv[5][0] == '1');
228+
} else if (strcmp(argv[1], "DialogSaveFilePanel") == 0) {
229+
result = DialogSaveFilePanel(argv[2], argv[3], argv[4], argv[5]);
230+
}
231+
232+
size_t size = result ? strlen(result) : 0;
233+
write(STDOUT_FILENO, &size, sizeof(size));
234+
if (result)
235+
write(STDOUT_FILENO, result, size);
236+
237+
return 0;
238+
}

0 commit comments

Comments
 (0)