blob: 4fce0ca44e8b578b49740660f2184e633e98acc5 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001// resource.cpp - Source to manage GUI resources
2
3#include <stdarg.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <fcntl.h>
8#include <sys/reboot.h>
9#include <sys/stat.h>
10#include <sys/time.h>
11#include <sys/mman.h>
12#include <sys/types.h>
13#include <sys/ioctl.h>
14#include <time.h>
15#include <unistd.h>
16#include <stdlib.h>
17
18#include <string>
19#include <sstream>
20#include <iostream>
21#include <iomanip>
22
23extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000024#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040025#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040026}
27
28#include "rapidxml.hpp"
29#include "objects.hpp"
30
31#define TMP_RESOURCE_NAME "/tmp/extract.bin"
32
33Resource::Resource(xml_node<>* node, ZipArchive* pZip)
34{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020035 if (node && node->first_attribute("name"))
36 mName = node->first_attribute("name")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -040037}
38
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020039int Resource::ExtractResource(ZipArchive* pZip, std::string folderName, std::string fileName, std::string fileExtn, std::string destFile)
Dees_Troy51a0e822012-09-05 15:24:24 -040040{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020041 if (!pZip)
42 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040043
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020044 std::string src = folderName + "/" + fileName + fileExtn;
Dees_Troy51a0e822012-09-05 15:24:24 -040045
46 const ZipEntry* binary = mzFindZipEntry(pZip, src.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020047 if (binary == NULL) {
48 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040049 }
50
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020051 unlink(destFile.c_str());
52 int fd = creat(destFile.c_str(), 0666);
53 if (fd < 0)
54 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040055
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020056 int ret = 0;
57 if (!mzExtractZipEntryToFile(pZip, binary, fd))
58 ret = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040059
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020060 close(fd);
61 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -040062}
63
64FontResource::FontResource(xml_node<>* node, ZipArchive* pZip)
65 : Resource(node, pZip)
66{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020067 std::string file;
Vojtech Bocek76ee9032014-09-07 15:01:56 +020068 xml_attribute<>* attr;
Dees_Troy51a0e822012-09-05 15:24:24 -040069
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020070 mFont = NULL;
71 if (!node)
72 return;
Dees_Troy51a0e822012-09-05 15:24:24 -040073
Vojtech Bocek76ee9032014-09-07 15:01:56 +020074 attr = node->first_attribute("filename");
75 if (!attr)
76 return;
Dees_Troy51a0e822012-09-05 15:24:24 -040077
Vojtech Bocek76ee9032014-09-07 15:01:56 +020078 file = attr->value();
79
80#ifndef TW_DISABLE_TTF
81 if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020082 {
Vojtech Bocek76ee9032014-09-07 15:01:56 +020083 m_type = TYPE_TTF;
84
85 attr = node->first_attribute("size");
86 if(!attr)
87 return;
88
89 int size = atoi(attr->value());
90 int dpi = 300;
91
92 attr = node->first_attribute("dpi");
93 if(attr)
94 dpi = atoi(attr->value());
95
96 if (ExtractResource(pZip, "fonts", file, "", TMP_RESOURCE_NAME) == 0)
97 {
98 mFont = gr_ttf_loadFont(TMP_RESOURCE_NAME, size, dpi);
99 unlink(TMP_RESOURCE_NAME);
100 }
101 else
102 {
103 file = std::string("/res/fonts/") + file;
104 mFont = gr_ttf_loadFont(file.c_str(), size, dpi);
105 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200106 }
107 else
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200108#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200109 {
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200110 m_type = TYPE_TWRP;
111
112 if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
113 {
114 attr = node->first_attribute("fallback");
115 if (!attr)
116 return;
117
118 file = attr->value();
119 }
120
121 if (ExtractResource(pZip, "fonts", file, ".dat", TMP_RESOURCE_NAME) == 0)
122 {
123 mFont = gr_loadFont(TMP_RESOURCE_NAME);
124 unlink(TMP_RESOURCE_NAME);
125 }
126 else
127 {
128 mFont = gr_loadFont(file.c_str());
129 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200130 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400131}
132
133FontResource::~FontResource()
134{
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200135 if(mFont)
136 {
137#ifndef TW_DISABLE_TTF
138 if(m_type == TYPE_TTF)
139 gr_ttf_freeFont(mFont);
140 else
141#endif
142 gr_freeFont(mFont);
143 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400144}
145
146ImageResource::ImageResource(xml_node<>* node, ZipArchive* pZip)
147 : Resource(node, pZip)
148{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200149 std::string file;
Dees_Troy51a0e822012-09-05 15:24:24 -0400150
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200151 mSurface = NULL;
152 if (!node)
153 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400154
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200155 if (node->first_attribute("filename"))
156 file = node->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400157
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200158 if (ExtractResource(pZip, "images", file, ".png", TMP_RESOURCE_NAME) == 0)
159 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400160 res_create_surface(TMP_RESOURCE_NAME, &mSurface);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200161 unlink(TMP_RESOURCE_NAME);
162 }
163 else if (ExtractResource(pZip, "images", file, "", TMP_RESOURCE_NAME) == 0)
164 {
165 // JPG includes the .jpg extension in the filename so extension should be blank
166 res_create_surface(TMP_RESOURCE_NAME, &mSurface);
167 unlink(TMP_RESOURCE_NAME);
168 }
169 else
Dees_Troy51a0e822012-09-05 15:24:24 -0400170 res_create_surface(file.c_str(), &mSurface);
171}
172
173ImageResource::~ImageResource()
174{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200175 if (mSurface)
176 res_free_surface(mSurface);
Dees_Troy51a0e822012-09-05 15:24:24 -0400177}
178
179AnimationResource::AnimationResource(xml_node<>* node, ZipArchive* pZip)
180 : Resource(node, pZip)
181{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200182 std::string file;
183 int fileNum = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400184
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200185 if (!node)
186 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400187
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200188 if (node->first_attribute("filename"))
189 file = node->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400190
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200191 for (;;)
192 {
193 std::ostringstream fileName;
194 fileName << file << std::setfill ('0') << std::setw (3) << fileNum;
Dees_Troy51a0e822012-09-05 15:24:24 -0400195
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200196 gr_surface surface;
197 if (pZip)
198 {
199 if (ExtractResource(pZip, "images", fileName.str(), ".png", TMP_RESOURCE_NAME) != 0)
200 break;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500201
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 if (res_create_surface(TMP_RESOURCE_NAME, &surface))
203 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400204
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 unlink(TMP_RESOURCE_NAME);
206 }
207 else
208 {
209 if (res_create_surface(fileName.str().c_str(), &surface))
210 break;
211 }
212 mSurfaces.push_back(surface);
213 fileNum++;
214 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400215}
216
217AnimationResource::~AnimationResource()
218{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 std::vector<gr_surface>::iterator it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400220
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200221 for (it = mSurfaces.begin(); it != mSurfaces.end(); ++it)
222 res_free_surface(*it);
223
224 mSurfaces.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400225}
226
227Resource* ResourceManager::FindResource(std::string name)
228{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200229 std::vector<Resource*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400230
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200231 for (iter = mResources.begin(); iter != mResources.end(); iter++)
232 {
233 if (name == (*iter)->GetName())
234 return (*iter);
235 }
236 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400237}
238
239ResourceManager::ResourceManager(xml_node<>* resList, ZipArchive* pZip)
240{
Ethan Yonker780cd392014-07-21 15:24:39 -0500241 LoadResources(resList, pZip);
242}
243
244void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip)
245{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200246 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -0400247
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200248 if (!resList)
249 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400250
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200251 child = resList->first_node("resource");
252 while (child != NULL)
253 {
254 xml_attribute<>* attr = child->first_attribute("type");
255 if (!attr)
256 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400257
258 std::string type = attr->value();
259
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200260 if (type == "font")
261 {
262 FontResource* res = new FontResource(child, pZip);
263 if (res == NULL || res->GetResource() == NULL)
264 {
265 xml_attribute<>* attr_name = child->first_attribute("name");
Dees_Troy51a0e822012-09-05 15:24:24 -0400266
267 if (!attr_name) {
268 std::string res_name = attr_name->value();
Dees_Troy2673cec2013-04-02 20:22:16 +0000269 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400270 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000271 LOGERR("Resource type (%s) failed to load\n", type.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400272
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200273 delete res;
274 }
275 else
276 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400277 mResources.push_back((Resource*) res);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200278 }
279 }
280 else if (type == "image")
281 {
282 ImageResource* res = new ImageResource(child, pZip);
283 if (res == NULL || res->GetResource() == NULL)
284 {
285 xml_attribute<>* attr_name = child->first_attribute("name");
Dees_Troy51a0e822012-09-05 15:24:24 -0400286
287 if (!attr_name) {
288 std::string res_name = attr_name->value();
Dees_Troy2673cec2013-04-02 20:22:16 +0000289 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400290 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000291 LOGERR("Resource type (%s) failed to load\n", type.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400292
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200293 delete res;
294 }
295 else
296 {
297 mResources.push_back((Resource*) res);
298 }
299 }
300 else if (type == "animation")
301 {
302 AnimationResource* res = new AnimationResource(child, pZip);
303 if (res == NULL || res->GetResource() == NULL)
304 {
305 xml_attribute<>* attr_name = child->first_attribute("name");
Dees_Troy51a0e822012-09-05 15:24:24 -0400306
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200307 if (!attr_name) {
308 std::string res_name = attr_name->value();
309 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
310 } else
311 LOGERR("Resource type (%s) failed to load\n", type.c_str());
312
313 delete res;
314 }
315 else
316 {
317 mResources.push_back((Resource*) res);
318 }
319 }
320 else
321 {
322 LOGERR("Resource type (%s) not supported.\n", type.c_str());
323 }
324
325 child = child->next_sibling("resource");
326 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400327}
328
329ResourceManager::~ResourceManager()
330{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200331 std::vector<Resource*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400332
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200333 for (iter = mResources.begin(); iter != mResources.end(); iter++)
334 delete *iter;
335
336 mResources.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400337}