1 //
2 // C++ Implementation: jinke/lbook V3 viewer plugin
3 //
4 // Description:
5 //
6 //
7 // Author: Vadim Lopatin <vadim.lopatin@coolreader.org>, (C) 2008
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 // support DBUS interface signals
14 #ifndef ENABLE_DBUS_VIEWER_EVENTS
15 #define ENABLE_DBUS_VIEWER_EVENTS 0
16 #endif
17
18 // flash leds while long operation
19 #ifndef LEDTHREAD
20 #define LEDTHREAD 0
21 #endif
22
23 // uncomment following line to allow running executables named .exe.txt
24 #define ALLOW_RUN_EXE 1
25 // uncomment to use separate .ini files for different formats
26 #define SEPARATE_INI_FILES 1
27
28 #include <unistd.h>
29 #include <sys/wait.h>
30 #include "cr3jinke.h"
31 #include <crengine.h>
32 #include <crgui.h>
33
34 #if ENABLE_DBUS_VIEWER_EVENTS==1
35 #define DBUS_API_SUBJECT_TO_CHANGE
36 #include <dbus/dbus.h>
37 #endif
38
39 #include <microwin/nano-X.h>
40 #include <microwin/nxcolors.h>
41 #include "cr3main.h"
42 #include "mainwnd.h"
43
44 #include <pthread.h>
45 #include <fcntl.h>
46 #include <sys/ioctl.h>
47 #include <unistd.h>
48 #include <semaphore.h>
49
50 //#include <math.h>
51
52 #define min(a,b) ((a)<(b)?(a):(b))
53 #define max(a,b) ((a)>(b)?(a):(b))
54
55
56
57 static bool firstDocUpdate = true;
58
59
60 status_info_t lastState = {0,0,0};
61
62 static char last_bookmark[2048]= {0};
63 static int last_bookmark_page = 0;
64
65 //static bool shuttingDown = false;
66
67 #define USE_JINKE_USER_DATA 0
68 #define USE_OWN_BATTERY_TEST 0
69
70 static int batteryState = -1;
71
checkPowerState()72 int checkPowerState()
73 {
74 FILE * fp = fopen("/tmp/batteryinfo", "rb");
75 char buf[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
76 int batteryvalue=0;
77 if (fp) {
78 fread(buf, 1, 20, fp);
79 batteryvalue=atoi(buf);
80 CRLog::trace("/tmp/batteryinfo = %d", batteryvalue);
81 if (batteryvalue>4 || batteryvalue<0)
82 batteryvalue=4;//6
83 batteryvalue = batteryvalue * 100 / 4;
84 batteryState = batteryvalue;
85 fclose(fp);
86 } else {
87 #if USE_OWN_BATTERY_TEST==1
88 FILE * f = fopen( "/dev/misc/s3c2410_batt", "rb" );
89 if ( !f ) {
90 #endif
91 batteryState = 100;
92 CRLog::debug("cannot read battery state");
93 #if USE_OWN_BATTERY_TEST==1
94 } else {
95 int ch = fgetc( f );
96 fclose(f);
97 if ( ch == ' ' )
98 batteryState = -1;
99 else if ( ch>=0 && ch <= 16 )
100 batteryState = ch * 100 / 16;
101 else
102 batteryState = 100;
103 }
104 #endif
105 }
106 return batteryState;
107 }
108
109 #include <cri18n.h>
110
111 #define VIEWER_WINDOW_X 0
112 #define VIEWER_WINDOW_Y 0
113 #define VIEWER_WINDOW_WIDTH 600
114 #define VIEWER_WINDOW_HEIGHT 800
115
116 #ifndef USE_OLD_NANOX
117
118 #define COLOR_LEVEL 4 //
119 #define BMPBUFGRAYLEVEL 2 //
120 #define BMP_PANEL_NUBS (1<<COLOR_LEVEL)//
121
122 const unsigned long panel256[]={
123 0X00000000,0X00010101,0X00020202,0X00030303,0X00040404,0X00050505,0X00060606,0X00070707,
124 0X00080808,0X00090909,0X000a0a0a,0X000b0b0b,0X000c0c0c,0X000d0d0d,0X000e0e0e,0X000f0f0f,
125 0X00101010,0X00111111,0X00121212,0X00131313,0X00141414,0X00151515,0X00161616,0X00171717,
126 0X00181818,0X00191919,0X001a1a1a,0X001b1b1b,0X001c1c1c,0X001d1d1d,0X001e1e1e,0X001f1f1f,
127 0X00202020,0X00212121,0X00222222,0X00232323,0X00242424,0X00252525,0X00262626,0X00272727,
128 0X00282828,0X00292929,0X002a2a2a,0X002b2b2b,0X002c2c2c,0X002d2d2d,0X002e2e2e,0X002f2f2f,
129 0X00303030,0X00313131,0X00323232,0X00333333,0X00343434,0X00353535,0X00363636,0X00373737,
130 0X00383838,0X00393939,0X003a3a3a,0X003b3b3b,0X003c3c3c,0X003d3d3d,0X003e3e3e,0X003f3f3f,
131 0X00404040,0X00414141,0X00424242,0X00434343,0X00444444,0X00454545,0X00464646,0X00474747,
132 0X00484848,0X00494949,0X004a4a4a,0X004b4b4b,0X004c4c4c,0X004d4d4d,0X004e4e4e,0X004f4f4f,
133 0X00505050,0X00515151,0X00525252,0X00535353,0X00545454,0X00555555,0X00565656,0X00575757,
134 0X00585858,0X00595959,0X005a5a5a,0X005b5b5b,0X005c5c5c,0X005d5d5d,0X005e5e5e,0X005f5f5f,
135 0X00606060,0X00616161,0X00626262,0X00636363,0X00646464,0X00656565,0X00666666,0X00676767,
136 0X00686868,0X00696969,0X006a6a6a,0X006b6b6b,0X006c6c6c,0X006d6d6d,0X006e6e6e,0X006f6f6f,
137 0X00707070,0X00717171,0X00727272,0X00737373,0X00747474,0X00757575,0X00767676,0X00777777,
138 0X00787878,0X00797979,0X007a7a7a,0X007b7b7b,0X007c7c7c,0X007d7d7d,0X007e7e7e,0X007f7f7f,
139 0X00808080,0X00818181,0X00828282,0X00838383,0X00848484,0X00858585,0X00868686,0X00878787,
140 0X00888888,0X00898989,0X008a8a8a,0X008b8b8b,0X008c8c8c,0X008d8d8d,0X008e8e8e,0X008f8f8f,
141 0X00909090,0X00919191,0X00929292,0X00939393,0X00949494,0X00959595,0X00969696,0X00979797,
142 0X00989898,0X00999999,0X009a9a9a,0X009b9b9b,0X009c9c9c,0X009d9d9d,0X009e9e9e,0X009f9f9f,
143 0X00a0a0a0,0X00a1a1a1,0X00a2a2a2,0X00a3a3a3,0X00a4a4a4,0X00a5a5a5,0X00a6a6a6,0X00a7a7a7,
144 0X00a8a8a8,0X00a9a9a9,0X00aaaaaa,0X00ababab,0X00acacac,0X00adadad,0X00aeaeae,0X00afafaf,
145 0X00b0b0b0,0X00b1b1b1,0X00b2b2b2,0X00b3b3b3,0X00b4b4b4,0X00b5b5b5,0X00b6b6b6,0X00b7b7b7,
146 0X00b8b8b8,0X00b9b9b9,0X00bababa,0X00bbbbbb,0X00bcbcbc,0X00bdbdbd,0X00bebebe,0X00bfbfbf,
147 0X00c0c0c0,0X00c1c1c1,0X00c2c2c2,0X00c3c3c3,0X00c4c4c4,0X00c5c5c5,0X00c6c6c6,0X00c7c7c7,
148 0X00c8c8c8,0X00c9c9c9,0X00cacaca,0X00cbcbcb,0X00cccccc,0X00cdcdcd,0X00cecece,0X00cfcfcf,
149 0X00d0d0d0,0X00d1d1d1,0X00d2d2d2,0X00d3d3d3,0X00d4d4d4,0X00d5d5d5,0X00d6d6d6,0X00d7d7d7,
150 0X00d8d8d8,0X00d9d9d9,0X00dadada,0X00dbdbdb,0X00dcdcdc,0X00dddddd,0X00dedede,0X00dfdfdf,
151 0X00e0e0e0,0X00e1e1e1,0X00e2e2e2,0X00e3e3e3,0X00e4e4e4,0X00e5e5e5,0X00e6e6e6,0X00e7e7e7,
152 0X00e8e8e8,0X00e9e9e9,0X00eaeaea,0X00ebebeb,0X00ececec,0X00ededed,0X00eeeeee,0X00efefef,
153 0X00f0f0f0,0X00f1f1f1,0X00f2f2f2,0X00f3f3f3,0X00f4f4f4,0X00f5f5f5,0X00f6f6f6,0X00f7f7f7,
154 0X00f8f8f8,0X00f9f9f9,0X00fafafa,0X00fbfbfb,0X00fcfcfc,0X00fdfdfd,0X00fefefe,0X00ffffff,
155 };
156 const unsigned long panel16[256]={
157 0x00000000,0x00505050,0x00808080,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
158 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
159 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
160 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
161 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
162 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
163 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
164 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
165 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
166 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
167 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
168 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
169 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
170 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
171 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
172 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
173 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
174 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
175 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
176 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
177 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
178 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
179 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
180 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
181 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
182 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
183 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
184 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
185 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
186 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
187 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
188 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,
189 };
190
191
192 typedef struct
193 {
194 unsigned short int bfType;
195 unsigned long bfSize;
196 unsigned short int bfReserved1;
197 unsigned short int bfReserved2;
198 unsigned long bfOffBits;
199 }BITMAPFILEHEADER;
200 #define BITMAPFILEHEADER_SIZE 14
201
202 typedef struct
203 {
204 unsigned long biSize;
205 long biWidth;
206 long biHeight;
207 unsigned short int biPlanes;
208 unsigned short int biBitCount;
209 unsigned long biCompression;
210 unsigned long biSizeImage;
211 long biXPelsPerMeter;
212 long biYPelsPerMeter;
213 unsigned long biClrUsed;
214 unsigned long biClrImportant;
215 }BITMAPINFOHEADER;
216 #define BITMAPINFOHEADER_SIZE sizeof(BITMAPINFOHEADER)
217
218 typedef struct
219 {
220 BITMAPFILEHEADER FileHeader;
221 BITMAPINFOHEADER BmpInfo;
222 MWPALENTRY BmpPanel[BMP_PANEL_NUBS];
223 }BMPHEADER_16;
224
225 typedef struct
226 {
227 BITMAPFILEHEADER FileHeader;
228 BITMAPINFOHEADER BmpInfo;
229 MWPALENTRY BmpPanel[256];
230 }BMPHEADER_256;
231
GrBitmapEx_Apollo_FOUR(GR_WINDOW_ID id,GR_GC_ID gc,int x,int y,int width,int height,int src_x,int src_y,int src_width,int src_height,GR_CHAR * imagebits)232 int GrBitmapEx_Apollo_FOUR(GR_WINDOW_ID id,GR_GC_ID gc,int x,int y,int width,int height,int src_x,int src_y, int src_width,int src_height, GR_CHAR *imagebits)
233
234 {
235 // TODO: Add extra validation here
236 //4 bit 16 level degree color
237
238
239 BMPHEADER_256 lpHeader;
240 GR_IMAGE_ID ImageId;
241 int HeaderLen;
242 int i;
243 int Lines;
244 int BmpBufBytsPerLine=0,BytesPerLine=0;
245
246 unsigned char char1,char2,char3,char4,BmpChar1;
247 unsigned char *Screen_Buf=NULL,*BmpFileBuf=NULL,*BufPtr=NULL,*HeaderBuf=NULL;
248 int GrayLevel=8;//256 gray level
249 int BmpWidth=0,BmpHeight=0,PixesPerByte=0,BmpPanelNumbers=0,Bmpheadersize=0;
250
251 BmpWidth=min(width,src_width);
252 BmpHeight=min(height,src_height);
253
254 PixesPerByte=8/GrayLevel;
255 BmpPanelNumbers=1<<GrayLevel;
256 BytesPerLine=(BmpWidth*GrayLevel+31)/32*4;
257 BmpBufBytsPerLine=(src_width*2+7)/8;
258
259
260 i=sizeof(BMPHEADER_256);
261 HeaderLen=BITMAPFILEHEADER_SIZE+sizeof(BITMAPINFOHEADER)+sizeof(MWPALENTRY)*BmpPanelNumbers;
262 memcpy((unsigned char *)&lpHeader.FileHeader.bfType,"BM",2);
263 lpHeader.FileHeader.bfSize=(BmpHeight*BytesPerLine)/PixesPerByte+HeaderLen;
264 lpHeader.FileHeader.bfReserved1=0;
265 lpHeader.FileHeader.bfReserved2=0;
266 lpHeader.FileHeader.bfOffBits=HeaderLen;
267 lpHeader.BmpInfo.biSize=sizeof(BITMAPINFOHEADER);
268 lpHeader.BmpInfo.biWidth=BmpWidth;
269 lpHeader.BmpInfo.biHeight=BmpHeight;
270 lpHeader.BmpInfo.biPlanes=1;
271 lpHeader.BmpInfo.biBitCount=GrayLevel;
272 lpHeader.BmpInfo.biCompression=0;
273 lpHeader.BmpInfo.biSizeImage=lpHeader.FileHeader.bfSize-HeaderLen;
274 lpHeader.BmpInfo.biXPelsPerMeter=0x257E;
275 lpHeader.BmpInfo.biYPelsPerMeter=0x257E;
276 lpHeader.BmpInfo.biClrUsed=0;
277 lpHeader.BmpInfo.biClrImportant=0;
278
279 Bmpheadersize=HeaderLen;
280 BmpFileBuf=new unsigned char[BmpHeight*BytesPerLine+Bmpheadersize];
281
282 if(!BmpFileBuf)
283 {
284 return 1;
285 }
286 memset(BmpFileBuf,0x0,BmpHeight*BytesPerLine+Bmpheadersize);
287 HeaderBuf=BmpFileBuf;
288 Screen_Buf=BmpFileBuf+Bmpheadersize;
289 BufPtr=Screen_Buf;
290
291 memcpy(HeaderBuf,(char *)&lpHeader.FileHeader.bfType,2);
292 memcpy(&HeaderBuf[2],(char *)&lpHeader.FileHeader.bfSize,4);
293 memcpy(&HeaderBuf[6],(char *)&lpHeader.FileHeader.bfReserved1,2);
294 memcpy(&HeaderBuf[8],(char *)&lpHeader.FileHeader.bfReserved2,2);
295 memcpy(&HeaderBuf[10],(char *)&lpHeader.FileHeader.bfOffBits,4);
296 HeaderBuf+=BITMAPFILEHEADER_SIZE;
297 memcpy(HeaderBuf,(unsigned char *)&lpHeader.BmpInfo,BITMAPINFOHEADER_SIZE);
298 HeaderBuf+=BITMAPINFOHEADER_SIZE;
299 memcpy(HeaderBuf,(unsigned char *)&panel16,sizeof(MWPALENTRY)*BmpPanelNumbers);
300 HeaderBuf=BmpFileBuf;
301
302 Lines=0;
303 //4 color degress change to 16 color degress,mainframe_img_bits is 4 color degress
304 for(Lines=0;Lines<BmpHeight;Lines++)
305 {
306
307 char1=0;
308 char2=0;
309 char3=0;
310 char4=0;
311 //
312 BufPtr=(unsigned char *)&Screen_Buf[(BmpHeight-1-Lines)*BytesPerLine];
313 for(i=0;i<(BmpWidth*2+7)/8;i++)
314 {
315 BmpChar1=imagebits[i+(Lines+src_y)*BmpBufBytsPerLine+src_x/4];
316 //
317 char1=BmpChar1&0xc0;
318 char1>>=6;
319 *BufPtr=char1;
320 BufPtr++;
321 char2=BmpChar1&0x30;
322 char2>>=4;
323 *BufPtr=char2;
324 BufPtr++;
325 char3=BmpChar1&0x0c;
326 char3>>=2;
327 *BufPtr=char3;
328 BufPtr++;
329 char4=BmpChar1&0x03;
330 *BufPtr=char4;
331 BufPtr++;
332 }
333 }
334 ImageId=GrLoadImageFromBuffer(BmpFileBuf,lpHeader.FileHeader.bfSize,GR_BACKGROUND_TOPLEFT);
335 GrDrawImageToFit(id,gc,x,y,BmpWidth,BmpHeight,ImageId);
336 GrFreeImage(ImageId);
337 delete[] BmpFileBuf;
338 return 0;
339 }
340
GrBitmapEx_Apollo_NEW(GR_WINDOW_ID id,GR_GC_ID gc,int x,int y,int width,int height,int src_x,int src_y,int src_width,int src_height,GR_CHAR * imagebits)341 int GrBitmapEx_Apollo_NEW(GR_WINDOW_ID id,GR_GC_ID gc,int x,int y,int width,int height,int src_x,int src_y, int src_width,int src_height, GR_CHAR *imagebits)
342 {
343
344 BMPHEADER_256 lpHeader;
345 GR_IMAGE_ID ImageId;
346 int HeaderLen;
347 int i;
348 int Lines;
349 int BmpBufBytsPerLine=0,BytesPerLine=0;
350
351
352 unsigned char char1,char2,char3,char4,BmpChar1;
353 unsigned char *Screen_Buf=NULL,*BmpFileBuf=NULL,*BufPtr=NULL,*HeaderBuf=NULL,*pimg = NULL;
354 int GrayLevel=8;//256 gray level
355 int BmpWidth=0,BmpHeight=0,PixesPerByte=0,BmpPanelNumbers=0,Bmpheadersize=0;
356 BmpWidth=min(width,src_width);
357 BmpHeight=min(height,src_height-src_y);
358 // BmpHeight=min(height,src_height);
359 if(BmpHeight<=0)
360 BmpHeight=1;
361
362 PixesPerByte=8/GrayLevel;
363 BmpPanelNumbers=1<<GrayLevel;
364 BytesPerLine=(BmpWidth*GrayLevel+31)/32*4;//
365 BmpBufBytsPerLine=(((src_width*GrayLevel+7)/8+3)/4)*4;
366
367
368 i=sizeof(BMPHEADER_256);
369 HeaderLen=BITMAPFILEHEADER_SIZE+sizeof(BITMAPINFOHEADER)+sizeof(MWPALENTRY)*BmpPanelNumbers;
370 memcpy((unsigned char *)&lpHeader.FileHeader.bfType,"BM",2);//
371 lpHeader.FileHeader.bfSize=(BmpHeight*BytesPerLine)/PixesPerByte+HeaderLen; //
372 lpHeader.FileHeader.bfReserved1=0;//
373 lpHeader.FileHeader.bfReserved2=0;//
374 lpHeader.FileHeader.bfOffBits=HeaderLen;//
375 lpHeader.BmpInfo.biSize=sizeof(BITMAPINFOHEADER);//BMP
376 lpHeader.BmpInfo.biWidth=BmpWidth;//
377 lpHeader.BmpInfo.biHeight=BmpHeight;//
378 lpHeader.BmpInfo.biPlanes=1;//
379 lpHeader.BmpInfo.biBitCount=GrayLevel;//
380 lpHeader.BmpInfo.biCompression=0;
381 lpHeader.BmpInfo.biSizeImage=lpHeader.FileHeader.bfSize-HeaderLen;
382 lpHeader.BmpInfo.biXPelsPerMeter=0x257E;
383 lpHeader.BmpInfo.biYPelsPerMeter=0x257E;
384 lpHeader.BmpInfo.biClrUsed=0;
385 lpHeader.BmpInfo.biClrImportant=0;
386
387 Bmpheadersize=HeaderLen;
388 BmpFileBuf=new unsigned char[BmpHeight*BytesPerLine+Bmpheadersize];
389
390 if(!BmpFileBuf)
391 {
392 return 1;
393 }
394 memset(BmpFileBuf,0xFF,BmpHeight*BytesPerLine+Bmpheadersize);
395 HeaderBuf=BmpFileBuf;
396 Screen_Buf=BmpFileBuf+Bmpheadersize;
397 BufPtr=Screen_Buf;
398
399 memcpy(HeaderBuf,(char *)&lpHeader.FileHeader.bfType,2);
400 memcpy(&HeaderBuf[2],(char *)&lpHeader.FileHeader.bfSize,4);
401 memcpy(&HeaderBuf[6],(char *)&lpHeader.FileHeader.bfReserved1,2);
402 memcpy(&HeaderBuf[8],(char *)&lpHeader.FileHeader.bfReserved2,2);
403 memcpy(&HeaderBuf[10],(char *)&lpHeader.FileHeader.bfOffBits,4);
404 HeaderBuf+=BITMAPFILEHEADER_SIZE;
405 memcpy(HeaderBuf,(unsigned char *)&lpHeader.BmpInfo,BITMAPINFOHEADER_SIZE);
406 HeaderBuf+=BITMAPINFOHEADER_SIZE;
407 memcpy(HeaderBuf,(unsigned char *)&panel256,sizeof(MWPALENTRY)*BmpPanelNumbers);
408 HeaderBuf=BmpFileBuf;
409
410 Lines=0;
411 BufPtr = (unsigned char *)(Screen_Buf+(BmpHeight-1)*BytesPerLine);
412 pimg = (unsigned char *)(imagebits + src_y*BmpBufBytsPerLine +src_x);
413 for(Lines=0;Lines<BmpHeight;Lines++)
414 {
415 //printf("%s line = %d,height =%d,byte = %d,buf =%d\n",__FUNCTION__,Lines,BmpHeight,BytesPerLine,BufPtr);
416 // BufPtr=(unsigned char *)&Screen_Buf[(BmpHeight-1-Lines)*BytesPerLine];
417 // memcpy(BufPtr,(unsigned char *)&imagebits[(Lines+src_y)*BmpBufBytsPerLine+src_x],BytesPerLine);
418 memcpy(BufPtr,pimg,BytesPerLine);
419 BufPtr -= BytesPerLine;
420 pimg += BmpBufBytsPerLine;
421 }
422
423
424
425
426 ImageId=GrLoadImageFromBuffer(BmpFileBuf,lpHeader.FileHeader.bfSize,GR_BACKGROUND_TOPLEFT);
427
428 GrDrawImageToFit(id,gc,x,y,BmpWidth,BmpHeight,ImageId);
429 printf("x=%d,y=%d,BmpWidth=%d,BmpHeight=%d\n",x,y,BmpWidth,BmpHeight);
430 GrFreeImage(ImageId);
431
432 delete[] BmpFileBuf;
433 return 0;
434 }
435
436 #endif
437
438 class LedThreadApp
439 {
440 public:
441 LedThreadApp();
442 ~LedThreadApp();
443 void init_led_sem();
444 void destroy_led_sem();
445 void post_led_sem();
446 void cancel_led_thread();
447 void create_led_thread();
448 private:
449 //class MainViewer *m_app;
450 pthread_t m_idled;
451
452 };
453
454 //LED STATE
455 #define LED_RED 1
456 #define LED_GREEN 2
457 #define LED_YELLOW 3
458 #define LED_OFF 0
459 #define WAITTIP 0
460 //Tip icon coordinate info
461 #define DYNTIPX 270
462 #define DYNTIPY 500
463 #define DYNTIPW 60
464 #define DYNTIPH 60
465
466
467 static int g_iOpenLed;
468 static int g_iLedOpened;
469 static volatile int g_ledActive = 0;
470 //static int g_iProcessingTipValue;
471
472 static sem_t g_semled;
473 void vTellLed(void *vptr);
474
LedThreadApp()475 LedThreadApp::LedThreadApp()
476 {
477 // m_app=ProcApp;
478
479 }
480
~LedThreadApp()481 LedThreadApp::~LedThreadApp()
482 {
483
484 }
485
486
init_led_sem()487 void LedThreadApp::init_led_sem()
488 {
489 #if LEDTHREAD==1
490 if(sem_init(&g_semled, 0,1) == -1)
491 exit(0);
492 #endif
493 }
494
destroy_led_sem()495 void LedThreadApp::destroy_led_sem()
496 {
497 #if LEDTHREAD==1
498 if(sem_destroy(&g_semled) == -1)
499 exit(0);
500 #endif
501 }
502
post_led_sem()503 void LedThreadApp::post_led_sem()
504 {
505 #if LEDTHREAD==1
506 if(sem_post(&g_semled) == -1)
507 exit(0);
508 #endif
509 }
510
cancel_led_thread()511 void LedThreadApp::cancel_led_thread()
512 {
513 #if LEDTHREAD==1
514 if(m_idled > 0){
515 pthread_cancel(m_idled);
516 }
517 #endif
518 }
519
520
create_led_thread()521 void LedThreadApp::create_led_thread()
522 {
523 #if LEDTHREAD==1
524 int ret_led;
525 ret_led = pthread_create(&m_idled, NULL, (void*(*)(void*))vTellLed, NULL);
526 if(ret_led != 0){
527 printf("Create pthread error!\n");
528 exit(1);
529 }
530 #endif
531 }
532
vTellLed(void * vptr)533 void vTellLed(void *vptr)
534 {
535 //int start = 0;
536 int locked;
537 g_iOpenLed = 1;
538 g_iLedOpened = 0;
539 // g_iProcessingTipValue = 0;
540
541 //set cancel type
542 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
543
544 if(g_iOpenLed)
545 {
546 g_iLedOpened = open("/dev/s3c2410_led", O_RDONLY);
547 // g_iLedOpened = open("/dev/misc/s3c2410_led", O_RDONLY);
548 g_iOpenLed = 0;
549 }
550 if(g_iLedOpened)
551 {
552 while(1)
553 {
554 if(!sem_trywait(&g_semled))
555 {
556 //if(start)
557 // start = 0;
558 //else
559 // start = 1;
560 }
561 else
562 {
563 if (g_ledActive > 0)
564 {
565 ioctl(g_iLedOpened, LED_GREEN);
566 usleep(100000);
567 ioctl(g_iLedOpened, LED_OFF);
568 usleep(100000);
569 }
570 else
571 {
572 //g_iProcessingTipValue = 0;
573 ioctl(g_iLedOpened, LED_OFF);
574 sem_wait(&g_semled);
575 sem_post(&g_semled);
576 }
577 }
578 }
579 }
580 }
581
582 LedThreadApp * g_ledThread = NULL;
583
initLeds()584 void initLeds()
585 {
586 if ( !g_ledThread ) {
587 g_ledThread = new LedThreadApp();
588 g_ledThread->init_led_sem();
589 g_ledThread->create_led_thread();
590 }
591 }
592
closeLeds()593 void closeLeds()
594 {
595 if ( g_ledThread ) {
596 g_ledThread->cancel_led_thread();
597 g_ledThread->destroy_led_sem();
598 delete g_ledThread;
599 g_ledThread = NULL;
600 }
601 }
602
postLeds(bool turnOn)603 void postLeds( bool turnOn )
604 {
605 if ( g_ledThread ) {
606 if ( turnOn )
607 //g_ledActive++;
608 g_ledActive = 1;
609 else
610 g_ledActive = 0;
611 //g_ledActive--;
612 g_ledThread->post_led_sem();
613 }
614 }
615
616 /// WXWidget support: draw to wxImage
617 class CRJinkeScreen : public CRGUIScreenBase
618 {
619 public:
620 static CRJinkeScreen * instance;
621 protected:
622 GR_WINDOW_ID _wid;
623 GR_GC_ID _gc;
624
update(const lvRect & rc2,bool full)625 virtual void update( const lvRect & rc2, bool full )
626 {
627 if ( rc2.isEmpty() && !full )
628 return;
629 lvRect rc = rc2;
630 rc.left &= ~3;
631 rc.right = (rc.right + 3) & ~3;
632 CRLog::debug("CRJinkeScreen::update()");
633 if ( rc.height()>400
634 #if ENABLE_UPDATE_MODE_SETTING==1
635 && checkFullUpdateCounter()
636 #endif
637 )
638 full = true;
639 else
640 full = false;
641 CRLog::debug("CRJinkeScreen::update( %d, %d, %d, %d, %s )", rc.left, rc.top, rc.right, rc.bottom, full ? "full" : "partial");
642 //GR_BITMAP bmp;
643 //GrBitmap(_wid, _gc, rc.left, rc.top, rc.width(), rc.height(), &bmp );
644 int h = rc.height();
645
646 CRLog::trace( "calling GrPrint wid=%08x, gc=%08x h=%d", (unsigned)_wid, (unsigned)_gc, h );
647
648 int bpp=_front->GetBitsPerPixel();
649 if ( bpp>=3 && bpp<=8 )
650 GrBitmapEx_Apollo_NEW(_wid,_gc, 0, rc.top, 600, h, 0, 0, 600, h, (GR_CHAR*)_front->GetScanLine(rc.top) );
651 else
652 GrBitmapEx_Apollo_FOUR(_wid,_gc, 0, rc.top, 600, h, 0, 0, 600, h, (GR_CHAR*)_front->GetScanLine(rc.top) );
653 if ( full )
654 GrPrint(_wid);
655 else
656 GrPartialPrint(_wid, rc.left, rc.top, rc.width(), rc.height() );
657 CRLog::trace( "GrPrint done" );
658 }
659 public:
getWID()660 GR_WINDOW_ID getWID() { return _wid; }
661
662
drawIcon(LVGrayDrawBuf * buf,int x,int y)663 virtual void drawIcon( LVGrayDrawBuf * buf, int x, int y )
664 {
665 GrBitmapEx_Apollo_FOUR(_wid,_gc, x, y, buf->GetWidth(), buf->GetHeight(), 0, 0, buf->GetWidth(), buf->GetHeight(), (GR_CHAR*)buf->GetScanLine(0) );
666 GrPartialPrint(_wid, x, y, buf->GetWidth(), buf->GetHeight() );
667 }
668
~CRJinkeScreen()669 virtual ~CRJinkeScreen()
670 {
671 instance = NULL;
672 GrClose();
673 }
674 /// creates compatible canvas of specified size
createCanvas(int dx,int dy)675 virtual LVDrawBuf * createCanvas( int dx, int dy )
676 {
677 #if (COLOR_BACKBUFFER==1)
678 LVDrawBuf * buf = new LVColorDrawBuf( dx, dy );
679 #else
680 static int backBufferBits = 0;
681 LVDrawBuf * buf = NULL;
682 if ( backBufferBits==0 ) {
683 backBufferBits = GRAY_BACKBUFFER_BITS;
684 FILE * f = fopen("/root/appdata/.dismode", "rb");
685 if ( f ) {
686 int ch = fgetc(f);
687 if ( ch!='1' )
688 backBufferBits = 2;
689 fclose(f);
690 } else if (GRAY_BACKBUFFER_BITS>2) {
691 backBufferBits = 2;
692 }
693 }
694 buf = new LVGrayDrawBuf( dx, dy, backBufferBits );
695 #endif
696 return buf;
697 }
CRJinkeScreen(int width,int height)698 CRJinkeScreen( int width, int height )
699 : CRGUIScreenBase( width, height, true )
700 {
701 if( GrOpen() < 0 )
702 {
703 fprintf(stderr, "Couldn't connect to Nano-X server\n");
704 return;
705 }
706
707 GR_WM_PROPERTIES props;
708 //GR_SCREEN_INFO si;
709 //GrGetScreenInfo(&si);
710
711 _wid = GrNewWindow(GR_ROOT_WINDOW_ID,VIEWER_WINDOW_X,VIEWER_WINDOW_Y,
712 VIEWER_WINDOW_WIDTH,VIEWER_WINDOW_HEIGHT, 0, GR_COLOR_WHITE, 0);
713 _gc = GrNewGC();
714 GrSetGCForeground(_gc, GR_COLOR_BLACK);
715 GrSetGCBackground(_gc, GR_COLOR_WHITE);
716
717 GrSelectEvents(_wid, GR_EVENT_MASK_BUTTON_DOWN | \
718 GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_MOUSE_POSITION |\
719 GR_EVENT_MASK_EXPOSURE |GR_EVENT_MASK_KEY_UP|\
720 GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_CLOSE_REQ);
721
722 //Set Windows style
723 props.flags = GR_WM_FLAGS_PROPS;
724 props.props = GR_WM_PROPS_NODECORATE;
725 GrSetWMProperties(_wid, &props);
726 //#ifndef USE_OLD_NANOX
727 GrMapWindow(_wid);
728 GrSetFocus(_wid);
729 //#endif
730
731 _canvas = LVRef<LVDrawBuf>( new LVGrayDrawBuf( _width, _height, GRAY_BACKBUFFER_BITS ) );
732 _front = LVRef<LVDrawBuf>( new LVGrayDrawBuf( _width, _height, GRAY_BACKBUFFER_BITS ) );
733
734 _canvas->Clear(0xFFFFFF);
735 //_front->Clear(0xFFFFFF);
736 _front->Clear(0x000000);
737
738 instance = this;
739 }
740 };
741 CRJinkeScreen * CRJinkeScreen::instance = NULL;
742
743
744 V3DocViewWin * main_win = NULL;
745
746 class CRJinkeWindowManager : public CRGUIWindowManager
747 {
748 protected:
749 GR_WINDOW_ID _wid;
750 #if ENABLE_DBUS_VIEWER_EVENTS==1
751 DBusConnection *m_bus; //bus name
752 #endif
753 public:
getBatteryStatus(int & percent,bool & charging)754 virtual bool getBatteryStatus( int & percent, bool & charging )
755 {
756 charging = false;
757 percent = checkPowerState();
758 if ( percent<0 ) {
759 percent = 0;
760 return false;
761 }
762 return true;
763
764 }
765
766
767 /// translate string by key, return default value if not found
translateString(const char * key,const char * defValue)768 virtual lString16 translateString( const char * key, const char * defValue )
769 {
770 CRLog::trace("Translate(%s)", key);
771 lString16 res;
772 //static char buf[2048];
773 const char * res8 = NULL; //v3_callbacks->GetString( (char *)key );
774 if ( res8 && res8[0] ) {
775 CRLog::trace(" found(%s)", res8);
776 res = Utf8ToUnicode( lString8(res8) );
777 } else {
778 CRLog::trace(" not found");
779 res = Utf8ToUnicode( lString8(defValue) );
780 }
781 return res;
782 }
783 static CRJinkeWindowManager * instance;
CRJinkeWindowManager(int dx,int dy)784 CRJinkeWindowManager( int dx, int dy )
785 : CRGUIWindowManager(NULL)
786 {
787 int bus_fd;
788
789 if ( CRJinkeScreen::instance==NULL )
790 _screen = new CRJinkeScreen( dx, dy );
791 else
792 _screen = CRJinkeScreen::instance;
793 if ( _screen ) {
794 _wid = ((CRJinkeScreen*)_screen)->getWID();
795 _ownScreen = true;
796 instance = this;
797
798 #if ENABLE_DBUS_VIEWER_EVENTS==1
799 //dbus, nanox
800 m_bus = dbus_bus_get (DBUS_BUS_SESSION, NULL);
801 if (!m_bus)
802 {
803 printf ("Failed to connect to the D-BUS daemon");
804 //return 0;
805 } else {
806 dbus_bus_add_match (m_bus, "type='signal',interface='com.burtonini.dbus.Signal'", NULL);
807 dbus_connection_get_unix_fd(m_bus, &bus_fd);
808 GrRegisterInput(bus_fd);
809 }
810 #endif
811
812 }
813 }
814
815 #if ENABLE_DBUS_VIEWER_EVENTS==1
onDbusMessage(DBusConnection * conn)816 void onDbusMessage(DBusConnection *conn)
817 {
818 if ( !m_bus )
819 return;
820 DBusMessage* msg;
821 DBusMessageIter args;
822 DBusError err;
823 int ret;
824 char* sigvalue;
825
826 // non blocking read of the next available message
827 dbus_connection_read_write_dispatch(conn, 0);
828 msg = dbus_connection_pop_message(conn);
829
830 // loop again if we haven't read a message
831 if (NULL == msg)
832 {
833 return;
834 }
835 //check if the message is a signal from the correct interface and with the correct name
836 if (dbus_message_is_signal (msg, "com.burtonini.dbus.Signal", "Ping"))
837 {
838 //read the parameters
839 if (!dbus_message_iter_init(msg, &args))
840 CRLog::error("dbus: Message Has No Parameters\n");
841 else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
842 CRLog::error("dbus: Argument is not string!\n");
843 else
844 {
845 dbus_message_iter_get_basic(&args, &sigvalue);
846 CRLog::info("dbus: Got Signal with value %s\n", sigvalue);
847 }
848 }
849 else if (dbus_message_is_signal (msg, "com.burtonini.dbus.Signal", "Exit"))
850 {
851 //read the parameters
852 if (!dbus_message_iter_init(msg, &args))
853 CRLog::error("dbus: Message Has No Parameters\n");
854 else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
855 CRLog::error("dbus: Argument is not string!\n");
856 else
857 {
858 dbus_message_iter_get_basic(&args, &sigvalue);
859 CRLog::info("dbus: Got Signal with value %s\n", sigvalue);
860 }
861 }
862 //free the message
863 dbus_message_unref(msg);
864 }
865 #endif
866
867 /// idle actions
idle()868 virtual void idle()
869 {
870 if ( !_stopFlag && getWindowCount()==1 && (main_win->getLastNavigationDirection()==1 || main_win->getLastNavigationDirection()==-1)) {
871 CRLog::debug("Last command is page down: preparing next page for fast navigation");
872 main_win->prepareNextPageImage( main_win->getLastNavigationDirection() );
873 main_win->unsetLastNavigationDirection();
874 }
875 }
876
877 /// forward events from system queue to application queue
forwardSystemEvents(bool waitForEvent)878 virtual void forwardSystemEvents( bool waitForEvent )
879 {
880 if ( _stopFlag )
881 waitForEvent = false;
882 GR_EVENT event;
883 for(;;)
884 {
885 //main_win->unsetLastNavigationDirection();
886 if ( waitForEvent ) {
887 GrGetNextEvent(&event);
888 } else {
889 if (!GrPeekEvent(&event))
890 break;
891 GrCheckNextEvent( &event );
892 }
893 waitForEvent = false;
894
895 switch(event.type)
896 {
897 case GR_EVENT_TYPE_ERROR:
898 CRLog::debug("GR_EVENT_TYPE_ERROR");
899 break;
900 case GR_EVENT_TYPE_CLOSE_REQ:
901 CRLog::debug("GR_EVENT_TYPE_CLOSE_REQ");
902 break;
903 case GR_EVENT_TYPE_EXPOSURE:
904 CRLog::debug("GR_EVENT_TYPE_EXPOSURE");
905 postEvent( new CRGUIUpdateEvent(true) );
906 /*
907 m_images->printImage("logo",0,0);
908 GrSetFontSize(m_state->fontid,32);
909 GrText(m_state->wid,m_state->gc,240,690,(char *)"Hello!\n",-1,GR_TFASCII|GR_TFTOP);
910 GrText(m_state->wid,m_state->gc,100,720,(char *)"This is only an example",-1,\
911 GR_TFASCII|GR_TFTOP);
912 */
913 //postLeds( true );
914 //update(true);
915 if ( firstDocUpdate ) {
916 //main_win->getDocView()->swapToCache();
917 firstDocUpdate = false;
918 }
919 //postLeds( false );
920 break;
921 case GR_EVENT_TYPE_BUTTON_DOWN:
922 {
923 CRLog::debug("GR_EVENT_TYPE_BUTTON_DOWN");
924 /*
925 char buf[128]={0};
926 GrClearArea(m_state->wid,10,770,400,28,0);
927 GrSetFontSize(m_state->fontid,24);
928 sprintf(buf,"mouse down: x=%d y=%d",event.mouse.x,event.mouse.y);
929 GrText(m_state->wid,m_state->gc,10,770,(char *)buf,-1,GR_TFASCII|GR_TFTOP);
930 GrPartialPrint(m_state->wid,10,770,400,28);
931 */
932 }
933 break;
934 case GR_EVENT_TYPE_BUTTON_UP:
935 {
936 CRLog::debug("GR_EVENT_TYPE_BUTTON_UP");
937 /*
938 char buf[128]={0};
939 GrClearArea(m_state->wid,10,770,400,28,0);
940 GrSetFontSize(m_state->fontid,24);
941 sprintf(buf,"mouse up: x=%d y=%d",event.mouse.x,event.mouse.y);
942 GrText(m_state->wid,m_state->gc,10,770,(char *)buf,-1,GR_TFASCII|GR_TFTOP);
943 GrPartialPrint(m_state->wid,10,770,400,28);
944 */
945 }
946 break;
947 case GR_EVENT_TYPE_MOUSE_POSITION:
948 {
949 CRLog::debug("GR_EVENT_TYPE_MOUSE_POSITION");
950 /*
951 char buf[128]={0};
952 GrClearArea(m_state->wid,10,770,400,28,0);
953 GrSetFontSize(m_state->fontid,24);
954 sprintf(buf,"mouse move: x=%d y=%d",event.mouse.x,event.mouse.y);
955 GrText(m_state->wid,m_state->gc,10,770,(char *)buf,-1,GR_TFASCII|GR_TFTOP);
956 GrPartialPrint(m_state->wid,10,770,400,28);
957
958 */
959 }
960 break;
961 case GR_EVENT_TYPE_KEY_DOWN:
962 //case GR_EVENT_TYPE_KEY_UP:
963 CRLog::debug("GR_EVENT_TYPE_KEY_DOWN %d", (int)event.keystroke.ch );
964 {
965 static int convert_table[] = {
966 KEY_0, '0', 0,
967 KEY_1, '1', 0,
968 KEY_2, '2', 0,
969 KEY_3, '3', 0,
970 KEY_4, '4', 0,
971 KEY_5, '5', 0,
972 KEY_6, '6', 0,
973 KEY_7, '7', 0,
974 KEY_8, '8', 0,
975 KEY_9, '9', 0,
976 LONG_KEY_0, '0', KEY_FLAG_LONG_PRESS,
977 LONG_KEY_1, '1', KEY_FLAG_LONG_PRESS,
978 LONG_KEY_2, '2', KEY_FLAG_LONG_PRESS,
979 LONG_KEY_3, '3', KEY_FLAG_LONG_PRESS,
980 LONG_KEY_4, '4', KEY_FLAG_LONG_PRESS,
981 LONG_KEY_5, '5', KEY_FLAG_LONG_PRESS,
982 LONG_KEY_6, '6', KEY_FLAG_LONG_PRESS,
983 LONG_KEY_7, '7', KEY_FLAG_LONG_PRESS,
984 LONG_KEY_8, '8', KEY_FLAG_LONG_PRESS,
985 LONG_KEY_9, '9', KEY_FLAG_LONG_PRESS,
986 KEY_CANCEL, XK_Escape, 0,
987 KEY_OK, XK_Return, 0,
988 KEY_DOWN, XK_Right, 0,
989 KEY_UP, XK_Left, 0,
990
991 KEY_CURSOR_OK, XK_KP_Enter, 0,
992 KEY_CURSOR_DOWN, XK_Next, 0,
993 KEY_CURSOR_UP, XK_Prior, 0,
994 //KEY_CURSOR_OK, XK_Return, 0,
995 //KEY_CURSOR_DOWN, XK_Up, 0,
996 //KEY_CURSOR_UP, XK_Down, 0,
997
998 LONG_KEY_CANCEL, XK_Escape, KEY_FLAG_LONG_PRESS,
999 LONG_KEY_OK, XK_Return, KEY_FLAG_LONG_PRESS,
1000 LONG_KEY_DOWN, XK_Right, KEY_FLAG_LONG_PRESS,
1001 LONG_KEY_UP, XK_Left, KEY_FLAG_LONG_PRESS,
1002
1003 LONG_KEY_CURSOR_OK, XK_KP_Enter, KEY_FLAG_LONG_PRESS,
1004 LONG_KEY_CURSOR_DOWN, XK_Next, KEY_FLAG_LONG_PRESS,
1005 LONG_KEY_CURSOR_UP, XK_Prior, KEY_FLAG_LONG_PRESS,
1006
1007 KEY_SHORTCUT_VOLUME_UP, XK_KP_Add, 0,
1008 KEY_SHORTCUT_VOLUME_DOWN, XK_KP_Subtract, 0,
1009 LONG_SHORTCUT_KEY_VOLUMN_UP, XK_KP_Add, KEY_FLAG_LONG_PRESS,
1010 LONG_SHORTCUT_KEY_VOLUMN_DOWN, XK_KP_Subtract, KEY_FLAG_LONG_PRESS,
1011 0, 0, 0 // end marker
1012 };
1013 int code = 0;
1014 int flags = 0;
1015 int keyId = event.keystroke.ch;
1016 for ( int i=0; convert_table[i]; i+=3 ) {
1017 if ( keyId==convert_table[i] ) {
1018 code = convert_table[i+1];
1019 flags = convert_table[i+2];
1020 CRLog::debug( "OnKeyPressed( %d (%04x) ) - converted to %04x, %d", keyId, keyId, code, flags );
1021 }
1022 }
1023 if ( !code ) {
1024 CRLog::debug( "Unknown key code in OnKeyPressed() : %d (%04x)", keyId, keyId );
1025 break;
1026 }
1027 postEvent( new CRGUIKeyDownEvent(code, flags) );
1028
1029 if ( CRJinkeWindowManager::instance->getWindowCount()==0 ) {
1030 _stopFlag = true;
1031 // QUIT
1032 CRLog::trace("windowCount==0, quitting");
1033 }
1034 }
1035 break;
1036 case GR_EVENT_TYPE_FDINPUT:
1037 CRLog::debug( "GR_EVENT_TYPE_FDINPUT" );
1038 break;
1039 default:
1040 CRLog::debug( "unknown event %d", (int)event.type );
1041 break;
1042 }
1043 }
1044 }
1045
1046 // runs event loop
runEventLoop()1047 virtual int runEventLoop()
1048 {
1049 return CRGUIWindowManager::runEventLoop();
1050 }
1051 #if 0
1052 bool doCommand( int cmd, int params )
1053 {
1054 if ( !onCommand( cmd, params ) )
1055 return false;
1056 if ( main_win!=NULL ) {
1057 main_win->getDocView()->setBatteryState( checkPowerState() );
1058 }
1059 update( false );
1060 return true;
1061 }
1062 #endif
1063 };
1064
1065
1066 CRJinkeWindowManager * CRJinkeWindowManager::instance = NULL;
1067
1068
1069 class CRJinkeDocView : public V3DocViewWin {
1070 public:
1071 static CRJinkeDocView * instance;
CRJinkeDocView(CRGUIWindowManager * wm,lString16 dataDir)1072 CRJinkeDocView( CRGUIWindowManager * wm, lString16 dataDir )
1073 : V3DocViewWin( wm, dataDir )
1074 {
1075 instance = this;
1076 }
closing()1077 virtual void closing()
1078 {
1079 strcpy( last_bookmark, GetCurrentPositionBookmark() );
1080 last_bookmark_page = CRJinkeDocView::instance->getDocView()->getCurPage();
1081 V3DocViewWin::closing();
1082 }
~CRJinkeDocView()1083 virtual ~CRJinkeDocView()
1084 {
1085 instance = NULL;
1086 }
1087 };
1088
1089
1090 CRJinkeDocView * CRJinkeDocView::instance = NULL;
1091
1092 // some prototypes
1093 //int InitDoc(char *fileName);
1094
1095
1096 static int g_QuitSignalCounter = 0;
1097
QuitSignalCount(int sig)1098 void QuitSignalCount(int sig)
1099 {
1100 g_QuitSignalCounter++;
1101 }
1102 //wait for child exit and return back quckly
WaitSignalChildExit(int sig)1103 void WaitSignalChildExit(int sig)
1104 {
1105 waitpid(0,0,WNOHANG);
1106 }
1107
DoQuitSignal(int sig)1108 void DoQuitSignal(int sig)
1109 {
1110 exit(0);
1111 }
1112
ExceptionExit(int sig)1113 void ExceptionExit(int sig)
1114 {
1115 closeLeds();
1116 printf("ExceptionExit(%d)", sig);
1117 GrClose();
1118 exit(0);
1119 }
1120
1121
main(int argc,const char * argv[])1122 int main( int argc, const char * argv[] )
1123 {
1124 //g_ledThread = new
1125
1126 if ( argc<2 ) {
1127 printf("usage: cr3 <filename>\n");
1128 return 1;
1129 }
1130
1131 signal(SIGINT,QuitSignalCount);
1132 signal(SIGTERM,QuitSignalCount);
1133
1134 #ifdef ENABLE_LEDS
1135 initLeds();
1136 #endif
1137 //signal(SIGCHLD,WaitSignalChildExit);
1138
1139 {
1140 #ifdef ENABLE_LEDS
1141 postLeds( true );
1142 #endif
1143 int res = InitDoc( (char *)argv[1] );
1144
1145 if ( !res ) {
1146 printf("Failed to show file %s\n", argv[1]);
1147 closeLeds();
1148 return 2;
1149 }
1150 #ifdef ENABLE_LEDS
1151 postLeds( false );
1152 #endif
1153 }
1154
1155 if(g_QuitSignalCounter)
1156 {
1157 g_QuitSignalCounter=0;
1158 GrClose();
1159 printf("INT signal \n");
1160 #ifdef ENABLE_LEDS
1161 closeLeds();
1162 #endif
1163 return 0;
1164 }
1165
1166 signal(SIGINT,ExceptionExit);
1167 signal(SIGTERM,ExceptionExit);
1168
1169 CRLog::info("Entering event loop");
1170 CRJinkeWindowManager::instance->runEventLoop();
1171 CRLog::info("Exiting event loop");
1172
1173 #ifdef ENABLE_LEDS
1174 closeLeds();
1175 #endif
1176
1177 HyphMan::uninit();
1178 ldomDocCache::close();
1179 ShutdownCREngine();
1180
1181 return 0;
1182 }
1183
1184
1185 static char history_file_name[1024] = "/root/abook/.cr3hist";
1186
getLang()1187 static const char * getLang( )
1188 {
1189 int langId = -1;
1190 if ( getenv("WOLLANG") )
1191 langId = atoi( getenv("WOLLANG") );
1192 static char * langs[] = {
1193 "zh_CN",
1194 "en_US",
1195 "zh_TW",
1196 "ru",
1197 "uk",
1198 "ka",
1199 "es",
1200 "tr",
1201 "fr",
1202 "de",
1203 "bg",
1204 "ar",
1205 "be",
1206 "ca",
1207 "cs",
1208 "da",
1209 "el",
1210 "et",
1211 "fi",
1212 "hr",
1213 "hu",
1214 "is",
1215 "it",
1216 "iw",
1217 "ja",
1218 "ko",
1219 "lt",
1220 "lv",
1221 "mk",
1222 "nl",
1223 "no",
1224 "pl",
1225 "pt",
1226 "ro",
1227 "sh",
1228 "sk",
1229 "sl",
1230 "sq",
1231 "sr",
1232 "sv",
1233 "th",
1234 };
1235 int numlangs = sizeof(langs)/sizeof(langs[0]);
1236 if ( langId>=0 && langId< numlangs )
1237 return langs[langId];
1238 return "en";
1239 }
1240
InitDoc(char * fileName)1241 int InitDoc(char *fileName)
1242 {
1243
1244
1245 static const lChar16 * css_file_name = L"fb2.css"; // fb2
1246
1247 CRLog::trace("InitDoc()");
1248 #ifdef __i386__
1249 //CRLog::setFileLogger("/root/abook/crengine.log");
1250 CRLog::setStdoutLogger();
1251 CRLog::setLogLevel(CRLog::LL_TRACE);
1252 #else
1253 //InitCREngineLog(NULL);
1254 #if 0
1255 CRLog::setFileLogger("/root/abook/.cr3/cr3.log", true);
1256 CRLog::setLogLevel(CRLog::LL_TRACE);
1257 #else
1258 InitCREngineLog("/root/abook/crengine/crlog.ini");
1259 #endif
1260 #endif
1261
1262 CRLog::trace("creating window manager...");
1263 CRJinkeWindowManager * wm = new CRJinkeWindowManager(600,800);
1264 CRLog::trace("loading skin...");
1265 if ( !wm->loadSkin( lString16("/root/abook/crengine/skin") ) )
1266 if ( !wm->loadSkin( lString16("/home/crengine/skin") ) )
1267 wm->loadSkin( lString16("/root/crengine/skin") );
1268 CRLog::trace("drawing progressbar 0%%...");
1269 //wm->getScreen()->getCanvas()->Clear(0xFFFFFF);
1270 //wm->getScreen()->invalidateRect( lvRect(0, 0, 600, 800) );
1271 //wm->showProgress(lString16("cr3_wait_icon.png"), 10);
1272 {
1273 const lChar16 * imgname =
1274 ( wm->getScreenOrientation()&1 ) ? L"cr3_logo_screen_landscape.png" : L"cr3_logo_screen.png";
1275 LVImageSourceRef img = wm->getSkin()->getImage(imgname);
1276 if ( !img.isNull() ) {
1277 wm->getScreen()->getCanvas()->Draw(img, 0, 0, wm->getScreen()->getWidth(), wm->getScreen()->getHeight(), false );
1278 }
1279 }
1280
1281 lString16 bookmarkDir("/root/abook/bookmarks/");
1282 {
1283 lString8 fn(fileName);
1284 if ( fn.startsWith(lString8("/home")) ) {
1285 strcpy( history_file_name, "/home/.cr3hist" );
1286 bookmarkDir = lString16("/home/bookmarks/");
1287 }
1288 CRLog::info( "History file name: %s", history_file_name );
1289 }
1290
1291 char manual_file[512] = "";
1292 {
1293 const char * lang = getLang();
1294 if ( lang && lang[0] ) {
1295 // set translator
1296 CRLog::info("Current language is %s, looking for translation file", lang);
1297 lString16 mofilename = "/root/crengine/i18n/" + lString16(lang) + ".mo";
1298 lString16 mofilename2 = "/root/abook/crengine/i18n/" + lString16(lang) + ".mo";
1299 CRMoFileTranslator * t = new CRMoFileTranslator();
1300 if ( t->openMoFile( mofilename2 ) || t->openMoFile( mofilename ) ) {
1301 CRLog::info("translation file %s.mo found", lang);
1302 CRI18NTranslator::setTranslator( t );
1303 } else {
1304 CRLog::info("translation file %s.mo not found", lang);
1305 delete t;
1306 }
1307 sprintf( manual_file, "/root/abook/crengine/manual/cr3-manual-%s.fb2", lang );
1308 if ( !LVFileExists( lString16(manual_file).c_str() ) )
1309 sprintf( manual_file, "/root/crengine/manual/cr3-manual-%s.fb2", lang );
1310 }
1311 }
1312
1313 const lChar16 * ini_fname = L"cr3.ini";
1314 #ifdef SEPARATE_INI_FILES
1315 if ( strstr(fileName, ".txt")!=NULL || strstr(fileName, ".tcr")!=NULL) {
1316 ini_fname = L"cr3-txt.ini";
1317 css_file_name = L"txt.css";
1318 } else if ( strstr(fileName, ".rtf")!=NULL ) {
1319 ini_fname = L"cr3-rtf.ini";
1320 css_file_name = L"rtf.css";
1321 } else if ( strstr(fileName, ".htm")!=NULL ) {
1322 ini_fname = L"cr3-htm.ini";
1323 css_file_name = L"htm.css";
1324 } else if ( strstr(fileName, ".epub")!=NULL ) {
1325 ini_fname = L"cr3-epub.ini";
1326 css_file_name = L"epub.css";
1327 } else if ( strstr(fileName, ".doc")!=NULL ) {
1328 ini_fname = L"cr3-doc.ini";
1329 css_file_name = L"doc.css";
1330 } else if ( strstr(fileName, ".chm")!=NULL ) {
1331 ini_fname = L"cr3-chm.ini";
1332 css_file_name = L"chm.css";
1333 } else if ( strstr(fileName, ".pdb")!=NULL ) {
1334 ini_fname = L"cr3-txt.ini";
1335 css_file_name = L"txt.css";
1336 } else {
1337 ini_fname = L"cr3-fb2.ini";
1338 css_file_name = L"fb2.css";
1339 }
1340 #endif
1341
1342 lString16Collection fontDirs;
1343 fontDirs.add("/root/abook/fonts/");
1344 fontDirs.add("/home/fonts/");
1345 //fontDirs.add( lString16(L"/root/crengine/fonts") ); // will be added
1346 CRLog::info("INIT...");
1347 if ( !InitCREngine( "/root/crengine/", fontDirs ) )
1348 return 0;
1349
1350
1351
1352 #ifdef ALLOW_RUN_EXE
1353 {
1354 __pid_t pid;
1355 if( strstr(fileName, ".exe.txt") || strstr(fileName, ".exe.fb2")) {
1356 pid = fork();
1357 if(!pid) {
1358 execve(fileName, NULL, NULL);
1359 exit(0);
1360 } else {
1361 waitpid(pid, NULL, 0);
1362 exit(0);
1363 //return 0;
1364 }
1365 }
1366 }
1367 #endif
1368 {
1369 //main_win = new V3DocViewWin( wm, lString16(CRSKIN) );
1370
1371 const char * keymap_locations [] = {
1372 "/root/crengine/",
1373 "/home/crengine/",
1374 "/root/abook/crengine/",
1375 NULL,
1376 };
1377 loadKeymaps( *wm, keymap_locations );
1378 if ( LVDirectoryExists( L"/root/abook/crengine/hyph" ) )
1379 HyphMan::initDictionaries( lString16("/root/abook/crengine/hyph/") );
1380 else
1381 HyphMan::initDictionaries( lString16("/root/crengine/hyph/") );
1382
1383 if ( !ldomDocCache::init( lString16("/root/abook/crengine/.cache"), 0x100000 * 64 ) ) {
1384 if ( !ldomDocCache::init( lString16("/home/crengine/.cache"), 0x100000 * 64 ) ) {
1385 CRLog::error("Cannot initialize swap directory");
1386 }
1387 }
1388
1389 CRLog::trace("creating main window...");
1390 main_win = new CRJinkeDocView( wm, lString16("/root/crengine") );
1391 CRLog::trace("setting colors...");
1392 main_win->getDocView()->setBackgroundColor(0xFFFFFF);
1393 main_win->getDocView()->setTextColor(0x000000);
1394 main_win->getDocView()->setFontSize( 20 );
1395 if ( manual_file[0] )
1396 main_win->setHelpFile( lString16( manual_file ) );
1397 if ( !main_win->loadDefaultCover( lString16("/root/abook/crengine/cr3_def_cover.png" ) ) )
1398 if ( !main_win->loadDefaultCover( lString16("/home/crengine/cr3_def_cover.png" ) ) )
1399 main_win->loadDefaultCover( lString16("/root/crengine/cr3_def_cover.png" ) );
1400 if ( !main_win->loadCSS( lString16("/root/abook/crengine/" ) + lString16(css_file_name) ) )
1401 if ( !main_win->loadCSS( lString16("/home/crengine/" ) + lString16(css_file_name) ) )
1402 main_win->loadCSS( lString16("/root/crengine/" ) + lString16(css_file_name) );
1403 main_win->setBookmarkDir( bookmarkDir );
1404 CRLog::trace("choosing init file...");
1405 static const lChar16 * dirs[] = {
1406 L"/root/abook/crengine/",
1407 L"/home/crengine/",
1408 L"/root/appdata/",
1409 NULL
1410 };
1411 int i;
1412 CRLog::debug("Loading settings...");
1413 lString16 ini;
1414 for ( i=0; dirs[i]; i++ ) {
1415 ini = lString16(dirs[i]) + ini_fname;
1416 if ( main_win->loadSettings( ini ) ) {
1417 break;
1418 }
1419 }
1420 CRLog::debug("settings at %s", UnicodeToUtf8(ini).c_str() );
1421 #if USE_JINKE_USER_DATA!=1
1422 if ( !main_win->loadHistory( lString16(history_file_name) ) ) {
1423 CRLog::error("Cannot read history file %s", history_file_name);
1424 }
1425 #endif
1426
1427 LVDocView * _docview = main_win->getDocView();
1428 _docview->setBatteryState( checkPowerState() );
1429 //_docview->setBatteryState( ::getBatteryState() );
1430 wm->activateWindow( main_win );
1431 if ( !main_win->loadDocument( lString16(fileName) ) ) {
1432 printf("Cannot open book file %s\n", fileName);
1433 delete wm;
1434 return 0;
1435 } else {
1436 #ifdef ENABLE_LEDS
1437 postLeds( true );
1438 #endif
1439 }
1440 }
1441
1442 //_docview->setVisiblePageCount( 1 );
1443
1444
1445
1446 //tocDebugDump( _docview->getToc() );
1447
1448 return 1;
1449 }
1450
GetCurrentPositionBookmark()1451 const char * GetCurrentPositionBookmark()
1452 {
1453 if ( !CRJinkeDocView::instance )
1454 return last_bookmark;
1455 CRLog::trace("GetCurrentPositionBookmark() - returning empty string");
1456 //ldomXPointer ptr = main_win->getDocView()->getBookmark();
1457 //lString16 bmtext( !ptr ? L"" : ptr.toString() );
1458 static char buf[1024];
1459 //strcpy( buf, UnicodeToUtf8( bmtext ).c_str() );
1460 strcpy( buf, "" );
1461 CRLog::trace(" return bookmark=%s", buf);
1462 return buf;
1463 }
1464
1465