2 #include "bcwindowbase.h"
4 #include "filesystem.h"
14 char *path_env = getenv("PATH");
15 char executable_name[BCTEXTLEN];
16 char *path_ptr = path_env;
18 // Get location of executable
19 FILE *fd = fopen("/proc/self/cmdline", "r");
22 perror(_("BC_Theme::BC_Theme: can't open /proc/self/cmdline.\n"));
27 fread(executable_name, 1, BCTEXTLEN, fd);
28 strcpy(path, executable_name);
35 // Search path environment for executable
43 fd = fopen(path, "r");
48 // Get next entry out of path_env
65 *new_ptr++ = *path_ptr++;
69 if(new_ptr - path > 0 && *(new_ptr - 1) != '/')
74 strcat(path, executable_name);
83 strcpy(default_path, path);
91 image_sets.remove_all_objects();
92 if(data_buffer) delete [] data_buffer;
93 if(contents_buffer) delete [] contents_buffer;
98 printf("BC_Theme::dump 1 image_sets=%d path=%s contents=%d\n",
102 for(int i = 0; i < contents.total; i++)
103 printf(" %s %x\n", contents.values[i], offsets.values[i]);
106 BC_Resources* BC_Theme::get_resources()
108 return BC_WindowBase::get_resources();
112 // These create single images for storage in the image_sets table.
113 VFrame* BC_Theme::new_image(char *title, char *path)
115 VFrame *existing_image = title[0] ? get_image(title) : 0;
116 if(existing_image) return existing_image;
118 BC_ThemeSet *result = new BC_ThemeSet(1, 0, title);
119 result->data[0] = new VFrame(get_image_data(path));
120 image_sets.append(result);
121 return result->data[0];
124 VFrame* BC_Theme::new_image(char *path)
126 return new_image("", path);
129 // These create image sets which are stored in the image_sets table.
130 VFrame** BC_Theme::new_image_set(char *title, int total, va_list *args)
132 VFrame **existing_image_set = title[0] ? get_image_set(title) : 0;
133 if(existing_image_set) return existing_image_set;
135 BC_ThemeSet *result = new BC_ThemeSet(total, 1, title);
136 image_sets.append(result);
137 for(int i = 0; i < total; i++)
139 char *path = va_arg(*args, char*);
140 result->data[i] = new_image(path);
145 VFrame** BC_Theme::new_image_set(char *title, int total, ...)
148 va_start(list, total);
149 VFrame **result = new_image_set(title, total, &list);
155 VFrame** BC_Theme::new_image_set(int total, ...)
158 va_start(list, total);
159 VFrame **result = new_image_set("", total, &list);
165 VFrame* BC_Theme::get_image(char *title)
167 for(int i = 0; i < image_sets.total; i++)
169 if(!strcmp(image_sets.values[i]->title, title))
171 return image_sets.values[i]->data[0];
177 // TODO: Need to return a default image
181 VFrame** BC_Theme::get_image_set(char *title)
183 for(int i = 0; i < image_sets.total; i++)
185 if(!strcmp(image_sets.values[i]->title, title))
187 return image_sets.values[i]->data;
193 // TODO: Need to return a default image set
209 VFrame** BC_Theme::new_button(char *overlay_path,
214 VFrame default_data(get_image_data(overlay_path));
215 BC_ThemeSet *result = new BC_ThemeSet(3, 1, "");
217 result->data[0] = new_image(up_path);
218 result->data[1] = new_image(hi_path);
219 result->data[2] = new_image(dn_path);
220 for(int i = 0; i < 3; i++)
221 overlay(result->data[i], &default_data);
226 VFrame** BC_Theme::new_button(char *overlay_path,
231 VFrame default_data(get_image_data(overlay_path));
232 BC_ThemeSet *result = new BC_ThemeSet(3, 0, "");
234 result->data[0] = new VFrame(*up);
235 result->data[1] = new VFrame(*hi);
236 result->data[2] = new VFrame(*dn);
237 for(int i = 0; i < 3; i++)
238 overlay(result->data[i], &default_data);
243 VFrame** BC_Theme::new_toggle(char *overlay_path,
248 char *checkedhi_path)
250 VFrame default_data(get_image_data(overlay_path));
251 BC_ThemeSet *result = new BC_ThemeSet(5, 1, "");
253 result->data[0] = new_image(up_path);
254 result->data[1] = new_image(hi_path);
255 result->data[2] = new_image(checked_path);
256 result->data[3] = new_image(dn_path);
257 result->data[4] = new_image(checkedhi_path);
258 for(int i = 0; i < 5; i++)
259 overlay(result->data[i], &default_data);
263 VFrame** BC_Theme::new_toggle(char *overlay_path,
270 VFrame default_data(get_image_data(overlay_path));
271 BC_ThemeSet *result = new BC_ThemeSet(5, 0, "");
273 result->data[0] = new VFrame(*up);
274 result->data[1] = new VFrame(*hi);
275 result->data[2] = new VFrame(*checked);
276 result->data[3] = new VFrame(*dn);
277 result->data[4] = new VFrame(*checkedhi);
278 for(int i = 0; i < 5; i++)
279 overlay(result->data[i], &default_data);
282 void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2)
286 unsigned char **in_rows;
287 unsigned char **out_rows;
291 w = MIN(src->get_w(), dst->get_w());
292 h = MIN(dst->get_h(), src->get_h());
299 h = MIN(dst->get_h(), src->get_h());
301 in_rows = src->get_rows();
302 out_rows = dst->get_rows();
304 switch(src->get_color_model())
307 switch(dst->get_color_model())
310 for(int i = 0; i < h; i++)
312 unsigned char *in_row = in_rows[i] + in_x1 * 4;
313 unsigned char *out_row = out_rows[i];
314 for(int j = 0; j < w; j++)
316 int opacity = in_row[3];
317 int transparency = 0xff - opacity;
318 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
319 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
320 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
321 out_row[3] = MAX(in_row[3], out_row[3]);
328 for(int i = 0; i < h; i++)
330 unsigned char *in_row = in_rows[i] + in_x1 * 4;
331 unsigned char *out_row = out_rows[i];
332 for(int j = 0; j < w; j++)
334 int opacity = in_row[3];
335 int transparency = 0xff - opacity;
336 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
337 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
338 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
349 void BC_Theme::set_path(char *path)
351 strcpy(this->path, path);
354 void BC_Theme::unset_path()
356 strcpy(this->path, default_path);
357 if(data_buffer) delete [] data_buffer;
358 if(contents_buffer) delete [] contents_buffer;
364 unsigned char* BC_Theme::get_image_data(char *title)
372 fprintf(stderr, _("Theme::get_image: %s is a directory.\n"), path);
375 FILE *fd = fopen(path, "r");
380 fprintf(stderr, _("Theme::get_image: %s when opening %s\n"), strerror(errno), path);
382 int data_offset, contents_offset;
387 if(fseek(fd, -8, SEEK_END) < 0)
389 fprintf(stderr, _("BC_Theme::get_image_data fseek %s\n"), strerror(errno));
392 total_bytes = ftell(fd);
393 if(fread(&data_offset, 1, 4, fd) != 4)
395 fprintf(stderr, _("BC_Theme::get_image_data fread 1 %s\n"), strerror(errno));
398 if(fread(&contents_offset, 1, 4, fd) != 4)
400 fprintf(stderr, _("BC_Theme::get_image_data fread 2 %s\n"), strerror(errno));
405 fseek(fd, data_offset, SEEK_SET);
406 data_size = contents_offset - data_offset;
407 data_buffer = new char[data_size];
408 fread(data_buffer, 1, data_size, fd);
410 fseek(fd, contents_offset, SEEK_SET);
411 contents_size = total_bytes - contents_offset;
412 contents_buffer = new char[contents_size];
413 fread(contents_buffer, 1, contents_size, fd);
415 char *start_of_title = contents_buffer;
416 for(int i = 0; i < contents_size; )
418 if(contents_buffer[i] == 0)
420 contents.append(start_of_title);
422 offsets.append(*(int*)(contents_buffer + i));
424 start_of_title = contents_buffer + i;
433 // Image is the same as the last one
434 if(last_image && !strcasecmp(last_image, title))
436 return (unsigned char*)(data_buffer + last_offset);
439 // Search for image anew.
440 for(int i = 0; i < contents.total; i++)
442 if(!strcasecmp(contents.values[i], title))
444 last_offset = offsets.values[i];
445 last_image = contents.values[i];
447 return (unsigned char*)(data_buffer + offsets.values[i]);
451 fprintf(stderr, _("Theme::get_image: %s not found.\n"), title);
455 void BC_Theme::check_used()
457 // Can't use because some images are gotten the old fashioned way.
460 for(int i = 0; i < used.total; i++)
465 printf(_("BC_Theme::check_used: Images aren't used.\n"));
466 printf("%s ", contents.values[i]);
470 if(got_it) printf("\n");
484 BC_ThemeSet::BC_ThemeSet(int total, int is_reference, char *title)
488 this->is_reference = is_reference;
489 data = new VFrame*[total];
492 BC_ThemeSet::~BC_ThemeSet()
498 for(int i = 0; i < total; i++)