138589Sabial/*- 238589Sabial * Copyright (c) 1998 Andrzej Bialecki 338589Sabial * All rights reserved. 438589Sabial * 538589Sabial * Redistribution and use in source and binary forms, with or without 638589Sabial * modification, are permitted provided that the following conditions 738589Sabial * are met: 838589Sabial * 1. Redistributions of source code must retain the above copyright 938589Sabial * notice, this list of conditions and the following disclaimer. 1038589Sabial * 2. Redistributions in binary form must reproduce the above copyright 1138589Sabial * notice, this list of conditions and the following disclaimer in the 1238589Sabial * documentation and/or other materials provided with the distribution. 1338589Sabial * 1438589Sabial * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1538589Sabial * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1638589Sabial * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1738589Sabial * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1838589Sabial * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1938589Sabial * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2038589Sabial * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2138589Sabial * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2238589Sabial * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2338589Sabial * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2438589Sabial * SUCH DAMAGE. 2538589Sabial * 2650479Speter * $FreeBSD$ 2738589Sabial */ 2838589Sabial 2938589Sabial/* 3038589Sabial * Small PNG viewer with scripting abilities 3138589Sabial */ 3238589Sabial 3338589Sabial#include <stdio.h> 3438589Sabial#include <errno.h> 3538589Sabial#include <fcntl.h> 3638589Sabial#include <signal.h> 3738589Sabial#include <termios.h> 3838589Sabial#include <sys/types.h> 3966834Sphk#include <sys/fbio.h> 4066834Sphk#include <sys/consio.h> 4166860Sphk#include <sys/mouse.h> 4238589Sabial#include <vgl.h> 4338589Sabial#include <png.h> 4438589Sabial 4538589Sabial#define NUMBER 8 4638589Sabial 4738589Sabialextern char *optarg; 4838589Sabialextern int optind; 4938589Sabial 5038589Sabial/* Prototypes */ 51104744Salfredint kbd_action(int x, int y, char hotkey); 5238589Sabial 5338589Sabialstruct action { 5438589Sabial int zoom; 5538589Sabial int rotate; 5638589Sabial int Xshift,Yshift; 5738589Sabial}; 5838589Sabial 5938589Sabialstruct menu_item { 6038589Sabial char *descr; 6138589Sabial char hotkey; 6238589Sabial int (*func)(int x, int y, char hotkey); 6338589Sabial}; 6438589Sabial 6538589Sabialstruct menu_item std_menu[]= { 6638589Sabial {"q Quit",'q',kbd_action}, 6738589Sabial {"n Next",'n',kbd_action}, 6838589Sabial {"p Previous",'p',kbd_action}, 6938589Sabial {"Z Zoom in",'Z',kbd_action}, 7038589Sabial {"z Zoom out",'z',kbd_action}, 7138589Sabial {"r Rotate",'r',kbd_action}, 7238589Sabial {"R Refresh",'R',kbd_action}, 7338589Sabial {"l Left",'l',kbd_action}, 7438589Sabial {"h Right",'h',kbd_action}, 7538589Sabial {"j Up",'j',kbd_action}, 7638589Sabial {"k Down",'k',kbd_action}, 7738589Sabial {NULL,0,NULL} 7838589Sabial}; 7938589Sabial 8038589Sabialchar *progname; 8138589SabialVGLBitmap pic,bkg; 8238589Sabialstruct action a; 8338589Sabialbyte pal_red[256]; 8438589Sabialbyte pal_green[256]; 8538589Sabialbyte pal_blue[256]; 8638589Sabialbyte pal_colors; 8738589Sabialdouble screen_gamma; 8838589Sabialint max_screen_colors=15; 8938589Sabialint quit,changed; 9038589Sabialchar **pres; 9138589Sabialint nimg=0; 9240616Sabialint auto_chg=0; 9338589Sabialint cur_img=0; 9438589Sabialchar act; 9538589SabialFILE *log; 9638589Sabial 9738589Sabialvoid 9838589Sabialusage() 9938589Sabial{ 10038589Sabial fprintf(stderr,"\nVGL graphics viewer, 1.0 (c) Andrzej Bialecki.\n"); 10138589Sabial fprintf(stderr,"\nUsage:\n"); 10238589Sabial fprintf(stderr,"\t%s [-r n] [-g n.n] filename\n",progname); 10338589Sabial fprintf(stderr,"\nwhere:\n"); 10438589Sabial fprintf(stderr,"\t-r n\tchoose resolution:\n"); 10538589Sabial fprintf(stderr,"\t\t0 - 640x480x16 (default)\n"); 10638589Sabial fprintf(stderr,"\t\t1 - 640x200x256\n"); 10738589Sabial fprintf(stderr,"\t\t2 - 320x240x256\n"); 10838589Sabial fprintf(stderr,"\t-g n.n\tset screen gamma (1.3 by default)\n"); 10938589Sabial fprintf(stderr,"\n"); 11038589Sabial} 11138589Sabial 11238589Sabialint 11338589Sabialpop_up(char *title,int x, int y) 11438589Sabial{ 11538589Sabial VGLBitmap sav,clr; 11638589Sabial int x1,y1,width,height,i,j; 11738589Sabial int last_pos,cur_pos,max_item; 11838589Sabial char buttons; 11938589Sabial char *t; 12038589Sabial 12138589Sabial sav.Type=VGLDisplay->Type; 12238589Sabial clr.Type=VGLDisplay->Type; 12338589Sabial width=0; 12438589Sabial height=0; 12538589Sabial max_item=0; 12638589Sabial i=0; 12738589Sabial while(std_menu[i].descr!=NULL) { 12838589Sabial height++; 12938589Sabial max_item++; 13038589Sabial if(strlen(std_menu[i].descr)>width) width=strlen(std_menu[i].descr); 13138589Sabial i++; 13238589Sabial } 13338589Sabial width=width*8+2; 13438589Sabial height=height*9+4+8; 13538589Sabial sav.Xsize=width; 13638589Sabial sav.Ysize=height; 13738589Sabial clr.Xsize=width; 13838589Sabial clr.Ysize=height; 13938589Sabial sav.Bitmap=(byte *)calloc(width*height,1); 14038589Sabial clr.Bitmap=(byte *)calloc(width*height,1); 14138589Sabial if(x>(VGLDisplay->Xsize-width)) x1=VGLDisplay->Xsize-width; 14238589Sabial else x1=x; 14338589Sabial if(y>(VGLDisplay->Ysize-height)) y1=VGLDisplay->Ysize-height; 14438589Sabial else y1=y; 14538589Sabial VGLMouseMode(VGL_MOUSEHIDE); 14638589Sabial VGLBitmapCopy(VGLDisplay,x1,y1,&sav,0,0,width,height); 14738589Sabial VGLFilledBox(VGLDisplay,x1,y1,x1+width-1,y1+height-1,pal_colors-1); 14838589Sabial VGLBitmapString(VGLDisplay,x1+1,y1+1,title,0,pal_colors-1,0,0); 14938589Sabial VGLLine(VGLDisplay,x1,y1+9,x1+width,y1+9,0); 15038589Sabial i=0; 15138589Sabial while(std_menu[i].descr!=NULL) { 15238589Sabial VGLBitmapString(VGLDisplay,x1+1,y1+11+i*9,std_menu[i].descr,0,pal_colors-1,0,0); 15338589Sabial i++; 15438589Sabial } 15538589Sabial last_pos=-1; 15638589Sabial VGLMouseMode(VGL_MOUSESHOW); 15738589Sabial do { 15838589Sabial pause(); 15938589Sabial VGLMouseStatus(&x,&y,&buttons); 16038589Sabial cur_pos=(y-y1-11)/9; 16138589Sabial if((cur_pos<0)||(cur_pos>max_item-1)) { 16238589Sabial if(last_pos==-1) last_pos=0; 16338589Sabial VGLBitmapString(VGLDisplay,x1+1,y1+11+last_pos*9,std_menu[last_pos].descr,0,pal_colors-1,0,0); 16438589Sabial last_pos=-1; 16538589Sabial } else if(last_pos!=cur_pos) { 16638589Sabial if(last_pos==-1) last_pos=0; 16738589Sabial VGLBitmapString(VGLDisplay,x1+1,y1+11+last_pos*9,std_menu[last_pos].descr,0,pal_colors-1,0,0); 16838589Sabial VGLBitmapString(VGLDisplay,x1+1,y1+11+cur_pos*9,std_menu[cur_pos].descr,pal_colors/2+1,pal_colors-1,0,0); 16938589Sabial last_pos=cur_pos; 17038589Sabial } 17138589Sabial } while (buttons & MOUSE_BUTTON3DOWN); 17238589Sabial VGLMouseMode(VGL_MOUSEHIDE); 17338589Sabial /* XXX Screws up totally when r==3. Libvgl bug! */ 17438589Sabial VGLBitmapCopy(&clr,0,0,VGLDisplay,x1,y1,width,height); 17538589Sabial VGLBitmapCopy(&sav,0,0,VGLDisplay,x1,y1,width,height); 17638589Sabial VGLMouseMode(VGL_MOUSESHOW); 17738589Sabial free(sav.Bitmap); 17838589Sabial free(clr.Bitmap); 17938589Sabial changed++; 18038589Sabial if((cur_pos>=0) && (cur_pos<max_item)) { 18138589Sabial std_menu[cur_pos].func(x,y,std_menu[cur_pos].hotkey); 18238589Sabial } 18338589Sabial changed++; 18438589Sabial return(0); 18538589Sabial} 18638589Sabial 18738589Sabialvoid 18838589Sabialdisplay( VGLBitmap *pic, 18938589Sabial byte *red, 19038589Sabial byte *green, 19138589Sabial byte *blue, 19238589Sabial struct action *e) 19338589Sabial{ 19438589Sabial VGLBitmap target; 19538589Sabial int x,y,i=0,j=0; 19638589Sabial 19738589Sabial VGLMouseMode(VGL_MOUSEHIDE); 19838589Sabial VGLRestorePalette(); 19938589Sabial /* XXX Broken in r!=2. Libvgl bug. */ 20038589Sabial //VGLClear(VGLDisplay,0); 20138589Sabial VGLBitmapCopy(&bkg,0,0,VGLDisplay,0,0,bkg.Xsize,bkg.Ysize); 20238589Sabial 20338589Sabial if(e!=NULL) { 20438589Sabial if(e->zoom!=1 || e->rotate) { 20538589Sabial target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize*e->zoom*e->zoom,1); 20638589Sabial if(e->rotate) { 20738589Sabial target.Xsize=pic->Ysize*e->zoom; 20838589Sabial target.Ysize=pic->Xsize*e->zoom; 20938589Sabial } else { 21038589Sabial target.Xsize=pic->Xsize*e->zoom; 21138589Sabial target.Ysize=pic->Ysize*e->zoom; 21238589Sabial } 21338589Sabial target.Type=pic->Type; 21438589Sabial for(x=0;x<pic->Xsize;x++) { 21538589Sabial for(y=0;y<pic->Ysize;y++) { 21638589Sabial for(i=0;i<e->zoom;i++) { 21738589Sabial for(j=0;j<e->zoom;j++) { 21838589Sabial if(e->rotate) { 21938589Sabial VGLSetXY(&target,target.Xsize-(e->zoom*y+i),e->zoom*x+j,VGLGetXY(pic,x,y)); 22038589Sabial } else { 22138589Sabial VGLSetXY(&target,e->zoom*x+i,e->zoom*y+j,VGLGetXY(pic,x,y)); 22238589Sabial } 22338589Sabial } 22438589Sabial } 22538589Sabial } 22638589Sabial } 22738589Sabial } else { 22838589Sabial target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize,sizeof(byte)); 22938589Sabial target.Xsize=pic->Xsize; 23038589Sabial target.Ysize=pic->Ysize; 23138589Sabial target.Type=pic->Type; 23238589Sabial VGLBitmapCopy(pic,0,0,&target,0,0,pic->Xsize,pic->Ysize); 23338589Sabial } 23438589Sabial } else { 23538589Sabial target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize,sizeof(byte)); 23638589Sabial target.Xsize=pic->Xsize; 23738589Sabial target.Ysize=pic->Ysize; 23838589Sabial target.Type=pic->Type; 23938589Sabial VGLBitmapCopy(pic,0,0,&target,0,0,pic->Xsize,pic->Ysize); 24038589Sabial } 24138589Sabial VGLSetPalette(red, green, blue); 24238589Sabial if(e!=NULL) { 24338589Sabial VGLBitmapCopy(&target,0,0,VGLDisplay,e->Xshift,e->Yshift,target.Xsize,target.Ysize); 24438589Sabial } else { 24538589Sabial VGLBitmapCopy(&target,0,0,VGLDisplay,0,0,target.Xsize,target.Ysize); 24638589Sabial } 24738589Sabial VGLMouseMode(VGL_MOUSESHOW); 24838589Sabial free(target.Bitmap); 24938589Sabial} 25038589Sabial 25138589Sabialint 25238589Sabialpng_load(char *filename) 25338589Sabial{ 25438589Sabial int i,j,k; 25538589Sabial FILE *fd; 25638589Sabial u_char header[NUMBER]; 25738589Sabial png_structp png_ptr; 25838589Sabial png_infop info_ptr,end_info; 25938589Sabial png_uint_32 width,height; 26038589Sabial int bit_depth,color_type,interlace_type; 26138589Sabial int compression_type,filter_type; 26238589Sabial int channels,rowbytes; 26338589Sabial double gamma; 26438589Sabial png_colorp palette; 26538589Sabial int num_palette; 26638589Sabial png_bytep *row_pointers; 26738589Sabial char c; 26838589Sabial int res=0; 26938589Sabial 27038589Sabial fd=fopen(filename,"rb"); 27138589Sabial 27238589Sabial if(fd==NULL) { 27338589Sabial VGLEnd(); 27438589Sabial perror("fopen"); 27538589Sabial exit(1); 27638589Sabial } 27738589Sabial fread(header,1,NUMBER,fd); 27838589Sabial if(!png_check_sig(header,NUMBER)) { 27938589Sabial fprintf(stderr,"Not a PNG file.\n"); 28038589Sabial return(-1); 28138589Sabial } 28238589Sabial png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL, 28338589Sabial NULL,NULL); 28438589Sabial info_ptr=png_create_info_struct(png_ptr); 28538589Sabial end_info=png_create_info_struct(png_ptr); 28638589Sabial if(!png_ptr || !info_ptr || !end_info) { 28738589Sabial VGLEnd(); 28838589Sabial fprintf(stderr,"failed to allocate needed structs!\n"); 28938589Sabial png_destroy_read_struct(&png_ptr,&info_ptr,&end_info); 29038589Sabial return(-1); 29138589Sabial } 29238589Sabial png_set_sig_bytes(png_ptr,NUMBER); 29338589Sabial png_init_io(png_ptr,fd); 29438589Sabial png_read_info(png_ptr,info_ptr); 29538589Sabial png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth, 29638589Sabial &color_type,&interlace_type,&compression_type,&filter_type); 29738589Sabial png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette); 29838589Sabial channels=png_get_channels(png_ptr,info_ptr); 29938589Sabial rowbytes=png_get_rowbytes(png_ptr,info_ptr); 30038589Sabial if(bit_depth==16) 30138589Sabial png_set_strip_16(png_ptr); 30238589Sabial if(color_type & PNG_COLOR_MASK_ALPHA) 30338589Sabial png_set_strip_alpha(png_ptr); 30438589Sabial if(png_get_gAMA(png_ptr,info_ptr,&gamma)) 30538589Sabial png_set_gamma(png_ptr,screen_gamma,gamma); 30638589Sabial else 30738589Sabial png_set_gamma(png_ptr,screen_gamma,0.45); 30838589Sabial if(res==0) { 30938589Sabial /* Dither */ 31038589Sabial if(color_type & PNG_COLOR_MASK_COLOR) { 31138589Sabial if(png_get_valid(png_ptr,info_ptr,PNG_INFO_PLTE)) { 31238589Sabial png_uint_16p histogram; 31338589Sabial png_get_hIST(png_ptr,info_ptr,&histogram); 31438589Sabial png_set_dither(png_ptr,palette,num_palette,max_screen_colors,histogram,0); 31538589Sabial } else { 31638589Sabial png_color std_color_cube[16]={ 31738589Sabial {0x00,0x00,0x00}, 31838589Sabial {0x02,0x02,0x02}, 31938589Sabial {0x04,0x04,0x04}, 32038589Sabial {0x06,0x06,0x06}, 32138589Sabial {0x08,0x08,0x08}, 32238589Sabial {0x0a,0x0a,0x0a}, 32338589Sabial {0x0c,0x0c,0x0c}, 32438589Sabial {0x0e,0x0e,0x0e}, 32538589Sabial {0x10,0x10,0x10}, 32638589Sabial {0x12,0x12,0x12}, 32738589Sabial {0x14,0x14,0x14}, 32838589Sabial {0x16,0x16,0x16}, 32938589Sabial {0x18,0x18,0x18}, 33038589Sabial {0x1a,0x1a,0x1a}, 33138589Sabial {0x1d,0x1d,0x1d}, 33238589Sabial {0xff,0xff,0xff}, 33338589Sabial }; 33438589Sabial png_set_dither(png_ptr,std_color_cube,max_screen_colors,max_screen_colors,NULL,0); 33538589Sabial } 33638589Sabial } 33738589Sabial } 33838589Sabial png_set_packing(png_ptr); 33938589Sabial if(png_get_valid(png_ptr,info_ptr,PNG_INFO_sBIT)) { 34038589Sabial png_color_8p sig_bit; 34138589Sabial 34238589Sabial png_get_sBIT(png_ptr,info_ptr,&sig_bit); 34338589Sabial png_set_shift(png_ptr,sig_bit); 34438589Sabial } 34538589Sabial png_read_update_info(png_ptr,info_ptr); 34638589Sabial png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth, 34738589Sabial &color_type,&interlace_type,&compression_type,&filter_type); 34838589Sabial png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette); 34938589Sabial channels=png_get_channels(png_ptr,info_ptr); 35038589Sabial rowbytes=png_get_rowbytes(png_ptr,info_ptr); 35138589Sabial row_pointers=malloc(height*sizeof(png_bytep)); 35238589Sabial for(i=0;i<height;i++) { 35338589Sabial row_pointers[i]=malloc(rowbytes); 35438589Sabial } 35538589Sabial png_read_image(png_ptr,row_pointers); 35638589Sabial png_read_end(png_ptr,end_info); 35738589Sabial png_destroy_read_struct(&png_ptr,&info_ptr,&end_info); 35838589Sabial fclose(fd); 35938589Sabial /* Set palette */ 36038589Sabial if(res) k=2; 36138589Sabial else k=2; 36238589Sabial for(i=0;i<256;i++) { 36338589Sabial pal_red[i]=255; 36438589Sabial pal_green[i]=255; 36538589Sabial pal_blue[i]=255; 36638589Sabial } 36738589Sabial for(i=0;i<num_palette;i++) { 36838589Sabial pal_red[i]=(palette+i)->red>>k; 36938589Sabial pal_green[i]=(palette+i)->green>>k; 37038589Sabial pal_blue[i]=(palette+i)->blue>>k; 37138589Sabial } 37238589Sabial pal_colors=num_palette; 37338589Sabial if(pic.Bitmap!=NULL) free(pic.Bitmap); 37438589Sabial pic.Bitmap=(byte *)calloc(rowbytes*height,sizeof(byte)); 37538589Sabial pic.Type=MEMBUF; 37638589Sabial pic.Xsize=rowbytes; 37738589Sabial pic.Ysize=height; 37838589Sabial for(i=0;i<rowbytes;i++) { 37938589Sabial for(j=0;j<height;j++) { 38038589Sabial VGLSetXY(&pic, 38138589Sabial i,j,row_pointers[j][i]); 38238589Sabial } 38338589Sabial } 38438589Sabial a.zoom=1; 38538589Sabial a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2; 38638589Sabial a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2; 38738589Sabial a.rotate=0; 38838589Sabial return(0); 38938589Sabial} 39038589Sabial 39138589Sabialvoid 39238589Sabialkbd_handler(int sig) 39338589Sabial{ 39438589Sabial u_char buf[10]; 39538589Sabial int res; 39638589Sabial 39738589Sabial res=read(0,&buf,10); 39838589Sabial changed++; 39938589Sabial act=buf[res-1]; 40038589Sabial} 40138589Sabial 40238589Sabialint 40338589Sabialkbd_action(int x, int y, char key) 40438589Sabial{ 40538589Sabial changed=0; 40640616Sabial if(key!='n') auto_chg=0; 40738589Sabial switch(key) { 40838589Sabial case 'q': 40938589Sabial quit=1; 41038589Sabial break; 41138589Sabial case 'Z': 41238589Sabial a.zoom++; 41338589Sabial changed++; 41438589Sabial break; 41538589Sabial case 'z': 41638589Sabial a.zoom--; 41738589Sabial if(a.zoom<1) a.zoom=1; 41838589Sabial changed++; 41938589Sabial break; 42038589Sabial case 'l': 42138589Sabial a.Xshift+=VGLDisplay->Xsize/5; 42238589Sabial changed++; 42338589Sabial break; 42438589Sabial case 'h': 42538589Sabial a.Xshift-=VGLDisplay->Xsize/5; 42638589Sabial changed++; 42738589Sabial break; 42838589Sabial case 'k': 42938589Sabial a.Yshift+=VGLDisplay->Ysize/5; 43038589Sabial changed++; 43138589Sabial break; 43238589Sabial case 'j': 43338589Sabial a.Yshift-=VGLDisplay->Ysize/5; 43438589Sabial changed++; 43538589Sabial break; 43638589Sabial case 'R': 43738589Sabial changed++; 43838589Sabial break; 43938589Sabial case 'r': 44038589Sabial if(a.rotate) a.rotate=0; 44138589Sabial else a.rotate=1; 44238589Sabial changed++; 44338589Sabial break; 44438589Sabial case '\n': 44538589Sabial case 'n': 44640616Sabial if(nimg>0) { 44740616Sabial if(cur_img<nimg-1) { 44840616Sabial cur_img++; 44940616Sabial } else { 45040616Sabial cur_img=0; 45140616Sabial } 45238589Sabial png_load(pres[cur_img]); 45338589Sabial changed++; 45438589Sabial } 45538589Sabial break; 45638589Sabial case 'p': 45740616Sabial if(nimg>0) { 45840616Sabial if(cur_img>0) { 45940616Sabial cur_img--; 46040616Sabial } else { 46140616Sabial cur_img=nimg-1; 46240616Sabial } 46338589Sabial png_load(pres[cur_img]); 46438589Sabial changed++; 46538589Sabial } 46638589Sabial break; 46738589Sabial } 46838589Sabial act=0; 46938589Sabial} 47038589Sabial 47138589Sabialint 47238589Sabialmain(int argc, char *argv[]) 47338589Sabial{ 47438589Sabial int i,j,k; 47538589Sabial char c; 47638589Sabial int res=0; 47738589Sabial int x,y; 47838589Sabial char buttons; 47938589Sabial struct termios t_new,t_old; 48038589Sabial FILE *fsc; 48138589Sabial 48238589Sabial char buf[100]; 48338589Sabial 48438589Sabial progname=argv[0]; 48538589Sabial screen_gamma=1.5; 48640122Sabial#ifdef DEBUG 48738589Sabial log=fopen("/png/view.log","w"); 48840122Sabial#endif 48938589Sabial while((c=getopt(argc,argv,"r:g:"))!=-1) { 49038589Sabial switch(c) { 49138589Sabial case 'r': 49238589Sabial res=atoi(optarg); 49338589Sabial if(res>0) max_screen_colors=256; 49438589Sabial break; 49538589Sabial case 'g': 49638589Sabial screen_gamma=atof(optarg); 49738589Sabial break; 49838589Sabial case '?': 49938589Sabial default: 50038589Sabial usage(); 50138589Sabial exit(0); 50238589Sabial } 50338589Sabial } 50438589Sabial switch(res) { 50538589Sabial case 0: 50638589Sabial VGLInit(SW_CG640x480); 50738589Sabial break; 50838589Sabial case 1: 50938589Sabial VGLInit(SW_VGA_CG320); 51038589Sabial break; 51138589Sabial case 2: 51238589Sabial VGLInit(SW_VGA_MODEX); 51338589Sabial break; 51438589Sabial default: 51538589Sabial fprintf(stderr,"No such resolution!\n"); 51638589Sabial usage(); 51738589Sabial exit(-1); 51838589Sabial } 51940122Sabial#ifdef DEBUG 52038589Sabial fprintf(log,"VGL initialised\n"); 52140122Sabial#endif 52238589Sabial VGLSavePalette(); 52338589Sabial if(argc>optind) { 52438589Sabial res=png_load(argv[optind]); 52538589Sabial } else { 52638589Sabial VGLEnd(); 52738589Sabial usage(); 52838589Sabial exit(0); 52938589Sabial } 53038589Sabial if(res) { 53138589Sabial /* Hmm... Script? */ 53238589Sabial fsc=fopen(argv[optind],"r"); 53340122Sabial#ifdef DEBUG 53438589Sabial fprintf(log,"Trying script %s\n",argv[optind]); 53540122Sabial#endif 53638589Sabial fgets(buf,99,fsc); 53740616Sabial buf[strlen(buf)-1]='\0'; 53840616Sabial if(strncmp("VIEW SCRIPT",buf,11)!=NULL) { 53938589Sabial VGLEnd(); 54038589Sabial usage(); 54138589Sabial } 54240616Sabial if(strlen(buf)>12) { 54340616Sabial auto_chg=atoi(buf+12); 54440616Sabial } 54538589Sabial fgets(buf,99,fsc); 54638589Sabial buf[strlen(buf)-1]='\0'; 54738589Sabial nimg=atoi(buf); 54838589Sabial if(nimg==0) { 54938589Sabial VGLEnd(); 55038589Sabial usage(); 55138589Sabial } 55238589Sabial pres=(char **)calloc(nimg,sizeof(char *)); 55338589Sabial for(i=0;i<nimg;i++) { 55438589Sabial fgets(buf,99,fsc); 55538589Sabial buf[strlen(buf)-1]='\0'; 55638589Sabial pres[i]=strdup(buf); 55738589Sabial } 55838589Sabial fclose(fsc); 55938589Sabial cur_img=0; 56040122Sabial#ifdef DEBUG 56138589Sabial fprintf(log,"Script with %d entries\n",nimg); 56240122Sabial#endif 56338589Sabial png_load(pres[cur_img]); 56438589Sabial } 56540616Sabial VGLMouseInit(VGL_MOUSEHIDE); 56638589Sabial /* Prepare the keyboard */ 56738589Sabial tcgetattr(0,&t_old); 56838589Sabial memcpy(&t_new,&t_old,sizeof(struct termios)); 56938589Sabial cfmakeraw(&t_new); 57038589Sabial tcsetattr(0,TCSAFLUSH,&t_new); 57138589Sabial fcntl(0,F_SETFL,O_ASYNC); 57238589Sabial /* XXX VGLClear doesn't work.. :-(( Prepare a blank background */ 57338589Sabial bkg.Bitmap=(byte *)calloc(VGLDisplay->Xsize*VGLDisplay->Ysize,1); 57438589Sabial bkg.Xsize=VGLDisplay->Xsize; 57538589Sabial bkg.Ysize=VGLDisplay->Ysize; 57638589Sabial bkg.Type=VGLDisplay->Type; 57738589Sabial signal(SIGIO,kbd_handler); 57838589Sabial a.zoom=1; 57938589Sabial a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2; 58038589Sabial a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2; 58138589Sabial a.rotate=0; 58238589Sabial quit=0; 58338589Sabial changed=0; 58438589Sabial display(&pic,pal_red,pal_green,pal_blue,&a); 58538589Sabial while(!quit) { 58638589Sabial if(act) { 58740122Sabial#ifdef DEBUG 58838589Sabial fprintf(log,"kbd_action(%c)\n",act); 58940122Sabial#endif 59038589Sabial kbd_action(x,y,act); 59138589Sabial } 59238589Sabial if(quit) break; 59338589Sabial if(changed) { 59440122Sabial#ifdef DEBUG 59538589Sabial fprintf(log,"changed, redisplaying\n"); 59640122Sabial#endif 59738589Sabial display(&pic,pal_red,pal_green,pal_blue,&a); 59838589Sabial changed=0; 59938589Sabial } 60040616Sabial if(auto_chg) { 60140616Sabial sleep(auto_chg); 60240616Sabial kbd_action(x,y,'n'); 60340616Sabial } else { 60440616Sabial pause(); 60540616Sabial } 60638589Sabial VGLMouseStatus(&x,&y,&buttons); 60738589Sabial if(buttons & MOUSE_BUTTON3DOWN) { 60840122Sabial#ifdef DEBUG 60938589Sabial fprintf(log,"pop_up called\n"); 61040122Sabial#endif 61138589Sabial pop_up("View",x,y); 61238589Sabial } 61338589Sabial } 61438589Sabial VGLEnd(); 61540122Sabial#ifdef DEBUG 61638589Sabial fclose(log); 61740122Sabial#endif 61838589Sabial exit(0); 61938589Sabial} 620