root/modules/gui_grid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. grid_lines_free_data
  2. new_grid
  3. new_gline
  4. skip_whitespace
  5. skip_to_eol
  6. skip_token
  7. process_title
  8. get_color
  9. get_value
  10. process_element
  11. parse_grid_file
  12. grid_lines_load
  13. gui_grid_draw_osd
  14. _module_loader
  15. _module_unloader
  16. _module_can_unload

   1 #include "camera_info.h"
   2 #include "keyboard.h"
   3 #include "conf.h"
   4 #include "gui.h"
   5 #include "gui_draw.h"
   6 #include "gui_lang.h"
   7 #include "gui_grid.h"
   8 #include "fileutil.h"
   9 
  10 #include "module_def.h"
  11 
  12 //-------------------------------------------------------------------
  13 #define GRID_REDRAW_INTERVAL        4
  14 
  15 //-------------------------------------------------------------------
  16 typedef enum {
  17     GRID_ELEM_LINE,
  18     GRID_ELEM_RECT,
  19     GRID_ELEM_FILLED_RECT,
  20     GRID_ELEM_ELLIPSE,
  21     GRID_ELEM_FILLED_ELLIPSE,
  22 } grid_elem_type;
  23 
  24 typedef struct _gline {
  25     grid_elem_type      type;
  26     coord               x0,y0,x1,y1;
  27     unsigned            clf, clb;
  28     struct _gline       *next;
  29 } gline;
  30 
  31 static int   resize;
  32 static gline *head;
  33 static gline *last;
  34 
  35 static int grid_loading = 0;
  36 static int interval = GRID_REDRAW_INTERVAL;
  37 
  38 //-------------------------------------------------------------------
  39 static void grid_lines_free_data() {
  40     while (head) {
  41         gline* p  = head;
  42         head = head->next;
  43         free(p);
  44     }
  45 }
  46 
  47 static void new_grid() {
  48     grid_lines_free_data();
  49     head = last = 0;
  50     resize = (camera_screen.width != 360) || (camera_screen.height != 240);
  51 }
  52 
  53 static gline* new_gline() {
  54     gline* p = malloc(sizeof(gline));
  55     if (p) {
  56         memset(p, 0, sizeof(gline));
  57         if (!head) head = p;
  58         if (last) last->next = p;
  59         last = p;
  60     }
  61     return p;
  62 }
  63 
  64 //-------------------------------------------------------------------
  65 static char* skip_whitespace(char* p) {
  66     while (*p && (*p == ' ' || *p == '\t' || *p == ',')) p += 1; // skip whitespace or comma
  67     return p;
  68 }
  69 
  70 static char* skip_to_eol(char* p) {
  71     while (*p && *p != '\n') p += 1; // skip to eol
  72     if (*p) p += 1;
  73     return p;
  74 }
  75 
  76 static char* skip_token(char* p) {
  77     while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != '\n') p += 1;
  78     return p;
  79 }
  80 
  81 //-------------------------------------------------------------------
  82 static void process_title(char *ptr) {
  83     register int i=0;
  84 
  85     ptr = skip_whitespace(ptr);
  86     while (i<(int)(sizeof(conf.grid_title)-1) && ptr[i] && ptr[i]!='\r' && ptr[i]!='\n') {
  87         conf.grid_title[i]=ptr[i];
  88         ++i;
  89     }
  90     conf.grid_title[i]=0;
  91 }
  92 
  93 //-------------------------------------------------------------------
  94 // Check for script colors
  95 static int get_color(char*p, char** np) {
  96     int rv = 0;
  97     if (strncmp(p,"trans",5) == 0)              rv = 255+1;
  98     else if (strncmp(p,"black",5) == 0)         rv = 255+2;
  99     else if (strncmp(p,"white",5) == 0)         rv = 255+3;
 100     else if (strncmp(p,"red_dark",8) == 0)      rv = 255+5;
 101     else if (strncmp(p,"red_light",9) == 0)     rv = 255+6;
 102     else if (strncmp(p,"red",3) == 0)           rv = 255+4;
 103     else if (strncmp(p,"green_dark",10) == 0)   rv = 255+8;
 104     else if (strncmp(p,"green_light",11) == 0)  rv = 255+9;
 105     else if (strncmp(p,"green",5) == 0)         rv = 255+7;
 106     else if (strncmp(p,"blue_dark",9) == 0)     rv = 255+11;
 107     else if (strncmp(p,"blue_light",10) == 0)   rv = 255+12;
 108     else if (strncmp(p,"blue",4) == 0)          rv = 255+10;
 109     else if (strncmp(p,"grey_trans",10) == 0)   rv = 255+19;
 110     else if (strncmp(p,"grey_dark",9) == 0)     rv = 255+14;
 111     else if (strncmp(p,"grey_light",10) == 0)   rv = 255+15;
 112     else if (strncmp(p,"grey",4) == 0)          rv = 255+13;
 113     else if (strncmp(p,"yellow_dark",11) == 0)  rv = 255+17;
 114     else if (strncmp(p,"yellow_light",12) == 0) rv = 255+18;
 115     else if (strncmp(p,"yellow",6) == 0)        rv = 255+16;
 116     else if (strncmp(p,"magenta",7) == 0)       rv = 255+20;
 117     if (rv > 0)
 118         while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != '\n') p += 1;
 119     if (np) *np = p;
 120     return rv;
 121 }
 122 
 123 static int get_value(char* p, int* failed, int is_color) {
 124     int rv = 0;
 125     int fnd = 0;
 126     char *np = p;
 127     rv = strtol(p, &np, 0);
 128     if (np != p) fnd = 1;
 129     if (!fnd && is_color) {
 130         char* np = p;
 131         rv = get_color(p, &np);
 132         if (np != p) fnd = 1;
 133     }
 134     *failed = !fnd;
 135     return rv;
 136 }
 137 
 138 static void process_element(char *ptr, int n, grid_elem_type type) {
 139     int i, failed;
 140     long nums[6];
 141 
 142     for (i=0; i<(int)(sizeof(nums)/sizeof(nums[0])) && i<n; ++i) {
 143         ptr = skip_whitespace(ptr);
 144         nums[i] = get_value(ptr, &failed, i >= 4);
 145         if (failed) // error
 146             return;
 147         ptr = skip_token(ptr);
 148     }
 149 
 150     gline* gptr = new_gline();
 151    
 152     if (gptr) {
 153         gptr->type=type;
 154         if (resize) {
 155             // Scale values for later resizing
 156             nums[0] = ((nums[0] << 14) + 180) / 360;
 157             nums[1] = ((nums[1] << 14) + 120) / 240;
 158             nums[2] = ((nums[2] << 14) + 180) / 360;
 159             nums[3] = ((nums[3] << 14) + 120) / 240;
 160         }
 161         gptr->x0=nums[0];  gptr->y0=nums[1];
 162         gptr->x1=nums[2];  gptr->y1=nums[3];
 163         gptr->clf=nums[4]; gptr->clb=nums[5];
 164     }
 165 }
 166 
 167 //-------------------------------------------------------------------
 168 static int parse_grid_file(char *ptr, int size)
 169 {
 170     conf.grid_title[0]=0;
 171 
 172     if (size > 0)
 173     {
 174         new_grid();
 175 
 176         while (ptr[0])
 177         {
 178             ptr = skip_whitespace(ptr);
 179             if (ptr[0]=='@')
 180             {
 181                 if (strncmp("@title", ptr, 6)==0) {
 182                     ptr+=6;
 183                     process_title(ptr);
 184                 } else if (strncmp("@line", ptr, 5)==0) {
 185                     ptr+=5;
 186                     process_element(ptr, 5, GRID_ELEM_LINE);
 187                 } else if (strncmp("@rectf", ptr, 6)==0) {
 188                     ptr+=6;
 189                     process_element(ptr, 6, GRID_ELEM_FILLED_RECT);
 190                 } else if (strncmp("@rect", ptr, 5)==0) {
 191                     ptr+=5;
 192                     process_element(ptr, 5, GRID_ELEM_RECT);
 193                 } else if (strncmp("@elpsf", ptr, 6)==0) {
 194                     ptr+=6;
 195                     process_element(ptr, 5, GRID_ELEM_FILLED_ELLIPSE);
 196                 } else if (strncmp("@elps", ptr, 5)==0) {
 197                     ptr+=5;
 198                     process_element(ptr, 5, GRID_ELEM_ELLIPSE);
 199                 }
 200             }
 201             ptr = skip_to_eol(ptr);
 202         }
 203     }
 204 
 205     return size;
 206 }
 207 
 208 //-------------------------------------------------------------------
 209 void grid_lines_load(const char *fn)
 210 {
 211     grid_loading = 1;
 212     if (process_file(fn, parse_grid_file, 1) > 0)  // non-zero length file found?
 213     {
 214         if (conf.grid_title[0]==0)                 // use filename if no @title string found
 215         {
 216             char* c = strrchr(fn, '/');
 217             strncpy(conf.grid_title, (c)?c+1:fn, sizeof(conf.grid_title));
 218             conf.grid_title[sizeof(conf.grid_title)-1] = 0;
 219         }
 220         strcpy(conf.grid_lines_file, fn);
 221     }
 222     grid_loading = 0;
 223 }
 224 
 225 //-------------------------------------------------------------------
 226 void gui_grid_draw_osd(int force)
 227 {
 228     if (camera_info.state.mode_rec_or_review && conf.show_grid_lines)
 229     {
 230         int xs=0, xo=0, ys=0, yo=0;
 231         gline* ptr;
 232         twoColors ucol = user_color(conf.grid_color);
 233 
 234         if (force || --interval==0) {
 235             if (resize) {
 236                 // Grid aspect ratio is 4:3 - fit to 3:2 or 16:9 as needed and center on screen
 237                 // Note: assumes aspect ratio of screen dimensions matches display aspect ratio
 238                 xs = (camera_screen.height * 4) / 3;
 239                 xo = (camera_screen.width - xs) / 2;
 240                 ys = camera_screen.height;
 241                 yo = 0;
 242             }
 243             for (ptr = head; ptr; ptr = ptr->next) {
 244                 twoColors col = (conf.grid_force_color) ? ucol : MAKE_COLOR(get_script_color(ptr->clb), get_script_color(ptr->clf));
 245                 int x0 = ptr->x0;
 246                 int y0 = ptr->y0;
 247                 int x1 = ptr->x1;
 248                 int y1 = ptr->y1;
 249                 if (resize) {
 250                     x0 = ((x0 * xs + 8192) >> 14) + xo;
 251                     y0 = ((y0 * ys + 8192) >> 14) + yo;
 252                     x1 = ((x1 * xs + 8192) >> 14);
 253                     y1 = ((y1 * ys + 8192) >> 14);
 254                 }
 255                 switch (ptr->type) {
 256                     case GRID_ELEM_LINE:
 257                         draw_line(x0, y0, x1+xo, y1+yo, col);
 258                         break;
 259                     case GRID_ELEM_RECT:
 260                         draw_rectangle(x0, y0, x1+xo, y1+yo, col, RECT_BORDER1);
 261                         break;
 262                     case GRID_ELEM_FILLED_RECT:
 263                         draw_rectangle(x0, y0, x1+xo, y1+yo, col, RECT_BORDER1|DRAW_FILLED);
 264                         break;
 265                     case GRID_ELEM_ELLIPSE:
 266                         draw_ellipse(x0, y0, (unsigned int)x1, (unsigned int)y1, col, 0);
 267                         break;
 268                     case GRID_ELEM_FILLED_ELLIPSE:
 269                         draw_ellipse(x0, y0, (unsigned int)x1, (unsigned int)y1, col, DRAW_FILLED);
 270                         break;
 271                 }
 272             }
 273             interval = GRID_REDRAW_INTERVAL;
 274         }
 275     }
 276 }
 277 
 278 // =========  MODULE INIT =================
 279 
 280 /***************** BEGIN OF AUXILARY PART *********************
 281   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 282  **************************************************************/
 283 
 284 //---------------------------------------------------------
 285 // PURPOSE:   Perform on-load initialisation
 286 // RETURN VALUE: 1 error, 0 ok
 287 //---------------------------------------------------------
 288 int _module_loader( __attribute__ ((unused))unsigned int* chdk_export_list )
 289 {
 290     grid_lines_load(conf.grid_lines_file);
 291     return 0;
 292 }
 293 
 294 //---------------------------------------------------------
 295 // PURPOSE: Finalize module operations (close allocs, etc)
 296 // RETURN VALUE: 0-ok, 1-fail
 297 //---------------------------------------------------------
 298 int _module_unloader()
 299 {
 300     grid_lines_free_data();
 301     return 0;
 302 }
 303 
 304 int _module_can_unload()
 305 {
 306     return (conf.show_grid_lines == 0 && !grid_loading);
 307 }
 308 
 309 /******************** Module Information structure ******************/
 310 
 311 libgrids_sym _libgrids =
 312 {
 313     {
 314          _module_loader, _module_unloader, _module_can_unload, 0, 0
 315     },
 316 
 317     gui_grid_draw_osd,
 318     grid_lines_load
 319 };
 320 
 321 ModuleInfo _module_info =
 322 {
 323     MODULEINFO_V1_MAGICNUM,
 324     sizeof(ModuleInfo),
 325     GUI_GRID_VERSION,                   // Module version
 326 
 327     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 328     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 329 
 330     (int32_t)"Grids (dll)",
 331     MTYPE_EXTENSION,            //Grid Display
 332 
 333     &_libgrids.base,
 334 
 335     CONF_VERSION,               // CONF version
 336     ANY_VERSION,                // CAM SCREEN version
 337     ANY_VERSION,                // CAM SENSOR version
 338     ANY_VERSION,                // CAM INFO version
 339 
 340     0,
 341 };
 342 
 343 /*************** END OF AUXILARY PART *******************/

/* [<][>][^][v][top][bottom][index][help] */