1 /** \file   uidata.c
2  * \brief   GTK3 binary resources handling
3  *
4  * Mostly a wrapper around the GResource API, which appears to be the way to
5  * handle binary resources in Gtk3 applications.
6  *
7  * \author  Bas Wassink <b.wassink@ziggo.nl>
8  *
9  * \note    WORK IN PROGRESS, leave this alone for now -- compyx
10  */
11 
12 /*
13  * This file is part of VICE, the Versatile Commodore Emulator.
14  * See README for copyright notice.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 2 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29  *  02111-1307  USA.
30  */
31 
32 
33 #include "vice.h"
34 
35 #include <gtk/gtk.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 
39 #include "archdep.h"
40 #include "debug_gtk3.h"
41 #include "lib.h"
42 #include "util.h"
43 
44 #include "uidata.h"
45 
46 
47 
48 /** \brief  Reference to the global GResource data
49  */
50 static GResource *gresource = NULL;
51 
52 
53 /** \brief  Intialize the GResource binary blob handling
54  *
55  * First tries to load from src/arch/gtk3/data and then from VICEDIR/data.
56  * Loading from VICEDIR/data will fail, the vice.gresource file doesn't get
57  * copied there yet with a make install, nor does the VICEDIR/data dir exist.
58  *
59  * \return  bool
60  */
uidata_init(void)61 int uidata_init(void)
62 {
63     GError *err = NULL;
64 #ifdef HAVE_DEBUG_GTK3UI
65     char **files;
66     int i;
67 #endif
68     char *path;
69     char *dir;
70 
71     /* try directory with VICE's data files */
72     dir = archdep_get_vice_datadir();
73     debug_gtk3("trying archdep_get_vice_datadir() (%s).", dir);
74     path = archdep_join_paths(dir, "vice.gresource", NULL);
75     lib_free(dir);
76 
77     gresource = g_resource_load(path, &err);
78     if (gresource == NULL && err != NULL) {
79         debug_gtk3("failed to load resource data '%s': %s.",
80                 path, err->message);
81         g_clear_error(&err);
82         lib_free(path);
83         return 0;
84     }
85     lib_free(path);
86     g_resources_register(gresource);
87 
88     /* debugging: show files in the resource blob */
89 #ifdef HAVE_DEBUG_GTK3UI
90     files = g_resource_enumerate_children(
91             gresource,
92             UIDATA_ROOT_PATH,
93             G_RESOURCE_LOOKUP_FLAGS_NONE,
94             &err);
95     if (files == NULL && err != NULL) {
96         debug_gtk3("couldn't enumerate children: %s.", err->message);
97         g_clear_error(&err);
98         return 0;
99     }
100     debug_gtk3("Listing files in the GResource file:");
101     for (i = 0; files[i] != NULL; i++) {
102         debug_gtk3("%d: %s.", i, files[i]);
103     }
104 #endif
105     return 1;
106 }
107 
108 
109 /** \brief  Clean up GResource data
110  */
uidata_shutdown(void)111 void uidata_shutdown(void)
112 {
113     debug_gtk3("freeing GResource data.");
114     if (gresource != NULL) {
115         g_free(gresource);
116         gresource = NULL;
117     }
118 }
119 
120 
121 /** \brief  Get a pixbuf from the GResource blob
122  *
123  * \param   name    virtual path to the file
124  *
125  * \return  pixbuf or `NULL` on error
126  */
uidata_get_pixbuf(const char * name)127 GdkPixbuf * uidata_get_pixbuf(const char *name)
128 {
129     GdkPixbuf *buf;
130     GError *err = NULL;
131     char *path;
132 
133     path = util_concat(UIDATA_ROOT_PATH, "/", name, NULL);
134     debug_gtk3("attempting to load resource '%s'.", path);
135     buf = gdk_pixbuf_new_from_resource(path, &err);
136     lib_free(path);
137     if (buf == NULL) {
138         debug_gtk3("failed: %s.", err->message);
139         /* TODO: log error */
140         g_clear_error(&err);
141     }
142     return buf;
143 }
144