git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

SDL/open_dialog/gtk.c

      1 #include "open_dialog.h"
      2 #include <SDL.h>
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <dlfcn.h>
      6 #include <stdbool.h>
      7 #include <string.h>
      8 
      9 #define GTK_FILE_CHOOSER_ACTION_OPEN 0
     10 #define GTK_FILE_CHOOSER_ACTION_SAVE 1
     11 #define GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER 2
     12 #define GTK_RESPONSE_ACCEPT -3
     13 #define GTK_RESPONSE_CANCEL -6
     14 
     15 
     16 void *_gtk_file_chooser_dialog_new (const char *title,
     17                                     void *parent,
     18                                     int action,
     19                                     const char *first_button_text,
     20                                     ...);
     21 bool _gtk_init_check (int *argc, char ***argv);
     22 int _gtk_dialog_run(void *);
     23 void _g_free(void *);
     24 void _gtk_widget_destroy(void *);
     25 char *_gtk_file_chooser_get_filename(void *);
     26 void _g_log_set_default_handler (void *function, void *data);
     27 void *_gtk_file_filter_new(void);
     28 void _gtk_file_filter_add_pattern(void *filter, const char *pattern);
     29 void _gtk_file_filter_set_name(void *filter, const char *name);
     30 void _gtk_file_chooser_add_filter(void *dialog, void *filter);
     31 void _gtk_main_iteration(void);
     32 bool _gtk_events_pending(void);
     33 unsigned long _g_signal_connect_data(void *instance,
     34                                      const char *detailed_signal,
     35                                      void *c_handler,
     36                                      void *data,
     37                                      void *destroy_data,
     38                                      unsigned connect_flags);
     39 void _gtk_file_chooser_set_current_name(void *dialog,
     40                                         const char *name);
     41 void *_gtk_file_chooser_get_filter(void *dialog);
     42 const char *_gtk_file_filter_get_name (void *dialog);
     43 #define g_signal_connect(instance, detailed_signal, c_handler, data) \
     44 g_signal_connect_data((instance), (detailed_signal), (c_handler), (data), NULL, 0)
     45 
     46 
     47 
     48 #define LAZY(symbol) static typeof(_##symbol) *symbol = NULL;\
     49 if (symbol == NULL) symbol = dlsym(handle, #symbol);\
     50 if (symbol == NULL) goto lazy_error
     51 #define TRY_DLOPEN(name) handle = handle? handle : dlopen(name, RTLD_NOW)
     52 
     53 void nop(void){}
     54 
     55 static void wait_mouse_up(void)
     56 {
     57     while (true) {
     58         if (!(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT))) break;
     59         SDL_Event event;
     60         SDL_PollEvent(&event);
     61     }
     62 }
     63 
     64 char *do_open_rom_dialog(void)
     65 {
     66     wait_mouse_up();
     67     static void *handle = NULL;
     68     
     69     TRY_DLOPEN("libgtk-3.so");
     70     TRY_DLOPEN("libgtk-3.so.0");
     71     TRY_DLOPEN("libgtk-2.so");
     72     TRY_DLOPEN("libgtk-2.so.0");
     73     
     74     if (!handle) {
     75         goto lazy_error;
     76     }
     77     
     78     
     79     LAZY(gtk_init_check);
     80     LAZY(gtk_file_chooser_dialog_new);
     81     LAZY(gtk_dialog_run);
     82     LAZY(g_free);
     83     LAZY(gtk_widget_destroy);
     84     LAZY(gtk_file_chooser_get_filename);
     85     LAZY(g_log_set_default_handler);
     86     LAZY(gtk_file_filter_new);
     87     LAZY(gtk_file_filter_add_pattern);
     88     LAZY(gtk_file_filter_set_name);
     89     LAZY(gtk_file_chooser_add_filter);
     90     LAZY(gtk_events_pending);
     91     LAZY(gtk_main_iteration);
     92     
     93     /* Shut up GTK */
     94     g_log_set_default_handler(nop, NULL);
     95     
     96     gtk_init_check(0, 0);
     97     
     98     
     99     void *dialog = gtk_file_chooser_dialog_new("Open ROM",
    100                                                0,
    101                                                GTK_FILE_CHOOSER_ACTION_OPEN,
    102                                                "_Cancel", GTK_RESPONSE_CANCEL,
    103                                                "_Open", GTK_RESPONSE_ACCEPT,
    104                                                NULL );
    105     
    106     
    107     void *filter = gtk_file_filter_new();
    108     gtk_file_filter_add_pattern(filter, "*.gb");
    109     gtk_file_filter_add_pattern(filter, "*.gbc");
    110     gtk_file_filter_add_pattern(filter, "*.sgb");
    111     gtk_file_filter_add_pattern(filter, "*.isx");
    112     gtk_file_filter_set_name(filter, "Game Boy ROMs");
    113     gtk_file_chooser_add_filter(dialog, filter);
    114     
    115     int res = gtk_dialog_run(dialog);
    116     char *ret = NULL;
    117     
    118     if (res == GTK_RESPONSE_ACCEPT) { 
    119         char *filename;
    120         filename = gtk_file_chooser_get_filename(dialog);
    121         ret = strdup(filename);
    122         g_free(filename);
    123     }
    124 
    125     while (gtk_events_pending()) {
    126         gtk_main_iteration();
    127     }
    128 
    129     gtk_widget_destroy(dialog);
    130 
    131     while (gtk_events_pending()) {
    132         gtk_main_iteration();
    133     }
    134     return ret;
    135     
    136 lazy_error:
    137     fprintf(stderr, "Failed to display GTK dialog\n");
    138     return NULL;
    139 }
    140 
    141 char *do_open_folder_dialog(void)
    142 {
    143     wait_mouse_up();
    144     static void *handle = NULL;
    145     
    146     TRY_DLOPEN("libgtk-3.so");
    147     TRY_DLOPEN("libgtk-3.so.0");
    148     TRY_DLOPEN("libgtk-2.so");
    149     TRY_DLOPEN("libgtk-2.so.0");
    150     
    151     if (!handle) {
    152         goto lazy_error;
    153     }
    154     
    155     
    156     LAZY(gtk_init_check);
    157     LAZY(gtk_file_chooser_dialog_new);
    158     LAZY(gtk_dialog_run);
    159     LAZY(g_free);
    160     LAZY(gtk_widget_destroy);
    161     LAZY(gtk_file_chooser_get_filename);
    162     LAZY(g_log_set_default_handler);
    163     LAZY(gtk_file_filter_new);
    164     LAZY(gtk_file_filter_add_pattern);
    165     LAZY(gtk_file_filter_set_name);
    166     LAZY(gtk_file_chooser_add_filter);
    167     LAZY(gtk_events_pending);
    168     LAZY(gtk_main_iteration);
    169     
    170     /* Shut up GTK */
    171     g_log_set_default_handler(nop, NULL);
    172     
    173     gtk_init_check(0, 0);
    174     
    175     
    176     void *dialog = gtk_file_chooser_dialog_new("Select Boot ROMs Folder",
    177                                                0,
    178                                                GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
    179                                                "_Cancel", GTK_RESPONSE_CANCEL,
    180                                                "_Open", GTK_RESPONSE_ACCEPT,
    181                                                NULL );
    182     
    183     
    184     int res = gtk_dialog_run(dialog);
    185     char *ret = NULL;
    186     
    187     if (res == GTK_RESPONSE_ACCEPT) {
    188         char *filename;
    189         filename = gtk_file_chooser_get_filename(dialog);
    190         ret = strdup(filename);
    191         g_free(filename);
    192     }
    193     
    194     while (gtk_events_pending()) {
    195         gtk_main_iteration();
    196     }
    197     
    198     gtk_widget_destroy(dialog);
    199     
    200     while (gtk_events_pending()) {
    201         gtk_main_iteration();
    202     }
    203     return ret;
    204     
    205 lazy_error:
    206     fprintf(stderr, "Failed to display GTK dialog\n");
    207     return NULL;
    208 }
    209 
    210 static void filter_changed(void *dialog,
    211                            void *unused,
    212                            void *unused2)
    213 {
    214     static void *handle = NULL;
    215     
    216     TRY_DLOPEN("libgtk-3.so");
    217     TRY_DLOPEN("libgtk-3.so.0");
    218     TRY_DLOPEN("libgtk-2.so");
    219     TRY_DLOPEN("libgtk-2.so.0");
    220     
    221     if (!handle) {
    222         goto lazy_error;
    223     }
    224     
    225     LAZY(gtk_file_chooser_get_filename);
    226     LAZY(gtk_file_chooser_set_current_name);
    227     LAZY(g_free);
    228     LAZY(gtk_file_chooser_get_filter);
    229     LAZY(gtk_file_filter_get_name);
    230     
    231     char *filename = gtk_file_chooser_get_filename(dialog);
    232     if (!filename) return;
    233     char *temp = filename + strlen(filename);
    234     char *basename = filename;
    235     bool deleted_extension = false;
    236     while (temp != filename) {
    237         temp--;
    238         if (*temp == '.' && !deleted_extension) {
    239             *temp = 0;
    240             deleted_extension = true;
    241         }
    242         else if (*temp == '/') {
    243             basename = temp + 1;
    244             break;
    245         }
    246     }
    247     
    248     char *new_filename = NULL;
    249     
    250     switch (gtk_file_filter_get_name(gtk_file_chooser_get_filter(dialog))[1]) {
    251         case 'p':
    252         default:
    253             asprintf(&new_filename, "%s.aiff", basename);
    254             break;
    255         case 'I':
    256             asprintf(&new_filename, "%s.wav", basename);
    257             break;
    258         case 'a':
    259             asprintf(&new_filename, "%s.raw", basename);
    260             break;
    261     }
    262     
    263     
    264     gtk_file_chooser_set_current_name(dialog, new_filename);
    265     free(new_filename);
    266     g_free(filename);
    267     return;
    268     
    269 lazy_error:
    270     fprintf(stderr, "Failed updating the file extension\n");
    271 }
    272 
    273 
    274 char *do_save_recording_dialog(unsigned frequency)
    275 {
    276     wait_mouse_up();
    277     static void *handle = NULL;
    278     
    279     TRY_DLOPEN("libgtk-3.so");
    280     TRY_DLOPEN("libgtk-3.so.0");
    281     TRY_DLOPEN("libgtk-2.so");
    282     TRY_DLOPEN("libgtk-2.so.0");
    283     
    284     if (!handle) {
    285         goto lazy_error;
    286     }
    287     
    288     
    289     LAZY(gtk_init_check);
    290     LAZY(gtk_file_chooser_dialog_new);
    291     LAZY(gtk_dialog_run);
    292     LAZY(g_free);
    293     LAZY(gtk_widget_destroy);
    294     LAZY(gtk_file_chooser_get_filename);
    295     LAZY(g_log_set_default_handler);
    296     LAZY(gtk_file_filter_new);
    297     LAZY(gtk_file_filter_add_pattern);
    298     LAZY(gtk_file_filter_set_name);
    299     LAZY(gtk_file_chooser_add_filter);
    300     LAZY(gtk_events_pending);
    301     LAZY(gtk_main_iteration);
    302     LAZY(g_signal_connect_data);
    303     LAZY(gtk_file_chooser_set_current_name);
    304     
    305     /* Shut up GTK */
    306     g_log_set_default_handler(nop, NULL);
    307     
    308     gtk_init_check(0, 0);
    309     
    310     
    311     void *dialog = gtk_file_chooser_dialog_new("Audio recording save location",
    312                                                0,
    313                                                GTK_FILE_CHOOSER_ACTION_SAVE,
    314                                                "_Cancel", GTK_RESPONSE_CANCEL,
    315                                                "_Save", GTK_RESPONSE_ACCEPT,
    316                                                NULL );
    317     
    318     
    319     void *filter = gtk_file_filter_new();
    320     gtk_file_filter_add_pattern(filter, "*.aiff");
    321     gtk_file_filter_add_pattern(filter, "*.aif");
    322     gtk_file_filter_add_pattern(filter, "*.aifc");
    323     gtk_file_filter_set_name(filter, "Apple AIFF");
    324     gtk_file_chooser_add_filter(dialog, filter);
    325     
    326     filter = gtk_file_filter_new();
    327     gtk_file_filter_add_pattern(filter, "*.wav");
    328     gtk_file_filter_set_name(filter, "RIFF WAVE");
    329     gtk_file_chooser_add_filter(dialog, filter);
    330     
    331     filter = gtk_file_filter_new();
    332     gtk_file_filter_add_pattern(filter, "*.raw");
    333     gtk_file_filter_add_pattern(filter, "*.pcm");
    334     static char raw_name[40];
    335 #ifdef GB_BIG_ENDIAN
    336     sprintf(raw_name, "Raw PCM (Stereo %dHz, 16-bit BE)", frequency);
    337 #else
    338     sprintf(raw_name, "Raw PCM (Stereo %dHz, 16-bit LE)", frequency);
    339 #endif
    340     gtk_file_filter_set_name(filter, raw_name);
    341     gtk_file_chooser_add_filter(dialog, filter);
    342     
    343     g_signal_connect(dialog, "notify::filter", filter_changed, NULL);
    344     gtk_file_chooser_set_current_name(dialog, "Untitled.aiff");
    345     
    346     int res = gtk_dialog_run(dialog);
    347     char *ret = NULL;
    348     
    349     if (res == GTK_RESPONSE_ACCEPT) {
    350         char *filename;
    351         filename = gtk_file_chooser_get_filename(dialog);
    352         ret = strdup(filename);
    353         g_free(filename);
    354     }
    355     
    356     while (gtk_events_pending()) {
    357         gtk_main_iteration();
    358     }
    359     
    360     gtk_widget_destroy(dialog);
    361     
    362     while (gtk_events_pending()) {
    363         gtk_main_iteration();
    364     }
    365     return ret;
    366     
    367 lazy_error:
    368     fprintf(stderr, "Failed to display GTK dialog\n");
    369     return NULL;
    370 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.