From: GetAway Date: Thu, 12 Jan 2017 15:10:17 +0000 (+0100) Subject: shellexec 2.0: add png support - thanks micha-bbg for help - add shadow X-Git-Url: https://git.webhop.me/?a=commitdiff_plain;h=36400a3d4f6e2d1c5a7e1c3a26b6599abd3c3320;p=shellexec.git shellexec 2.0: add png support - thanks micha-bbg for help - add shadow --- diff --git a/fb_display.c b/fb_display.c new file mode 100644 index 0000000..dbf7fca --- /dev/null +++ b/fb_display.c @@ -0,0 +1,159 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +//#include "config.h" +#include +#include +#include "text.h" +#include "io.h" +#include "gfx.h" +#include "fb_display.h" + +extern unsigned int alpha; + +void blit2FB(void *fbbuff, + uint32_t width, uint32_t height, + uint32_t xoffs, uint32_t yoffs, + uint32_t xp, uint32_t yp, + int cpp); + +void fb_display(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, int clearflag, int alpha) +{ + void *fbbuff = NULL; + int bp = 0; + if(rgbbuff==NULL) + return; + + /* correct panning */ + if(x_pan > x_size - (int)var_screeninfo.xres) x_pan = 0; + if(y_pan > y_size - (int)var_screeninfo.yres) y_pan = 0; + /* correct offset */ + if(x_offs + x_size > (int)var_screeninfo.xres) x_offs = 0; + if(y_offs + y_size > (int)var_screeninfo.yres) y_offs = 0; + + /* blit buffer 2 fb */ + fbbuff = convertRGB2FB(rgbbuff, x_size * y_size, var_screeninfo.bits_per_pixel, &bp, alpha); + if(fbbuff==NULL) + return; + /* ClearFB if image is smaller */ + if(clearflag) + clearFB(); + blit2FB(fbbuff, x_size, y_size, x_offs, y_offs, x_pan, y_pan, bp); + free(fbbuff); +} + +void blit2FB(void *fbbuff, + uint32_t width, uint32_t height, + uint32_t xoffs, uint32_t yoffs, + uint32_t xp, uint32_t yp, + int cpp) +{ + int count, count2, xc, yc; + + int ssx=startx+xoffs; + int ssy=starty+yoffs; + + xc = (width > var_screeninfo.xres) ? var_screeninfo.xres : width; + yc = (height > var_screeninfo.yres) ? var_screeninfo.yres : height; + + int xo = (ssx/*xoffs*/ * cpp)/sizeof(uint32_t); + + switch(cpp){ + case 4: + { + uint32_t * data = (uint32_t *) fbbuff; + + uint32_t * d = (uint32_t *)lbb + xo + stride * ssy/*yoffs*/; + uint32_t * d2; + + for (count = 0; count < yc; count++ ) { + uint32_t *pixpos = &data[(count + yp) * width]; + d2 = (uint32_t *) d; + for (count2 = 0; count2 < xc; count2++ ) { + uint32_t pix = *(pixpos + xp); + if ((pix & 0xff000000) == 0xff000000) + *d2 = pix; + else { + uint8_t *in = (uint8_t *)(pixpos + xp); + uint8_t *out = (uint8_t *)d2; + int a = in[3]; /* TODO: big/little endian */ + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + } + d2++; + pixpos++; + } + d += stride; + } + } + break; + } +} + +void clearFB() +{ + memset(lbb, 0, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t)); + memcpy(lfb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t)); +} + +void* convertRGB2FB(unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp, int alpha) +{ + unsigned long i; + unsigned int *fbbuff = NULL; + + switch(bpp) + { + case 24: + case 32: + *cpp = 4; + fbbuff = (unsigned int *) malloc(count * sizeof(unsigned int)); + if(fbbuff==NULL) + { + printf("Error: malloc\n"); + return NULL; + } + if(alpha) { + for(i = 0; i < count ; i++) { + fbbuff[i] = ((rgbbuff[i*4+3] << 24) & 0xFF000000) | + ((rgbbuff[i*4] << 16) & 0x00FF0000) | + ((rgbbuff[i*4+1] << 8) & 0x0000FF00) | + ((rgbbuff[i*4+2]) & 0x000000FF); + } + } + else + { + int transp; + for(i = 0; i < count ; i++) { + transp = 0; + if(rgbbuff[i*3] || rgbbuff[i*3+1] || rgbbuff[i*3+2]) + transp = 0xFF; + fbbuff[i] = (transp << 24) | + ((rgbbuff[i*3] << 16) & 0xFF0000) | + ((rgbbuff[i*3+1] << 8) & 0xFF00) | + (rgbbuff[i*3+2] & 0xFF); + } + } + break; + default: + fprintf(stderr, "Unsupported video mode! You've got: %dbpp\n", bpp); + exit(1); + } + return (void *)fbbuff; +} diff --git a/fb_display.h b/fb_display.h new file mode 100644 index 0000000..87ab753 --- /dev/null +++ b/fb_display.h @@ -0,0 +1,26 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#ifndef __pictureviewer_fbdisplay__ +#define __pictureviewer_fbdisplay__ + +void* convertRGB2FB(unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp, int alpha); +void fb_display(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, int clearflag, int alpha); +void clearFB(); + +#endif diff --git a/gfx.c b/gfx.c index 50a0539..3e6e61c 100644 --- a/gfx.c +++ b/gfx.c @@ -2,33 +2,11 @@ #include "current.h" #include "gfx.h" +#include "resize.h" +#include "pngw.h" +#include "fb_display.h" -char circle[] = -{ - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, - 0,2,1,1,1,1,1,1,1,1,1,1,1,1,2,0, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, - 0,2,1,1,1,1,1,1,1,1,1,1,1,1,2,0, - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0 -}; - -size_t GetCircleHeight() -{ - return sqrt(sizeof(circle)); -} - -//typedef struct { unsigned char width_lo; unsigned char width_hi; unsigned char height_lo; unsigned char height_hi; unsigned char transp; } IconHeader; +extern const char NOMEM[]; void RenderBox(int sx, int sy, int ex, int ey, int rad, int col) { @@ -124,79 +102,85 @@ void RenderBox(int sx, int sy, int ex, int ey, int rad, int col) } } -/****************************************************************************** - * RenderCircle - ******************************************************************************/ - -void RenderCircle(int sx, int sy, char col) -{ - int x, y; - uint32_t pix = bgra[col]; - uint32_t *p = lbb + startx + sx; - int s = stride * (starty + sy); - int h = GetCircleHeight(); - - for(y = 0; y < h * h; y += h, s += stride) - for(x = 0; x < h; x++) - switch(circle[x + y]) { - case 1: *(p + x + s) = pix; break; - case 2: *(p + x + s) = 0xFFFFFFFF; break; - } -} - /****************************************************************************** * PaintIcon ******************************************************************************/ -/*void PaintIcon(char *filename, int x, int y, unsigned char offset) +int paintIcon(const char *const fname, int xstart, int ystart, int xsize, int ysize, int *iw, int *ih) { - IconHeader iheader; - unsigned int width, height,count,count2; - unsigned char pixbuf[768],*pixpos,compressed,pix1,pix2; - unsigned char * d = (lbb+(startx+x)+var_screeninfo.xres*(starty+y)); - unsigned char * d2; - int fd; +FILE *tfh; +int x1, y1, rv=-1, alpha=0, bpp=0; - fd = open(filename, O_RDONLY); +int imx,imy,dxo,dyo,dxp,dyp; +unsigned char *buffer=NULL; - if (fd == -1) + if((tfh=fopen(fname,"r"))!=NULL) { - printf("%s \n", __plugin__, filename); - return; - } - - read(fd, &iheader, sizeof(IconHeader)); - - width = (iheader.width_hi << 8) | iheader.width_lo; - height = (iheader.height_hi << 8) | iheader.height_lo; - + if(png_getsize(fname, &x1, &y1)) + { + perror(__plugin__ " \n"); + fclose(tfh); + return -1; + } + // no resize + if (xsize == 0 || ysize ==0) + { + xsize = x1; + ysize = y1; + } + if((buffer=(unsigned char *) malloc(x1*y1*4))==NULL) + { + printf(NOMEM); + fclose(tfh); + return -1; + } - for (count=0; count> 1 ); - pixpos = (unsigned char*) &pixbuf; - d2 = d; - for (count2=0; count2> 1; count2 ++ ) + if(!(rv=png_load(fname, &buffer, &x1, &y1, &bpp))) { - compressed = *pixpos; - pix1 = (compressed & 0xf0) >> 4; - pix2 = (compressed & 0x0f); + alpha=(bpp==4)?1:0; + scale_pic(&buffer,x1,y1,xstart,ystart,xsize,ysize,&imx,&imy,&dxp,&dyp,&dxo,&dyo,alpha); - if (pix1 != iheader.transp) - { - *d2=pix1 + offset; - } - d2++; - if (pix2 != iheader.transp) - { - *d2=pix2 + offset; - } - d2++; - pixpos++; + fb_display(buffer, imx, imy, dxp, dyp, dxo, dyo, 0, alpha); } - d += var_screeninfo.xres; + free(buffer); + fclose(tfh); } - close(fd); - return; + *iw = imx; + *ih = imy; + return (rv)?-1:0; +} + +void scale_pic(unsigned char **buffer, int x1, int y1, int xstart, int ystart, int xsize, int ysize, + int *imx, int *imy, int *dxp, int *dyp, int *dxo, int *dyo, int alpha) +{ + float xfact=0, yfact=0; + int txsize=0, tysize=0; + int txstart =xstart, tystart= ystart; + + if (xsize > (ex-xstart)) txsize= (ex-xstart); + else txsize= xsize; + if (ysize > (ey-ystart)) tysize= (ey-ystart); + else tysize=ysize; + xfact= 1000*txsize/x1; + xfact= xfact/1000; + yfact= 1000*tysize/y1; + yfact= yfact/1000; + + if ( xfact <= yfact) + { + *imx=(int)x1*xfact; + *imy=(int)y1*xfact; + } + else + { + *imx=(int)x1*yfact; + *imy=(int)y1*yfact; + } + if ((x1 != *imx) || (y1 != *imy)) + *buffer=color_average_resize(*buffer,x1,y1,*imx,*imy,alpha); + + *dxp=0; + *dyp=0; + *dxo=txstart; + *dyo=tystart; } -*/ diff --git a/gfx.h b/gfx.h index 35539bc..76c4a04 100644 --- a/gfx.h +++ b/gfx.h @@ -2,8 +2,8 @@ #define __GFX_H__ void RenderBox(int sx, int sy, int ex, int ey, int mode, int color); -void RenderCircle(int sx, int sy, char type); -size_t GetCircleHeight(); -//void PaintIcon(char *filename, int x, int y, unsigned char offset); +int paintIcon(const char *const fname, int xstart, int ystart, int xsize, int ysize, int *iw, int *ih); +void scale_pic(unsigned char **buffer, int x1, int y1, int xstart, int ystart, int xsize, int ysize, + int *imx, int *imy, int *dxp, int *dyp, int *dxo, int *dyo, int alpha); #endif diff --git a/icons.h b/icons.h new file mode 100644 index 0000000..770f34e --- /dev/null +++ b/icons.h @@ -0,0 +1,10 @@ +#ifndef __icons_h__ +#define __icons_h__ + + +#define ICON_BUTTON_RED "/share/tuxbox/neutrino/icons/rot.png" +#define ICON_BUTTON_GREEN "/share/tuxbox/neutrino/icons/gruen.png" +#define ICON_BUTTON_YELLOW "/share/tuxbox/neutrino/icons/gelb.png" +#define ICON_BUTTON_BLUE "/share/tuxbox/neutrino/icons/blau.png" + +#endif diff --git a/png_helper.cpp b/png_helper.cpp new file mode 100644 index 0000000..0ab9468 --- /dev/null +++ b/png_helper.cpp @@ -0,0 +1,21 @@ + +#include "pngw.h" + +int png_load_ext(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp); +int fh_png_getsize(const char *filename, int *x, int *y); + +extern "C" +{ + +int png_load(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp) +{ + return png_load_ext(filename, buffer, xp, yp, bpp); +} + +int png_getsize(const char *filename, int *x, int *y) +{ + return fh_png_getsize(filename, x, y); +} + +} + diff --git a/pngw.cpp b/pngw.cpp new file mode 100644 index 0000000..85493a6 --- /dev/null +++ b/pngw.cpp @@ -0,0 +1,237 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#include +#include +#include +#include +#include + +#include "pngw.h" + +#define FH_ERROR_OK 0 +#define FH_ERROR_FILE 1 /* read/access error */ +#define FH_ERROR_FORMAT 2 /* file format error */ +#define FH_ERROR_MALLOC 3 /* error during malloc */ +#define PNG_BYTES_TO_CHECK 4 +#define min(x,y) ((x) < (y) ? (x) : (y)) + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp); + +int fh_png_id(const char *name) +{ + int fd; + char id[4]; + fd=open(name,O_RDONLY); if(fd==-1) return(0); + read(fd,id,4); + close(fd); + if(id[1]=='P' && id[2]=='N' && id[3]=='G') return(1); + return(0); +} + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp); + +int int_png_load(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp, bool alpha) +{ + static const png_color_16 my_background = {0, 0, 0, 0, 0}; + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + unsigned int i; + int bit_depth, color_type, interlace_type, number_passes, pass, int_bpp; + png_byte * fbptr; + FILE * fh; + bool updateInfo_alreadyRead; + + if(!(fh=fopen(name,"rb"))) + return(FH_ERROR_FILE); + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(png_ptr == NULL) { + fclose(fh); + return(FH_ERROR_FORMAT); + } + info_ptr = png_create_info_struct(png_ptr); + if(info_ptr == NULL) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } +#if (PNG_LIBPNG_VER < 10500) + if (setjmp(png_ptr->jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + png_init_io(png_ptr,fh); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + updateInfo_alreadyRead = false; + if (alpha) // 24bit or gray scale PNGs with alpha-channel + { + *bpp = png_get_channels(png_ptr, info_ptr); + if ((*bpp == 2) && (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) { + if (bit_depth < 8) { + /* Extract multiple pixels with bit depths of 1, 2, and 4 + from a single byte into separate bytes + (useful for paletted and grayscale images). */ + png_set_packing(png_ptr); + /* Expand grayscale images to the full 8 bits + from 1, 2, or 4 bits/pixel */ +#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 9 + png_set_gray_1_2_4_to_8(png_ptr); +#else + png_set_expand_gray_1_2_4_to_8(png_ptr); +#endif + } + /* Expand the grayscale to 24-bit RGB if necessary. */ + png_set_gray_to_rgb(png_ptr); + /* Update the users info structure */ + png_read_update_info(png_ptr, info_ptr); + updateInfo_alreadyRead = true; + *bpp = png_get_channels(png_ptr, info_ptr); + if (*bpp != 4) { + /* No 4 channels found + load PNG without alpha channel */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return fh_png_load(name, buffer, xp, yp); + } + } + else if ((*bpp != 4) || !(color_type & PNG_COLOR_MASK_ALPHA)) { + /* No 4 channels & not an alpha channel found + load PNG without alpha channel */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return fh_png_load(name, buffer, xp, yp); + } + int_bpp = 4; + + /* Expand paletted or RGB images with transparency + to full alpha channels so the data will + be available as RGBA quartets. */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + }else // All other PNGs + { + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_set_palette_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + /* other possibility for png_set_background: use png_get_bKGD */ + } + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + png_set_gray_to_rgb(png_ptr); + png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + } + /* this test does not trigger for 8bit-paletted PNGs with newer libpng (1.2.36 at least), + but the data delivered is with alpha channel anyway, so always strip alpha for now + */ +#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 36 + if (color_type & PNG_COLOR_MASK_ALPHA) +#endif + png_set_strip_alpha(png_ptr); + if (bit_depth < 8) + png_set_packing(png_ptr); + int_bpp = 3; + } + if (bit_depth == 16) + png_set_strip_16(png_ptr); + number_passes = png_set_interlace_handling(png_ptr); + /* Update the users info structure */ + if (updateInfo_alreadyRead == 0) + png_read_update_info(png_ptr,info_ptr); + unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (width * int_bpp != rowbytes) + { + printf("[pngw.cpp]: Error processing %s - please report (including image).\n", name); + printf(" width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)rowbytes); + fclose(fh); + return(FH_ERROR_FORMAT); + } + for (pass = 0; pass < number_passes; pass++) + { + fbptr = (png_byte *)(*buffer); + for (i = 0; i < height; i++, fbptr += width * int_bpp) + png_read_row(png_ptr, fbptr, NULL); + } + png_read_end(png_ptr, info_ptr); + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_OK); +} + +int png_load_ext(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp) +{ + return int_png_load(name, buffer, xp, yp, bpp, true); +} + +int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp) +{ + return int_png_load(name, buffer, xp, yp, NULL, false); +} + +int fh_png_getsize(const char *name,int *x,int *y) +{ + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + FILE *fh; + + if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); + if(png_ptr == NULL) { + fclose(fh); + return(FH_ERROR_FORMAT); + } + info_ptr = png_create_info_struct(png_ptr); + if(info_ptr == NULL) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + +#if (PNG_LIBPNG_VER < 10500) + if (setjmp(png_ptr->jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fh); + return(FH_ERROR_FORMAT); + } + + png_init_io(png_ptr,fh); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + *x=width; + *y=height; + fclose(fh); + return(FH_ERROR_OK); +} diff --git a/pngw.h b/pngw.h new file mode 100644 index 0000000..a09901a --- /dev/null +++ b/pngw.h @@ -0,0 +1,34 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#ifndef __PNGW_H__ +#define __PNGW_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +int png_load(const char *filename, unsigned char **buffer, int* xp, int* yp, int* bpp); +int png_getsize(const char *filename, int *x, int *y); + +#ifdef __cplusplus +} +#endif + +#endif // __PNGW_H__ diff --git a/resize.c b/resize.c new file mode 100644 index 0000000..f397c37 --- /dev/null +++ b/resize.c @@ -0,0 +1,95 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +#include +#include +#include + +unsigned char * color_average_resize(unsigned char * orgin, int ox, int oy, int dx, int dy, int alpha) +{ + unsigned char *cr,*p,*q; + int i,j,k,l,ya,yb; + int sq,r,g,b,a; + cr = (unsigned char*) malloc(dx * dy * ((alpha) ? 4 : 3)); + if(cr==NULL) + { + printf("Error: malloc\n"); + return(orgin); + } + p=cr; + + int xa_v[dx]; + for(i=0;i=ox) + xb_v[i]=ox-1; + } + + if (alpha) + { + for(j=0;j=oy) yb=oy-1; + for(i=0;i=oy) yb=oy-1; + for(i=0;i #include #include +#include +#include #include "current.h" - +#include "icons.h" #include "text.h" #include "io.h" #include "gfx.h" +#include "pngw.h" + -#define SH_VERSION 1.37 +#define SH_VERSION 2.0 static char CFG_FILE[128]="/var/tuxbox/config/shellexec.conf"; -//#define FONT "/usr/share/fonts/md_khmurabi_10.ttf" #define FONT2 "/share/fonts/pakenham.ttf" // if font is not in usual place, we look here: char FONT[128]="/share/fonts/neutrino.ttf"; // CMCST, CMCS, CMCT, CMC, CMCIT, CMCI, CMHT, CMH // WHITE, BLUE0, TRANSP, CMS, ORANGE, GREEN, YELLOW, RED +// COL_MENUCONTENT_PLUS_0 - 3, COL_SHADOW_PLUS_0 unsigned char bl[] = { 0x00, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0x00, 0x80, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char gn[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xC0, 0x00, 0xFF, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char rd[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x80, 0x80, - 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char tr[] = { 0xFF, 0xFF, 0xFF, 0xA0, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00}; -uint32_t bgra[20]; +uint32_t bgra[22]; void TrimString(char *strg); // OSD stuff @@ -81,7 +85,7 @@ char VFD[256]=""; char url[256]="time.fu-berlin.de"; char *line_buffer=NULL; char *trstr; -int paging=1, mtmo=120, radius=11; +int paging=1, mtmo=120, radius=0, radius_small=0; int ixw=600, iyw=680, xoffs=13, vfd=0; char INST_FILE[]="/tmp/rc.locked"; int instance=0; @@ -312,6 +316,11 @@ int Read_Neutrino_Cfg(char *entry) } } } + if((strncmp(entry, tstr, 10) == 0) && (strncmp(entry, "font_file=", 10) == 0)) + { + sscanf(tstr, "font_file=%127s", FONT); + rv = 1; + } //printf("%s\n%s=%s -> %d\n",tstr,entry,cfptr,rv); } fclose(nfh); @@ -476,7 +485,8 @@ int Check_Config(void) } else { - if(strstr(line_buffer,"FONT=")==line_buffer) + int neutrinofont = Read_Neutrino_Cfg("font_file="); + if(neutrinofont!=1 && strstr(line_buffer,"FONT=")==line_buffer) { strcpy(FONT,strchr(line_buffer,'=')+1); } @@ -1303,6 +1313,7 @@ void clean_string(char *trstr, char *lcstr) static void ShowInfo(MENU *m, int knew ) { + int icon_w=0, icon_h=0, xsize=0, ysize=0; int loop, dloop, ldy, stlen; double scrollbar_len, scrollbar_ofs, scrollbar_cor; int index=m->act_entry,tind=m->act_entry; @@ -1325,6 +1336,7 @@ static void ShowInfo(MENU *m, int knew ) tind=index; //frame layout + RenderBox(6, 6, ixw+6, iyw+6, radius, COL_SHADOW_PLUS_0); RenderBox(0, 0, ixw, iyw, radius, CMC); // titlebar @@ -1351,18 +1363,34 @@ static void ShowInfo(MENU *m, int knew ) scrollbar_cor = scrollbar_len*(double)MAX_FUNCS; RenderBox(ixw-sbw + sbo, moffs + scrollbar_ofs + sbo, ixw - sbo, moffs + scrollbar_ofs + scrollbar_cor - sbo, radius, COL_MENUCONTENT_PLUS_3); } + int iw,ih; + int offset, hoffs = (m->headermed[m->act_header]==1)?0:46; + int ioffs = xoffs+8; // + half standard icon + if(m->icon[m->act_header]) + { + png_getsize(m->icon[m->act_header], &icon_w, &icon_h); + // limit icon size + if(icon_w > 150 || icon_h > 36) { + icon_w = xsize = 150; + icon_h = ysize = 36; + } + if (icon_w > 32) { + offset = ioffs-16; + } + else + offset = ioffs-icon_w/2; + paintIcon(m->icon[m->act_header], offset, (moffs-icon_h)/2+1, xsize, ysize, &iw, &ih); + } // Title text + if (icon_w > 32) { + hoffs = offset+iw+8; + } lcstr=strdup(m->headertxt[m->act_header]); clean_string(m->headertxt[m->act_header],lcstr); - RenderString(lcstr, (m->headermed[m->act_header]==1)?0:45, moffs-(moffs-FSIZE_BIG)/2, ixw-sbw-((m->headermed[m->act_header]==1)?0:45) , (m->headermed[m->act_header]==1)?CENTER:LEFT, FSIZE_BIG, CMHT); + RenderString(lcstr, hoffs, moffs-(moffs-FSIZE_BIG)/2+2, ixw-sbw-hoffs, (m->headermed[m->act_header]==1)?CENTER:LEFT, FSIZE_BIG, CMHT); free(lcstr); - if(m->icon[m->act_header]) - { - //PaintIcon(m->icon[m->act_header],xoffs-6,soffs+2,1); - } - index /= MAX_FUNCS; dloop=0; ldy=dy; @@ -1409,11 +1437,11 @@ static void ShowInfo(MENU *m, int knew ) coffs=clh; } } - RenderString(dstr, 45, my+soffs-(dy-font_size)/2-coffs, ixw-sbw-65, LEFT, font_type, (((loop%MAX_FUNCS) == (tind%MAX_FUNCS)) && (sbar) && (!nosel))?CMCST:(nosel)?CMCIT:CMCT); + RenderString(dstr, 46, my+soffs-(dy-font_size)/2-coffs+2, ixw-sbw-65, LEFT, font_type, (((loop%MAX_FUNCS) == (tind%MAX_FUNCS)) && (sbar) && (!nosel))?CMCST:(nosel)?CMCIT:CMCT); } if(pl->type==TYP_MENU) { - RenderString(">", 30, my+soffs-(dy-FSIZE_MED)/2, 65, LEFT, MED, (((loop%MAX_FUNCS) == (tind%MAX_FUNCS)) && (sbar) && (!nosel))?CMCST:CMCT); + RenderString(">", 30, my+soffs-(dy-FSIZE_MED)/2+1, 65, LEFT, MED, (((loop%MAX_FUNCS) == (tind%MAX_FUNCS)) && (sbar) && (!nosel))?CMCST:CMCT); } if(pl->underline) { @@ -1456,25 +1484,20 @@ static void ShowInfo(MENU *m, int knew ) } if((pl->type!=TYP_COMMENT) && ((pl->type!=TYP_INACTIVE) || (pl->showalways==2))) { - int ch = GetCircleHeight(); + icon_w = icon_h = 0; + png_getsize(ICON_BUTTON_RED, &icon_w, &icon_h); direct[dloop++]=(pl->type!=TYP_INACTIVE)?loop:-1; switch(dloop) { - case 1: RenderCircle(xoffs,my+soffs-(dy+ch)/2,RED); break; - case 2: RenderCircle(xoffs,my+soffs-(dy+ch)/2,GREEN); break; - case 3: RenderCircle(xoffs,my+soffs-(dy+ch)/2,YELLOW); break; - case 4: RenderCircle(xoffs,my+soffs-(dy+ch)/2,BLUE0); break; -/* - case 1: PaintIcon("/share/tuxbox/neutrino/icons/rot.raw",xoffs-2,my-15,1); break; - case 2: PaintIcon("/share/tuxbox/neutrino/icons/gruen.raw",xoffs-2,my-15,1); break; - case 3: PaintIcon("/share/tuxbox/neutrino/icons/gelb.raw",xoffs-2,my-15,1); break; - case 4: PaintIcon("/share/tuxbox/neutrino/icons/blau.raw",xoffs-2,my-15,1); break; -*/ + case 1: paintIcon(ICON_BUTTON_RED, ioffs-icon_w/2, my+soffs-(dy+icon_h)/2, 0, 0, &iw, &ih); break; + case 2: paintIcon(ICON_BUTTON_GREEN, ioffs-icon_w/2, my+soffs-(dy+icon_h)/2, 0, 0, &iw, &ih); break; + case 3: paintIcon(ICON_BUTTON_YELLOW, ioffs-icon_w/2, my+soffs-(dy+icon_h)/2, 0, 0, &iw, &ih); break; + case 4: paintIcon(ICON_BUTTON_BLUE, ioffs-icon_w/2, my+soffs-(dy+icon_h)/2, 0, 0, &iw, &ih); break; default: if(dloop<15) { sprintf(tstr,"%1d",(dloop-4)%10); - RenderString(tstr, xoffs, my+soffs-(dy-FSIZE_SMALL)/2, 15, CENTER, SMALL, ((loop%MAX_FUNCS) == (tind%MAX_FUNCS))?CMCST:((pl->type==TYP_INACTIVE)?CMCIT:CMCT)); + RenderString(tstr, xoffs, my+soffs-(dy-FSIZE_SMALL)/2+2, 15, CENTER, SMALL, ((loop%MAX_FUNCS) == (tind%MAX_FUNCS))?CMCST:((pl->type==TYP_INACTIVE)?CMCIT:CMCT)); } break; } @@ -1612,10 +1635,12 @@ int main (int argc, char **argv) rd[index]=(float)tv*2.55; } - if(Read_Neutrino_Cfg("rounded_corners")>0) - radius=11; + if(Read_Neutrino_Cfg("rounded_corners")>0) { + radius = 11; + radius_small = 7; + } else - radius=0; + radius = radius_small = 0; mtmo = Read_Neutrino_Cfg("timing.menu"); if (mtmo < 0) @@ -1630,7 +1655,23 @@ int main (int argc, char **argv) tr[index]=tr[cindex]; cindex=index; } - for (index = 0; index <= COL_MENUCONTENT_PLUS_3; index++) + sprintf(trstr,"infobar_alpha"); + if((tv=Read_Neutrino_Cfg(trstr))>=0) + tr[COL_SHADOW_PLUS_0]=255-(float)tv*2.55; + + sprintf(trstr,"infobar_blue"); + if((tv=Read_Neutrino_Cfg(trstr))>=0) + bl[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + sprintf(trstr,"infobar_green"); + if((tv=Read_Neutrino_Cfg(trstr))>=0) + gn[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + sprintf(trstr,"infobar_red"); + if((tv=Read_Neutrino_Cfg(trstr))>=0) + rd[COL_SHADOW_PLUS_0]=(float)tv*2.55*0.4; + + for (index = 0; index <= COL_SHADOW_PLUS_0; index++) bgra[index] = (tr[index] << 24) | (rd[index] << 16) | (gn[index] << 8) | bl[index]; fb = open(FB_DEVICE, O_RDWR); @@ -1654,7 +1695,7 @@ int main (int argc, char **argv) perror(__plugin__ " \n"); return -1; } - if(!(lfb = (uint32_t*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) + if(!(lfb = (uint32_t*)mmap(0, fix_screeninfo.smem_len, PROT_WRITE|PROT_READ, MAP_SHARED, fb, 0))) { perror(__plugin__ " \n"); return -1; diff --git a/shellexec.h b/shellexec.h index 40e959c..1223dea 100644 --- a/shellexec.h +++ b/shellexec.h @@ -128,14 +128,37 @@ FT_UInt prev_glyphindex; FT_Bool use_kerning; //devs - int fb, debounce, rblock; //framebuffer stuff - -enum {FILL, GRID}; - -enum {CMCST, CMCS, CMCT, CMC, CMCIT, CMCI, CMHT, CMH, WHITE, BLUE0, GTRANSP, CMS, ORANGE, GREEN, YELLOW, RED, COL_MENUCONTENT_PLUS_0, COL_MENUCONTENT_PLUS_1, COL_MENUCONTENT_PLUS_2, COL_MENUCONTENT_PLUS_3}; +enum { + FILL, + GRID +}; + +enum { + CMCST, + CMCS, + CMCT, + CMC, + CMCIT, + CMCI, + CMHT, + CMH, + WHITE, + BLUE0, + GTRANSP, + CMS, + ORANGE, + GREEN, + YELLOW, + RED, + COL_MENUCONTENT_PLUS_0, + COL_MENUCONTENT_PLUS_1, + COL_MENUCONTENT_PLUS_2, + COL_MENUCONTENT_PLUS_3, + COL_SHADOW_PLUS_0 +}; #define TRANSP 0 extern uint32_t bgra[]; diff --git a/starter.c b/starter.c index a83ecfd..2f31068 100644 --- a/starter.c +++ b/starter.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "current.h" diff --git a/text.c b/text.c index d584191..3c47ad5 100644 --- a/text.c +++ b/text.c @@ -485,8 +485,9 @@ char *rmptr, *rmstr, *rmdptr; void ShowMessage(char *mtitle, char *message, int wait) { - extern int radius; + extern int radius, radius_small; int ixw=420; + int iyw=wait?327:300; int lx=startx; //int ly=starty; char *tdptr; @@ -495,23 +496,24 @@ void ShowMessage(char *mtitle, char *message, int wait) //starty=sy; //layout - RenderBox(0, 178, ixw, 327, radius, CMH); - RenderBox(2, 180, ixw-4, 323, radius, CMC); + RenderBox(0+4, 178+4, ixw+4, iyw+4, radius, COL_SHADOW_PLUS_0); + RenderBox(0, 178, ixw, iyw, radius, CMC); RenderBox(0, 178, ixw, 220, radius, CMH); //message tdptr=strdup(mtitle); remove_tabs(tdptr); - RenderString(tdptr, 2, 213, ixw-10, CENTER, FSIZE_BIG, CMHT); + RenderString(tdptr, 5, 215, ixw-10, CENTER, FSIZE_BIG, CMHT); free(tdptr); tdptr=strdup(message); remove_tabs(tdptr); - RenderString(tdptr, 2, 270, ixw-10, CENTER, FSIZE_MED, CMCT); + RenderString(tdptr, 5, 270, ixw-10, CENTER, FSIZE_MED, CMCT); free(tdptr); if(wait) { - RenderBox(ixw/2-25, 286, ixw/2+25, 310, radius, CMCS); + RenderBox(ixw/2-35+4, 286+4, ixw/2+35+4, 310+4, radius_small, COL_SHADOW_PLUS_0); + RenderBox(ixw/2-35, 286, ixw/2+35, 310, radius_small, CMCS); RenderString("OK", ixw/2-25, 312, 50, CENTER, FSIZE_MED, CMCT); } memcpy(lfb, lbb, var_screeninfo.xres*var_screeninfo.yres*sizeof(uint32_t));