]> git.vomp.tv Git - vompclient.git/blob - osdvector.cc
Changes in signaloff/on and doreboot, enhance hardware deinitialisation
[vompclient.git] / osdvector.cc
1 /*\r
2     Copyright 2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include "osdvector.h"\r
22 #include "surfacevector.h"\r
23 \r
24 OsdVector::OsdVector()\r
25 {\r
26         setlocale(LC_CTYPE,"C.UTF-8");\r
27 }\r
28 \r
29 OsdVector::~OsdVector()\r
30 {\r
31 \r
32 }\r
33 \r
34 \r
35 int OsdVector::getFD()\r
36 {\r
37         return 0;\r
38 }\r
39 \r
40 void OsdVector::screenShot(const char* fileName)\r
41 {\r
42         //Do nothing,\r
43 }\r
44 \r
45 Surface * OsdVector::createNewSurface()\r
46 {\r
47         return new SurfaceVector(this);\r
48 }\r
49 \r
50 void OsdVector::BeginPainting()\r
51 {\r
52         surfaces_mutex.Lock();\r
53 }\r
54 void OsdVector::EndPainting()\r
55 {\r
56         surfaces_mutex.Unlock();\r
57 }\r
58 \r
59 void OsdVector::Blank()\r
60 {\r
61         // do nothing? remove this one?\r
62 }\r
63 \r
64 int OsdVector::restore()\r
65 {\r
66         // First clear the contents of all registered surfaces\r
67         surfaces_mutex.Lock();\r
68 \r
69         //Now go through all surfaces and draw them\r
70         list<SurfaceCommands>::iterator curdraw=scommands.begin();\r
71         while (curdraw!=scommands.end()) {\r
72                 (*curdraw).commands.clear();\r
73                 curdraw++;\r
74         }\r
75         //also clear all handles, they are now invalid, no need to release them\r
76         images_ref.clear();;\r
77         monobitmaps.clear();\r
78         jpegs.clear();\r
79         styles.clear();\r
80         styles_ref.clear();\r
81 \r
82         surfaces_mutex.Unlock();\r
83         return 1;\r
84 }\r
85 \r
86 void OsdVector::drawSurfaces()\r
87 {\r
88         surfaces_mutex.Lock();\r
89         list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface\r
90         list<SurfaceCommands>::iterator itty1=scommands.begin();\r
91         while (itty1!=scommands.end()) {\r
92                 list<SurfaceCommands>::iterator itty2=itty1;\r
93                 itty2++;\r
94                 bool hidden=false;\r
95                 while (itty2!=scommands.end()) {\r
96                         SurfaceCommands & ref1=*itty1;\r
97                         SurfaceCommands & ref2=*itty2;\r
98                         if (ref1.x>=ref2.x && ref1.y>=ref2.y\r
99                                         && (ref1.x+ref1.w) <= (ref2.x+ref2.w)\r
100                                         && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {\r
101                                 hidden=true;\r
102                                 break;\r
103                         }\r
104                         itty2++;\r
105                 }\r
106                 if (!hidden) { // we are not hidden, perfect\r
107                         todraw.push_back(&(*itty1));\r
108                 }\r
109                 itty1++;\r
110         }\r
111         //Now go through all surfaces and draw them\r
112         list<SurfaceCommands*>::iterator curdraw=todraw.begin();\r
113         while (curdraw!=todraw.end()) {\r
114                 drawSetTrans(*(*curdraw));\r
115                 list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();\r
116                 list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();\r
117                 while (commands!=end) {\r
118                         executeDrawCommand(*commands);\r
119                         commands++;\r
120                 }\r
121                 curdraw++;\r
122         }\r
123 \r
124         surfaces_mutex.Unlock();\r
125 }\r
126 \r
127 \r
128 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,\r
129                         list<SVGCommand>& commands)\r
130 {\r
131         surfaces_mutex.Lock();\r
132         //First determine it is already in our system\r
133         list<SurfaceCommands>::iterator itty=scommands.begin();\r
134         while (itty!=scommands.end()) {\r
135                 if ((*itty).surf==surf) {\r
136                         //decrease the references\r
137                         dereferenceSVGCommand((*itty).commands);\r
138                         break;\r
139                 }\r
140                 itty++;\r
141         }\r
142         // if not insert it\r
143         if (itty==scommands.end()) {\r
144                 SurfaceCommands new_sc;\r
145                 new_sc.surf=surf;\r
146                 new_sc.x=x;\r
147                 new_sc.y=y;\r
148                 new_sc.w=width;\r
149                 new_sc.h=height;\r
150                 itty=scommands.insert(itty,new_sc);\r
151         }\r
152         // then clear and copy\r
153         (*itty).commands.clear();\r
154         (*itty).commands=commands;\r
155         //increase the references\r
156         list<SVGCommand>::iterator sitty=(*itty).commands.begin();\r
157         while (sitty!=(*itty).commands.end())\r
158         {\r
159                 incStyleRef((*sitty).getRef());\r
160                 ImageIndex ii=(*sitty).getImageIndex();\r
161                 if (ii) incImageRef(ii);\r
162                 sitty++;\r
163         }\r
164         cleanupOrphanedRefs();\r
165 \r
166         surfaces_mutex.Unlock();\r
167 }\r
168 \r
169 void OsdVector::removeSurface(const SurfaceVector *surf)\r
170 {\r
171         surfaces_mutex.Lock();\r
172         //First determine it is already in our system\r
173         list<SurfaceCommands>::iterator itty=scommands.begin();\r
174         while (itty!=scommands.end()) {\r
175                 if ((*itty).surf==surf) {\r
176                         dereferenceSVGCommand((*itty).commands);\r
177                         (*itty).commands.clear();\r
178                         scommands.erase(itty);\r
179                         break;\r
180                 }\r
181                 itty++;\r
182         }\r
183         surfaces_mutex.Unlock();\r
184 \r
185 }\r
186 \r
187 void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )\r
188 {\r
189 \r
190         list<SVGCommand>::iterator sitty = commands.begin();\r
191         while (sitty != commands.end()) {\r
192                 removeStyleRef((*sitty).getRef());\r
193                 ImageIndex ii = (*sitty).getImageIndex();\r
194                 if (ii) removeImageRef(ii);\r
195                 sitty++;\r
196         }\r
197 }\r
198 \r
199 void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )\r
200 {\r
201         list<SVGCommand>::iterator sitty=commands.begin();\r
202         while (sitty!=commands.end())\r
203         {\r
204                 incStyleRef((*sitty).getRef());\r
205                 ImageIndex ii=(*sitty).getImageIndex();\r
206                 if (ii) incImageRef(ii);\r
207                 sitty++;\r
208         }\r
209 }\r
210 \r
211 void OsdVector::incImageRef(ImageIndex index)\r
212 {\r
213         if (images_ref.find(index)==images_ref.end()) {\r
214                 images_ref[index]=1;\r
215         } else {\r
216                 images_ref[index]++;\r
217         }\r
218 }\r
219 \r
220 void OsdVector::removeImageRef(const ImageIndex ref)\r
221 {\r
222         images_ref[ref]--;\r
223 }\r
224 \r
225 void OsdVector::cleanupOrphanedRefs()\r
226 { // Do some garbage collection\r
227         map<ImageIndex,unsigned int>::iterator iitty=images_ref.begin();\r
228         while (iitty!=images_ref.end()) {\r
229                 int count=(*iitty).second;\r
230                 if (count==0) {\r
231                         ImageIndex ref=(*iitty).first;\r
232                         images_ref.erase(iitty++);\r
233                         destroyImageRef(ref);\r
234                 } else ++iitty;\r
235         }\r
236         map<unsigned int,unsigned int>::iterator sitty=styles_ref.begin();\r
237         while (sitty!=styles_ref.end()) {\r
238                 int count=(*sitty).second;\r
239                 if (count==0) {\r
240                         unsigned int ref=(*sitty).first;\r
241                         styles_ref.erase(sitty++);\r
242                         destroyStyleRef(ref);\r
243                 } else ++sitty;\r
244 \r
245         }\r
246 }\r
247 \r
248 \r
249 unsigned int OsdVector::getImageRef(ImageIndex index)\r
250 {\r
251         if (images_ref.find(index)==images_ref.end()) {\r
252                 return -1;\r
253         } else {\r
254                 return images_ref[index];\r
255         }\r
256 }\r
257 \r
258 void OsdVector::incStyleRef(unsigned int index)\r
259 {\r
260         if (styles_ref.find(index)==styles_ref.end()) {\r
261                 styles_ref[index]=1;\r
262         } else {\r
263                 styles_ref[index]++;\r
264         }\r
265 }\r
266 \r
267 void OsdVector::removeStyleRef(unsigned int index)\r
268 {\r
269         styles_ref[index]--;\r
270 }\r
271 \r
272 unsigned int OsdVector::getStyleRef(const DrawStyle &c)\r
273 {\r
274         unsigned int style_handle=0;\r
275         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())\r
276         {\r
277                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);\r
278         } else {\r
279                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];\r
280                 //Now check if the handle is valid\r
281                 if (styles_ref.find(style_handle)==styles_ref.end()) {\r
282                         //invalid handle recreate\r
283                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);\r
284                 }\r
285         }\r
286         incStyleRef(style_handle);\r
287         return style_handle;\r
288 }\r
289 \r
290 unsigned int OsdVector::getColorRef(const Colour &c)\r
291 {\r
292         unsigned int style_handle=0;\r
293         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())\r
294         {\r
295                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);\r
296         } else {\r
297                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];\r
298                 if (styles_ref.find(style_handle)==styles_ref.end()) {\r
299                         //invalid handle recreate\r
300                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);\r
301                 }\r
302         }\r
303         incStyleRef(style_handle);\r
304         return style_handle;\r
305 }\r
306 \r
307 unsigned int OsdVector::getStyleRef(unsigned int index)\r
308 {\r
309         if (styles_ref.find(index)==styles_ref.end()) {\r
310                 return -1;\r
311         } else {\r
312                 return styles_ref[index];\r
313         }\r
314 }\r
315 \r
316 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)\r
317 {\r
318         ImageIndex image_handle=0;\r
319         if (jpegs.find(fileName)==jpegs.end())\r
320         {\r
321                 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);\r
322         } else {\r
323                 image_handle=jpegs[fileName];\r
324                 *width=0;\r
325                 *height=0;\r
326                 if (images_ref.find(image_handle)==images_ref.end()) {\r
327                         //invalid handle recreate\r
328                         image_handle=jpegs[fileName]=createJpeg(fileName,width,height);\r
329                 }\r
330         }\r
331         incImageRef(image_handle);\r
332         return image_handle;\r
333 }\r
334 \r
335 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)\r
336 {\r
337         ImageIndex image_handle;\r
338         if (monobitmaps.find(base)==monobitmaps.end())\r
339         {\r
340                 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);\r
341         } else {\r
342                 image_handle=monobitmaps[base];\r
343                 if (images_ref.find(image_handle)==images_ref.end()) {\r
344                         //invalid handle recreate\r
345                         image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);\r
346                 }\r
347         }\r
348         incImageRef(image_handle);\r
349         return image_handle;\r
350 }\r
351 \r
352 ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)\r
353 {\r
354         ImageIndex image_handle;\r
355         image_handle=createImagePalette(width,height,image_data,palette_data);\r
356         incImageRef(image_handle);\r
357         return image_handle;\r
358 }\r