00001
00008
00009
00010
00011
00012 #include "FBlib.h"
00013 #include "FBpriv.h"
00014 #include <stdlib.h>
00015
00016 int FB_visible = 1;
00017 int fb_rotate = FB_ROTATE_NONE;
00018
00019 int FB_initlib(char *dev)
00020 {
00021 int ioctl_err;
00022 char *errstr;
00023 struct vt_mode vtmode;
00024 char *strrot;
00025
00026 if(!strcmp(dev, ""))
00027 dev = "/dev/fb0";
00028 fbufd = open(dev, O_RDWR);
00029 if(fbufd < 0)
00030 {
00031 errstr = strerror(errno);
00032 fprintf(stderr, "FBlib:open %s failed: %s \n", dev, errstr);
00033 return -1;
00034 }
00035 ioctl_err = ioctl(fbufd,FBIOGET_FSCREENINFO,&fb_fix_info);
00036 if(ioctl_err < 0)
00037 {
00038 errstr = strerror(errno);
00039 fprintf(stderr,"FBlib:ioctl FBIOGET_FSCREENINFO failed: %s \n",errstr);
00040 return IOCTL_ERR;
00041 }
00042
00043 ioctl_err = ioctl(fbufd,FBIOGET_VSCREENINFO,&backup_var_info);
00044
00045 ioctl_err = ioctl(fbufd,FBIOGET_VSCREENINFO,&work_var_info);
00046 if(ioctl_err < 0)
00047 {
00048 errstr=strerror(errno);
00049 fprintf(stderr,"FBlib:ioctl FBIOGET_VSCREENINFO failed: %s \n",errstr);
00050 return IOCTL_ERR;
00051 }
00052
00053 work_var_info.xoffset = 0;
00054 work_var_info.yoffset = 0;
00055
00056 ioctl_err = ioctl(fbufd,FBIOPUT_VSCREENINFO,&work_var_info);
00057 if(ioctl_err < 0)
00058 {
00059 errstr = strerror(errno);
00060 fprintf(stderr,"FBlib:ioctl FBIOPUT_VSCREENINFO failed: %s \n",errstr);
00061 return IOCTL_ERR;
00062 }
00063
00064 screensize = fb_fix_info.smem_len;
00065 visiblesize = work_var_info.xres * work_var_info.yres * (work_var_info.bits_per_pixel/8);
00066
00067 ioctl_err = ioctl(TTY, VT_GETMODE, &vtmode);
00068 if(ioctl_err < 0)
00069 {
00070 errstr = strerror(errno);
00071 fprintf(stderr,"FBlib:ioctl VT_GETMODE failed: %s \n",errstr);
00072 return IOCTL_ERR;
00073 }
00074 vtmode.mode = VT_PROCESS;
00075 vtmode.relsig = SIGUSR2;
00076 vtmode.acqsig = SIGUSR2;
00077
00078 signal(SIGUSR2, fb_switch);
00079
00080 ioctl_err = ioctl(TTY, VT_SETMODE, &vtmode);
00081 if(ioctl_err < 0)
00082 {
00083 errstr = strerror(errno);
00084 fprintf(stderr,"FBlib:ioctl VT_SETMODE failed: %s \n",errstr);
00085 return IOCTL_ERR;
00086 }
00087
00088 ioctl_err = fb_map();
00089
00090 if(ioctl_err < 0)
00091 return ioctl_err;
00092
00093 FB_change_font(DEFAULT_FONT);
00094
00095 inc_x = work_var_info.bits_per_pixel/8;
00096 inc_y = fb_fix_info.line_length;
00097
00098
00099 strrot = getenv("FB_ROTATE");
00100 if(strrot!=NULL)
00101 {
00102 if(strncmp(strrot,"90",2)==0)
00103 {
00104 FB_setrotation(FB_ROTATE_90);
00105 }
00106 else if(strncmp(strrot,"180",3)==0)
00107 {
00108 FB_setrotation(FB_ROTATE_180);
00109 }
00110 else if(strncmp(strrot,"270",3)==0)
00111 {
00112 FB_setrotation(FB_ROTATE_270);
00113 }
00114
00115 }
00116
00117 return OK;
00118 }
00119
00120 int FB_exit()
00121 {
00122 int ioctl_err;
00123 char *errstr;
00124
00125 if(!FB_visible && (b_store != NULL))
00126 {
00127 free(b_store);
00128 b_store = NULL;
00129 }
00130
00131 ioctl_err = ioctl(fbufd,FBIOPUT_VSCREENINFO,&backup_var_info);
00132 if(ioctl_err < 0)
00133 {
00134 errstr = strerror(errno);
00135 fprintf(stderr,"FBlib:ioctl FBIOPUT_VSCREENINFO failed: %s \n",errstr);
00136 return IOCTL_ERR;
00137 }
00138 fb_unmap();
00139 close(fbufd);
00140 if(uses_keyboard)
00141 FB_kb_end();
00142 printf("\n");
00143 return OK;
00144 }
00145
00146
00147 int fb_map()
00148 {
00149 fbp=(char*)mmap(0, screensize, PROT_WRITE | PROT_READ, MAP_SHARED, fbufd, 0);
00150 if(fbp<0)
00151 {
00152 fprintf(stderr,"FBlib:mmap failed: %s \n",strerror(errno));
00153 return MMAP_ERR;
00154 }
00155 fb_visp = fbp;
00156 return 0;
00157 }
00158
00159
00160 int fb_unmap()
00161 {
00162 munmap(fbp, screensize);
00163 return 0;
00164 }
00165
00166 void fb_switch(int n_sig)
00167 {
00168 static int switching=0;
00169
00170 signal(SIGUSR2, fb_switch);
00171 if(switching && (n_sig == SIGUSR2))
00172 return;
00173 if(switching == 0)
00174 switching = 1;
00175 if(FB_visible)
00176 {
00177 b_store = (char*)malloc(visiblesize);
00178 if(b_store == NULL)
00179 fprintf(stderr,"FBlib:cannot use backing store for VT switch");
00180 else
00181 memcpy(b_store, fbp, visiblesize);
00182 fb_unmap();
00183 fbp = b_store;
00184 FB_visible = 0;
00185 if(ioctl(TTY,VT_RELDISP,1) < 0)
00186 {
00187 fprintf(stderr,"FBlib:ioctl VT_RELDISP failed: %s \n",strerror(errno));
00188 fb_map();
00189 free(b_store);
00190 FB_visible=1;
00191 }
00192 }
00193 else
00194 {
00195 if(ioctl(TTY,VT_RELDISP,VT_ACKACQ) < 0)
00196 {
00197 fprintf(stderr,"FBlib:ioctl VT_RELDISP failed: %s (FATAL error)\n",strerror(errno));
00198 FB_exit();
00199 exit(1);
00200 }
00201 fb_map();
00202 memcpy(fbp, b_store, visiblesize);
00203 free(b_store);
00204 b_store=NULL;
00205 FB_visible=1;
00206 }
00207 switching=0;
00208 return;
00209 }