/* X11 screen routines. Copyright (c) 2001-2003 by Salvador E. Tropea (SET) Covered by the GPL license. Thanks to José Ángel Sánchez Caso (JASC). He implemented a first X11 driver. This implementation is completly different but JASC's code gave me the first notions about how an X11 application works. ToDo: * The SetDisPaletteColors does a redraw, it should be avoided, at least for 8 bpp modes, BTW they are untested. Configuration variables: Font10x20=0 Selects the 10x20 font instead of 8x16 ScreenWidth ScreenHeight ScreenPalette FontWidth FontHeight LoadSecondaryFont AppCP ScrCP InpCP HideCursorWhenNoFocus DontResizeToCells Don't resize the window to a cells multiple size if the WM fails to follow the hints. This helps to avoid problems found in KDE 3.1 alpha. InternalBusyCursor When enabled we use our own mouse cursor for it Unicode16 Try using unicode16 mode. UnicodeFont Name of the font to use for unicode16 mode. UseUpdateThread Uses a separated thread to update the window content. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include // That's a nasty side effect: X defines Boolean! #if (defined(TVOS_UNIX) || defined(TVCompf_Cygwin)) && defined(HAVE_X11) #include #endif #define Uses_stdio #define Uses_stdlib #define Uses_string #define Uses_unistd // TScreenX11::System #define Uses_signal #define Uses_AllocLocal #define Uses_TDisplay #define Uses_TScreen #define Uses_TGKey // For TGKeyX11 #define Uses_TEvent // For THWMouseX11 #define Uses_TVCodePage #define Uses_TVOSClipboard // Only for testing purposes #define Uses_TVFontCollection #define Uses_TVPartitionTree556 #include // I delay the check to generate as much dependencies as possible #if (defined(TVOS_UNIX) || defined(TVCompf_Cygwin)) && defined(HAVE_X11) // X11 defines their own values #undef True #undef False #define True 1 #define False 0 #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_LINUX_PTHREAD #include #endif #ifdef TVOSf_Solaris // At least in the Solaris 7 box I tested looks like ITIMER_REAL is broken // and behaves like ITIMER_VIRTUAL #define ITIMER_USED ITIMER_REALPROF #define TIMER_ALARM SIGPROF #else #define ITIMER_USED ITIMER_REAL #define TIMER_ALARM SIGALRM #endif const unsigned foWmin=5, foHmin=7, foWmax=20, foHmax=32; const int cursorDelay=300000; /***************************************************************************** TScreenX11 screen stuff. *****************************************************************************/ Display *TScreenX11::disp; ulong TScreenX11::screen; Visual *TScreenX11::visual; Window TScreenX11::rootWin; Window TScreenX11::mainWin; Colormap TScreenX11::cMap; GC TScreenX11::gc; GC TScreenX11::cursorGC=NULL; XIC TScreenX11::xic=NULL; XIM TScreenX11::xim=NULL; Atom TScreenX11::theProtocols; ulong TScreenX11::colorMap[16]; XImage *TScreenX11::ximgFont[256]; /* Our "font" is just a collection of images */ XImage *TScreenX11::ximgSecFont[256]; XImage *TScreenX11::cursorImage=NULL; int TScreenX11::fg; int TScreenX11::bg; char TScreenX11::cursorEnabled=1; char TScreenX11::cursorInScreen=0; uchar TScreenX11::curAttr; uchar TScreenX11::primaryFontChanged=0; char *TScreenX11::cursorData=NULL; char TScreenX11::hideCursorWhenNoFocus=1; char TScreenX11::dontResizeToCells=0; struct timeval TScreenX11::refCursorTime, TScreenX11::curCursorTime; XSizeHints *TScreenX11::sizeHints=NULL; XClassHint *TScreenX11::classHint=NULL; void (*TScreenX11::writeLine)(int x, int y, int w, void *str, unsigned color)= TScreenX11::writeLineCP; void (*TScreenX11::redrawBuf)(int x, int y, unsigned w, unsigned off)= TScreenX11::redrawBufCP; TScreenX11::~TScreenX11() { STOP_UPDATE_THREAD; if (sizeHints) XFree(sizeHints); if (classHint) XFree(classHint); if (xic) XDestroyIC(xic); if (xim) XCloseIM(xim); DestroyXImageFont(0); DestroyXImageFont(1); if (cursorImage) XDestroyImage(cursorImage); if (disp) { if (cursorGC) XFreeGC(disp,cursorGC); XDestroyWindow(disp,mainWin); XCloseDisplay(disp); //This could do all of the above for us, but anyway... } delete[] screenBuffer; } void TScreenX11::clearScreen() { SEMAPHORE_ON; XSetForeground(disp,gc,colorMap[bg]); XFillRectangle(disp,mainWin,gc,0,0,maxX*fontW,maxY*fontH); XSetForeground(disp,gc,colorMap[fg]); char space[2]; space[charPos]=' '; space[attrPos]=curAttr; unsigned c=maxX*maxY; while (c--) screenBuffer[c]=*((ushort *)space); SEMAPHORE_OFF; } inline void TScreenX11::drawChar(GC gc, unsigned x, unsigned y, uchar aChar, uchar aAttr) { if (useSecondaryFont && (aAttr & 0x8)) XPutImage(disp,mainWin,gc,ximgSecFont[aChar],0,0,x,y,fontW,fontH); else XPutImage(disp,mainWin,gc,ximgFont[aChar],0,0,x,y,fontW,fontH); } void TScreenX11::setCharacter(unsigned offset, uint32 value) { SEMAPHORE_ON; screenBuffer[offset]=value; unsigned x,y; x=(offset%maxX)*fontW; y=(offset/maxX)*fontH; uchar *theChar=(uchar *)(screenBuffer+offset); uchar newChar=theChar[charPos]; uchar newAttr=theChar[attrPos]; XSetBgFg(newAttr); UnDrawCursor(); drawChar(gc,x,y,newChar,newAttr); DrawCursor(); XFlush(disp); SEMAPHORE_OFF; } void TScreenX11::setCharacters(unsigned offset, ushort *values, unsigned count) { SEMAPHORE_ON; unsigned x,y; x=(offset%maxX)*fontW; y=(offset/maxX)*fontH; uchar *b=(uchar *)values,newChar,newAttr; uchar *sb=(uchar *)(screenBuffer+offset); unsigned oldAttr=0x100; UnDrawCursor(); while (count--) { newChar=b[charPos]; newAttr=b[attrPos]; if (newChar!=sb[charPos] || newAttr!=sb[attrPos]) { sb[charPos]=newChar; sb[attrPos]=newAttr; if (newAttr!=oldAttr) { XSetBgFg(newAttr); oldAttr=newAttr; } drawChar(gc,x,y,newChar,newAttr); } x+=fontW; b+=2; sb+=2; } DrawCursor(); XFlush(disp); SEMAPHORE_OFF; } int TScreenX11::System(const char *command, pid_t *pidChild, int in, int out, int err) { if (!pidChild) { // If the caller asks for redirection replace the requested handles if (in!=-1) dup2(in,STDIN_FILENO); if (out!=-1) dup2(out,STDOUT_FILENO); if (err!=-1) dup2(err,STDERR_FILENO); return system(command); } pid_t cpid=fork(); if (cpid==0) {// Ok, we are the child // I'm not sure about it, but is the best I have right now. // Doing it we can kill this child and all the subprocesses // it creates by killing the group. It also have an interesting // effect that I must evaluate: By doing it this process lose // the controlling terminal and won't be able to read/write // to the parents console. I think that's good. if (setsid()==-1) _exit(127); // If the caller asks for redirection replace the requested handles if (in!=-1) dup2(in,STDIN_FILENO); if (out!=-1) dup2(out,STDOUT_FILENO); if (err!=-1) dup2(err,STDERR_FILENO); if (NO_EXEC_IN_THREAD && IS_SECOND_THREAD_ON) {// That's very Linux specific: // For some (unknown) reason we can't use exec here. If we use exec then // the update thread dies and the "monitoring" thread becomes a Zombie. // The only safe way is to call system(), it have code to stop // multithreading and then call exec. That's the only safe way. //pthread_kill_other_threads_np(); <= Useless // Note: this solution is incomplete, if the user tries to kill the // child using pidChild then the update thread will misteriously die. // For this reason I use a watchdog that checks if the thread worked // in the last second. If not we revert to manual screen update. system(command); // Here we must exit but without deallocating resources! just exit, // that's all _exit(0); } else {// This is much more efficient, but only works if pthreads are off. char *argv[4]; argv[0]=getenv("SHELL"); if (!argv[0]) argv[0]="/bin/sh"; argv[1]="-c"; argv[2]=(char *)command; argv[3]=0; execvp(argv[0],argv); // We get here only if exec failed _exit(127); } } if (cpid==-1) {// Fork failed do it manually *pidChild=0; return system(command); } *pidChild=cpid; return 0; } uchar TScreenX11::shapeFont10x20[]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x4C,0x80,0x4C,0x80,0x7C,0x80,0x79,0x80,0x73,0x80,0x73,0x80,0x73,0x80,0x7F,0x80,0x73,0x80,0x73,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x80,0x6D,0x80,0x67,0x00,0x00,0x00,0x39,0x80,0x6D,0x80,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x36,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x67,0x80,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x36,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x6D,0x80,0x6D,0x80,0x6F,0x80,0x6C,0x00,0x6C,0x00,0x6D,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x3F,0x00,0x7F,0x80,0x7F,0x80,0x3F,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x7E,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x1F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x7C,0x00,0x60,0x00,0x60,0x00,0x78,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x0F,0x80,0x0C,0x00,0x0C,0x00,0x0F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,0x60,0x00,0x60,0x00,0x66,0x00,0x3C,0x00,0x00,0x00,0x1F,0x00,0x19,0x80,0x19,0x80,0x1F,0x00,0x1E,0x00,0x1B,0x00,0x19,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x00,0x00,0x0F,0x80,0x0C,0x00,0x0C,0x00,0x0F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x55,0x40,0x00,0x00,0xAA,0x80,0x00,0x00,0x55,0x40,0x00,0x00,0xAA,0x80,0x00,0x00,0x55,0x40,0x00,0x00,0xAA,0x80,0x00,0x00,0x55,0x40,0x00,0x00,0xAA,0x80,0x00,0x00,0x55,0x40,0x00,0x00,0xAA,0x80,0x00,0x00, 0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80,0x55,0x40,0xAA,0x80, 0x55,0x40,0xFF,0xC0,0xAA,0x80,0xFF,0xC0,0x55,0x40,0xFF,0xC0,0xAA,0x80,0xFF,0xC0,0x55,0x40,0xFF,0xC0,0xAA,0x80,0xFF,0xC0,0x55,0x40,0xFF,0xC0,0xAA,0x80,0xFF,0xC0,0x55,0x40,0xFF,0xC0,0xAA,0x80,0xFF,0xC0, 0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0, 0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00, 0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xC0, 0x00,0x00,0x00,0x00,0x66,0x00,0x76,0x00,0x7E,0x00,0x7E,0x00,0x6E,0x00,0x66,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x3C,0x00,0x3C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x1F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x38,0x00,0x0E,0x00,0x03,0x80,0x0E,0x00,0x38,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x0E,0x00,0x38,0x00,0xE0,0x00,0x38,0x00,0x0E,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x18,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x07,0x80,0x1F,0x80,0x7F,0x80,0x7F,0x80,0x1F,0x80,0x07,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x78,0x00,0x7E,0x00,0x7F,0x80,0x7F,0x80,0x7E,0x00,0x78,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x3F,0x00,0x6D,0x80,0x4C,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x4C,0x80,0x6D,0x80,0x3F,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0xFF,0x80,0xFF,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0xFF,0x80,0xFF,0x80,0x60,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x3F,0x00,0x6D,0x80,0x4C,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x4C,0x80,0x6D,0x80,0x3F,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x33,0x00,0x61,0x80,0xFF,0xC0,0xFF,0xC0,0x61,0x80,0x33,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x19,0x80,0x31,0x80,0x7F,0x80,0x7F,0x80,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x3F,0xC0,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x7F,0x80,0x36,0x00,0x36,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3F,0x00,0x6D,0x80,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x3F,0x00,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x6D,0x80,0x3F,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x80,0x6D,0x80,0x6F,0x00,0x3B,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x1B,0x80,0x1E,0xC0,0x36,0xC0,0x33,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x3C,0x00,0x18,0x00,0x38,0x00,0x6C,0x00,0x66,0xC0,0x63,0x80,0x63,0x00,0x77,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x7F,0x80,0x1E,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1C,0x00,0x3C,0x00,0x6C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x0E,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x03,0x00,0x0E,0x00,0x03,0x00,0x01,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x0F,0x00,0x1B,0x00,0x33,0x00,0x63,0x00,0x63,0x00,0x7F,0x80,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x21,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x67,0x80,0x6F,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6F,0x00,0x66,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x66,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x67,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x63,0x00,0x63,0x00,0x66,0x00,0x66,0x00,0x7C,0x00,0x66,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x73,0x80,0x73,0x80,0x7F,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x71,0x80,0x71,0x80,0x79,0x80,0x79,0x80,0x6D,0x80,0x6D,0x80,0x67,0x80,0x67,0x80,0x63,0x80,0x63,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x6D,0x80,0x67,0x80,0x33,0x00,0x1F,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x60,0x00,0x60,0x00,0x30,0x00,0x1E,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x73,0x80,0x73,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x73,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1D,0x80,0x33,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x18,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x80,0x63,0x80,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x60,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x07,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x31,0x80,0x31,0x80,0x31,0x80,0x1F,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5B,0x00,0x7F,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x73,0x00,0x6E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1D,0x80,0x33,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x39,0x80,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0x00,0x3F,0x00,0x01,0x80,0x01,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x19,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x7F,0x80,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x61,0x80,0x33,0x00,0x1E,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x78,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x80,0x6D,0x80,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x0F,0xC0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xFF,0xC0,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x04,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x13,0xC0,0x10,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC0,0x10,0x00,0x13,0xC0,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x13,0xC0,0x10,0x00,0x13,0xC0,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x08,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0xF2,0x00,0x02,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0xF3,0xC0,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x02,0x00,0xF2,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0xF2,0x00,0x02,0x00,0xF2,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0xF3,0xC0,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0xF3,0xC0,0x00,0x00,0xF3,0xC0,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x00,0x60,0x00,0x60,0x00,0x61,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x18,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7C,0x00,0x56,0xC0,0x73,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3F,0x00,0x6D,0x80,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x3F,0x00,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x6D,0x80,0x3F,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x3F,0x00,0x0C,0x00,0x3F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x63,0x00,0x30,0x00,0x3C,0x00,0x66,0x00,0x33,0x00,0x19,0x80,0x0F,0x00,0x03,0x00,0x31,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x5E,0x80,0x52,0x80,0x50,0x80,0x52,0x80,0x5E,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x0D,0x80,0x1B,0x00,0x36,0x00,0x6C,0x00,0xD8,0x00,0x6C,0x00,0x36,0x00,0x1B,0x00,0x0D,0x80,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x7F,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x5E,0x80,0x52,0x80,0x5E,0x80,0x54,0x80,0x56,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x36,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x36,0x00,0x06,0x00,0x0C,0x00,0x06,0x00,0x36,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x77,0x00,0x7D,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x7F,0x80,0x7D,0x80,0x7D,0x80,0x7D,0x80,0x3D,0x80,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x0D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x06,0x00,0x36,0x00,0x1C,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x6C,0x00,0x36,0x00,0x1B,0x00,0x0D,0x80,0x06,0xC0,0x0D,0x80,0x1B,0x00,0x36,0x00,0x6C,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x60,0x00,0x20,0x80,0x21,0x00,0x72,0x00,0x04,0x00,0x09,0x00,0x13,0x00,0x25,0x00,0x4F,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x60,0x00,0x20,0x80,0x21,0x00,0x72,0x00,0x04,0x00,0x0B,0x00,0x14,0x80,0x20,0x80,0x41,0x00,0x02,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x08,0x00,0x30,0x80,0x09,0x00,0x72,0x00,0x04,0x00,0x09,0x00,0x13,0x00,0x25,0x00,0x4F,0x80,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x1E,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1E,0x00,0x36,0x00,0x36,0x00,0x66,0x00,0x66,0x00,0x7F,0x80,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x67,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x06,0x00,0x36,0x00,0x1C,0x00, 0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x3F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0xF9,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x61,0x80,0x71,0x80,0x79,0x80,0x79,0x80,0x6D,0x80,0x6D,0x80,0x67,0x80,0x67,0x80,0x63,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x33,0x00,0x63,0x80,0x63,0x80,0x65,0x80,0x65,0x80,0x65,0x80,0x69,0x80,0x69,0x80,0x69,0x80,0x71,0x80,0x33,0x00,0x3E,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x31,0x80,0x31,0x80,0x31,0x80,0x31,0x80,0x31,0x80,0x3F,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x33,0x00,0x76,0x00,0x36,0x00,0x33,0x00,0x31,0x80,0x31,0x80,0x31,0x80,0x33,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3E,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x00,0x4D,0x80,0x0D,0x80,0x0F,0x00,0x3C,0x00,0x6C,0x00,0x6C,0x80,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x0C,0x00,0x06,0x00,0x36,0x00,0x1C,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x07,0xC0,0x01,0x80,0x1D,0x80,0x33,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x3F,0x00,0x26,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x7F,0x80,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x33,0x00,0x65,0x80,0x65,0x80,0x69,0x80,0x69,0x80,0x33,0x00,0x3E,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x61,0x80,0x33,0x00,0x1E,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x33,0x00,0x31,0x80,0x31,0x80,0x31,0x80,0x33,0x00,0x3E,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x33,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x61,0x80,0x33,0x00,0x1E,0x00, }; uchar TScreenX11::shapeFont8x16[]= { 0x00,0x00,0x7E,0xC3,0x99,0x99,0xF3,0xE7,0xE7,0xFF,0xE7,0xE7,0x7E,0x00,0x00,0x00, // 0 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x6E,0xF8,0xD8,0xD8,0xDC,0xD8,0xD8,0xD8,0xF8,0x6E,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x00,0x6E,0xDB,0xDB,0xDF,0xD8,0xDB,0x6E,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00, //  0x00,0x88,0x88,0xF8,0x88,0x88,0x00,0x3E,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00, //  0x00,0xF8,0x80,0xE0,0x80,0x80,0x00,0x3E,0x20,0x38,0x20,0x20,0x00,0x00,0x00,0x00, //  0x00,0x70,0x88,0x80,0x88,0x70,0x00,0x3C,0x22,0x3C,0x24,0x22,0x00,0x00,0x00,0x00, //  0x00,0x80,0x80,0x80,0x80,0xF8,0x00,0x3E,0x20,0x38,0x20,0x20,0x00,0x00,0x00,0x00, //  0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, // \t 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA, // \n 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77, // 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // \r 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //  0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, //  0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, //  0x00,0x88,0xC8,0xA8,0x98,0x88,0x00,0x20,0x20,0x20,0x20,0x3E,0x00,0x00,0x00,0x00, //  0x00,0x88,0x88,0x50,0x50,0x20,0x00,0x3E,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x0E,0x38,0xE0,0x38,0x0E,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0xE0,0x38,0x0E,0x38,0xE0,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x06,0x0C,0xFE,0x18,0x30,0xFE,0x60,0xC0,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x06,0x1E,0x7E,0xFE,0x7E,0x1E,0x06,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0xC0,0xF0,0xFC,0xFE,0xFC,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, //  0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // 0x1A 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x06,0x36,0x66,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, // ! 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // " 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00, // # 0x00,0x10,0x10,0x7C,0xD6,0xD0,0xD0,0x7C,0x16,0x16,0xD6,0x7C,0x10,0x10,0x00,0x00, // $ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00, // % 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // & 0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00, // ( 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00, // ) 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, // * 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, // , 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, // . 0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00,0x00,0x00,0x00, // / 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // 0 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00, // 1 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00, // 2 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, // 3 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, // 4 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, // 5 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // 6 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, // 7 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // 8 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00, // 9 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, // : 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, // ; 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00, // < 0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // = 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00, // > 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, // ? 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00, // @ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // A 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00, // B 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00, // C 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00, // D 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, // E 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, // F 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00, // G 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // H 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // I 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, // J 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, // K 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, // L 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // M 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // N 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // O 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, // P 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00, // Q 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, // R 0x00,0x00,0x7C,0xC6,0xC6,0x64,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // S 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // T 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // U 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00, // V 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00, // W 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00, // X 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Y 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00, // Z 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00, // [ 0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,0x00, // \ . 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00, // ] 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, // _ 0x00,0x30,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ` 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // a 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00, // b 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // c 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // d 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // e 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, // f 0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00, // g 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, // h 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // i 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // j 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00, // k 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // l 0x00,0x00,0x00,0x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0x00,0x00,0x00,0x00, // m 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, // n 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // o 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, // p 0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00, // q 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, // r 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00, // s 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00, // t 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // u 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, // v 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00, // w 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, // x 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00, // y 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, // z 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00, // { 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, // | 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, // } 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 0x00,0x66,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, //  0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // € 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ‚ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ƒ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // „ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // … 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // † 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // ‡ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ˆ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ‰ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Š 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ‹ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // Œ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // Ž 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, // 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ‘ 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ’ 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6F,0x60,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // “ 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // ” 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // • 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // – 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6F,0x60,0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // — 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ˜ 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEC,0x0C,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ™ 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // š 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // › 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0xEC,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // œ 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEC,0x0C,0xEC,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xEF,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // ž 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEF,0x00,0xEF,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C, // Ÿ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xFE,0x00,0x00,0x00,0x00, //   0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00, // ¡ 0x00,0x00,0x00,0x00,0x10,0x7C,0xD6,0xD0,0xD0,0xD0,0xD6,0x7C,0x10,0x00,0x00,0x00, // ¢ 0x00,0x00,0x38,0x6C,0x60,0x60,0xF0,0x60,0x60,0x66,0xF6,0x6C,0x00,0x00,0x00,0x00, // £ 0x00,0x00,0x00,0x00,0xC6,0x7C,0x6C,0x6C,0x7C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00, // ¤ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00, // ¥ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, // ¦ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00, // § 0x00,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ¨ 0x00,0x00,0x3C,0x42,0x99,0xA5,0xA1,0xA5,0x99,0x42,0x3C,0x00,0x00,0x00,0x00,0x00, // © 0x00,0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ª 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00, // « 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, // ¬ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ­ 0x00,0x00,0x3C,0x42,0xB9,0xA5,0xB9,0xA5,0xA5,0x42,0x3C,0x00,0x00,0x00,0x00,0x00, // ® 0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ¯ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ° 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x7E,0x00,0x00,0x00,0x00, // ± 0x38,0x6C,0x18,0x30,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ² 0x38,0x6C,0x18,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ³ 0x00,0x18,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ´ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xF6,0xC0,0xC0,0xC0,0x00, // µ 0x00,0x00,0x7F,0xD6,0xD6,0x76,0x36,0x36,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x00, // ¶ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // · 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x6C,0x38,0x00, // ¸ 0x30,0x70,0x30,0x30,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ¹ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // º 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00, // » 0x00,0x60,0xE0,0x60,0x66,0x0C,0x18,0x30,0x66,0xCE,0x1A,0x3F,0x06,0x06,0x00,0x00, // ¼ 0x00,0x60,0xE0,0x60,0x66,0x0C,0x18,0x30,0x6E,0xDB,0x06,0x0C,0x1F,0x00,0x00,0x00, // ½ 0x70,0xD8,0x30,0xD8,0x76,0x0C,0x18,0x30,0x66,0xCE,0x1A,0x3F,0x06,0x06,0x00,0x00, // ¾ 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x30,0x60,0xC6,0xC6,0x7C,0x00,0x00, // ¿ 0x60,0x30,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // À 0x0C,0x18,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // Á 0x10,0x38,0x6C,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, //  0x76,0xDC,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // à 0x00,0x6C,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // Ä 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // Å 0x00,0x00,0x3E,0x78,0xD8,0xD8,0xFC,0xD8,0xD8,0xD8,0xD8,0xDE,0x00,0x00,0x00,0x00, // Æ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x66,0x3C,0x00, // Ç 0x60,0x30,0x00,0xFE,0x66,0x60,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, // È 0x0C,0x18,0x00,0xFE,0x66,0x60,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, // É 0x10,0x38,0x6C,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, // Ê 0x00,0x6C,0x00,0xFE,0x66,0x60,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, // Ë 0x60,0x30,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Ì 0x06,0x0C,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Í 0x18,0x3C,0x66,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Î 0x00,0x66,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Ï 0x00,0x00,0xF8,0x6C,0x66,0x66,0xF6,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00, // Ð 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, // Ñ 0x60,0x30,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ò 0x0C,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ó 0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ô 0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Õ 0x00,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ö 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, // × 0x00,0x00,0x7E,0xC6,0xCE,0xCE,0xDE,0xF6,0xE6,0xE6,0xC6,0xFC,0x00,0x00,0x00,0x00, // Ø 0x60,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ù 0x0C,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ú 0x10,0x38,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Û 0x00,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // Ü 0x06,0x0C,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // Ý 0x00,0x00,0xF0,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00, // Þ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xCC,0xC6,0xC6,0xC6,0xD6,0xDC,0x80,0x00,0x00,0x00, // ß 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // à 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // á 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // â 0x00,0x00,0x76,0xDC,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // ã 0x00,0x00,0x00,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // ä 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // å 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0x1B,0x7F,0xD8,0xDB,0x7E,0x00,0x00,0x00,0x00, // æ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x6C,0x38,0x00, // ç 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // è 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // é 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // ê 0x00,0x00,0x00,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, // ë 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // ì 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // í 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // î 0x00,0x00,0x00,0x6C,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, // ï 0x00,0x78,0x30,0x78,0x0C,0x7E,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // ð 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, // ñ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // ò 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // ó 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // ô 0x00,0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // õ 0x00,0x00,0x00,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, // ö 0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // ÷ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCE,0xDE,0xFE,0xF6,0xE6,0xFC,0x00,0x00,0x00,0x00, // ø 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // ù 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // ú 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // û 0x00,0x00,0x00,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, // ü 0x00,0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00, // ý 0x00,0x00,0xF0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,0x00, // þ 0x00,0x00,0x00,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00 // 255 }; TScreenFont256 TScreenX11::font8x16={ 8,16,shapeFont8x16 }; TScreenFont256 TScreenX11::font10x20={ 10,20,shapeFont10x20 }; TScreenFont256 *TScreenX11::defaultFont=&font8x16; void TScreenX11::AdjustCursorImage() { if (cursorImage) XDestroyImage(cursorImage); cursorData=(char *)malloc(fontSz); cursorImage=XCreateImage(disp,visual,1,XYBitmap,0,cursorData,fontW,fontH,8,0); cursorImage->byte_order=cursorImage->bitmap_bit_order=MSBFirst; } /************************** Experimental code for testing should be removed or at least made better */ static TVFontCollection *uF; static int firstGlyph, lastGlyph, numGlyphs; static XImage **unicodeGlyphs; static TVPartitionTree556 *u2c; static uchar *glyphs; static const char *tryUnicodeFont=NULL; static Font x11Font; static int x11FontOffset; static int useX11Font=0; static const char *DataPaths[]= { "/usr/share/rhtvision", "/usr/local/share/rhtvision", "/usr/share/setedit", "/usr/local/share/setedit", 0 }; static void ConcatUpto(char *d, const char *o1, const char *o2, const char *o3, int size) { int i=0; while (iGetError()) {// Get the information for all the available glyphs glyphs=uF->GetFontFull(fontW,fontH,firstGlyph,lastGlyph); if (glyphs) {// Create a table to hold all the XImage pointers numGlyphs=lastGlyph-firstGlyph+1; unicodeGlyphs=new XImage *[numGlyphs]; memset(unicodeGlyphs,0,sizeof(XImage *)*numGlyphs); // Create a TVPartitionTree556 to convert Unicode into internal code u2c=new TVPartitionTree556(); int i; for (i=0; i=firstGlyph && TVCodePage::InternalMap[i].code<=lastGlyph) u2c->add(TVCodePage::InternalMap[i].unicode,TVCodePage::InternalMap[i].code); drawingMode=unicode16; } /*else printf("Error al obtener la font (%d,%d)\n",fontW,fontH);*/ } /*else printf("Error al cargar la font\n");*/ } inline uint16 TScreenX11::unicode2index(uint16 unicode) { uint16 code=u2c->isearch(unicode); //printf("D U+%04X -> %d |",aChar,code); if (code==0xFFFF) { code=0; // This should be the "unknown" //printf("U+%04X|",aChar); } else code-=firstGlyph; return code; } inline void TScreenX11::checkUnicodeGlyph(uint16 code) { if (!unicodeGlyphs[code]) {// Not yet created, create it char *data=(char *)malloc(fontSz); memcpy(data,glyphs+code*fontSz,fontSz); /* Create a BitMap Image with this data */ unicodeGlyphs[code]=XCreateImage(disp,visual,1,XYBitmap,0,data,fontW,fontH,8,0); /* Set the bit order, this is faster */ unicodeGlyphs[code]->byte_order=unicodeGlyphs[code]->bitmap_bit_order=MSBFirst; } } inline void TScreenX11::drawCharU16(GC gc, unsigned x, unsigned y, uint16 aChar) { // Find the internal code and convert it into an index uint16 code=unicode2index(aChar); // Find the XImage checkUnicodeGlyph(code); XPutImage(disp,mainWin,gc,unicodeGlyphs[code],0,0,x,y,fontW,fontH); } void TScreenX11::setCharactersU16(unsigned offset, ushort *values, unsigned count) { SEMAPHORE_ON; unsigned x,y; x=(offset%maxX)*fontW; y=(offset/maxX)*fontH; uint16 *b=(uint16 *)values,newChar,newAttr; uint16 *sb=screenBuffer+offset*2; unsigned oldAttr=0x10000; UnDrawCursor(); while (count--) { newChar=b[charPos]; newAttr=b[attrPos]; if (newChar!=sb[charPos] || newAttr!=sb[attrPos]) { sb[charPos]=newChar; sb[attrPos]=newAttr; if (newAttr!=oldAttr) { XSetBgFg(newAttr); oldAttr=newAttr; } drawCharU16(gc,x,y,newChar); } x+=fontW; b+=2; sb+=2; } DrawCursor(); XFlush(disp); SEMAPHORE_OFF; } void TScreenX11::setCharacterU16(unsigned offset, uint32 value) { SEMAPHORE_ON; uint16 newChar=value; uint16 newAttr=value>>16; offset*=2; screenBuffer[offset]=newChar; screenBuffer[offset+1]=newAttr; unsigned x,y; x=(offset%maxX)*fontW; y=(offset/maxX)*fontH; XSetBgFg(newAttr); UnDrawCursor(); drawCharU16(gc,x,y,newChar); DrawCursor(); XFlush(disp); SEMAPHORE_OFF; } /***************************************************************************** The following members are used to draw Unicode16 with X11 fonts. *****************************************************************************/ void TScreenX11::writeLineX11U16(int x, int y, int w, void *str, unsigned color) { if (!w) return; // Nothing to do SEMAPHORE_ON; XSetBgFg(color); XChar2b *s=(XChar2b *)str; #ifndef TV_BIG_ENDIAN // Lamentably X11 needs values in big endian style :-( AllocLocalStr(aux,w*2); s=(XChar2b *)aux; uchar *ori=(uchar *)str; int i; for (i=0; i=0) { writeLineX11U16(x,y,len,tmp,last); dst=tmp; x+=len; len=0; } last=color; } *dst++=letra; values+=2; len++; sb+=2; } writeLineX11U16(x,y,len,tmp,color); SEMAPHORE_OFF; } /******************* End of experimental code for testing should be removed */ // Look for one font in the specified foundry and family with the specified // height (in pixels) and a specified width (+/- 1 of tolerance). // The font must have "c" spacing and slant must be regular (not italic). // The encoding should be unicode. char *TScreenX11::SearchX11Font(const char *foundry, const char *family, int w, int h) { AllocLocalStr(pattern,strlen(foundry)+strlen(family)+64); char *ret=NULL; int cant; XFontStruct *info; sprintf(pattern,"-%s-%s-*-r-*-*-%d-*-*-*-c-*-iso10646-*",foundry,family,h); char **list=XListFontsWithInfo(disp,pattern,400,&cant,&info); printf("matchs: %d\n",cant); if (list) { char *oneLess,*oneMore,*exact; oneLess=oneMore=exact=NULL; int i=0; while (!exact && ifid; #if 0 x11FontOffset=fontInfo->max_bounds.ascent; fontW=fontInfo->max_bounds.width; fontH=x11FontOffset+fontInfo->max_bounds.descent; #else x11FontOffset=fontInfo->ascent; fontW=fontInfo->max_bounds.width; fontH=x11FontOffset+fontInfo->descent; #endif printf("Font size: %dx%d\n",fontW,fontH); printf("as: %d de: %d\n",fontInfo->max_bounds.ascent,fontInfo->max_bounds.descent); printf("2: as: %d de: %d\n",fontInfo->ascent,fontInfo->descent); } DeleteArray(x11FontName); } } if (drawingMode!=unicode16) {// Use our fonts but encoded using Unicode tryUnicodeFont=optSearch("UnicodeFont"); LoadFontAsUnicode(); } } if (drawingMode!=unicode16) {// Unicode16 not requested or just failed // Do the work for internal code page fonts if (fontW==10 || fontH==20) defaultFont=&font10x20; else defaultFont=&font8x16; freeFontData=1; if (!frCB || !(useFont=frCB(0,fontW,fontH))) { useFont=defaultFont; freeFontData=0; } fontW=useFont->w; fontH=useFont->h; fontWb=(useFont->w+7)/8; fontSz=fontWb*fontH; fontData=useFont->data; aux=0; if (frCB && optSearch("LoadSecondaryFont",aux) && aux) secFont=frCB(1,fontW,fontH); } if (0) { printf("Drawing mode: %s\n",drawingMode==unicode16 ? "Unicode 16" : "Code Page"); if (useX11Font) printf("Using X11 fonts\n"); } TDisplayX11::Init(); TScreen::clearScreen=clearScreen; if (drawingMode==unicode16) { if (useX11Font) { //TScreen::setCharacter=setCharacterU16; Use Default TScreen::setCharacters=setCharactersX11U16; writeLine=writeLineX11U16; } else { TScreen::setCharacter=setCharacterU16; TScreen::setCharacters=setCharactersU16; writeLine=writeLineU16; } redrawBuf=redrawBufU16; } else { TScreen::setCharacter=setCharacter; TScreen::setCharacters=setCharacters; writeLine=writeLineCP; redrawBuf=redrawBufCP; } TScreen::System_p=System; TScreen::setWindowTitle=setWindowTitle; TScreen::getWindowTitle=getWindowTitle; TScreen::setDisPaletteColors=SetDisPaletteColors; TScreen::getFontGeometry=GetFontGeometry; TScreen::getFontGeometryRange=GetFontGeometryRange; if (drawingMode==codepage) { TScreen::setFont_p=SetFont; TScreen::restoreFonts=RestoreFonts; } TScreen::setCrtModeRes_p=SetCrtModeRes; TDisplay::beep=Beep; TVX11Clipboard::Init(); TGKeyX11::Init(); THWMouseX11::Init(); /* Initialize common variables */ cShapeFrom=fontH*875/1000; cShapeTo=fontH; setCrtData(); startupCursor=cursorLines; startupMode=screenMode; if (drawingMode==unicode16) screenBuffer=new uint16[screenWidth*screenHeight*2]; else screenBuffer=new uint16[screenWidth*screenHeight]; /* Get screen and graphic context */ screen=DefaultScreen(disp); gc=DefaultGC(disp,screen); visual=DefaultVisual(disp,screen); if (useX11Font) XSetFont(disp,gc,x11Font); if (drawingMode==codepage) { /* Create what we'll use as font */ CreateXImageFont(0,fontData,fontW,fontH); if (freeFontData) {/* Provided by the call back */ DeleteArray(useFont->data); delete useFont; } if (secFont) { CreateXImageFont(1,secFont->data,fontW,fontH); DeleteArray(secFont->data); delete secFont; } } /* Create the cursor image */ AdjustCursorImage(); /* Set the locales */ if (setlocale(LC_ALL,"")==NULL) fprintf(stderr,"Error: setlocale()!\n"); /* Create a simple window */ rootWin=RootWindow(disp,screen); mainWin=XCreateSimpleWindow(disp,rootWin, 0,0, /* win position */ maxX*fontW,maxY*fontH, /* win size */ 0, /* frame width */ BlackPixel(disp,screen), /* Border color */ BlackPixel(disp,screen)); /* Background */ /* This is useful if we use subwindows. hints.flags=InputHint; hints.input=True; XSetWMHints(disp,mainWin,&hints);*/ /* This is how we provide a title for the window. If the application wants it should call setWindowTitle. XTextProperty name; char *s="Test"; XStringListToTextProperty(&s,1,&name);*/ classHint->res_name="tvapp"; /* Take resources for tvapp */ classHint->res_class="XTVApp"; /* X Turbo Vision Application */ /* Size hints are just hints, not all WM take care about them */ sizeHints->flags=PResizeInc | PMinSize | PBaseSize; /* Fonts increments */ sizeHints->width_inc =fontW; sizeHints->height_inc=fontH; sizeHints->min_width =fontW*40; sizeHints->min_height=fontH*20; sizeHints->base_width=sizeHints->base_height=0; XSetWMProperties(disp,mainWin, NULL, /* Visible title, i.e. &name */ NULL, /* Icon title, i.e. &name */ NULL,0, /* Command line */ sizeHints, /* Normal size hints, resize increments */ NULL, /* Window manager hints, nothing (i.e. icon) */ classHint); /* Resource name and class of window */ /* This is needed to release the memory used for the title XFree((char *)name.value);*/ /* Ask to be notified when they kill the window */ theProtocols=XInternAtom(disp,"WM_DELETE_WINDOW",True); XSetWMProtocols(disp,mainWin,&theProtocols,1); /* Initialize the Input Context for international support */ if ((xim=XOpenIM(disp,NULL,NULL,NULL))==NULL) { printf("Error: XOpenIM()!\n"); exit(0); } xic=XCreateIC(xim,XNInputStyle,XIMPreeditNothing | XIMStatusNothing, XNClientWindow,mainWin,NULL); if (xic==NULL) { printf("Error: XCreateIC()!\n"); XCloseIM(xim); exit(0); } // This prints which locale was detected for the X Input Methode. // It should have a very big impact in the way input is interpreted, but I // couldn't verify it. I'm trying using japanese ;-) //printf("Locale: %s\n",XLocaleOfIM(xim)); /* We will accept the Input Context default events ... */ unsigned long mask, fevent; XGetICValues(xic,XNFilterEvents,&fevent,NULL); /* plus these */ mask=ExposureMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask/*PointerMotionMask*/; XSelectInput(disp,mainWin,mask|fevent); /* OK, now put the window on the display */ XMapWindow(disp,mainWin); /* Map the VGA Text BIOS colors */ cMap=DefaultColormap(disp,screen); XColor query; TScreenColor *pal=parseUserPalette() ? UserStartPalette : PC_BIOSPalette; for (int col=0; col<16; col++) { query.red =pal[col].R*256; query.green=pal[col].G*256; query.blue =pal[col].B*256; query.flags= ~0; XAllocColor(disp,cMap,&query); colorMap[col]=query.pixel; } memcpy(ActualPalette,pal,sizeof(ActualPalette)); /* A graphics context for the text cursor */ cursorGC=XCreateGC(disp,mainWin,0,0); if (useX11Font) /* Select the same font for this context */ XSetFont(disp,cursorGC,x11Font); /* Create the cursor timer */ gettimeofday(&refCursorTime,0); XSetBackground(disp,gc,colorMap[0]); XSetForeground(disp,gc,colorMap[7]); clearScreen(); // Setup the driver properties. // Our code page isn't fixed. // We can change the palette. // A redraw is needed after setting the palette. But currently is in the color setting. // We can set the fonts and even change their size. flags0=CanSetPalette | CanReadPalette | CodePageVar | CursorShapes /*| PalNeedsRedraw*/ | CanSetVideoSize | NoUserScreen; if (drawingMode==codepage) // We can't change the font when using Unicode16 mode flags0|=CanSetBFont | CanSetSBFont | CanSetFontSize; if (createCursors()) TScreen::showBusyState=ShowBusyState; START_UPDATE_THREAD; } void TScreenX11::CreateXImageFont(int which, uchar *font, unsigned w, unsigned h) { char *data; int i,bytesLine,bytesShape; bytesLine=(w+7)/8; bytesShape=bytesLine*h; XImage **f=which ? ximgSecFont : ximgFont; for (i=0; i<256; font+=bytesShape, i++) {/* Load the shape */ data=(char *)malloc(bytesShape); memcpy(data,font,bytesShape); /* Create a BitMap Image with this data */ f[i]=XCreateImage(disp,visual,1,XYBitmap,0,data,w,h,8,0); /* Set the bit order, this is faster */ f[i]->byte_order=f[i]->bitmap_bit_order=MSBFirst; } if (which) useSecondaryFont=1; } void TScreenX11::DestroyXImageFont(int which) { int i; if (which) { if (useSecondaryFont) { for (i=0; i<256; i++) if (ximgSecFont[i]) XDestroyImage(ximgSecFont[i]); useSecondaryFont=0; } } else for (i=0; i<256; i++) if (ximgFont[i]) XDestroyImage(ximgFont[i]); } int TScreenX11::setWindowTitle(const char *aName) { SEMAPHORE_ON; XTextProperty name; char *s=(char *)aName; XStringListToTextProperty(&s,1,&name); XSetWMName(disp,mainWin,&name); XFree((char *)name.value); SEMAPHORE_OFF; return 1; } const char *TScreenX11::getWindowTitle(void) { SEMAPHORE_ON; XTextProperty name; const char *ret=NULL; if (XGetWMName(disp,mainWin,&name)) { char *s=newStr((char *)name.value); XFree((char *)name.value); ret=s; } SEMAPHORE_OFF; return ret; } int TScreenX11::SetDisPaletteColors(int from, int number, TScreenColor *colors) { SEMAPHORE_ON; XColor query; int i; ulong newMap[16]; for (i=0; i0) {// If we allocated at least one color: // Deallocated the old colors XFreeColors(disp,cMap,colorMap+from,i,0); // Copy the new ones memcpy(colorMap+from,newMap,sizeof(ulong)*i); // Force a redraw. This is not needed for 8 bpp. // Is just a dirty hack. FullRedraw(); } SEMAPHORE_OFF; return i; } void TScreenX11::FullRedraw() { unsigned y,off; for (y=0,off=0; y<(unsigned)maxY; y++,off+=maxX) redrawBuf(0,y,maxX,off); } /***************************************************************************** Routines to create a blinking cursor *****************************************************************************/ void TScreenX11::UnDrawCursor() { if (!cursorInScreen) return; SEMAPHORE_ON; unsigned offset=cursorX+cursorY*maxX; if (drawingMode==codepage) { uchar *theChar=(uchar *)(screenBuffer+offset); uchar newChar=theChar[charPos]; uchar newAttr=theChar[attrPos]; XSetBgFgC(newAttr); drawChar(cursorGC,cursorX*fontW,cursorY*fontH,newChar,newAttr); } else { if (useX11Font) { uint16 *buf=screenBuffer+offset*2; writeLineX11U16(cursorX,cursorY,1,buf+charPos,buf[attrPos]); } else { uint16 *buf=screenBuffer+offset*2; uchar newChar=buf[charPos]; uchar newAttr=buf[attrPos]; XSetBgFgC(newAttr); drawCharU16(cursorGC,cursorX*fontW,cursorY*fontH,newChar); } } cursorInScreen=0; SEMAPHORE_OFF; return; } void TScreenX11::XSetBgFgC(uint16 attr) { int bg=attr>>4; int fg=attr & 0xF; XSetBackground(disp,cursorGC,colorMap[bg]); XSetForeground(disp,cursorGC,colorMap[fg]); } void TScreenX11::XSetBgFg(uint16 attr) { int bg=attr>>4; int fg=attr & 0xF; XSetBackground(disp,gc,colorMap[bg]); XSetForeground(disp,gc,colorMap[fg]); } void TScreenX11::DrawCursor() { //fprintf(stderr,"DrawCursor: cursorEnabled=%d\n",cursorEnabled); if (cursorEnabled) { SEMAPHORE_ON; cursorInScreen=!cursorInScreen; /* Create an image with the character under cursor */ unsigned offset=cursorX+cursorY*maxX; int attr; if (drawingMode==codepage) { uchar *theChar=(uchar *)(screenBuffer+offset); attr=theChar[attrPos]; memcpy(cursorData,useSecondaryFont && (attr & 8) ? ximgSecFont[theChar[charPos]]->data : ximgFont[theChar[charPos]]->data,fontSz); } else { uint16 *buf=screenBuffer+offset*2; attr=buf[attrPos]; if (useX11Font) { writeLineX11U16(cursorX,cursorY,1,buf,attr); if (cursorInScreen) { XSetBgFgC(attr); int y; for (y=cShapeFrom; y0 || curCursorTime.tv_usec>cursorDelay) { DrawCursor(); gettimeofday(&refCursorTime,0); } while (1) { /* Check if we have generic events in the queue */ if (XCheckMaskEvent(disp,~(aMouseEvent|aKeyEvent),&event)!=True) { /* Process message that doesn't have mask */ if (XCheckTypedEvent(disp,ClientMessage,&event)==True) { if ((Atom)event.xclient.data.l[0]==theProtocols) { TGKeyX11::sendQuit=1; } } else if (XCheckTypedEvent(disp,SelectionRequest,&event)==True) {// Another application wants the content of our clipboard XEvent respond; XSelectionRequestEvent *req=&(event.xselectionrequest); if (req->target==XA_STRING && TVX11Clipboard::buffer) { XChangeProperty(disp,req->requestor,req->property,XA_STRING, 8/*bits*/,PropModeReplace, (const uchar *)TVX11Clipboard::buffer, TVX11Clipboard::length); respond.xselection.property=req->property; } else // Strings only please respond.xselection.property= None; respond.xselection.type=SelectionNotify; respond.xselection.display=req->display; respond.xselection.requestor=req->requestor; respond.xselection.selection=req->selection; respond.xselection.target=req->target; respond.xselection.time=req->time; XSendEvent(disp,req->requestor,0,0,&respond); XFlush(disp); } else if (XCheckTypedEvent(disp,SelectionNotify,&event)==True) { TVX11Clipboard::waiting=0; TVX11Clipboard::property=event.xselection.property; } SEMAPHORE_OFF; return; } /* Not sure if needed, but documentation says it helps if the event should be redirected to another window */ if (XFilterEvent(&event,0)==True) continue; switch (event.type) { case Expose: { if (windowSizeChanged) // Ignore them until the application gets break; // notified about the new size /*printf("Expose: %d %d %d %d\n",event.xexpose.x,event.xexpose.y, event.xexpose.width,event.xexpose.height);*/ int x=event.xexpose.x/fontW; int y=event.xexpose.y/fontH; unsigned src=y*maxX+x; newPW=event.xexpose.x+event.xexpose.width; int x2=newPW/fontW; if (newPW%fontW) x2++; if (x2>=maxX) x2=maxX; newPW=event.xexpose.y+event.xexpose.height; int y2=newPW/fontH; if (newPW%fontH) y2++; if (y2>=maxY) y2=maxY; int w=x2-x; int h=y2-y; /*printf("x1,y1 %d,%d x2,y2 %d,%d w,h %d,%d\n",x,y,x2,y2,w,h);*/ while (h) { redrawBuf(x,y,w,src); src+=maxX; y++; h--; } XFlush(disp); } break; case FocusIn: //printf("Focus in\n"); if (xic) XSetICFocus(xic); EnableCursor(); break; case FocusOut: //printf("Focus out\n"); if (xic) XUnsetICFocus(xic); if (hideCursorWhenNoFocus) DisableCursor(); break; case ConfigureNotify: /* Currently masked if (event.xresizerequest.window!=mainWin) break;*/ lastW=windowSizeChanged ? newX : maxX; lastH=windowSizeChanged ? newY : maxY; newX=event.xconfigure.width /fontW; newY=event.xconfigure.height/fontH; /* Minimal size */ if (newX<40) newX=40; if (newY<20) newY=20; /* If size changed indicate it */ if ((newX!=(int)lastW) || (newY!=(int)lastH)) windowSizeChanged=1; /* KDE 3.1 alpha maximize doesn't use cell sizes and our resize confuses KDE. */ if (dontResizeToCells) break; /* Force the window to have a size in chars */ newPW=fontW*newX; newPH=fontH*newY; if ((unsigned)event.xconfigure.width==newPW && (unsigned)event.xconfigure.height==newPH) break; //printf("Nuevo: %d,%d (%d,%d)\n",newX,newY,lastW,lastH); XResizeWindow(disp,mainWin,newPW,newPH); //printf("Nuevo 2: %d,%d\n",newX,newY); break; } } SEMAPHORE_OFF; } void TScreenX11::writeLineCP(int x, int y, int w, void *s, unsigned color) { if (w<=0) return; // Nothing to do SEMAPHORE_ON; XSetBgFg(color); x*=fontW; y*=fontH; UnDrawCursor(); XImage **f=(useSecondaryFont && (color & 8)) ? ximgSecFont : ximgFont; uchar *str=(uchar *)s; while (w--) { XPutImage(disp,mainWin,gc,f[*str],0,0,x,y,fontW,fontH); str++; x+=fontW; } SEMAPHORE_OFF; } void TScreenX11::redrawBufCP(int x, int y, unsigned w, unsigned off) { int len = 0; /* longitud a escribir */ int letra = 0; int color = 0; int last = -1; AllocLocalStr(tmp,w*sizeof(char)); uchar *dst = (uchar *)tmp; uchar *b=(uchar *)(screenBuffer+off); if (y>=maxY) { printf("Y=%d\n",y); return; } while (w--) { letra=b[charPos]; color=b[attrPos]; if (color!=last) { if (last>=0) { writeLine(x,y,len,tmp,last); // Print last same color block dst=(uchar *)tmp; x+=len; len=0; } last=color; } *dst++=letra; b+=2; len++; } writeLine(x,y,len,tmp,color); // Print last block } void TScreenX11::writeLineU16(int x, int y, int w, void *s, unsigned color) { if (w<=0) return; // Nothing to do SEMAPHORE_ON; XSetBgFg(color); x*=fontW; y*=fontH; UnDrawCursor(); uint16 *str=(uint16 *)s; while (w--) { uint16 code=unicode2index(*str); checkUnicodeGlyph(code); XPutImage(disp,mainWin,gc,unicodeGlyphs[code],0,0,x,y,fontW,fontH); str++; x+=fontW; } SEMAPHORE_OFF; } void TScreenX11::redrawBufU16(int x, int y, unsigned w, unsigned off) { int len = 0; /* longitud a escribir */ int letra = 0; int color = 0; int last = -1; AllocLocalUShort(tmp,w*2); uint16 *dst=tmp; uint16 *b=screenBuffer+off*2; while (w--) { letra=b[charPos]; color=b[attrPos]; if (color!=last) { if (last>=0) { writeLine(x,y,len,tmp,last); dst=tmp; x+=len; len=0; } last=color; } *dst++=letra; b+=2; len++; } writeLine(x,y,len,tmp,color); } TScreen *TV_XDriverCheck() { TScreenX11 *drv=new TScreenX11(); if (!TScreen::initialized) { delete drv; return 0; } return drv; } /***************************************************************************** X11 clipboard routines This clipboard implementation is heavily based on the X Windows Copy-Paste mini HOWTO by Stelios Xathakis, *****************************************************************************/ char *TVX11Clipboard::buffer=NULL; unsigned TVX11Clipboard::length=0; int TVX11Clipboard::waiting=0; Atom TVX11Clipboard::property=0; const char *TVX11Clipboard::x11NameError[]= { NULL, __("No available selection"), __("Unsupported data type"), __("No data"), __("X11 error"), __("Another application holds the clipboard") }; void TVX11Clipboard::Init() { TVOSClipboard::copy=copy; TVOSClipboard::paste=paste; TVOSClipboard::destroy=destroy; TVOSClipboard::available=2; // We have 2 clipboards TVOSClipboard::name="X11"; TVOSClipboard::errors=x11clipErrors; TVOSClipboard::nameErrors=x11NameError; } /**[txh]******************************************************************** Description: Copies the content of the buffer to the X11 clipboard. The id value selects which clipboard we will use. As current recommendations says applications should use XA_CLIPBOARD that's id==0. For id==1 we use the XA_PRIMARY mechanism, this is the one used for "selections".@* The string doesn't have to be null terminated, we ever copy len+1 bytes adding a 0 at the end. Return: !=0 if ok. ***************************************************************************/ int TVX11Clipboard::copy(int id, const char *b, unsigned len) { if (id>1) return 0; Atom clip=id==0 ? XA_CLIPBOARD(TScreenX11::disp) : XA_PRIMARY; // First create a copy, in X11 the clipboard is held by the application if (buffer) delete[] buffer; length=len; buffer=new char[length+1]; memcpy(buffer,b,len); buffer[len]=0; //printf("Copiando: `%s' %d\n",buffer,length); SEMAPHORE_ON; XSetSelectionOwner(TScreenX11::disp,clip,TScreenX11::mainWin,CurrentTime); XFlush(TScreenX11::disp); int ret=0; if (XGetSelectionOwner(TScreenX11::disp,clip)==TScreenX11::mainWin) ret=1; else TVOSClipboard::error=x11clipAnother; SEMAPHORE_OFF; // The rest is done by TScreenX11 return ret; } /**[txh]******************************************************************** Description: Returns a newly allocated buffer containing the contents of the indicated clipboard. @x{copy}.@* The buffer should be deallocated with delete[]. The string is NULL terminated because we ensure it.@* The returned length doesn't include the EOL. Return: NULL if error, a new buffer if ok. ***************************************************************************/ char *TVX11Clipboard::paste(int id, unsigned &lenRet) { if (id>1) return NULL; SEMAPHORE_ON; Atom clip=id==0 ? XA_CLIPBOARD(TScreenX11::disp) : XA_PRIMARY; Window owner; int format, result; unsigned long len, bytes, dummy; unsigned char *data; owner=XGetSelectionOwner(TScreenX11::disp,clip); if (owner==None) { TVOSClipboard::error=x11clipNoSelection; SEMAPHORE_OFF; return NULL; } // What a hell should I use as property here? I use XA_STRING because it was // used by the example. BTW the example failed with Eterm. XConvertSelection(TScreenX11::disp,clip,XA_STRING,XA_STRING,TScreenX11::mainWin, CurrentTime); XFlush(TScreenX11::disp); SEMAPHORE_OFF; waiting=1; while (waiting) if (!IS_SECOND_THREAD_ON) TScreenX11::ProcessGenericEvents(); if (property!=XA_STRING) { TVOSClipboard::error=x11clipWrongType; return NULL; } // Check the size SEMAPHORE_ON; Atom type; XGetWindowProperty(TScreenX11::disp,TScreenX11::mainWin,XA_STRING,0,0,0, AnyPropertyType,&type,&format,&len,&bytes,&data); if (bytes<=0) { TVOSClipboard::error=x11clipNoData; SEMAPHORE_OFF; return NULL; } result=XGetWindowProperty(TScreenX11::disp,TScreenX11::mainWin,XA_STRING, 0,bytes,0,AnyPropertyType,&type,&format,&len, &dummy,&data); if (result!=Success) { XFree(data); TVOSClipboard::error=x11clipX11Error; SEMAPHORE_OFF; return NULL; } char *ret=new char[bytes+1]; memcpy(ret,data,bytes); ret[bytes]=0; XFree(data); lenRet=bytes; SEMAPHORE_OFF; //printf("Recibiendo: `%s' %ld\n",ret,bytes); return ret; } void TVX11Clipboard::destroy() { if (buffer) { delete[] buffer; buffer=0; } } /***************************************************************************** Fonts routines *****************************************************************************/ int TScreenX11::GetFontGeometry(unsigned &w, unsigned &h) { w=fontW; h=fontH; return 1; } int TScreenX11::GetFontGeometryRange(unsigned &wmin, unsigned &hmin, unsigned &wmax, unsigned &hmax) { wmin=foWmin; hmin=foHmin; wmax=foWmax; hmax=foHmax; return 1; } int TScreenX11::SetFont(int changeP, TScreenFont256 *fontP, int changeS, TScreenFont256 *fontS, int fontCP, int appCP) { if (!changeP && !changeS) return 1; // Check for restore fonts if (changeP && !fontP && ((!changeS && !useSecondaryFont) || (changeS && !fontS))) fontP=defaultFont; // Solve the sizes unsigned wP, hP, wS, hS; if (changeP) { if (fontP) { wP=fontP->w; hP=fontP->h; } else { wP=defaultFont->w; hP=defaultFont->h; } } else { wP=fontW; hP=fontH; } if (changeS) { if (fontS) { wS=fontS->w; hS=fontS->h; } else {// Disabled wS=wP; hS=hP; } } else { if (useSecondaryFont) { wS=fontW; hS=fontH; } else {// Disabled wS=wP; hS=hP; } } if (wP!=wS || hP!=hS) return 0; // Check if the size is in the range if (wPfoWmax || hPfoHmax) return 0; // Change the requested fonts SEMAPHORE_ON; if (changeP) { DestroyXImageFont(0); if (fontP && fontP->data) { CreateXImageFont(0,fontP->data,wP,hP); primaryFontChanged=1; } else { CreateXImageFont(0,defaultFont->data,wP,hP); primaryFontChanged=0; } } if (changeS) { DestroyXImageFont(1); if (fontS) CreateXImageFont(1,fontS->data,wP,hP); } // Change the code page if (changeP && fontCP!=-1) { if (appCP==-1) TVCodePage::SetScreenCodePage(fontCP); else TVCodePage::SetCodePage(appCP,fontCP,-1); } // Verify if we need to resize if (wP!=fontW || hP!=fontH) { DoResize(wP,hP); } else { FullRedraw(); } SEMAPHORE_OFF; return 1; } void TScreenX11::RestoreFonts() { SetFont(1,NULL,1,NULL,TVCodePage::ISOLatin1Linux,TVCodePage::ISOLatin1Linux); } void TScreenX11::DoResize(unsigned w, unsigned h) { SEMAPHORE_ON; UnDrawCursor(); if (w!=fontW || h!=fontH) { unsigned start=100*cShapeFrom/fontH; unsigned end =100*cShapeTo/fontH; fontW=w; fontWb=(w+7)/8; fontH=h; fontSz=fontWb*h; AdjustCursorImage(); /* Change the cursor shape */ SetCursorShape(start,end); /* Inform the WM about this change*/ sizeHints->width_inc =fontW; sizeHints->height_inc=fontH; sizeHints->min_width =fontW*40; sizeHints->min_height=fontH*20; XSetWMNormalHints(disp,mainWin,sizeHints); } /* Change the size */ XResizeWindow(disp,mainWin,maxX*fontW,maxY*fontH); /* Compute cursor position and draw it */ SetCursorPos(cursorX,cursorY); DrawCursor(); SEMAPHORE_OFF; } TScreenFont256 *TScreenX11::ChooseClosestFont(unsigned fW, unsigned fH) { TScreenFont256 *nFont=NULL; if (fW==8 || fH==16) nFont=&font8x16; else if (fW==10 || fH==20) nFont=&font10x20; else { unsigned target=fW*fH; int dif1=abs(8*16-target); int dif2=abs(10*20-target); if (dif1w; nH=nFont->h; if ((nW!=fontW || nH!=fontH) && useSecondaryFont) { if (frCB && (nsFont=frCB(1,nW,nH))) releaseSFont=1; } } SEMAPHORE_ON; if (nFont) { DestroyXImageFont(0); CreateXImageFont(0,nFont->data,nW,nH); if (resetFont) primaryFontChanged=0; if (releaseFont) { DeleteArray(nFont->data); delete nFont; } } if (useSecondaryFont) { DestroyXImageFont(1); if (nsFont) CreateXImageFont(1,nsFont->data,nW,nH); } // Should I check the size? maxX=w; maxY=h; delete[] screenBuffer; screenBuffer=new ushort[maxX*maxY]; memset(screenBuffer,0,maxX*maxY*sizeof(ushort)); DoResize(nW,nH); SEMAPHORE_OFF; return (nW==(unsigned)fW && nH==(unsigned)fH) ? 1 : 2; } /* Busy indicator by Roman Valyushenko */ /* These are the bitmaps I created. They show a pointer with watch near. Could be used to indicate some background computations. */ const int busyCursorWidth=28; const int busyCursorHeight=20; Cursor TScreenX11::busyCursor, TScreenX11::leftPtr; char TScreenX11::busyCursorMap[]= { 0xff, 0xff, 0xff, 0x1f, 0xfd, 0xff, 0xff, 0x1f, 0xf9, 0xff, 0xff, 0x1f, 0xf1, 0xff, 0xff, 0x1f, 0xe1, 0x7f, 0xc0, 0x1f, 0xc1, 0x7f, 0xc0, 0x1f, 0x81, 0x3f, 0x80, 0x1f, 0x01, 0x9f, 0x3b, 0x1f, 0x01, 0xce, 0x7b, 0x1e, 0xc1, 0xef, 0xfb, 0x1e, 0xc9, 0xef, 0xf1, 0x18, 0x9d, 0xef, 0xf1, 0x18, 0x9f, 0xef, 0xfe, 0x18, 0x3f, 0x6f, 0xff, 0x1e, 0x3f, 0xcf, 0x7f, 0x1e, 0xff, 0x9f, 0x3f, 0x1f, 0xff, 0x3f, 0x80, 0x1f, 0xff, 0x7f, 0xc0, 0x1f, 0xff, 0x7f, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0x1f }; char TScreenX11::busyCursorMask[]= { 0xfc, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x1f, 0xe0, 0x3f, 0x80, 0x1f, 0xc0, 0x3f, 0x80, 0x1f, 0x80, 0x3f, 0x80, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x10, 0x80, 0x07, 0x00, 0x10, 0x08, 0x07, 0x00, 0x10, 0x0c, 0x07, 0x00, 0x10, 0x1f, 0x06, 0x00, 0x10, 0x1f, 0x06, 0x00, 0x1c, 0x3f, 0x0f, 0x00, 0x1e, 0xff, 0x1f, 0x00, 0x1f, 0xff, 0x3f, 0x80, 0x1f, 0xff, 0x3f, 0x80, 0x1f, 0xff, 0x3f, 0x80, 0x1f }; /* This is the function which creates cursors. On success it return true, otherwise false */ Boolean TScreenX11::createCursors() { long useInternal=0; optSearch("InternalBusyCursor",useInternal); if (useInternal) { Pixmap busyCursorPixmap, busyCursorPixmapMask; busyCursorPixmap=XCreatePixmapFromBitmapData(disp,mainWin,(char*)&busyCursorMap, busyCursorWidth,busyCursorHeight, BlackPixel(disp,screen), WhitePixel(disp,screen),1); if (busyCursorPixmap==None) return False; busyCursorPixmapMask=XCreatePixmapFromBitmapData(disp,mainWin,(char*)&busyCursorMask, busyCursorWidth,busyCursorHeight, BlackPixel(disp,screen), WhitePixel(disp,screen),1); if (busyCursorPixmapMask==None) { XFreePixmap(disp,busyCursorPixmap); return False; } XColor busyCursorFg, busyCursorBg; Status status; status=XAllocNamedColor(disp,DefaultColormap(disp,DefaultScreen(disp)), "black",&busyCursorFg,&busyCursorFg); if (!status) { XFreePixmap(disp,busyCursorPixmap); XFreePixmap(disp,busyCursorPixmapMask); return False; } status=XAllocNamedColor(disp,DefaultColormap(disp,DefaultScreen(disp)), "white",&busyCursorBg,&busyCursorBg); if (!status) { XFreePixmap(disp,busyCursorPixmap); XFreePixmap(disp,busyCursorPixmapMask); return False; } busyCursor=XCreatePixmapCursor(disp,busyCursorPixmap,busyCursorPixmapMask, &busyCursorFg,&busyCursorBg,1,1); XFreePixmap(disp,busyCursorPixmap); XFreePixmap(disp,busyCursorPixmapMask); } else busyCursor=XCreateFontCursor(disp,XC_watch); leftPtr=XCreateFontCursor(disp,XC_left_ptr); return True; /* Success */ } /* This is the function to change the cursor. */ Boolean TScreenX11::ShowBusyState(Boolean busyState) { SEMAPHORE_ON; if (busyState) XDefineCursor(disp,mainWin,busyCursor); else XDefineCursor(disp,mainWin,leftPtr); XFlush(disp); /* Show it right now */ SEMAPHORE_OFF; return defaultShowBusyState(busyState); } void TScreenX11::Beep() { SEMAPHORE_ON; XBell(disp,50); SEMAPHORE_OFF; } /***************************************************************************** Update thread stuff: Problem: In X11 (and most GUI systems) the contents of the window aren't stored/cached. So when a window is not visible (exposed is the X11 term) its contents aren't stored anywhere. When the window (or a portion) becomes exposed X11 sends an expose event. If the application isn't collecting expose events, because is blocked waiting for a child completion or performing a long computation, the exposed portion of the window is filled with a black rectangle (this color is selected during TScreenX11 creation). This is very bad for applications like RHIDE where the debugger is blocked until the debuggee is stoped. It means that you most probably won't be able to see RHIDE's window content while the debuggee is running. Even when it isn't critical is ugly. The idea is to periodically collect the expose events even when the process is blocked. I (SET) implemented it using two different approaches: 1) POSIX threads. They seems to be poorly implemented in Linux (i.e. glibc 2.2.5 and 2.3.1). This solution is elegant but unstable, at least for SETEdit and RHIDE running in Debian GNU/Linux Woody and Sarge. 2) setitimer and SIGALRM. This is really simple and seems to be more stable. I keep both so people can experiment with both, each approachs have its advantes and disadvantages. *****************************************************************************/ #if USE_ALARM_FOR_THREAD /***************************************************************************** Update thread using the setitimer approach. This approach uses the timer alarm (SIGALRM for Linux and SIGPROF for Solaris, looks like Solaris didn't implement it properly). This mechanism is much more reliable than the POSIX thread mechanism, at least for Linux. The use of a signal ensures: 1) The main "thread" can't take the CPU while the signal is executing. And as the signal blocks itself by default it doesn't have to be reentrant. 2) A child process doesn't inherits the timers so there is no risk to inherit problems. Advantages: 1) The mutex implementation is trivial. 2) We don't need pthread library. Disadvantages: 1) The program can't use this alarm for itself. 2) Implementations of the alarm mechanism should be POSIX compliant. *****************************************************************************/ // Used to print a mark every 250 updates #define TIC 0 // Prints some debug info when the mechanism is dis/enabled #define DBG_ALM_STATE 0 int TVX11UpdateThread::running=0; int TVX11UpdateThread::initialized=0; const int refreshTime=10000; // 10 ms static sig_atomic_t mutex; static int updates=0; static volatile int safeToUnHook; void TVX11UpdateThread::UpdateThread(int signum) { // Here TIMER_ALARM signal is blocked and the process can take the CPU if (!mutex) {// No mutex, we can do our work. TScreenX11::ProcessGenericEvents(); } if (TIC) { updates++; if (updates>250) { printf("Tic (%d)\n",getpid()); updates=0; } } if (running) {// We still running, set the timer again microAlarm(refreshTime); } else safeToUnHook=1; } void TVX11UpdateThread::StartUpdateThread() { long aux; if (TScreen::optSearch("UseUpdateThread",aux) && aux==1) { if (DBG_ALM_STATE) printf("Using setitimer for the update stuff (PID=%d)\n",getpid()); mutex=0; initialized=1; running=1; safeToUnHook=0; // Trap the alarm signal struct sigaction s; s.sa_handler=UpdateThread; sigemptyset(&s.sa_mask); #if defined(SA_RESTART) s.sa_flags=SA_RESTART; #else s.sa_flags=0; #endif // SA_RESTART sigaction(TIMER_ALARM,&s,NULL); // Set the alarm microAlarm(refreshTime); } } void TVX11UpdateThread::microAlarm(unsigned int usec) { struct itimerval newV; newV.it_interval.tv_usec=0; newV.it_interval.tv_sec=0; newV.it_value.tv_usec=(long int)usec; newV.it_value.tv_sec=0; setitimer(ITIMER_USED,&newV,0); } void TVX11UpdateThread::SemaphoreOn() { mutex++; // We will never collide with the signal because the signal is atomic from // our point of view. } void TVX11UpdateThread::SemaphoreOff() { --mutex; if (mutex<0) printf("Oh no!!! mutex<0\n"); } int TVX11UpdateThread::CheckSecondThread() { return (initialized && running); } void TVX11UpdateThread::StopUpdateThread() { if (IS_SECOND_THREAD_ON) { if (DBG_ALM_STATE) printf("Stopping update thread for PID=%d\n",getpid()); running=0; while (!safeToUnHook); // Un-Trap the alarm signal struct sigaction s; s.sa_handler=SIG_IGN; sigemptyset(&s.sa_mask); #if defined(SA_RESTART) s.sa_flags=SA_RESTART; #else s.sa_flags=0; #endif // SA_RESTART sigaction(TIMER_ALARM,&s,NULL); } } #elif HAVE_LINUX_PTHREAD /************************************************************************** Update thread stuff This code is under test and for this reason must be enabled manually defining the UseUpdateThread configuration variable. Some important details: [glibc 2.2.5 also 2.3.1] * Linux threads are implemented using processes (clone kernel syscall). I think that they will never be really POSIX compliant if this mechanism is used. One major flaw is that getpid() will return a different value for each thread exposing the fake implementation. * Looks like exec can't be reliably called from a multithread program. It works perfectly for small and medium examples but does all kind of nasty things when called from big programs like SETEdit. Looking at the glibc code you can see system() implementation knows it and checks if we have "threads", in this case it first disables all async events. This is done with a macro and I couldn't find any function in glibc to do the same from my code. * According to POSIX when you do a fork the new process inherits all the threads and calling exec terminates all threads. In this way fork/exec work ok. In Linux implementation it doesn't happend. According to glibc docs: `pthread_kill_other_threads_np' is a non-portable LinuxThreads extension. It causes all threads in the program to terminate immediately, except the calling thread which proceeds normally. It is intended to be called just before a thread calls one of the `exec' functions, e.g. `execve'. ... According to POSIX 1003.1c, a successful `exec*' in one of the threads should automatically terminate all other threads in the program. This behavior is not yet implemented in LinuxThreads. Calling `pthread_kill_other_threads_np' before `exec*' achieves much of the same behavior, except that if `exec*' ultimately fails, then all other threads are already killed. But as threads aren't inherited you kill nothing or the parent threads :-( If you call it and then try to create a new thread it is created but your process dies with "Signal Real-time 0". * The first time you create a "thread" an auxiliar process is created. Looks like this process is the one in charge to coordinate the other processes that emulates threads. This should be transparent, but it isn't. If you fork/create a process group/system and then you kill the group then it kills your threads and the auxiliar process becomes a Zombie. Calling exec from big programs looks like you have chances to get a thread switch and then the exec tries to attach to the "thread" process. This confusion kills the thread, lets the child sleeping and the auxiliar process becomes a Zombie. I figure out that implementing POSIX threads is a complex task and that I could be doing wrong things, but is also obvious that LinuxThreads as implemented by glibc 2.2.5 is a nightmare. **************************************************************************/ // Linux implementation of POSIX threads // Here to avoid pulling the headers everywhere static pthread_t th; static pthread_mutex_t mutex; int TVX11UpdateThread::running=0; int TVX11UpdateThread::initialized=0; timeval TVX11UpdateThread::refWatchDog, TVX11UpdateThread::nowWatchDog; int TVX11UpdateThread::watchDogVal=1; void *TVX11UpdateThread::UpdateThread(void *) { // I tried it in the hope that could help to kill childs without affecting // this thread, but isn't enough. if (0) { sigset_t newMask; sigemptyset(&newMask); sigaddset(&newMask,SIGTERM); pthread_sigmask(SIG_BLOCK,&newMask,NULL); } running=1; while (running) { usleep(10); watchDogVal=0; TScreenX11::ProcessGenericEvents(); } return NULL; } void TVX11UpdateThread::SemaphoreOn() { if (initialized) pthread_mutex_lock(&mutex); } void TVX11UpdateThread::SemaphoreOff() { if (initialized) pthread_mutex_unlock(&mutex); } int TVX11UpdateThread::CheckSecondThread() { if (!initialized || !running) return 0; gettimeofday(&nowWatchDog,0); timeval aux=nowWatchDog; SubstractRef(nowWatchDog,refWatchDog); if (nowWatchDog.tv_sec>=1) { if (watchDogVal) { printf("Oops! looks like the update thread is dead\n"); running=0; return 0; } watchDogVal=1; refWatchDog=aux; } return 1; } void TVX11UpdateThread::StartUpdateThread() { long aux; if (TScreen::optSearch("UseUpdateThread",aux) && aux==1) { // This initialization needs Unix 98 compliance. // Linux is ok and the Solaris 7 manpages says that's also ok. pthread_mutexattr_t mt_attr; pthread_mutexattr_init(&mt_attr); pthread_mutexattr_settype(&mt_attr,PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex,&mt_attr); // Now we can use the mutex initialized=1; gettimeofday(&refWatchDog,0); if (pthread_create(&th,NULL,UpdateThread,NULL)==0) printf("Update thread succesfuly created\n"); else perror("Error creating update thread"); } } void TVX11UpdateThread::StopUpdateThread() { if (IS_SECOND_THREAD_ON) { void *ret; running=0; printf("Waiting for update thread completion\n"); if (pthread_join(th,&ret)==0) printf("Update thread finished OK\n"); else perror("Error waiting for update thread completion"); } } #endif // End of Linux implementation of POSIX threads #else #include #include #include #endif // defined(TVOS_UNIX) && defined(HAVE_X11)