blob: 74f020b62211baa50f4eb32c36f358845e62c585 [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;
Ethan Yonker619a7212014-12-03 16:47:37 -0600152 if (!node) {
153 LOGERR("ImageResource node is NULL\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200154 return;
Ethan Yonker619a7212014-12-03 16:47:37 -0600155 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400156
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200157 if (node->first_attribute("filename"))
158 file = node->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400159
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200160 if (ExtractResource(pZip, "images", file, ".png", TMP_RESOURCE_NAME) == 0)
161 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400162 res_create_surface(TMP_RESOURCE_NAME, &mSurface);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200163 unlink(TMP_RESOURCE_NAME);
164 }
165 else if (ExtractResource(pZip, "images", file, "", TMP_RESOURCE_NAME) == 0)
166 {
167 // JPG includes the .jpg extension in the filename so extension should be blank
168 res_create_surface(TMP_RESOURCE_NAME, &mSurface);
169 unlink(TMP_RESOURCE_NAME);
170 }
171 else
Dees_Troy51a0e822012-09-05 15:24:24 -0400172 res_create_surface(file.c_str(), &mSurface);
173}
174
175ImageResource::~ImageResource()
176{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200177 if (mSurface)
178 res_free_surface(mSurface);
Dees_Troy51a0e822012-09-05 15:24:24 -0400179}
180
181AnimationResource::AnimationResource(xml_node<>* node, ZipArchive* pZip)
182 : Resource(node, pZip)
183{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200184 std::string file;
185 int fileNum = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400186
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200187 if (!node)
188 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400189
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200190 if (node->first_attribute("filename"))
191 file = node->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400192
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200193 for (;;)
194 {
195 std::ostringstream fileName;
196 fileName << file << std::setfill ('0') << std::setw (3) << fileNum;
Dees_Troy51a0e822012-09-05 15:24:24 -0400197
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200198 gr_surface surface;
199 if (pZip)
200 {
201 if (ExtractResource(pZip, "images", fileName.str(), ".png", TMP_RESOURCE_NAME) != 0)
202 break;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500203
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200204 if (res_create_surface(TMP_RESOURCE_NAME, &surface))
205 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400206
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200207 unlink(TMP_RESOURCE_NAME);
208 }
209 else
210 {
211 if (res_create_surface(fileName.str().c_str(), &surface))
212 break;
213 }
214 mSurfaces.push_back(surface);
215 fileNum++;
216 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400217}
218
219AnimationResource::~AnimationResource()
220{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200221 std::vector<gr_surface>::iterator it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400222
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 for (it = mSurfaces.begin(); it != mSurfaces.end(); ++it)
224 res_free_surface(*it);
225
226 mSurfaces.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400227}
228
229Resource* ResourceManager::FindResource(std::string name)
230{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200231 std::vector<Resource*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400232
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200233 for (iter = mResources.begin(); iter != mResources.end(); iter++)
234 {
235 if (name == (*iter)->GetName())
236 return (*iter);
237 }
238 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400239}
240
241ResourceManager::ResourceManager(xml_node<>* resList, ZipArchive* pZip)
242{
Ethan Yonker780cd392014-07-21 15:24:39 -0500243 LoadResources(resList, pZip);
244}
245
246void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip)
247{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200248 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -0400249
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200250 if (!resList)
251 return;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200252 child = resList->first_node("resource");
253 while (child != NULL)
254 {
255 xml_attribute<>* attr = child->first_attribute("type");
256 if (!attr)
257 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400258
259 std::string type = attr->value();
260
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200261 if (type == "font")
262 {
263 FontResource* res = new FontResource(child, pZip);
264 if (res == NULL || res->GetResource() == NULL)
265 {
Ethan Yonker619a7212014-12-03 16:47:37 -0600266 std::string res_name;
267 if (child->first_attribute("name"))
268 res_name = child->first_attribute("name")->value();
269 if (res_name.empty() && child->first_attribute("filename"))
270 res_name = child->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400271
Ethan Yonker619a7212014-12-03 16:47:37 -0600272 if (!res_name.empty()) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000273 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400274 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000275 LOGERR("Resource type (%s) failed to load\n", type.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400276
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200277 delete res;
278 }
279 else
280 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400281 mResources.push_back((Resource*) res);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200282 }
283 }
284 else if (type == "image")
285 {
286 ImageResource* res = new ImageResource(child, pZip);
287 if (res == NULL || res->GetResource() == NULL)
288 {
Ethan Yonker619a7212014-12-03 16:47:37 -0600289 std::string res_name;
290 if (child->first_attribute("name"))
291 res_name = child->first_attribute("name")->value();
292 if (res_name.empty() && child->first_attribute("filename"))
293 res_name = child->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400294
Ethan Yonker619a7212014-12-03 16:47:37 -0600295 if (!res_name.empty()) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000296 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400297 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000298 LOGERR("Resource type (%s) failed to load\n", type.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400299
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200300 delete res;
301 }
302 else
303 {
304 mResources.push_back((Resource*) res);
305 }
306 }
307 else if (type == "animation")
308 {
309 AnimationResource* res = new AnimationResource(child, pZip);
310 if (res == NULL || res->GetResource() == NULL)
311 {
Ethan Yonker619a7212014-12-03 16:47:37 -0600312 std::string res_name;
313 if (child->first_attribute("name"))
314 res_name = child->first_attribute("name")->value();
315 if (res_name.empty() && child->first_attribute("filename"))
316 res_name = child->first_attribute("filename")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400317
Ethan Yonker619a7212014-12-03 16:47:37 -0600318 if (!res_name.empty()) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200319 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
320 } else
321 LOGERR("Resource type (%s) failed to load\n", type.c_str());
322
323 delete res;
324 }
325 else
326 {
327 mResources.push_back((Resource*) res);
328 }
329 }
330 else
331 {
332 LOGERR("Resource type (%s) not supported.\n", type.c_str());
333 }
334
335 child = child->next_sibling("resource");
336 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400337}
338
339ResourceManager::~ResourceManager()
340{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200341 std::vector<Resource*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400342
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200343 for (iter = mResources.begin(); iter != mResources.end(); iter++)
344 delete *iter;
345
346 mResources.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400347}