config.h000644 000423 000000 00000006305 11501540144 012731 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: config.h 8060 2010-12-14 01:12:22Z luigi $ * * Parser for config files -- similar to the .ini files * * Each section starts with [name] * and has multiple "key = value" entries. * Whitespace is generally allowed both in keys and values, * a ';' starts a comment unless it is in quotes, and # on the * left hand side also acts as a comment marker. * A trivial 'include = filename' statement is also supported. */ #ifndef _CONFIG_H_ #define _CONFIG_H_ struct entry { struct entry *next; char *key; /* pointer to key name */ char *value; /* pointer to key value */ uint16_t len1; /* metadata */ }; struct section; struct config; /* * various accessors. * As a special case, if the path in cfg_read starts with a newline, * then we consider it an immediate string. */ /* load a config file and create or extend a config */ struct config * cfg_read(const char *path, const char *base, struct config *old); void cfg_free(struct config *pdb) ; /* find a specific section. If name == NULL, return the first one, * then if config == NULL name is interpreted as a section and * we return the next entry. So iteration is * for (s = cfg_find_section(cfg, NULL); s; s = cfg_find_section(NULL, (void *)s) ) */ struct section *cfg_find_section(struct config *, const char *name) ; /* find an entry. If key == NULL return the first entry, * then iteration can be explicit as the struct is public */ const struct entry *cfg_find_entry(const struct section *s, const char *key) ; /* * find the value for given cfg/section. If cfg == NULL sec is * the pointer to the section. */ const char *cfg_find_val(struct config *, const char *sec, const char *key); const char *cfg_section_name(const struct section *); /* * skipws() and trimws() are generic string functions useful in other * places as well. */ char *skipws(char *p); char *trimws(char *s, char *end); #endif /* _CONFIG_H_ */ dynstring.h000644 000423 000000 00000007475 11476311006 013522 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: dynstring.h 7958 2010-12-04 01:15:04Z luigi $ * * An implementation of dynamic strings (and in general, extensible * data structures) inherited from the one i wrote myself for asterisk. * * This is similar to the libsbuf that is available in FreeBSD * * USE: declare the dynamic string: dynstr s = NULL; * then use as asprintf(), e.g. dsprintf(&s, fmt, ...); * or, to append a chunk of bytes: ds_append(&s, ptr, len) * * Use ds_len(s), ds_data(s), ds_reset(s), ds_free(s) to get the * length, data pointer, reset the content, and free the memory. * * This code has been originally designed for strings, however * ds_append() supports appending arbitrary chunks of bytes to * the structure, and in fact it is very convenient to implement * some form of dynamic arrays. */ #ifndef __DYNSTRING_H #define __DYNSTRING_H typedef struct __dynstr * dynstr; /* sprintf and append bytes to a dynamic string */ int dsprintf(dynstr *s, const char *fmt, ...); /* append a chunk of bytes to the structure */ int ds_append(dynstr *s, const void *d, int len); /* truncate or extend to the desired size */ int ds_truncate(dynstr *s, int desired_size); /* Adjust the array so that it includes an entry of index i * and size recsize (i.e. at least recsize*[i+1] bytes) */ int ds_adjust(dynstr *s, int i, int recsize); /* Return a pointer to the content (or to "" if empty). * The function never returns NULL; use ds_len() to tell if the * block of memory is not allocated or otherwise empty. */ const char *ds_data(dynstr s); /* return the length in bytes of the content */ int ds_len(dynstr s); // returns the string lenght /* return the total size of the allocated buffer */ int ds_size(dynstr s); // returns the buffer size /* remove the initial n bytes from the string, shifting content up */ int ds_shift(dynstr s, int n); // returns the string lenght /* reset the buffer to the empty string, without deallocating */ void ds_reset(dynstr s); // resets the buffer to empty string /* Create a dynstr with given initial size. * Note that the 'used' field is set to 0 so ds_len will return 0 * Normally you don't need to call ds_create unless you want * to set special properties on the string such as bounded size. */ dynstr ds_create(int len); /* * Create a dynamic string that references an external buffer. * The string is readonly. */ dynstr ds_ref(const char *base, int len); /* frees the space used. Returns NULL for convenience */ void *ds_free(dynstr s); // frees the space #endif /* __DYNSTRING_H */ font.h000644 000423 000000 00000316436 11476422651 012460 0ustar00luigiwheel000000 000000 /* cp437-8x16 8x16 */ static unsigned char pixels[]; static struct font font_pixmap = { .code_first = 0, .code_last = 255, .width = 8, .height = 16, .bpp = 4, .pixmap = pixels, }; static unsigned char pixels[] = { /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xf0, 0x0f, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 11 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0xff, 0x00, 0xf0, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 12 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 13 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 14 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xf0, 0x0f, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16 */ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 17 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 19 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 21 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 22 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 25 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 26 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28 */ 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, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 29 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 31 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 33 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 34 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 35 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 37 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 41 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 43 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 44 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 45 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 46 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 47 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 49 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 51 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 52 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 53 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 55 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 57 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 59 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 61 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 62 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 63 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 65 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 66 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 67 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 69 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 71 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 72 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 73 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 74 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 75 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 76 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 77 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x00, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 79 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 81 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 82 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 83 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 84 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 85 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 86 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 87 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 91 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 92 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 93 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 94 */ 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 96 */ 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 101 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 102 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 103 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 105 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 106 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* 107 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 108 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 109 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 110 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 111 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 113 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, /* 114 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 115 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 116 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 117 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 118 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 119 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0x0f, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 121 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 122 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 123 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 124 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 125 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 126 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 127 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 129 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 130 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 131 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 132 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 133 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 134 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 135 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 137 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 138 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 139 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 140 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 141 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 142 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 143 */ 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 144 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 145 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 146 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 147 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 148 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 149 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 150 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 151 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 153 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 154 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 155 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 156 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 157 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 158 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 159 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 161 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 162 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 163 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 164 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 165 */ 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0xff, 0x00, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 166 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 167 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 169 */ 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, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 170 */ 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, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 171 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 172 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xf0, 0xf0, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 173 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 174 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 175 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 176 */ 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x00, /* 177 */ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, /* 178 */ 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0xff, /* 179 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 180 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 181 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 182 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 183 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 185 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 186 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 187 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 188 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 189 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 190 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 191 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 192 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 193 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 194 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 195 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 196 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 197 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 198 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 199 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 200 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 201 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 202 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 203 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 204 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 205 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 206 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 207 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 208 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 209 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 210 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 211 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 212 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 213 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 214 */ 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 215 */ 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, /* 216 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 217 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 218 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 219 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 220 */ 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 221 */ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, /* 222 */ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, /* 223 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 224 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 225 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 226 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 227 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 228 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 229 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 230 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 231 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 232 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 233 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 234 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0xff, 0xf0, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 235 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 236 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 237 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0x00, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 238 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 239 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 240 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 241 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 242 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 243 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 244 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, /* 245 */ 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 246 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 247 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 248 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 249 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 250 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 251 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 252 */ 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 253 */ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0x00, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 254 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 255 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; myts.h000644 000423 000000 00000010017 11476311006 012457 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: myts.h 7958 2010-12-04 01:15:04Z luigi $ This is a framework for event-based programming. The entire state of the application is reachable through a global "struct my_args _me". Each sub-application is described by a "struct app" which contains callbacks for boot, argument parsing, callbacks, destructor, and private data. */ #ifndef _MYTS_H_ #define _MYTS_H_ #include #include #include #include #include #include /* gettimeofday */ #include #include #include /* inet_aton */ extern int verbose; #define DBG(level, format, ...) do { \ if (verbose >= level) { \ struct timeval now; gettimeofday(&now, NULL); \ fprintf(stderr, "%5d.%03d [%-14.14s %4d] " format, \ (int)(now.tv_sec %86400), (int)(now.tv_usec / 1000), \ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } } while(0) /* * descriptor of an application. */ struct app { int (*init)(void); int (*parse)(int *argc, char *argv[]); int (*start)(void); int (*end)(void); void *data; /* pointer to private data */ }; /* * callback in 'prepare' mode returns 1 if fd active. * callback in 'run' mode returns 0 if ok, 1 if dying. * destruction must be done in the callback itself */ struct cb_args { struct timeval now; struct timeval due; /* earliest due descriptor */ fd_set *r; fd_set *w; int maxfd; int run; /* 0: prepare select, 1: run */ }; typedef int (*cb_fn)(void *sess, struct cb_args *a); struct sess { struct sess *next; struct app *app; /* parent application */ cb_fn cb; void *arg; /* identifier */ int fd; }; /* * All sessions should start with a 'struct sess' */ /* * my_args contains all the arguments for the program * The current app is me->app * The current session is me->sess; */ struct my_args { struct app **all_apps; // array of all applications struct app *app; // app under service struct sess *sess; struct sess *tmp_sess; struct sess *cur; // session under service int verbose; /* allow read all file systems */ }; extern struct my_args __me; /* * Constructor for a new session */ void *new_sess(int size, int fd, cb_fn cb, void *arg); /* * generic socket open routine (general use) */ int opensock(struct sockaddr_in sa, int udp, int client); /* add a millisecond value to a timer */ void timeradd_ms(const struct timeval *src, int ms, struct timeval *dst); /* set dst to the min of the two */ void timersetmin(struct timeval *dst, const struct timeval *cur); /* returns true if dst is set and <= 'now' */ int timerdue(const struct timeval *dst, const struct timeval *now); extern struct app http_app; #endif /* _MYTS_H_ */ pixop.h000644 000423 000000 00000002251 11501540100 012607 0ustar00luigiwheel000000 000000 /* * (C) 2010 Andy * * routines to use the eink screen */ #ifndef _PIXOP_H_ #define _PIXOP_H_ typedef struct pixmap_str { int width; int height; int bpp; /* bits per pixel */ unsigned char *surface; // 1 byte = 2 pixels } pixmap_t; struct font { int code_first; int code_last; int width; int height; int bpp; unsigned char *pixmap; }; /* correct offset and length to the "visible" range */ static inline void c_truncate(int *ofs, int *len, int bound) { if (*ofs < 0) { /* decrease size by offset */ *len += *ofs; *ofs = 0; } if (*ofs > bound) { *len = 0; *ofs = bound; } if (*len <= 0) *len = 0; if (*ofs + *len > bound) *len = bound - *ofs; } int get_char_pixmap(const struct font *f, int code, pixmap_t *ppx) ; const struct font * getfngfont(const char *path) ; void freefngfont(const struct font *) ; int pix_fill(pixmap_t* dst, int bx, int by, int wd, int ht, int color) ; int pix_blt(pixmap_t* dst, int dx, int dy, pixmap_t* src, int sx, int sy, int width, int height, int bg) ; void pix_invert(pixmap_t *p) ; pixmap_t * pix_alloc(int w, int h) ; void pix_free(pixmap_t *p) ; #endif screen.h000644 000423 000000 00000001352 11477254551 012760 0ustar00luigiwheel000000 000000 /* * (C) 2010 Andy * * eink screen routines */ #ifndef _SCREEN_H_ #define _SCREEN_H_ #include "pixop.h" /* defines below simply mimic values of fx_type from einkfb.h */ /* XXX shall we reuse them ? */ #define UMODE_MASK 11 #define UMODE_BUFISMASK 14 #define UMODE_NONE -1 #define UMODE_FLASH 20 #define UMODE_INVERT 21 #define UMODE_PARTIAL 0 // 0 XXX full and partial are the same ? #define UMODE_FULL 1 typedef struct fbscreen { int fd ; int screensize ; int cur_x, cur_y; /* for string processing */ pixmap_t pixmap ; struct font *font; /* default font */ } fbscreen_t; fbscreen_t *fb_open(void) ; void fb_close(fbscreen_t *fb) ; void fb_update_area(fbscreen_t *fb, int mode, int x0, int y0, int x1, int y1, void *pbuf) ; #endif terminal.h000644 000423 000000 00000005143 11476365616 013322 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: terminal.h 7959 2010-12-04 07:37:03Z luigi $ */ #ifndef _TERMINAL_H_ #define _TERMINAL_H_ /* * terminal support for kiterm and launchpad. * The routines support creation of a terminal session, * various manipulations, sending characters to the terminal, * and exporting the framebuffer. */ /* * term_new creates a session, and possibly specifies a callback to invoke * on special events (typically destruction). */ struct sess *term_new(char *cmd, const char *name, int rows, int cols, void (*cb)(struct sess *)); /* lookup a session by name */ struct sess *term_find(const char *name); /* return the name */ const char *term_name(struct sess *s); /* send nul-terminated string to the terminal */ int term_keyin(struct sess *, char *k); /* send a signal to the terminal session */ int term_kill(struct sess *sh, int sig); /* * terminal state. The flags can be used to update modified, callback, name * when calling term_state(s, ptr) with a non-null ptr. * For convenience, term_state() returns the 'modified' state. */ enum { TS_MOD = 1, TS_CB = 2, TS_NAME = 4 }; struct term_state { int flags; int modified, rows, cols, cur; int pid; void (*cb)(struct sess *); char *name; char *data; }; int term_state(struct sess *sh, struct term_state *ptr); #endif /* _TERMINAL_H* */ linux/000755 000423 000000 00000000000 11475434527 012467 5ustar00luigiwheel000000 000000 linux/einkfb.h000644 000423 000000 00000037514 11475434517 014107 0ustar00luigiwheel000000 000000 #ifndef _EINKFB_H #define _EINKFB_H #define EINK_1BPP 1 #define EINK_2BPP 2 #define EINK_4BPP 4 #define EINK_8BPP 8 #define EINK_BPP_MAX EINK_8BPP #define EINK_WHITE 0x00 // For whacking all the pixels in a... #define EINK_BLACK 0xFF // ...byte (8, 4, 2, or 1) at once. // Replace EINK_WHITE & EINK_BLACK with the following macros. // #define eink_white(b) EINK_WHITE #define eink_black(b) EINK_BLACK // For pixels (at bytes at a time) other than white/black, the following holds. // #define eink_pixels(b, p) (p) #define EINK_ORIENT_LANDSCAPE 1 #define EINK_ORIENT_PORTRAIT 0 #define BPP_SIZE(r, b) (((r)*(b))/8) #define BPP_MAX(b) (1 << (b)) #define U_IN_RANGE(n, m, M) ((((n) == 0) && ((m) == 0)) || (((n) > (m)) && ((n) <= (M)))) #define IN_RANGE(n, m, M) (((n) >= (m)) && ((n) <= (M))) #define ORIENTATION(x, y) (((y) > (x)) ? EINK_ORIENT_PORTRAIT : EINK_ORIENT_LANDSCAPE) struct raw_image_t { int xres, // image's width, in pixels yres, // image's height bpp; // image's pixel (bit) depth u8 start[]; // actual start of image }; typedef struct raw_image_t raw_image_t; struct image_t { int xres, // image's visual width, in pixels xlen, // image's actual width, used for rowbyte & memory size calculations yres, // image's height bpp; // image's pixel (bit) depth u8 *start; // pointer to start of image }; typedef struct image_t image_t; #define INIT_IMAGE_T() { 0, 0, 0, 0, NULL } enum splash_screen_type { // Simple (non-composite) splash screens. // //splash_screen_powering_off = 0, // Deprecated. //splash_screen_powering_on, // Deprecated. //splash_screen_powering_off_wireless, // Deprecated. //splash_screen_powering_on_wireless, // Deprecated. //splash_screen_exit, // Deprecated. splash_screen_logo = 5, //splash_screen_usb_internal, // Deprecated. //splash_screen_usb_external, // Deprecated. //splash_screen_usb, // Deprecated. //splash_screen_sleep, // Deprecated. //splash_screen_update, // Deprecated. //num_splash_screens, // Deprecated. // Composite splash screens & messages. // //splash_screen_drivemode_0, // Deprecated. //splash_screen_drivemode_1, // Deprecated. //splash_screen_drivemode_2, // Deprecated. //splash_screen_drivemode_3, // Deprecated. splash_screen_power_off_clear_screen = 16,// Message: clear screen and power down controller. //splash_screen_screen_saver_picture, // Deprecated. splash_screen_shim_picture = 18, // Message: shim wants a picture displayed. splash_screen_lowbatt, // Picture: Not composite, post-legacy ordering (Mario only). splash_screen_reboot, // Picture: Composite (not used on Fiona). splash_screen_update_initial, // Composite software-update screens. splash_screen_update_success, // splash_screen_update_failure, // splash_screen_update_failure_no_wait, // splash_screen_repair_needed, // More composite screens. splash_screen_boot, // splash_screen_invalid = -1 }; typedef enum splash_screen_type splash_screen_type; // Alias some of the legacy enumerations for Mario. // #define splash_screen_usb_recovery_util ((splash_screen_type)8) // splash_screen_usb struct power_override_t { u_int cmd; u_long arg; }; typedef struct power_override_t power_override_t; enum fx_type { // Deprecated from the HAL, but still supported by the Shim. // fx_mask = 11, // Only for use with update_area_t's non-NULL buffer which_fx. fx_buf_is_mask = 14, // Same as fx_mask, but doesn't require a doubling (i.e., the buffer & mask are the same). fx_none = -1, // No legacy-FX to apply. // Screen-update FX, supported by HAL. // fx_flash = 20, // Only for use with update_area_t (for faking a flashing update). fx_invert = 21, // Only for use with update_area_t (only inverts output data). fx_update_partial = 0, // eInk GU/PU/MU-style (non-flashing) update. fx_update_full = 1 // eInk GC-style (slower, flashing) update. }; typedef enum fx_type fx_type; // The only valid legacy-FX types for area updates are fx_mask and fx_buf_is_mask. // #define UPDATE_AREA_FX(f) \ ((fx_mask == (f)) || \ (fx_buf_is_mask == (f))) // The default ("none") for area updates is partial (non-flashing); full (flashing) updates // are for FX and such (i.e., explicit completion is desired). // #define UPDATE_AREA_PART(f) \ ((fx_none == (f)) || \ (fx_update_partial == (f))) #define UPDATE_AREA_FULL(f) \ (UPDATE_AREA_FX(f) || \ (fx_update_full == (f))) #define UPDATE_AREA_MODE(f) \ (UPDATE_AREA_FULL(f) ? fx_update_full \ : fx_update_partial) // For use with the FBIO_EINK_UPDATE_DISPLAY ioctl. // #define UPDATE_PART(f) \ (fx_update_partial == (f)) #define UPDATE_FULL(f) \ (fx_update_full == (f)) #define UPDATE_MODE(f) \ (UPDATE_FULL(f) ? fx_update_full \ : fx_update_partial) struct rect_t { // Note: The bottom-right (x2, y2) coordinate is actually such that (x2 - x1) and (y2 - y1) // are xres and yres, respectively, when normally xres and yres would be // (x2 - x1) + 1 and (y2 - y1) + 1, respectively. // int x1, y1, x2, y2; }; typedef struct rect_t rect_t; #define INIT_RECT_T() { 0, 0, 0, 0 } #define MAX_EXCLUDE_RECTS 8 struct fx_t { fx_type update_mode, // Screen-update FX: fx_update_full | fx_update_partial. which_fx; // Shim (legacy) FX. int num_exclude_rects; // 0..MAX_EXCLUDE_RECTS. rect_t exclude_rects[MAX_EXCLUDE_RECTS]; }; typedef struct fx_t fx_t; #define INIT_FX_T() \ { fx_update_partial, fx_none, 0, { \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T(), \ INIT_RECT_T()} } struct update_area_t { // Note: The bottom-right (x2, y2) coordinate is actually such that (x2 - x1) and (y2 - y1) // are xres and yres, respectively, when normally xres and yres would be // (x2 - x1) + 1 and (y2 - y1) + 1, respectively. // int x1, y1, // Top-left... x2, y2; // ...bottom-right. fx_type which_fx; // FX to use. __u8 *buffer; // If NULL, extract from framebuffer, top-left to bottom-right, by rowbytes. }; typedef struct update_area_t update_area_t; #define INIT_UPDATE_AREA_T() { 0, 0, 0, 0, fx_none, NULL } struct progressbar_xy_t { int x, y; // Top-left corner of progressbar's position (ignores x for now). }; typedef struct progressbar_xy_t progressbar_xy_t; enum screen_saver_t { screen_saver_invalid = 0, screen_saver_valid }; typedef enum screen_saver_t screen_saver_t; enum orientation_t { orientation_portrait, orientation_portrait_upside_down, orientation_landscape, orientation_landscape_upside_down }; typedef enum orientation_t orientation_t; #define num_orientations (orientation_landscape_upside_down + 1) #define ORIENTATION_PORTRAIT(o) \ ((orientation_portrait == (o)) || (orientation_portrait_upside_down == (o))) #define ORIENTATION_LANDSCAPE(o) \ ((orientation_landscape == (o)) || (orientation_landscape_upside_down == (o))) #define ORIENTATION_SAME(o1, o2) \ ((ORIENTATION_PORTRAIT(o1) && ORIENTATION_PORTRAIT(o2)) || \ (ORIENTATION_LANDSCAPE(o1) && ORIENTATION_LANDSCAPE(o2))) enum einkfb_events_t { einkfb_event_update_display = 0, // FBIO_EINK_UPDATE_DISPLAY einkfb_event_update_display_area, // FBIO_EINK_UPDATE_DISPLAY_AREA einkfb_event_blank_display, // FBIOBLANK (fb.h) einkfb_event_rotate_display, // FBIO_EINK_SET_DISPLAY_ORIENTATION einkfb_event_null = -1 }; typedef enum einkfb_events_t einkfb_events_t; struct einkfb_event_t { einkfb_events_t event; // Not all einkfb_events_t use all of the einkfb_event_t fields. fx_type update_mode; // Screen-update FX: fx_update_full | fx_update_partial. // Note: The bottom-right (x2, y2) coordinate is actually such that (x2 - x1) and (y2 - y1) // are xres and yres, respectively, when normally xres and yres would be // (x2 - x1) + 1 and (y2 - y1) + 1, respectively. // int x1, y1, // Top-left... x2, y2; // ...bottom-right. orientation_t orientation; // Display rotated into this orientation. }; typedef struct einkfb_event_t einkfb_event_t; enum reboot_behavior_t { reboot_screen_asis, reboot_screen_clear, reboot_screen_splash }; typedef enum reboot_behavior_t reboot_behavior_t; enum progressbar_badge_t { progressbar_badge_success, progressbar_badge_failure, progressbar_badge_none }; typedef enum progressbar_badge_t progressbar_badge_t; enum sleep_behavior_t { sleep_behavior_allow_sleep, sleep_behavior_prevent_sleep }; typedef enum sleep_behavior_t sleep_behavior_t; #define EINK_FRAME_BUFFER "/dev/fb/0" #define SIZEOF_EINK_EVENT sizeof(einkfb_event_t) #define EINK_EVENTS "/dev/misc/eink_events" #define EINK_ROTATE_FILE "/sys/devices/platform/eink_fb.0/send_fake_rotate" #define EINK_ROTATE_FILE_LEN 1 #define ORIENT_PORTRAIT orientation_portrait #define ORIENT_PORTRAIT_UPSIDE_DOWN orientation_portrait_upside_down #define ORIENT_LANDSCAPE orientation_landscape #define ORIENT_LANDSCAPE_UPSIDE_DOWN orientation_landscape_upside_down #define ORIENT_ASIS (-1) #define EINK_USID_FILE "/var/local/eink/usid" #define EINK_CLEAR_SCREEN 0 #define EINK_CLEAR_BUFFER 1 #define FBIO_EINK_SCREEN_CLEAR FBIO_EINK_CLEAR_SCREEN, EINK_CLEAR_SCREEN #define FBIO_EINK_BUFFER_CLEAR FBIO_EINK_CLEAR_SCREEN, EINK_CLEAR_BUFFER #define FBIO_MIN_SCREEN splash_screen_powering_off #define FBIO_MAX_SCREEN num_splash_screens #define FBIO_SCREEN_IN_RANGE(s) \ ((FBIO_MIN_SCREEN <= (s)) && (FBIO_MAX_SCREEN > (s))) #define FBIO_MAGIC_NUMBER 'F' // Implemented in the eInk HAL. // #define FBIO_EINK_UPDATE_DISPLAY _IO(FBIO_MAGIC_NUMBER, 0xdb) // 0x46db (fx_type) #define FBIO_EINK_UPDATE_DISPLAY_AREA _IO(FBIO_MAGIC_NUMBER, 0xdd) // 0x46dd (update_area_t *) #define FBIO_EINK_RESTORE_DISPLAY _IO(FBIO_MAGIC_NUMBER, 0xef) // 0x46ef (fx_type) #define FBIO_EINK_SET_REBOOT_BEHAVIOR _IO(FBIO_MAGIC_NUMBER, 0xe9) // 0x46e9 (reboot_behavior_t) #define FBIO_EINK_GET_REBOOT_BEHAVIOR _IO(FBIO_MAGIC_NUMBER, 0xed) // 0x46ed (reboot_behavior_t *) #define FBIO_EINK_SET_DISPLAY_ORIENTATION _IO(FBIO_MAGIC_NUMBER, 0xf0) // 0x46f0 (orientation_t) #define FBIO_EINK_GET_DISPLAY_ORIENTATION _IO(FBIO_MAGIC_NUMBER, 0xf1) // 0x46f1 (orientation_t *) #define FBIO_EINK_SET_SLEEP_BEHAVIOR _IO(FBIO_MAGIC_NUMBER, 0xf2) // 0x46f2 (sleep_behavior_t) #define FBIO_EINK_GET_SLEEP_BEHAVIOR _IO(FBIO_MAGIC_NUMBER, 0xf3) // 0x46f3 (sleep_behavior_t *) // Implemented in the eInk Shim. // #define FBIO_EINK_UPDATE_DISPLAY_FX _IO(FBIO_MAGIC_NUMBER, 0xe4) // 0x46e4 (fx_t *) #define FBIO_EINK_SPLASH_SCREEN _IO(FBIO_MAGIC_NUMBER, 0xdc) // 0x46dc (splash_screen_type) #define FBIO_EINK_SPLASH_SCREEN_SLEEP _IO(FBIO_MAGIC_NUMBER, 0xe0) // 0x46e0 (splash_screen_type) #define FBIO_EINK_OFF_CLEAR_SCREEN _IO(FBIO_MAGIC_NUMBER, 0xdf) // 0x46df (EINK_CLEAR_SCREEN || EINK_CLEAR_BUFFER) #define FBIO_EINK_CLEAR_SCREEN _IO(FBIO_MAGIC_NUMBER, 0xe1) // 0x46e1 (no args) #define FBIO_EINK_POWER_OVERRIDE _IO(FBIO_MAGIC_NUMBER, 0xe3) // 0x46e3 (power_override_t *) #define FBIO_EINK_PROGRESSBAR _IO(FBIO_MAGIC_NUMBER, 0xea) // 0x46ea (int: 0..100 -> draw progressbar || !(0..100) -> clear progressbar) #define FBIO_EINK_PROGRESSBAR_SET_XY _IO(FBIO_MAGIC_NUMBER, 0xeb) // 0x46eb (progressbar_xy_t *) #define FBIO_EINK_PROGRESSBAR_BADGE _IO(FBIO_MAGIC_NUMBER, 0xec) // 0x46ec (progressbar_badge_t); #define FBIO_EINK_PROGRESSBAR_BACKGROUND _IO(FBIO_MAGIC_NUMBER, 0xf4) // 0x46f4 (int: EINKFB_WHITE || EINKFB_BLACK) // Deprecated from the HAL & Shim. // //#define FBIO_EINK_UPDATE_DISPLAY_ASYNC _IO(FBIO_MAGIC_NUMBER, 0xde) // 0x46de (fx_type: fx_update_full || fx_update_partial) //#define FBIO_EINK_FAKE_PNLCD _IO(FBIO_MAGIC_NUMBER, 0xe8) // 0x46e8 (char *) // For use with /proc/eink_fb/update_display. // #define PROC_EINK_UPDATE_DISPLAY_CLS 0 // FBIO_EINK_CLEAR_SCREEN #define PROC_EINK_UPDATE_DISPLAY_PART 1 // FBIO_EINK_UPDATE_DISPLAY(fx_update_partial) #define PROC_EINK_UPDATE_DISPLAY_FULL 2 // FBIO_EINK_UPDATE_DISPLAY(fx_update_full) #define PROC_EINK_UPDATE_DISPLAY_AREA 3 // FBIO_EINK_UPDATE_DISPLAY_AREA //#define PROC_EINK_UPDATE_DISPLAY_REST 4 // FBIO_EINK_RESTORE_SCREEN #define PROC_EINK_UPDATE_DISPLAY_SCRN 5 // FBIO_EINK_SPLASH_SCREEN #define PROC_EINK_UPDATE_DISPLAY_OVRD 6 // FBIO_EINK_FPOW_OVERRIDE #define PROC_EINK_UPDATE_DISPLAY_FX 7 // FBIO_EINK_UPDATE_DISPLAY_FX //#define PROC_EINK_UPDATE_DISPLAY_SYNC 8 // FBIO_EINK_SYNC_BUFFERS //#define PROC_EINK_UPDATE_DISPLAY_PNLCD 9 // FBIO_EINK_FAKE_PNLCD #define PROC_EINK_SET_REBOOT_BEHAVIOR 10 // FBIO_EINK_SET_REBOOT_BEHAVIOR #define PROC_EINK_SET_PROGRESSBAR_XY 11 // FBIO_EINK_PROGRESSBAR_SET_XY #define PROC_EINK_UPDATE_DISPLAY_SCRN_SLP 12 // FBIO_EINK_SPLASH_SCREEN_SLEEP #define PROC_EINK_PROGRESSBAR_BADGE 13 // FBIO_EINK_PROGRESSBAR_BADGE #define PROC_EINK_SET_DISPLAY_ORIENTATION 14 // FBIO_EINK_SET_DISPLAY_ORIENTATION #define PROC_EINK_RESTORE_DISPLAY 15 // FBIO_EINK_RESTORE_DISPLAY #define PROC_EINK_SET_SLEEP_BEHAVIOR 16 // FBIO_EINK_SET_SLEEP_BEHAVIOR #define PROC_EINK_PROGRESSBAR_BACKGROUND 17 // FBIO_EINK_PROGRESSBAR_BACKGROUND #define PROC_EINK_UPDATE_DISPLAY_WHICH 18 // FBIO_EINK_UPDATE_DISPLAY //#define PROC_EINK_FAKE_PNLCD_TEST 100 // Programmatically drive FBIO_EINK_FAKE_PNLCD (not implemented). #define PROC_EINK_GRAYSCALE_TEST 101 // Fills display with white-to-black ramp at current bit depth. // Inter-module/inter-driver eink ioctl access. // extern int fiona_eink_ioctl_stub(unsigned int cmd, unsigned long arg); #define eink_sys_ioctl(cmd, arg) (get_fb_ioctl() ? (*get_fb_ioctl())((unsigned int)cmd, (unsigned long)arg) \ : fiona_eink_ioctl_stub((unsigned int)cmd, (unsigned long)arg)) #endif // _EINKFB_H linux/fb.h000644 000423 000000 00000034636 11475434527 013243 0ustar00luigiwheel000000 000000 #ifndef _LINUX_FB_H #define _LINUX_FB_H //#include #include typedef uint32_t __u32; typedef uint16_t __u16; typedef uint8_t __u8; /* Definitions of frame buffers */ #define FB_MAJOR 29 #define FB_MAX 32 /* sufficient for now */ /* ioctls 0x46 is 'F' */ #define FBIOGET_VSCREENINFO 0x4600 #define FBIOPUT_VSCREENINFO 0x4601 #define FBIOGET_FSCREENINFO 0x4602 #define FBIOGETCMAP 0x4604 #define FBIOPUTCMAP 0x4605 #define FBIOPAN_DISPLAY 0x4606 #define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor) /* 0x4607-0x460B are defined below */ /* #define FBIOGET_MONITORSPEC 0x460C */ /* #define FBIOPUT_MONITORSPEC 0x460D */ /* #define FBIOSWITCH_MONIBIT 0x460E */ #define FBIOGET_CON2FBMAP 0x460F #define FBIOPUT_CON2FBMAP 0x4610 #define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */ #define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank) #define FBIO_ALLOC 0x4613 #define FBIO_FREE 0x4614 #define FBIOGET_GLYPH 0x4615 #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ #define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ #define FB_TYPE_TEXT 3 /* Text/attributes */ #define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */ #define FB_AUX_TEXT_MDA 0 /* Monochrome text */ #define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */ #define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */ #define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */ #define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */ #define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */ #define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */ #define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */ #define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */ #define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */ #define FB_VISUAL_TRUECOLOR 2 /* True color */ #define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */ #define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */ #define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */ #define FB_ACCEL_NONE 0 /* no hardware accelerator */ #define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */ #define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */ #define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */ #define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */ #define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */ #define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */ #define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */ #define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */ #define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */ #define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */ #define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */ #define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */ #define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */ #define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */ #define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */ #define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */ #define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */ #define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */ #define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */ #define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */ #define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */ #define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */ #define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */ #define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */ #define FB_ACCEL_SUN_TCX 25 /* Sun tcx */ #define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */ #define FB_ACCEL_NV3 27 /* nVidia RIVA 128 */ #define FB_ACCEL_NV4 28 /* nVidia RIVA TNT */ #define FB_ACCEL_NV5 29 /* nVidia RIVA TNT2 */ #define FB_ACCEL_CT_6555x 30 /* C&T 6555x */ #define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */ #define FB_ACCEL_ATI_RAGE128 32 /* ATI Rage128 family */ #define FB_ACCEL_IGS_CYBER2000 33 /* CyberPro 2000 */ #define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */ #define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */ #define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */ #define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */ #define FB_ACCEL_ATI_RADEON 38 /* ATI Radeon family */ #define FB_ACCEL_I810 39 /* Intel 810/815 */ #define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 650, 740 */ #define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre") */ #define FB_ACCEL_I830 42 /* Intel 830M/845G/85x/865G */ #define FB_ACCEL_NV_10 43 /* nVidia Arch 10 */ #define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */ #define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */ #define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */ #define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */ #define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */ #define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ #define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ #define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ #define FB_ACCEL_NEOMAGIC_NM2097 93 /* NeoMagic NM2097 */ #define FB_ACCEL_NEOMAGIC_NM2160 94 /* NeoMagic NM2160 */ #define FB_ACCEL_NEOMAGIC_NM2200 95 /* NeoMagic NM2200 */ #define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */ #define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */ #define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */ #define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */ #define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */ #define FB_ACCEL_SAVAGE3D_MV 0x82 /* S3 Savage3D-MV */ #define FB_ACCEL_SAVAGE2000 0x83 /* S3 Savage2000 */ #define FB_ACCEL_SAVAGE_MX_MV 0x84 /* S3 Savage/MX-MV */ #define FB_ACCEL_SAVAGE_MX 0x85 /* S3 Savage/MX */ #define FB_ACCEL_SAVAGE_IX_MV 0x86 /* S3 Savage/IX-MV */ #define FB_ACCEL_SAVAGE_IX 0x87 /* S3 Savage/IX */ #define FB_ACCEL_PROSAVAGE_PM 0x88 /* S3 ProSavage PM133 */ #define FB_ACCEL_PROSAVAGE_KM 0x89 /* S3 ProSavage KM133 */ #define FB_ACCEL_S3TWISTER_P 0x8a /* S3 Twister */ #define FB_ACCEL_S3TWISTER_K 0x8b /* S3 TwisterK */ #define FB_ACCEL_SUPERSAVAGE 0x8c /* S3 Supersavage */ #define FB_ACCEL_PROSAVAGE_DDR 0x8d /* S3 ProSavage DDR */ #define FB_ACCEL_PROSAVAGE_DDRK 0x8e /* S3 ProSavage DDR-K */ struct fb_fix_screeninfo { char id[16]; /* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */ /* (physical address) */ __u32 smem_len; /* Length of frame buffer mem */ __u32 type; /* see FB_TYPE_* */ __u32 type_aux; /* Interleave for interleaved Planes */ __u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; /* zero if no hardware panning */ __u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; /* length of a line in bytes */ unsigned long mmio_start; /* Start of Memory Mapped I/O */ /* (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ __u32 accel; /* Indicate to driver which */ /* specific chip/card we have */ __u16 reserved[3]; /* Reserved for future compatibility */ }; /* Interpretation of offset for color fields: All offsets are from the right, * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you * can use the offset as right argument to <<). A pixel afterwards is a bit * stream and is written to video memory as that unmodified. This implies * big-endian byte order if bits_per_pixel is greater than 8. */ struct fb_bitfield { __u32 offset; /* beginning of bitfield */ __u32 length; /* length of bitfield */ __u32 msb_right; /* != 0 : Most significant bit is */ /* right */ }; #define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */ #define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/ #define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */ #define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */ #define FB_ACTIVATE_MASK 15 /* values */ #define FB_ACTIVATE_VBL 16 /* activate values on next vbl */ #define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */ #define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */ #define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/ #define FB_ACTIVATE_INV_MODE 256 /* invalidate videomode */ #define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */ #define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ #define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ #define FB_SYNC_EXT 4 /* external sync */ #define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ #define FB_SYNC_BROADCAST 16 /* broadcast video timings */ /* vtotal = 144d/288n/576i => PAL */ /* vtotal = 121d/242n/484i => NTSC */ #define FB_SYNC_ON_GREEN 32 /* sync on green */ #define FB_VMODE_NONINTERLACED 0 /* non interlaced */ #define FB_VMODE_INTERLACED 1 /* interlaced */ #define FB_VMODE_DOUBLE 2 /* double scan */ #define FB_VMODE_MASK 255 #define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ #define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ #define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ /* * Display rotation support */ #define FB_ROTATE_UR 0 #define FB_ROTATE_CW 1 #define FB_ROTATE_UD 2 #define FB_ROTATE_CCW 3 #define PICOS2KHZ(a) (1000000000UL/(a)) #define KHZ2PICOS(a) (1000000000UL/(a)) struct fb_var_screeninfo { __u32 xres; /* visible resolution */ __u32 yres; __u32 xres_virtual; /* virtual resolution */ __u32 yres_virtual; __u32 xoffset; /* offset from virtual to visible */ __u32 yoffset; /* resolution */ __u32 bits_per_pixel; /* guess what */ __u32 grayscale; /* != 0 Graylevels instead of colors */ struct fb_bitfield red; /* bitfield in fb mem if true color, */ struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; struct fb_bitfield transp; /* transparency */ __u32 nonstd; /* != 0 Non standard pixel format */ __u32 activate; /* see FB_ACTIVATE_* */ __u32 height; /* height of picture in mm */ __u32 width; /* width of picture in mm */ __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ /* Timing: All values in pixclocks, except pixclock (of course) */ __u32 pixclock; /* pixel clock in ps (pico seconds) */ __u32 left_margin; /* time from sync to picture */ __u32 right_margin; /* time from picture to sync */ __u32 upper_margin; /* time from sync to picture */ __u32 lower_margin; __u32 hsync_len; /* length of horizontal sync */ __u32 vsync_len; /* length of vertical sync */ __u32 sync; /* see FB_SYNC_* */ __u32 vmode; /* see FB_VMODE_* */ __u32 rotate; /* angle we rotate counter clockwise */ __u32 reserved[5]; /* Reserved for future compatibility */ }; struct fb_cmap { __u32 start; /* First entry */ __u32 len; /* Number of entries */ __u16 *red; /* Red values */ __u16 *green; __u16 *blue; __u16 *transp; /* transparency, can be NULL */ }; struct fb_con2fbmap { __u32 console; __u32 framebuffer; }; /* VESA Blanking Levels */ #define VESA_NO_BLANKING 0 #define VESA_VSYNC_SUSPEND 1 #define VESA_HSYNC_SUSPEND 2 #define VESA_POWERDOWN 3 enum { /* screen: unblanked, hsync: on, vsync: on */ FB_BLANK_UNBLANK = VESA_NO_BLANKING, /* screen: blanked, hsync: on, vsync: on */ FB_BLANK_NORMAL = VESA_NO_BLANKING + 1, /* screen: blanked, hsync: on, vsync: off */ FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1, /* screen: blanked, hsync: off, vsync: on */ FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1, /* screen: blanked, hsync: off, vsync: off */ FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1 }; #define FB_VBLANK_VBLANKING 0x001 /* currently in a vertical blank */ #define FB_VBLANK_HBLANKING 0x002 /* currently in a horizontal blank */ #define FB_VBLANK_HAVE_VBLANK 0x004 /* vertical blanks can be detected */ #define FB_VBLANK_HAVE_HBLANK 0x008 /* horizontal blanks can be detected */ #define FB_VBLANK_HAVE_COUNT 0x010 /* global retrace counter is available */ #define FB_VBLANK_HAVE_VCOUNT 0x020 /* the vcount field is valid */ #define FB_VBLANK_HAVE_HCOUNT 0x040 /* the hcount field is valid */ #define FB_VBLANK_VSYNCING 0x080 /* currently in a vsync */ #define FB_VBLANK_HAVE_VSYNC 0x100 /* verical syncs can be detected */ struct fb_vblank { __u32 flags; /* FB_VBLANK flags */ __u32 count; /* counter of retraces since boot */ __u32 vcount; /* current scanline position */ __u32 hcount; /* current scandot position */ __u32 reserved[4]; /* reserved for future compatibility */ }; /* Internal HW accel */ #define ROP_COPY 0 #define ROP_XOR 1 struct fb_copyarea { __u32 dx; __u32 dy; __u32 width; __u32 height; __u32 sx; __u32 sy; }; struct fb_fillrect { __u32 dx; /* screen-relative */ __u32 dy; __u32 width; __u32 height; __u32 color; __u32 rop; }; struct fb_image { __u32 dx; /* Where to place image */ __u32 dy; __u32 width; /* Size of image */ __u32 height; __u32 fg_color; /* Only used when a mono bitmap */ __u32 bg_color; __u8 depth; /* Depth of the image */ const char *data; /* Pointer to image data */ struct fb_cmap cmap; /* color map info */ }; /* * hardware cursor control */ #define FB_CUR_SETIMAGE 0x01 #define FB_CUR_SETPOS 0x02 #define FB_CUR_SETHOT 0x04 #define FB_CUR_SETCMAP 0x08 #define FB_CUR_SETSHAPE 0x10 #define FB_CUR_SETSIZE 0x20 #define FB_CUR_SETALL 0xFF struct fbcurpos { __u16 x, y; }; struct fb_cursor { __u16 set; /* what to set */ __u16 enable; /* cursor on/off */ __u16 rop; /* bitop operation */ const char *mask; /* cursor mask bits */ struct fbcurpos hot; /* cursor hot spot */ struct fb_image image; /* Cursor image */ }; #ifdef CONFIG_FB_BACKLIGHT /* Settings for the generic backlight code */ #define FB_BACKLIGHT_LEVELS 128 #define FB_BACKLIGHT_MAX 0xFF #endif #endif /* _LINUX_FB_H */ myts.c000644 000423 000000 00000015740 11476635647 012506 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: myts.c 7972 2010-12-05 07:31:05Z luigi $ Framework for event based programming. Each application supplies a descriptor with init, parse, start routine and a pointer to app-specific data. Each application is then expected to record handlers that are called before and after a select() to define which descriptors to poll, and when a timeout is due. */ #include "myts.h" #include /* ugly to include the C source, but this simplifies use with tcc -run */ #ifndef SPLIT #include "dynstring.c" #include "cp437.c" #include "http.c" #include "terminal.c" #include "config.c" #include "launchpad.c" #include "screen.c" #include "pixop.c" #endif int verbose; struct my_args __me; /* the list of applications to use */ extern struct app http_app, lpad, sip_app; struct app *all_apps[] = { &http_app, &lpad, // &sip_app, NULL, }; /* add a millisecond value to a timer */ void timeradd_ms(const struct timeval *src, int ms, struct timeval *dst) { dst->tv_usec = src->tv_usec + (ms*1000); dst->tv_sec = src->tv_sec + dst->tv_usec / 1000000; dst->tv_usec %= 1000000; } /* set dst to the min of the two -- if cur is unset, ignore */ void timersetmin(struct timeval *dst, const struct timeval *cur) { if (timerisset(cur) && timercmp(cur, dst, <)) *dst = *cur; } /* returns true if dst set and <= 'now' */ int timerdue(const struct timeval *dst, const struct timeval *now) { return (timerisset(dst) && timercmp(dst, now, <=)); } /* generic socket open routine. */ int opensock(struct sockaddr_in sa, int udp, int client) { int fd; int i; DBG(2, "open %s %s socket %s %d\n", client ? "client" : "server", udp ? "UDP" : "TCP", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); fd = socket(sa.sin_family, udp ? SOCK_DGRAM : SOCK_STREAM, 0); if (fd < 0) { perror(" cannot create socket"); return -1; } fcntl(fd, F_SETFD, 1 ); // close on exec i = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i) ) < 0 ) { perror(" cannot reuseaddr"); goto error; } if (client) { if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in))) { perror("connect"); goto error; } } else { if (bind(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in))) { perror("bind"); goto error; } if (!udp) { if (listen(fd, 20) < 0 ) { perror("listen"); goto error; } } } return fd; error: if (fd >= 0) close(fd); return -1; } /* * Generic session creation routine. * size is the size of the descriptor, fd is the main file descriptor * on which to work (ignored if -2, causes an error if -1), * cb is the callback function and arg a session-specific argument. * NB: the new session is stored in a temporary list, otherwise * it might interfere with the scanning of the main list. * Lists are merged at the beginning of each mainloop. */ void *new_sess(int size, int fd, cb_fn cb, void *arg) { struct sess *s; if (fd != -2) { /* ignore fd in case -2 */ if (fd < 0) return NULL; fcntl(fd, F_SETFL, O_NONBLOCK); } s = calloc(1, size); if (!s) { close(fd); DBG(0, "alloc failed\n"); return NULL; } s->cb = cb; s->arg = arg; s->fd = fd; s->next = __me.tmp_sess; __me.tmp_sess = s; return s; } /* * Main loop implementing connection handling */ int mainloop(struct my_args *me) { for (;;) { int n; struct sess *s, *nexts, **ps; fd_set r, w; struct cb_args a = { .maxfd = 0, .r = &r, .w = &w, .run = 0 /* prepare select */ }; FD_ZERO(&r); FD_ZERO(&w); gettimeofday(&a.now, NULL); a.due = a.now; a.due.tv_sec += 1000; /* prepare for select */ if (me->tmp_sess) { for (n = 1, s = me->tmp_sess; s->next; s = s->next) n++; DBG(2, "merging %d new sessions\n", n); s->next = me->sess; me->sess = me->tmp_sess; me->tmp_sess = NULL; } for (n = 0, s = me->sess; s; s = s->next) { n++; me->cur = s; me->app = s->app; if (s->cb(s, &a) && a.maxfd < s->fd) a.maxfd = s->fd; } gettimeofday(&a.now, NULL); a.due.tv_sec -= a.now.tv_sec; a.due.tv_usec -= a.now.tv_usec; if (a.due.tv_usec < 0) { a.due.tv_usec += 1000000; a.due.tv_sec--; } if (a.due.tv_sec > 100) a.due.tv_sec = 100; if (a.due.tv_sec < 0) a.due.tv_sec = a.due.tv_usec = 0; DBG(2, "%d sessions due in %d.%06d\n", n, (int)a.due.tv_sec, (int)a.due.tv_usec); n = select(a.maxfd + 1, &r, &w, NULL, &a.due); gettimeofday(&a.now, NULL); if (n <= 0) { FD_ZERO(&r); FD_ZERO(&w); DBG(2, "select returns %d\n", n); /* still call handlers on timeouts and signals */ } for (n = 0; wait3(NULL, WNOHANG, NULL) >0; n++) ; if (n) DBG(1, "%d children terminated\n", n); a.run = 1; /* now execute the handlers */ for (ps = &me->sess; (s = *ps) ;) { DBG(2, "handle session %p\n", s); me->cur = s; me->app = s->app; nexts = s->next; if (s->cb(s, &a)) /* socket dead, unlink */ *ps = nexts; else ps = &s->next; } } return 0; } int main(int argc, char *argv[]) { struct app **app, *a; int i; memset(&__me, 0, sizeof(__me)); __me.all_apps = all_apps; /* main program arguments */ for (i = 1 ; i < argc; i++) { char *optval, *opt = argv[i]; /* options without arguments */ if (!strcmp(opt, "-v") || !strcmp(opt, "--verbose")) { verbose ++; __me.verbose ++; continue; } if (argc < 3) break; /* options with argument */ optval = argv[i+1]; break; } for (app = all_apps; (a = *app); app++) { __me.app = a; if ( a->init) a->init(); if ( a->parse) a->parse(&argc, argv); if ( a->start) a->start(); } mainloop(&__me); return 0; } terminal.c000644 000423 000000 00000052251 11511644733 013305 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: terminal.c 8169 2011-01-07 17:32:36Z luigi $ * * terminal routines. This code interfaces with a shell session * over a PTY, and interprets ANSI control sequences to render the * screen into a text buffer, which can then be exported to clients * for display. */ #include "myts.h" #include "terminal.h" #include /* kill */ #include /* struct winsize */ #ifdef linux #include #else #include /* forkpty */ #endif #include #include /* isalnum */ #define KMAX 256 /* keyboard queue */ #define SMAX 256 /* screen queue */ /* * flags for terminal emulation. * kf_priv cursor keys mode * kf_nocursor is set to hide the cursor ESC [?25l * kf_graphics means we received the ESC-(B command * kf_dographic means we are in "graphic" mode, where we * enter by either ESC-(B or SO, and exit with ESC-(0 or SI * kf_wrapped is used to manage wrapping -- when we write to * the last char of a line, do not advance the cursor but set the * marker, which is then used to handle future scroll sequences */ enum { kf_priv = 1, kf_nocursor =2, kf_graphics = 4, kf_dographic = 8, kf_insert = 0x10, kf_autowrap = 0x20, kf_wrapped = 0x40, }; /* * values used for the 'attribute' page. The low 3 bits are used * for foreground color, the next 3 bits are background color. */ enum { ka_fg_shift = 0, /* foreground mask shift */ ka_bg_shift = 3, /* backround mask shift */ ka_fg= 0x07, /* foreground mask */ ka_bg = 0x38, /* background mask */ }; /* * struct my_sess describes a shell session to which we talk. */ struct my_sess { struct sess sess; char *name; /* session name */ int pid; /* pid of the child */ void (*cb)(struct sess *); /* screen/keyboard buf have len *pos. *pos is the next byte to send */ int kseq; // need a sequence number for kb input ? int klen; /* pending input for keyboard */ char keys[KMAX]; int kflags; /* dec mode etc */ int slen; /* pending input for screen */ char sbuf[SMAX]; /* store pagelen instead of recomputing it all the times */ int rows, cols, pagelen; /* geometry */ int cur; /* cursor offset */ int modified; /* ... since last read */ int nowrap; /* do not wrap lines */ /* the scroll region (in rows, defaults to 0..rows-1). * we store row, i.e. the first line to be left unchanged. */ int scroll_top, scroll_bottom; /* the page is made of rows*cols chars followed by attributes * with the same layout */ /* * attributes -- we use bits for foreground and bg color. */ uint8_t cur_attr; /* current attributes */ char *page; /* dump of the screen */ }; int term_keyin(struct sess *sess, char *k) { struct my_sess *sh = (struct my_sess *)sess; /* map arrow keys to DEC in private mode. */ if ((sh->kflags & kf_priv) && strlen(k) > 2 && k[0] == '\033' && k[1] == '[' && index("ABCD", k[2])) { k[1] = 'O'; } /* silently drop chars in case of overflow */ strncat(sh->keys + sh->klen, k, sizeof(sh->keys) - 1 - sh->klen); sh->klen = strlen(sh->keys); return 0; } /* return the 'modified' flag. * If ptr is set, clears the modified flag and returns * the info to access the screen area. */ int term_state(struct sess *sess, struct term_state *ptr) { struct my_sess *sh = (struct my_sess *)sess; int ret; if (!sh) return 0; ret = sh->modified; DBG(2, "called on %s %s modified %d\n", sh->name, ptr ? "reset" : "keep", ret); if (ptr) { if (ptr->flags & TS_MOD) sh->modified = ptr->modified; else ptr->modified = sh->modified; if (ptr->flags & TS_CB) sh->cb = ptr->cb; else ptr->cb = sh->cb; if (ptr->flags & TS_NAME) sh->name = ptr->name; else ptr->name = sh->name; ptr->rows = sh->rows; ptr->rows = sh->rows; ptr->cols = sh->cols; ptr->cur = (sh->kflags & kf_nocursor) ? -1 : sh->cur; ptr->data = sh->page; } return ret; } /* erase part of the 'screen' from 'start' for 'len' bytes. * also taking care of the attributes. */ static void erase(struct my_sess *sh, int start, int len) { char *x = sh->page + start; DBG(2, "x %p start %d pagelen %d len %d\n", x, start, sh->pagelen, len); memset(x, ' ', len); memset(x + sh->pagelen, sh->cur_attr, len); } /* scroll up one line, erase last line */ static void page_scroll(struct my_sess *sh) { char *p = sh->page + sh->scroll_top * sh->cols; int l = (sh->scroll_bottom - sh->scroll_top - 1) * sh->cols; memcpy(p, p + sh->cols, l); p += sh->pagelen; /* move to attributes */ memcpy(p, p + sh->cols, l); erase(sh, (sh->scroll_bottom - 1)*sh->cols, sh->cols); } #define B() do { \ if (sh->cur < 0) { \ DBG(0, "cur %d\n", sh->cur); \ sh->cur = 0; \ } else if (sh->cur > sh->pagelen) { \ DBG(0, "cur %d\n", sh->cur); \ sh->cur = sh->pagelen; \ } \ } while(0) /* * interpret a CSI sequence. Return 0 if all ok, 1 if the sequence * is incomplete so we should wait for more chars. In all cases, *s * points to the first unused character. * Codes are taken from the FreeBSD 'syscons' driver. */ static int do_csi(struct my_sess *sh, char **s, int curcol) { /* see http://en.wikipedia.org/wiki/ANSI_escape_code */ char *x, *parm, *base = *s + 2, cmd, mark=' '; int n; int a1= 1, a2= 1, a3 = 1; DBG(3, "+++ CSI FOUND ESC-%s\n", *s+1); /* index() matches a NUL, so we need to check before */ if (!*base) return 1; // process later if (index("<=>?", *base)) /* private ANSI code */ mark = *base++; if (!*base) return 1; // process later // skip parameters for (parm = base; *parm && index("0123456789;", *parm); parm++) ; DBG(3, "+++ now PARM %s\n", parm); cmd = parm[0]; if (!cmd) return 1; // process later *s = parm; /* XXX parse a variable number of args */ n = sscanf(base, "%d;%d;%d", &a1, &a2, &a3); /* print potentially invalid commands */ if (!index("ABCDGHJKPXdghlmr", cmd)) DBG(0, "ANSI sequence (%d)(%d) %d %d %d cmd %d( ESC-[%.*s)\n", n, mark, a1, a2, a3, cmd, (parm+1 - base), base); switch (cmd) { case 'A': // up, hang at curcol sh->cur -= sh->cols * a1; if (sh->cur < 0) sh->cur = curcol; break; case 'B': // down, hang at curcol sh->cur += sh->cols * a1; if (sh->cur >= sh->pagelen) sh->cur = sh->pagelen -sh->cols + curcol; break; case 'C': // right if (a1 >= sh->cols - curcol) a1 = sh->cols - curcol - 1; sh->cur += a1; B(); break; case 'D': // left if (a1 > curcol) a1 = curcol; sh->cur -= a1; B(); break; case 'G': /* horizontal position absolute */ case '`': /* horizontal position absolute */ if (a1 > sh->cols) a1 = sh->cols; sh->cur += (a1 -1 ) - curcol; B(); break; case 'H': case 'f': // both are cursor position, ok DBG(2, "a1 %d a2 %d\n", a1, a2); if (a1 > sh->rows) a1 = sh->rows; else if (a1 < 1) a1 = 1; if (a2 > sh->cols) a2 = sh->cols; else if (a2 < 1) a2 = 1; // XXX a1 -1 or just a1 ? sh->cur = (a1 - 1)*sh->cols + a2 - 1; B(); break; case 'd': /* vertical position absolute */ if (a1 >= sh->rows) a1 = sh->rows; sh->cur = (a1 - 1)*sh->cols + curcol; B(); break; case 'g': /* tab clear, ignore */ break; case 'h': /* set mode/set dec mode, incomplete */ if (mark == '?') { switch (a1) { case 1: /* Cursor keys mode. */ sh->kflags |= kf_priv; /* set cursor mode */ break; case 25: /* Display cursor. */ sh->kflags &= ~kf_nocursor; break; case 7: /* Autowrap mode. */ //s->nowrap = 0; // XXX //break; case 2: /* DECANM: ANSI/VT52 mode. */ case 3: /* 132 column mode. */ case 5: /* Inverse video. */ case 6: /* Origin mode. */ #if 0 t->t_stateflags |= TS_ORIGIN; t->t_originreg = t->t_scrollreg; t->t_cursor.tp_row = t->t_scrollreg.ts_begin; t->t_cursor.tp_col = 0; t->t_stateflags &= ~TS_WRAPPED; teken_funcs_cursor(t); #endif case 8: /* Autorepeat mode. */ case 40: /* Allow 132 columns. */ case 45: /* Enable reverse wraparound. */ case 47: /* Switch to alternate buffer. */ default: goto notfound; } } else { switch (a1) { case 4: /* insert mode */ default: goto notfound; } } break; case 'J': /* erase display, fixed */ if (n == 0) a1 = 0; if (a1 == 1) { /* erase from top to cursor */ erase(sh, 0, sh->cur); } else if (a1 == 2) { /* erase entire page */ erase(sh, 0, sh->pagelen); // sh->cur = 0; // XXX msdos ansy.sys } else { /* erase from cursor to bottom */ erase(sh, sh->cur, sh->pagelen - sh->cur); } break; case 'K': /* erase line, ok */ if (n == 0) a1 = 0; if (a1 == 1) { /* from beg. to cursor */ erase(sh, sh->cur - curcol, curcol); } else if (a1 == 2) { /* entire line */ x = sh->page + sh->cur - curcol; erase(sh, sh->cur - curcol, sh->cols); } else { /* from cursor to end of line */ x = sh->page + sh->cur; erase(sh, sh->cur, sh->cols - curcol); } break; case 'l': /* reset mode */ /* n = 1, mark = '?' */ if (mark == '?') { /* reset dec mode */ switch (a1) { case 1: /* normal cursors */ sh->kflags &= ~kf_priv; /* back to normal */ break; case 25: /* Hide cursor. */ sh->kflags |= kf_nocursor; break; case 2: /* DECANM: ANSI/VT52 mode. */ case 3: /* 132 column mode. */ case 5: /* Inverse video. */ case 6: /* Origin mode. */ case 7: /* Autowrap mode. */ case 8: /* Autorepeat mode. */ case 12: // XXX what ? case 40: /* Disallow 132 columns. */ case 45: /* Disable reverse wraparound. */ case 47: /* Switch to alternate buffer. */ default: // we got 12, 1000, 1049 goto notfound; } } else { /* reset mode */ switch (a1) { case 4: /* disable insert mode */ default: goto notfound; } } /* XXX resets the INSERT flag */ break; case 'm': /* set_graphic_rendition */ { /* right now ignore attributes, fix later */ int i, arg[3] = {a1, a2, a3}; if (n == 0) { arg[0] = 0; n = 1; } for (i=0; i < 3 && i < n; i++) { switch(arg[i]) { case 0: /* reset */ sh->cur_attr = 0; break; case 1: /* bold */ case 4: /* underline */ case 5: /* blink */ case 7: /* reverse */ case 22: /* remove bold */ case 24: /* remove underline */ case 25: /* remove blink */ case 27: /* remove reverse */ case 30: /* Set foreground color: black */ case 31: /* Set foreground color: red */ case 32: /* Set foreground color: green */ case 33: /* Set foreground color: brown */ case 34: /* Set foreground color: blue */ case 35: /* Set foreground color: magenta */ case 36: /* Set foreground color: cyan */ case 37: /* Set foreground color: white */ DBG(2, "setattr fg %d\n", arg[i]); sh->cur_attr &= ~ka_fg; sh->cur_attr |= (37 - arg[i]); break; case 39: /* Set default foreground color. */ DBG(2, "setattr fg %d\n", arg[i]); sh->cur_attr &= ~ka_fg; break; case 40: /* Set background color: black */ case 41: /* Set background color: red */ case 42: /* Set background color: green */ case 43: /* Set background color: brown */ case 44: /* Set background color: blue */ case 45: /* Set background color: magenta */ case 46: /* Set background color: cyan */ case 47: /* Set background color: white */ DBG(1, "setattr bg %d\n", arg[i]); sh->cur_attr &= ~ka_bg; sh->cur_attr |= (47 - arg[i]) << ka_bg_shift; break; case 49: /* Set default background color. */ DBG(1, "setattr bg %d\n", arg[i]); sh->cur_attr &= ~ka_bg; break; default: goto notfound; } } } break; case 'P': /* delete n characters */ if (curcol + a1 < sh->cols) { char *dst = sh->page + sh->cur; int l = sh->cols - curcol - a1; memcpy(dst, dst + a1, l); dst += sh->pagelen; memcpy(dst, dst + a1, l); /* attributes */ erase(sh, sh->cur + l, a1); } else { erase(sh, sh->cur, sh->cols - curcol); } break; case 'r': /* change scroll region */ DBG(2, "scroll region to %d, %d\n", a1-1, a2-1); /* change y scroll region to a1-1,a2-1, * position cursor to row a1-1 */ if (n == 0) { /* defaults */ a1 = 1; a2 = sh->rows - 1; } if (a1 >= 1 && a1 <= a2 && a2 <= sh->rows) { sh->scroll_top = a1 - 1; sh->scroll_bottom = a2; sh->cur = (a1 - 1) * sh->cols; B(); } break; case 'X': /* erase char, the next n characters */ if (a1 + curcol > sh->cols) a1 = sh->cols - curcol; erase(sh, sh->cur, a1); break; default: notfound: DBG(0, "-- at %4d ANSI sequence (%d) %d %d %d ( ESC-[%c%.*s)\n", sh->cur, n, a1, a2, a3, mark, (parm+1 - base), base); } return 0; } /* * append a string to a page, interpreting ANSI sequences * Returns a pointer to leftover chars. */ static char *page_append(struct my_sess *sh, char *s) { const uint8_t special[] = { /* box drawing chars, UTF8 and CP-437 */ // 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, '?', 0xb1, '?', '?', '?', '?', 0xf8, 0xf1, // 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba, '?', '?', 0xd9, 0xbf, 0xda, 0xc0, 0xc5, '?', // 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c, '?', 0xc4, '?', '?', 0xc3, 0xb4, 0xc1, 0xc2, // 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7 0xb3, 0xf3, 0xf2, 0xe3, '?', 0x9c, 0xfa, '?' }; for (; *s; s++) { char c = *s; int curcol; if (sh->cur >= sh->pagelen) { // XXX the '>' should not happen ? DBG(0, "+++ scroll at %d / %d +++\n", sh->cur, sh->pagelen); sh->cur = sh->pagelen - sh->cols; // beginning of last line page_scroll(sh); } curcol = sh->cur % sh->cols; switch (c) { case '\r': /* CR */ sh->cur -= curcol; B(); break; case 0x0e: /* shift-out */ sh->kflags |= kf_dographic; break; case 0x0f: /* shift-in */ sh->kflags &= ~kf_dographic; break; case 7: /* BEL, ignore */ break; case '\t': /* XXX simplified version, 8-pos tabs */ if (curcol >= sh->pagelen - 8) sh->cur += (sh->cols - 1 - curcol); else sh->cur += 8 - (sh->cur % 8); B(); break; case '\b': // backspace if (curcol > 0) sh->cur--; B(); break; case '\033': /* escape */ if (!s[1]) goto done; // incomplete sequence, process later if (s[1] == '[' ) { // CSI found if (do_csi(sh, &s, curcol)) goto done; /* continue later */ } else { if (!index("()>=H", s[1])) DBG(0, "other ESC-%.*s\n", 1, s+1); /* * ESC-( charset G0 used * ESC-) charset G1 used * ESC-= keypad mode 1 * ESC-> keypad mode 0 * ESC-H memorize tab position as X */ if (index("()", s[1])) { /* treat g0 and g1 the same */ if (!s[2]) return s; // process later s += 2; switch (*s) { case '0': /* g0_scs_special graphics */ DBG(1, "enter graphics at %d\n", sh->cur); sh->kflags |= (s[-1] == '(') ? (kf_graphics | kf_dographic) : kf_dographic; break; case 'B': /* g0_scs_us_ascii */ DBG(1, "exit graphics at %d\n", sh->cur); sh->kflags &= ~(kf_graphics | kf_dographic); break; default: DBG(0, "unrecognised ESC ( %c\n", *s); } } else if (index("H=>", s[1])) { /* ignore these */ /* H horiz. tab set, ignore */ /* = keypad app mode */ /* > keypad numeric mode */ s++; } else { DBG(0, "non ANSI sequence %d ESC-%c\n", s[1], s[1]); s++; /* skip the char */ } } break; default: /* all other chars */ /* XXX make room in insert mode ? */ if (sh->kflags & kf_wrapped) { /* absorb the wrap */ sh->cur++; B(); sh->kflags &= ~kf_wrapped; } else if (*s == '\n') { sh->cur += sh->cols; B(); } if (sh->cur >= sh->scroll_bottom * sh->cols) { sh->cur -= sh->cols; B(); page_scroll(sh); } if (*s == '\n') /* already handled above */ break; if (*s >= 0x60 && *s < 0x7f && (sh->kflags & kf_dographic) && sh->kflags & kf_graphics) sh->page[sh->cur] = special[(*s - 0x60)]; else sh->page[sh->cur] = *s; sh->page[sh->cur + sh->pagelen] = sh->cur_attr; if (curcol != sh->cols -1) sh->cur++; else if (sh->nowrap) sh->kflags |= kf_wrapped; } if (sh->cur >= sh->pagelen) { DBG(0,"--- ouch, overflow on c %d\n", c); sh->cur = 0; // XXX what should we do ? */ } } done: if (*s) { DBG(3, "----- leftover stuff ESC [%s]\n", s+1); } return s; } static int term_keyboard(struct my_sess *sh) { int l = write(sh->sess.fd, sh->keys, sh->klen); if (l <= 0) { DBG(1, "error writing to keyboard\n"); return 1; /* error, currently ignored */ } if (l < sh->klen) DBG(0, "short write to keyboard %d out of %d\n", l, sh->klen); // ioctl(sh->sess.fd, TIOCDRAIN); // XXX blocks strcpy(sh->keys, sh->keys + l); sh->klen -= l; return 0; } /* process screen output from the shell */ static int term_screen(struct my_sess *sh) { char *s; int spos = strlen(sh->sbuf); int l = read(sh->sess.fd, sh->sbuf + spos, sizeof(sh->sbuf) - 1 - spos); if (l <= 0) { DBG(0, "--- shell read error, dead %d\n", l); sh->sess.fd = -1; /* report error. */ return 1; } spos += l; sh->sbuf[spos] = '\0'; DBG(2, "got %d bytes for %s\n", l, sh->name); sh->modified = 1; /* maybe not... */ s = page_append(sh, sh->sbuf); /* returns unprocessed pointer */ strcpy(sh->sbuf, s); return 0; } /* * Callback for I/O with the shell */ int handle_shell(void *_s, struct cb_args *a) { struct my_sess *sh = _s; if (sh->sess.fd < 0) { /* dead */ if (a->run == 0) return 0; if (sh->cb) sh->cb(_s); free(sh); /* otherwise destroy */ return 1; } DBG(1, "poll %p %s\n", sh, sh->name); if (a->run == 0) { FD_SET(sh->sess.fd, a->r); if (sh->klen) /* have bytes to send to keyboard */ FD_SET(sh->sess.fd, a->w); return 1; } if (FD_ISSET(sh->sess.fd, a->w)) term_keyboard(sh); if (FD_ISSET(sh->sess.fd, a->r)) term_screen(sh); /* can close the fd. handle later */ return 0; } /* * Create a "terminal" child process, and talk to it through a slave pty * using event-based sessions. "name" is the identifier. */ struct sess *term_new(char *cmd, const char *name, int rows, int cols, void (*cb)(struct sess *)) { int l, ln = strlen(name) + 1; struct winsize ws; struct my_sess *s; if (rows < 4 || rows > 80) rows = 25; if (cols < 10 || cols > 160) cols = 80; l = rows*cols; DBG(1, "create shell %s %s %dx%d\n", name, cmd, rows, cols); /* allocate space for page and attributes */ s = new_sess(sizeof(*s) + l*2 + ln, -2, handle_shell, NULL); if (!s) { DBG(0, "failed to create session for %s\n", name); return NULL; } s->cb = cb; s->rows = rows; s->cols = cols; s->pagelen = s->rows * s->cols; s->modified = 1; s->nowrap = 0; /* XXX */ s->scroll_top =0; s->scroll_bottom = rows; s->cur = 0; s->cur_attr = 0; s->name = (char *)(s + 1); s->page = s->name + ln; /* one set for chars, one for attributes */ erase(s, 0, s->pagelen); strcpy(s->name, name); bzero(&ws, sizeof(ws)); ws.ws_row = rows; ws.ws_col = cols; s->pid = forkpty(&s->sess.fd, NULL, NULL, &ws); DBG(3, "forkpty gives pid %d pty %d\n", s->pid, s->sess.fd); if (s->pid < 0) { DBG(0, "forkpty failed\n"); /* failed. mark session as dying, will be freed later */ s->sess.fd = -1; /*mark as dying */ return NULL; } if (s->pid == 0) { /* this is the child, execvp the shell */ char *av[] = { cmd, NULL}; //putenv("TERM=linux"); execvp(av[0], av); exit(1); /* notreached normally */ } fcntl(s->sess.fd, F_SETFL, O_NONBLOCK); return (struct sess *)s; } const char *term_name(struct sess *s) { return s->cb == handle_shell ? ((struct my_sess *)s)->name : ""; } int term_kill(struct sess *sess, int sig) { struct my_sess *sh = (struct my_sess *)sess; if (sh) kill(sh->pid, sig); return 0; } struct sess *term_find(const char *name) { struct sess *s; for (s = __me.sess; s; s = s->next) { if (s->cb == handle_shell && !strcmp(name, ((struct my_sess *)s)->name)) break; } return s; } dynstring.c000644 000423 000000 00000021202 11476311006 013475 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: dynstring.c 7958 2010-12-04 01:15:04Z luigi $ * * An implementation of dynamic strings (and in general, extensible * data structures) inherited from the one i wrote myself for asterisk. * * Note that the internals of the dynstring are opaquE */ #include "dynstring.h" #include /* vsnprintf */ #include /* varargs */ #include #include /* bcopy */ #include #define START_SIZE 48 // initial size /* * This is the internal representation of the object -- a header * followed by an inline buffer. The entire chunk is malloc()ed or * realloc()ed as needed. * * 'len' represents the size of the buffer space, excluding the * space occupied by the structure. * Special case: len = 0 and used >0 represents a reference to * an external string (ds_readonly() will return true). * As an implementation detail, we make the last byte unavailable * for users so we put a NUL byte there and guarantee that strings * are well terminated. */ struct __dynstr { size_t len; /* The current size of the buffer */ size_t used; /* Amount of space used */ char str[0]; /* The string buffer */ }; static int ds_readonly(dynstr s) { return (s->len == 0 && s->used > 0); } const char *ds_data(dynstr s) { const char **pp; if (!s) return ""; if (s->len > 0) return s->str; if (s->used == 0) return ""; pp = (const char **)&(s->str); return pp[0]; } /* * Create a reference to an existing string. In this case the len * field is 0 and 'used' is the length of the string we point to. */ dynstr ds_ref(const char *p, int len) { dynstr d = ds_create(sizeof(const char *)); const char **pp = (const char **)&(d->str); pp[0] = p; d->len = 0; d->used = len; return d; } void *ds_free(dynstr s) { if (s) free(s); return NULL; } int ds_len(dynstr s) { return s ? s->used : 0; } /* * When returning the available space, decrement by 1 so we * can add a '\0' at the end without overwriting user data */ int ds_size(dynstr s) { return s ? s->len - 1 : 0; } void ds_reset(dynstr buf) { if (buf) { buf->used = 0; if (buf->len) buf->str[0] = '\0'; } } dynstr ds_create(int init_len) { dynstr buf; buf = (dynstr)calloc(1, sizeof(*buf) + init_len); if (buf == NULL) return NULL; buf->len = init_len; buf->used = 0; return buf; } static int dynstr_make_space(dynstr *buf, size_t new_len) { dynstr newbuf; if (buf == NULL) return 0; if (ds_readonly(*buf)) return -1; if (new_len <= (*buf)->len) return 0; /* success */ /* make it slightly larger than requested */ if (new_len < 1000) new_len += new_len; else new_len += 1000; newbuf = (dynstr)realloc(*buf, new_len + sizeof(struct __dynstr)); if (newbuf == NULL) return -1; *buf = newbuf; (*buf)->len = new_len; return 0; } static int __dynstr_helper(dynstr *buf, size_t max_len, int append, const char *fmt, va_list ap); #define DYNSTR_BUILD_RETRY -2 #define DYNSTR_BUILD_FAILED -3 /* * Append to a dynamic string using a va_list */ #define vadsprintf(buf, max_len, fmt, ap) \ ({ \ int __res; \ while ((__res = __dynstr_helper(buf, max_len, \ 1, fmt, ap)) == DYNSTR_BUILD_RETRY) { \ va_end(ap); \ va_start(ap, fmt); \ } \ (__res); \ }) /*! * Append to a dynamic string - same as sprintf(). */ int __attribute__ ((format (printf, 2, 3))) dsprintf(dynstr *buf, const char *fmt, ...) { int res; va_list ap; if (buf == NULL) return 0; va_start(ap, fmt); res = vadsprintf(buf, 0 /* max_len */, fmt, ap); va_end(ap); return res; } /* * Append a buffer to a dynamic string (and also a '\0' to ease printing). * If d == NULL only extend */ int ds_append(dynstr *buf, const void *d, int len) { int need; if (buf == NULL) return 0; if (*buf == NULL) *buf = ds_create(START_SIZE); if (*buf == NULL) return DYNSTR_BUILD_FAILED; if (len < 0) { /* the 'truncate' */ need = -len + 1; } else { need = (*buf)->used + len + 1; } if (need > (*buf)->len) { if (dynstr_make_space(buf, need)) return DYNSTR_BUILD_FAILED; } if (len < 0) { (*buf)->used = -len; } else { if (d) bcopy(d, (*buf)->str + (*buf)->used, len); (*buf)->used += len; } (*buf)->str[(*buf)->used] = '\0'; return 0; } int ds_truncate(dynstr *buf, int want) { if (buf && *buf && ds_readonly(*buf) && want <= (*buf)->used) { (*buf)->used = want; return 0; } return ds_append(buf, NULL, -want); } /* adjust used to the desired length */ int ds_adjust(dynstr *buf, int i, int recsize) { int l = ds_len(*buf); int want = (i+1)*recsize; if (l < want) ds_truncate(buf, want); return 0; } /* remove the initial n bytes from the string, shifting up the content */ int ds_shift(dynstr d, int n) { if (!d || n < 0 || n > d->used) return -1; d->used -= n; // residual size if (ds_readonly(d)) { /* for readonly string, shift instead of move */ const char **pp = (const char **)&(d->str); pp[0] += n; } else { bcopy(d->str + n, d->str, d->used); d->str[d->used] = '\0'; } return d->used; } __attribute__((format (printf, 4, 0))) static int __dynstr_helper(dynstr *buf, size_t max_len, int append, const char *fmt, va_list ap) { int res, need; int offset; if (buf == NULL) return 0; if (*buf == NULL) *buf = ds_create(START_SIZE); if (*buf == NULL) return DYNSTR_BUILD_FAILED; offset = (append && (*buf)->len) ? (*buf)->used : 0; if (max_len < 0) max_len = (*buf)->len; /* don't exceed the allocated space */ /* * Ask vsnprintf how much space we need. Remember that vsnprintf * does not count the final '\0' so we must add 1. */ res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap); need = res + offset + 1; /* * If there is not enough space and we are below the max length, * reallocate the buffer and return a message telling to retry. */ if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) { if (max_len && max_len < need) /* truncate as needed */ need = max_len; else if (max_len == 0) /* if unbounded, give more room for next time */ need += 16 + need/4; if (dynstr_make_space(buf, need)) return DYNSTR_BUILD_FAILED; (*buf)->str[offset] = '\0'; /* Truncate the partial write. */ /* va_end() and va_start() must be done before calling * vsnprintf() again. */ return DYNSTR_BUILD_RETRY; } /* update space used, keep in mind the truncation */ (*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset; return res; } cp437.c000644 000423 000000 00000024527 11477240222 012333 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: cp437.c 7989 2010-12-06 13:47:53Z luigi $ * * code to map cp437 into html entities */ #include "myts.h" #include #include /* strtol */ static char cp437[] = " \n\ 0x00 0x0000 NULL\n\ 0x01 0x263A ☺ While Smiling Face\n\ 0x02 0x263B ☻ Black Smiling Face\n\ 0x03 0x2665 ♥ Black Heart Suit\n\ 0x04 0x2666 ♦ Black Diamond Suit\n\ 0x05 0x2663 ♣ Black Club Suit\n\ 0x06 0x2660 ♠ Black Spades Suit\n\ 0x07 0x2022 • Bullet\n\ 0x08 0x25D8 ◘ Inverse Bullet\n\ 0x09 0x25CB ○ White Circle\n\ 0x0A 0x25D9 ◙ Inverse White Circle\n\ 0x0B 0x2642 ♂ Male Sign\n\ 0x0C 0x2640 ♀ Female Sign\n\ 0x0D 0x266A ♪ Eighth Note\n\ 0x0E 0x266B ♫ Beamed Eighth Note\n\ 0x0F 0x263C ☼ White Sun With Rays\n\ 0x10 0x25BA ► Black Right-Pointing Pointer\n\ 0x11 0x25C4 ◄ Black Left-Pointing Pointer\n\ 0x12 0x2195 ↕ Up Down Arrow\n\ 0x13 0x203C ‼ Double Exclamation Mark\n\ 0x14 0x00B6 ¶ Pilcrow Sign\n\ 0x15 0x00A7 § Section Sign\n\ 0x16 0x25AC ▬ Black Rectangle\n\ 0x17 0x21A8 ↨ Up Down Arrow With Base\n\ 0x18 0x2191 ↑ Upwards Arrow\n\ 0x19 0x2193 ↓ Downwards Arrow\n\ 0x1A 0x2192 → Rightwards Arrow\n\ 0x1B 0x2190 ← Leftwards Arrow\n\ 0x1C 0x221F ∟ Right Angle\n\ 0x1D 0x2194 ↔ Left Right Arrow\n\ 0x1E 0x25B2 ▲ Black Up-Pointing Triangle\n\ 0x1F 0x25BC ▼ Black Down-Pointing Triangle\n\ 0x7F 0x2302 ⌂ House\n\ 0x80 0x00C7 Ç Latin Capital Letter C With Cedilla\n\ 0x81 0x00FC ü Latin Small Letter U With Diaeresis\n\ 0x82 0x00E9 é Latin Small Letter E With Acute\n\ 0x83 0x00E2 â Latin Small Letter A With Circumflex\n\ 0x84 0x00E4 ä Latin Small Letter A With Diaeresis\n\ 0x85 0x00E0 à Latin Small Letter A With Grave\n\ 0x86 0x00E5 å Latin Small Letter A With Ring Above\n\ 0x87 0x00E7 ç Latin Small Letter C With Cedilla\n\ 0x88 0x00EA ê Latin Small Letter E With Circumflex\n\ 0x89 0x00EB ë Latin Small Letter E With Diaeresis\n\ 0x8A 0x00E8 è Latin Small Letter E With Grave\n\ 0x8B 0x00EF ï Latin Small Letter I With Diaeresis\n\ 0x8C 0x00EE î Latin Small Letter I With Circumflex\n\ 0x8D 0x00EC ì Latin Small Letter I With Grave\n\ 0x8E 0x00C4 Ä Latin Capital Letter A With Diaeresis\n\ 0x8F 0x00C5 Å Latin Capital Letter A With Ring Above\n\ 0x90 0x00C9 É Latin Capital Letter E With Acute\n\ 0x91 0x00E6 æ Latin Small Ligature Ae\n\ 0x92 0x00C6 Æ Latin Capital Ligature Ae\n\ 0x93 0x00F4 ô Latin Small Letter O With Circumflex\n\ 0x94 0x00F6 ö Latin Small Letter O With Diaeresis\n\ 0x95 0x00F2 ò Latin Small Letter O With Grave\n\ 0x96 0x00FB û Latin Small Letter U With Circumflex\n\ 0x97 0x00F9 ù Latin Small Letter U With Grave\n\ 0x98 0x00FF ÿ Latin Small Letter Y With Diaeresis\n\ 0x99 0x00D6 Ö Latin Capital Letter O With Diaeresis\n\ 0x9A 0x00DC Ü Latin Capital Letter U With Diaeresis\n\ 0x9B 0x00A2 ¢ Cent Sign\n\ 0x9C 0x00A3 £ Pound Sign\n\ 0x9D 0x00A5 ¥ Yen Sign\n\ 0x9E 0x20A7 ₧ Peseta Sign\n\ 0x9F 0x0192 ƒ Latin Small Letter F With Hook\n\ 0xA0 0x00E1 á Latin Small Letter A With Acute\n\ 0xA1 0x00ED í Latin Small Letter I With Acute\n\ 0xA2 0x00F3 ó Latin Small Letter O With Acute\n\ 0xA3 0x00FA ú Latin Small Letter U With Acute\n\ 0xA4 0x00F1 ñ Latin Small Letter N With Tilde\n\ 0xA5 0x00D1 Ñ Latin Capital Letter N With Tilde\n\ 0xA6 0x00AA ª Feminine Ordinal Indicator\n\ 0xA7 0x00BA º Masculine Ordinal Indicator\n\ 0xA8 0x00BF ¿ Inverted Question Mark\n\ 0xA9 0x2310 ⌐ Reversed Not Sign\n\ 0xAA 0x00AC ¬ Not Sign\n\ 0xAB 0x00BD ½ Vulgar Fraction One Half\n\ 0xAC 0x00BC ¼ Vulgar Fraction One Quarter\n\ 0xAD 0x00A1 ¡ Inverted Exclamation Mark\n\ 0xAE 0x00AB « Left-Pointing Double Angle Quotation Mark\n\ 0xAF 0x00BB » Right-Pointing Double Angle Quotation Mark\n\ 0xB0 0x2591 ░ Light Shade\n\ 0xB1 0x2592 ▒ Medium Shade\n\ 0xB2 0x2593 ▓ Dark Shade\n\ 0xB3 0x2502 │ Box Drawings Light Vertical\n\ 0xB4 0x2524 ┤ Box Drawings Light Vertical And Left\n\ 0xB5 0x2561 ╡ Box Drawings Vertical Single And Left Double\n\ 0xB6 0x2562 ╢ Box Drawings Vertical Double And Left Single\n\ 0xB7 0x2556 ╖ Box Drawings Down Double And Left Single\n\ 0xB8 0x2555 ╕ Box Drawings Down Single And Left Double\n\ 0xB9 0x2563 ╣ Box Drawings Double Vertical And Left\n\ 0xBA 0x2551 ║ Box Drawings Double Vertical\n\ 0xBB 0x2557 ╗ Box Drawings Double Down And Left\n\ 0xBC 0x255D ╝ Box Drawings Double Up And Left\n\ 0xBD 0x255C ╜ Box Drawings Up Double And Left Single\n\ 0xBE 0x255B ╛ Box Drawings Up Single And Left Double\n\ 0xBF 0x2510 ┐ Box Drawings Light Down And Left\n\ 0xC0 0x2514 └ Box Drawings Light Up And Right\n\ 0xC1 0x2534 ┴ Box Drawings Light Up And Horizontal\n\ 0xC2 0x252C ┬ Box Drawings Light Down And Horizontal\n\ 0xC3 0x251C ├ Box Drawings Light Vertical And Right\n\ 0xC4 0x2500 ─ Box Drawings Light Horizontal\n\ 0xC5 0x253C ┼ Box Drawings Light Vertical And Horizontal\n\ 0xC6 0x255E ╞ Box Drawings Vertical Single And Right Double\n\ 0xC7 0x255F ╟ Box Drawings Vertical Double And Right Single\n\ 0xC8 0x255A ╚ Box Drawings Double Up And Right\n\ 0xC9 0x2554 ╔ Box Drawings Double Down And Right\n\ 0xCA 0x2569 ╩ Box Drawings Double Up And Horizontal\n\ 0xCB 0x2566 ╦ Box Drawings Double Down And Horizontal\n\ 0xCC 0x2560 ╠ Box Drawings Double Vertical And Right\n\ 0xCD 0x2550 ═ Box Drawings Double Horizontal\n\ 0xCE 0x256C ╬ Box Drawings Double Vertical And Horizontal\n\ 0xCF 0x2567 ╧ Box Drawings Up Single And Horizontal Double\n\ 0xD0 0x2568 ╨ Box Drawings Up Double And Horizontal Single\n\ 0xD1 0x2564 ╤ Box Drawings Down Single And Horizontal Double\n\ 0xD2 0x2565 ╥ Box Drawings Down Double And Horizontal Single\n\ 0xD3 0x2559 ╙ Box Drawings Up Double And Right Single\n\ 0xD4 0x2558 ╘ Box Drawings Up Single And Right Double\n\ 0xD5 0x2552 ╒ Box Drawings Down Single And Right Double\n\ 0xD6 0x2553 ╓ Box Drawings Down Double And Right Single\n\ 0xD7 0x256B ╫ Box Drawings Vertical Double And Horizontal Single\n\ 0xD8 0x256A ╪ Box Drawings Vertical Single And Horizontal Double\n\ 0xD9 0x2518 ┘ Box Drawings Light Up And Left\n\ 0xDA 0x250C ┌ Box Drawings Light Down And Right\n\ 0xDB 0x2588 █ Full Block\n\ 0xDC 0x2584 ▄ Lower Half Block\n\ 0xDD 0x258C ▌ Left Half Block\n\ 0xDE 0x2590 ▐ Right Half Block\n\ 0xDF 0x2580 ▀ Upper Half Block\n\ 0xE0 0x03B1 α Greek Small Letter Alpha\n\ 0xE1 0x00DF ß Greek Capital Letter Beta / Latin Small Letter Esset\n\ 0xE2 0x0393 Γ Greek Capital Letter Gamma\n\ 0xE3 0x03C0 π Greek Small Letter Pi\n\ 0xE4 0x03A3 Σ Greek Capital Letter Sigma\n\ 0xE5 0x03C3 σ Greek Small Letter Sigma\n\ 0xE6 0x00B5 µ Greek Small Letter Mu\n\ 0xE7 0x03C4 τ Greek Small Letter Tau\n\ 0xE8 0x03A6 Φ Greek Capital Letter Phi\n\ 0xE9 0x0398 Θ Greek Capital Letter Theta\n\ 0xEA 0x03A9 Ω Greek Capital Letter Omega\n\ 0xEB 0x03B4 δ Greek Small Letter Delta\n\ 0xEC 0x221E ∞ Infinity\n\ 0xED 0x03C6 φ Greek Small Letter Phi\n\ 0xEE 0x03B5 ε Greek Small Letter Epsilon\n\ 0xEF 0x2229 ∩ Intersection\n\ 0xF0 0x2261 ≡ Identical To\n\ 0xF1 0x00B1 ± Plus-Minus Sign\n\ 0xF2 0x2265 ≥ Greater-Than Or Equal To\n\ 0xF3 0x2264 ≤ Less-Than Or Equal To\n\ 0xF4 0x2320 ⌠ Top Half Integral\n\ 0xF5 0x2321 ⌡ Bottom Half Integral\n\ 0xF6 0x00F7 ÷ Division Sign\n\ 0xF7 0x2248 ≈ Almost Equal To\n\ 0xF8 0x00B0 ° Degree Sign\n\ 0xF9 0x2219 ∙ Bullet Operator\n\ 0xFA 0x00B7 · Middle Dot\n\ 0xFB 0x221A √ Square Root\n\ 0xFC 0x207F ⁿ Superscript Latin Small Letter N\n\ 0xFD 0x00B2 ² Superscript Two\n\ 0xFE 0x25A0 ■ Black Square\n\ 0xFF 0x00A0     No-Break Space\n\ "; #include #include char *map437[256]; int build_map437(int argc, char *argv[]) { char *a, *b = cp437; DBG(2, "cp437 is %s\n", b); while ( (a = strsep(&b, "\n")) ) { int i = 0; char *v[3]; v[0] = v[1] = v[2] = "-none-"; for (i=0; a && i < 3;) { char *c = strsep(&a, " \t"); if (!c) break; if (!c[0] || (i == 2 && c[0] != '&')) continue; v[i++] = c; } i = strtol(v[0], NULL, 0); if (isalnum(i) || i == 32) v[2] = NULL; map437[i] = v[2]; DBG(2, "fields %s %s\n", v[0], v[2] ? v[2] : "same"); } map437[8] = map437[9] = map437[10] = map437[13] = map437[27] = map437[127] = NULL; return 0; } http.c000644 000423 000000 00000037643 11477240222 012455 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: http.c 7996 2010-12-06 14:58:07Z luigi $ Backend for web-based terminal. This implements a very simple web server, and an application specific part in charge of passing shell data over http. http routines */ #include "dynstring.h" #include "myts.h" #include "terminal.h" #include /* gethostbyname */ #include #include #include /* PROT_READ and mmap */ #ifdef linux #include /* strcasestr */ /* strcasestr prototype is problematic */ char *strcasestr(const char *haystack, const char *pneedle); #endif extern char *map437[256]; int build_map437(int argc, char *argv[]); #define INBUFSZ 4096 /* * struct client contains support for talking to the browser. * It contains a buffer for receiving the incoming request, * hold a copy of the response, and support for an mmapped file. * Initially, reply = 0, len = sizeof(inbuf) and pos = 0, * we accumulate data into inbuf and call parse_msg() to tell * whether we are done. * During the reply phase, inbuf contains the response hdr, * possibly map contains the body, len = header length, body_len = body_len * and pos = 0. We first send the header, then toggle len = -body_len, * and then send the body. When done, detach the buffer. * If filep is set, then map is a mapped file, otherwise points to * some other buffer and does not need to be freed. */ struct client { struct sess sess; int reply; /* set when replying */ int pos, len; /* read position and length */ struct timeval due; /* when a response is due */ struct sess *sh; char inbuf[INBUFSZ]; /* I/O buffer */ dynstr response; /* memory mapped file */ int filep; int body_len; char *map; }; /* supported mime types -- suffix space mime. Default is text/plain. * processed by getmime(filename) */ static const char *mime_types[] = { "html text/html", "htm text/html", "js text/javascript", "css text/css", NULL }; struct http_desc { struct sockaddr_in sa; int unsafe; /* allow unsafe file access */ char *cmd; /* command to run */ int http_timeout; /* timeout for http session */ }; struct http_desc desc, *http; /* set to me.app->data */ static void add_digit(int *c, char ** const src) { const char *hex = "0123456789abcdef0123456789ABCDEF"; const char *p = *src; p = (*p) ? index(hex, *p) : NULL; if (!p) return; *c = *c * 16 + ((p - hex)&0xf); (*src)++; } /* convert the html encoding back to plain ascii * XXX must be fixed to handle UTF8 */ static char *unescape(char *s) { char *src, *dst; int c; for (src = dst = s; *src; ) { c = *src++; if (c == '+') c = ' '; else if (c == '%') { c = '\0'; add_digit(&c, &src); add_digit(&c, &src); } *dst++ = c; } *dst++ = '\0'; return s; } static int build_response(struct client *ss, const char *ret); /* process requests coming from the browser */ int u_mode(struct client *ss, char *body) { /* request parameters */ char *s = NULL, *k = ""; int refresh = 0, rows = 0, cols = 0, color=0; char *cur, *p, *p2; int i; struct sess *sess; /* extract parameters */ for (p = body; (cur = strsep(&p, "&")); ) { if (!*cur) continue; p2 = strsep(&cur, "="); if (!strcmp(p2, "s")) s = cur; // session id if (!strcmp(p2, "w")) cols = atoi(cur); // width if (!strcmp(p2, "h")) rows = atoi(cur); // height if (!strcmp(p2, "c")) color = atoi(cur); // color if (!strcmp(p2, "k")) k = cur; // keys if (!strcmp(p2, "r")) refresh = 1; /* force refresh */ } if (!s || !*s) { /* list sessions */ dsprintf(&ss->response, "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n\r\n" "

Active sessions

\n"); /* XXX explore current sessions ... */ i = 0; for (sess = __me.sess; sess; sess = sess->next) { const char *name = term_name(sess); if (name) dsprintf(&ss->response, "%2d %s\n", ++i, name, name); } dsprintf(&ss->response, "

\n"); ss->len = ds_len(ss->response); return 0; } sess = term_find(s); if (!sess) sess = term_new(http->cmd, s, rows, cols, NULL); if (!sess) { dsprintf(&ss->response, "HTTP/1.1 400 fork failed\r\n\r\n"); ss->len = ds_len(ss->response); return 0; } if (k[0]) { unescape(k); term_keyin(sess, k); } ss->sh = sess; /* prepare for updates */ gettimeofday(&ss->due, NULL); if (!k[0] && !refresh && !term_state(sess, NULL)) { DBG(2, "/* no modifications, wait before reply */\n"); ss->due.tv_sec += http->http_timeout; } return 0; } static int build_response(struct client *ss, const char *ret) { struct term_state st = { .flags = TS_MOD, .modified = 0 }; int mod = term_state(ss->sh, &st); if (!ret) { /* not supplied by the user */ ret = (mod) ? "
" : "";
    }
    dsprintf(&ss->response,
            "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/xml; charset=cp437;\r\n\r\n"
	    "%s", ret);
    if (ss->sh) {
	const char *src = st.data;
	unsigned char done = '\0';
	int i;

	/* convert text so that it does not interfere with the XML.
	 * mostly, we need utf8 encoding for 'special' characters
	 * Colors and the like are dealt with using ''
	 * (surely needed for the cursor).
	 * Make sure we always have rows*cols chars.
	 */
	for (i=0; i < st.rows * st.cols;) {
	    unsigned char cc = done ? done : (unsigned char)src[i];
	    int use_span = i == st.cur;
	    if (!cc) done = cc = ' ';
	    /* XXX todo: if there is a color change, close previous span
	     * and open a new one if needed.
	     */
	    if (use_span)
		dsprintf(&ss->response, "");
	    /* some chars are unmodified */
#if 1
	    if (map437[cc])
		dsprintf(&ss->response, "%s", map437[cc]); /* entity chars */
	    else if (isalnum(cc) || index("\n ", cc)) /* XXX maybe more */
		dsprintf(&ss->response, "%c", cc); /* unmodified chars */
	    else
		dsprintf(&ss->response, "%%%02x", cc); /* escaped chars */
#else
	    if (isalnum(cc) || index("\n ", cc)) /* XXX maybe more */
		dsprintf(&ss->response, "%c", cc); /* unmodified chars */
	    else if (cc <= 0x7f)	/* one-byte utf8 */
		dsprintf(&ss->response, "%%%02x", cc);
	    else			/* two-byte codes */
		dsprintf(&ss->response, "%%%02x%%%02x",
			0xc0+(cc>>6), 0xc0+(cc&0x3f));
#endif
	    /* XXX and here i should do three-byte codes */
	    /* XXX the span should not close here */
	    if (use_span)
		dsprintf(&ss->response, "");
	    if (++i % st.cols == 0)
		dsprintf(&ss->response, "\n"); /* unmodified chars */
	}
	DBG(3, "done %d chars at %p %s\n", i, src, ds_data(ss->response));
	/* XXX also close the main span */
	dsprintf(&ss->response, "
"); } ss->len = ds_len(ss->response); DBG(2, "response %s\n", ds_data(ss->response)); return 0; } struct client *new_client(int fd, cb_fn cb, void *arg) { struct client *s = new_sess(sizeof(struct client), fd, cb, arg); if (!s) return NULL; s->filep = -1; /* no file */ s->pos = 0; s->len = sizeof(s->inbuf); return s; } static int parse_msg(struct client *s); static int http_write(struct client *s); /* * callback for the http session */ int handle_http(void *_s, struct cb_args *a) { struct client *s = _s; if (a->run == 0) { if (s->reply) timersetmin(&a->due, &s->due); if (!s->reply) FD_SET(s->sess.fd, a->r); else if ( term_state(s->sh, NULL) || timercmp(&s->due, &a->now, <)) FD_SET(s->sess.fd, a->w); else return 0; return 1; } if (FD_ISSET(s->sess.fd, a->r)) { int l; /* accumulate request */ l = read(s->sess.fd, s->inbuf + s->pos, s->len - s->pos); DBG(2, "read %p returns %d %s\n", s, l, s->inbuf); if (l <= 0) { DBG(1, "buf [%s]\n", s->inbuf); s->len = 0; // mark done with read } else { s->pos += l; } parse_msg(s); /* check if msg is complete */ } if (FD_ISSET(s->sess.fd, a->w)) { http_write(s); } if (s->len != 0) /* socket still active */ return 0; /* else dead */ ds_free(s->response); free(s); return 1; } /* support function to return mime types. */ static const char *getmime(const char *res) { const char **p, *suffix; int lres = strlen(res); res += lres; /* move to the end of the resource */ for (p = mime_types; (suffix = *p); p++) { int lsuff = strcspn(suffix, " "); if (lsuff > lres) continue; if (!bcmp(res - lsuff, suffix, lsuff)) return suffix + lsuff + 1; } return "text/plain"; /* default */ } /* * A stripped down parser for http, which also interprets what * we need to do. */ static int parse_msg(struct client *s) { char *a, *b, *c = s->inbuf; /* strsep support */ char *body, *method = "", *resource = ""; int row, tok; int clen = -1; char *err = "generic error"; if (s->pos == s->len) { // buffer full, we are done DBG(0, "--- XXX input buffer full\n"); s->len = 0; // complete } /* locate the end of the header. If not found, just return */ body = strstr(s->inbuf, "\n\r\n") + 3; if (body < s->inbuf) body = strstr(s->inbuf, "\n\n") + 2; if (body < s->inbuf && s->len) return 0; /* quick search for content length */ a = strcasestr(s->inbuf, "Content-length:"); if (a && a < body) { sscanf(a + strlen("Content-length:") + 1, "%d", &clen); DBG(2, "content length = %d, body len %d\n", clen, s->pos - (body - s->inbuf)); if (s->pos - (body - s->inbuf) != clen) return 0; /* body incomplete */ } /* if no content length, hope body is complete */ /* now parse the header */ for (row=0; (b = strsep(&c, "\r\n"));) { if (*b == '\0') continue; if (b > body) { body = b; break; } row++; for (tok=0; (a = strsep(&b, " \t"));) { if (*a == '\0') continue; tok++; if (row == 1) { if (tok == 1) method = a; if (tok == 2) resource = a; } } } s->reply = 1; /* body found, we move to reply mode. */ DBG(2, "%s %s\n+++ request body [%s]\n", method, resource, body); s->pos = 0; if (!strcmp(method, "POST") && !strcmp(resource, "/u")) { return u_mode(s, body); /* ajax request using POST */ } else if (!strcmp(method, "GET") && !strncmp(resource, "/u?", 3)) { return u_mode(s, resource+3); /* ajax request using GET */ } else { /* request for a file, map and serve it */ struct stat sb; char *query_args = resource; resource = strsep(&query_args, "?&"); err = "invalid pathname"; if (!http->unsafe && resource[1] == '/') goto error; /* avoid absolute pathnames */ for (a = resource+1; *a; a++) { /* avoid back pointers */ if (*a == '.' && a[1] == '.') goto error; } if (!strcmp(resource, "/")) resource = "/ajaxterm.html"; s->filep = open(resource+1, O_RDONLY); err = "open failed"; if (s->filep < 0 || fstat(s->filep, &sb)) goto error; err = "mmap failed"; /* linux wants MAP_PRIVATE or MAP_SHARED, not 0 */ s->map = mmap(NULL, (int)sb.st_size, PROT_READ, MAP_PRIVATE, s->filep, (off_t)0); if (s->map == MAP_FAILED) goto error; s->body_len = sb.st_size; dsprintf(&s->response, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %d\r\n\r\n", getmime(resource+1), (int)sb.st_size); s->len = ds_len(s->response); return 0; } error: if (s->filep >= 0) close(s->filep); dsprintf(&s->response, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n\r\nResource %s : %s\n", resource, err); s->len = ds_len(s->response); return 0; } static int http_write(struct client *s) { int l; if (s->response == NULL) build_response(s, NULL); /* first write the header, then set s->len negative and * write the mapped file */ if (s->len > 0) { l = write(s->sess.fd, ds_data(s->response) + s->pos, s->len - s->pos); } else { l = write(s->sess.fd, s->map + s->pos, s->body_len - s->pos); } if (l <= 0) goto write_done; s->pos += l; DBG(1, "written1 %d/%d\n", s->pos, s->len); if (s->pos == s->len) { /* header sent, move to the body */ s->len = -s->body_len; s->pos = 0; } DBG(1, "written2 %d/%d\n", s->pos, -s->len); if (s->pos == -s->len) { /* body sent, close */ write_done: DBG(1, "reply complete\n"); /* the kindle wants shutdown before close */ shutdown(s->sess.fd, SHUT_RDWR); close(s->sess.fd); s->len = 0; if (s->filep) { if (s->map) munmap(s->map, s->body_len); close(s->filep); } } return 0; } /* callback for the listener socket */ int handle_listen(void *_s, struct cb_args *a) { struct sockaddr_in sa; unsigned int l = sizeof(sa); int fd; struct client *s = _s; if (a->run == 0) { /* always listen */ FD_SET(s->sess.fd, a->r); return 1; } if (!FD_ISSET(s->sess.fd, a->r)) return 0; DBG(1, "listening socket\n"); bzero(&sa, sizeof(sa)); fd = accept(s->sess.fd, (struct sockaddr *)&sa, &l); if (fd < 0) { DBG(0, "listen failed\n"); return -1; } new_client(fd, handle_http, NULL); return 0; } /* init routine, fill default parameters */ static int http_init(void) { struct sockaddr_in *sa; http = __me.app->data; http->http_timeout = 20; sa = &http->sa; DBG(1, "http init routine\n"); memset(sa, 0, sizeof(*sa)); sa->sin_family = PF_INET; sa->sin_port = htons(8022); inet_aton("127.0.0.1", &sa->sin_addr); http->cmd = "login"; build_map437(0, NULL); return 0; } /* * fetch arguments from the command line */ static int http_parse(int *ac, char *argv[]) { int argc = *ac; DBG(1, "http parse routine\n"); for ( ; argc > 1 ; argc--, argv++) { char *optval, *opt = argv[1]; /* options without arguments */ if (!strcmp(opt, "--unsafe")) { http->unsafe = 1; continue; } if (argc < 3) break; /* options with argument */ optval = argv[2]; argc--; argv++; if (!strcmp(opt, "--cmd")) { http->cmd = optval; continue; } if (!strcmp(opt, "--port")) { http->sa.sin_port = htons(atoi(optval)); continue; } if (!strcmp(opt, "--addr")) { struct hostent *h = gethostbyname(optval); if (h) { http->sa.sin_addr = *(struct in_addr *)(h->h_addr); } else if (!inet_aton(argv[1], &http->sa.sin_addr)) { perror("cannot parse address"); return 1; } continue; } break; } return 0; } /* create the session */ static int http_start(void) { struct sockaddr_in *sa = &http->sa; DBG(1, "listen on %s:%d cmd %s\n", inet_ntoa(sa->sin_addr), ntohs(sa->sin_port), http->cmd); new_client(opensock(*sa, 0 /* TCP */, 0 /* server */), handle_listen, NULL); return 0; } struct app http_app = { .init = http_init, .parse = http_parse, .start = http_start, .data = &desc}; config.c000644 000423 000000 00000022336 11501537074 012736 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * a config file has a number of section marked by [section-name] * followed by 'key = value' lines. * A \\ protects the next character, while strings in ' and " are * also protected. * A ';' anywhere, or a # in the left hand side start a comment. * Spaces are allowed both in key and value. */ #define _GNU_SOURCE /* asprintf */ #include #include #include #include #include #include #include #include #include #include "config.h" extern int verbose; #ifndef DBG #define DBG(level, format, ...) do { \ if (verbose >= level) \ fprintf(stderr, "[%-14.14s %4d] " format, \ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } while(0) #endif struct section { struct section *next; char *name; struct entry *keys; /* children */ }; /* * A buffer contains inline the storage for the backing file, * and in case we read from multiple files we need to link * the buffers together. * Individual entries (section and entry) are allocated * individually. */ struct config { struct config *next; /* chain pointer */ char *pbuf ; /* pointer to the config file buffer (inline) */ struct section *sections ; /* first section */ }; /* skip leading whitespace */ char *skipws(char *p) { return p ? p + strspn(p, " \t\r\n") : p; } /* trim trailing unescaped whitespace, including comments. * 'end' points to the first character after our string. If NULL, it is computed. * Unfortunately, to understand escape sequences one must process left to right. */ char *trimws(char *s, char *end) { int in_quote = 0; char *start = s, *last_ws = NULL; if (end == NULL) end = s + strlen(s); if (end == s) return start; for (; s < end; s++) { if (*s == '\\') { if (s+1 < end) s++; last_ws = NULL; } else if (in_quote) { in_quote = (*s != '"' && *s != '\''); } else if (*s == '"' || *s == '\'') { in_quote = 1; last_ws = NULL; } else if (*s == ';' || (s == start && *s == '#')) { if (!last_ws) last_ws = s; break; } else if (index(" \t\r\n", *s)) { if (!last_ws) last_ws = s; } else last_ws = NULL; } if (last_ws) s = last_ws; *s = '\0'; return start; } /* * Parse a name in key = value pair. If sep[0] == '=' * and '=' is not found return an error. * Trim left and right whitespace. */ static char *parse_name(char **p, const char *sep) { char c, *q; int l; if (!sep || !p || !*p || !**p) return NULL; q = *p = skipws(*p); for (l=0; q[l] && !index(sep, q[l]); l++) { if (q[l] == '\\' && q[l+1]) l++; } if (sep[0] == '=' && q[l] != '=') /* looking for a key, missing = */ return NULL; *p += l; c = q[l]; q[l] = '\0'; if (c) (*p)++; trimws(q, q+l); return q; } /* parse the content of a config file. We expect the buffer to be * persistent and writable. */ static int cfg_parse(struct config *db, char *p, const char *basedir) { struct section *cur; struct entry *kcur; DBG(3, "start, db %p content\n%.50s\n...\n", db, p); cur = NULL; kcur = NULL; while (p && *p) { char c; char *start; char *key, *val; start = strsep(&p, "\n"); /* to end of line */ start = skipws(start); /* skip whitespace */ trimws(start, p - 1); switch (*start) { case '\0': /* comment line */ case ';': /* comment line */ case '#': /* comment line */ break ; case '[': /* section delimiter */ key = ++start; /* skip it */ while (isalnum(*key) || index("-_", *key)) key++; c = *key; *key = '\0'; if (c) key++; if (c != ']') { DBG(0, "invalid section name %s %c\n", start, c); break; } DBG(1, "start section %s\n", start); cur = cfg_find_section(db, start); if (!cur) { /* allocate new */ cur = calloc(1, sizeof(struct section)); if (cur == NULL) { DBG(0, "cannot allocate section %s\n", start); return -1; } cur->next = db->sections; db->sections = cur; cur->name = start; } break; default: /* it a a key/value string then */ DBG(3, "key name pair\n"); key = parse_name(&start, "=\r\n"); val = key ? parse_name(&start, "\r\n") : NULL; DBG(2, "after parse name next p %p %d\n", p, *p); if (!val) { if (key) { DBG(0, "cannot parse name %s\n", start); return -1; } break; } DBG(1, "key [%s] val [%s]\n", key, val); if (!strcmp(key, "include")) { DBG(1, "processing include %s\n", val); cfg_read(val, basedir, db); break; } if (!cur) { DBG(0, "key val outside section, ignore\n"); break; } kcur = (struct entry *)cfg_find_entry(cur, start); if (kcur) { DBG(0, "replace val %s\n", kcur->value); // XXX should we add ? } else { kcur = calloc(1, sizeof(struct entry)); if (kcur == NULL) { DBG(0, "cannot allocate key %s\n", start); return -1; } kcur->next = cur->keys; cur->keys = kcur; kcur->key = key; } kcur->value = val; break ; } } DBG(1, "END db %p\n", db); return 0; } /* * Creates a database for file 'path', optionally prepending 'base' to * the file name. If 'path' starts with newline, then this is an * immediate string with the content of the file. * If the db argument is non null then it appends to the existing db. */ struct config *cfg_read(const char *path, const char *base, struct config *old) { struct config *db = NULL; int n, len, fd = -1; char *buf; DBG(1, "%s\n", path); if (path == NULL) return NULL; if (path[0] == '\n') { len = strlen(path); goto immediate; } if ( (fd = open(path, O_RDONLY)) >= 0) goto good; if (path[0] != '.' && path[0] != '/') { // try alternate location char *p; asprintf(&p, "%s/%s", base, path); fd = open(p, O_RDONLY); if ( fd >= 0) goto good; } DBG(0, "error opening %s\n", path); return old; good: len = lseek(fd, 0, SEEK_END) ; lseek(fd, 0, SEEK_SET) ; immediate: // allocate memory for descriptor + data + trailing '\0' db = calloc(1, sizeof(struct config) + len + 1); if (db == NULL) goto error; buf = db->pbuf = (char *)(db + 1); // data are after descriptor // read the file if (fd < 0) { memcpy(db->pbuf, path, len); } else { n = read(fd, db->pbuf, len); if (n != len) { DBG(0, "cannot read file %s size %d\n", path, len) ; goto error; } close(fd) ; /* don't need the file open anymore .. */ fd = -1; } if (old) { /* link the db to the next one */ db->next = old; old->next = db; db = old; } /* do not abort if we are extending another file */ if (!cfg_parse(db, buf, base) || old) return db ; DBG(0, "can't create db structure\n") ; error: if (db) free(db); if (fd >= 0) close(fd) ; return old ; } /* * destructor for the data structure */ void cfg_free(struct config *p) { struct section *s; struct entry *k; if (!p) return; while ( (s = p->sections) ) { p->sections = s->next; while ( (k = s->keys) ) { s->keys = k->next; free(k); } free(s); } free(p) ; } const char *cfg_section_name(const struct section *sec) { return sec ? sec->name : NULL; } struct section *cfg_find_section(struct config *db, const char *name) { struct section *s; if (db == NULL) /* iterate, use name as current ptr */ return name ? ((struct section *)name)->next : NULL; s = db->sections; if (name == NULL) return s; for (; s; s = s->next) if (!strcasecmp(name, s->name)) return s; return NULL ; } const struct entry * cfg_find_entry(const struct section *s, const char *name) { const struct entry *k ; if (!s) return NULL; k = s->keys; if (name == NULL) return k; for (; k; k = k->next) if (strcasecmp(name, k->key) == 0) return k; return NULL ; } const char *cfg_find_val(struct config *db, const char *sec, const char *name) { const struct section *s = db ? cfg_find_section(db, sec) : (const struct section *)sec; const struct entry *k = cfg_find_entry(s, name); return k ? k->value : NULL; } launchpad.c000644 000423 000000 00000105077 11501540001 013414 0ustar00luigiwheel000000 000000 /* * Copyright (C) 2010 Luigi Rizzo, Universita' di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Inspired by launchpad code from Andy M. aka h1uke h1ukeguy @ gmail.com * but there is barely any of the original code left here. */ /* * launchpad+terminal+webserver program for Kindle. * See top level README for details, * and config.c for the config file format. */ #define _GNU_SOURCE /* asprintf */ #include #include #include #include #include #include #include #include #include #include /* dirname */ #include #include #ifdef __FreeBSD__ enum { EV_KEY = 1, }; struct input_event { struct timeval time; uint16_t type; uint16_t code; int32_t value; }; #else #include #endif #include "myts.h" #include "config.h" #include "dynstring.h" #include "terminal.h" #include "pixop.h" #include "screen.h" /* * Each key entry has a name, a type and one or two parameters. * The name is normally the ascii char (case sensitive) * or the key name (case insensitive). * The type is 0 for send, 1 for sendshift, 2 for sendfw, 3 for sym. * The code is the code to send, or the y steps for symbols. * Additionally, symbols need an x steps. */ enum k_type { KT_SEND = 0, KT_FW, KT_VOL, KT_SHIFT, KT_ALT, KT_SYM }; struct key_entry { char *name; /* not null terminated */ uint8_t namelen; uint8_t type; /* send, sendshift, sym */ uint8_t code; /* or x-steps if sym */ uint8_t ysteps; /* if sym */ }; /* each I/O channel has different name and fd for input and output */ struct iodesc { char *namein; char *nameout; int fdin; int fdout; }; /* support for multiple terminal sessions */ struct terminal { struct terminal *next; struct sess *the_shell; char name[0]; /* dynamically allocated */ }; /* * Overall state for the launchpad. * The destructor must: * - preserve all terminal sessions * - call cfg_free(db) * - call cfg_read and init */ struct lp_state { /* e[] contains events sorted by name, with nentries entries. * by_code[] is a direct access array to get an event by code, * with pointers into e[] */ int nentries; struct key_entry e[256]; /* table of in/out events */ struct key_entry *by_code[256]; /* events by code */ /* actions is a list of configured actions, pointing into the * [actions] section of the db. */ struct config *db; /* the database */ struct entry *actions; /* list of actions */ char *script_path; /* where to look for scripts */ int xsym, ysym; /* initial SYMBOL position (1, 1) */ /* codes for various keys */ int fw_left, fw_right, fw_up, fw_down, fw_select; int intro, trailer, del, sym; int term_end, term_esc, term_shift, term_ctrl, term_sym; int term_fn; int hot_interval; /* duration of hot interval */ int key_delay; /* inter-key delay */ int refresh_delay; /* screen refresh delay */ struct iodesc kpad, fw, vol; /* names and descriptors */ /* dynamic state */ /* fb, curterm, save_pixmap are either all set or all clear */ struct terminal *curterm; /* current session */ fbscreen_t *fb; /* the framebuffer */ dynstr save_pixmap; /* saved pixmap */ /* various timeouts, nonzero if active */ struct timeval screen_due; /* next screen refresh */ struct timeval hotkey_due; /* end of hotkey mode */ struct timeval keys_due; /* keys to send back to the kindle */ dynstr pending; /* list of pending keypresses */ volatile int got_signal; /* changed by the handler */ int hotkey_mode; int hot_seq_len; #define MAXSEQ 32 uint8_t hot_seq[MAXSEQ]; // input collected in hot mode uint8_t hot_seq_dev[MAXSEQ]; // src dev for the above /* This area must be preserved on reinit */ int savearea[0]; /* area below preserved on reinit */ struct terminal *allterm; /* all terminal sessions */ char basedir[1024]; char *cfg_name; /* points into basedir */ int verbose; }; static struct lp_state lpad_desc; static struct lp_state *lps; static void capture_input(int capture); /* * Debugging support to emulate events on the host. * 1: shift down, 2: shift up other chars are up+down */ int host_event(int fd, struct input_event *kbbuf, int l) { char c, *pc; struct input_event *p = kbbuf; static int intro=0; static char map[] = /* same as Kindle keys */ "..1234567890....qwertyuiop....asdfghjkl.....zxcvbnm"; int i = read(fd, &c, 1); memset(p, 0, l*2); if (i <= 0) return 0; if (isalpha(c)) c = tolower(c); if (c == '1' && !intro) { /* introducer ON */ *p++ = (struct input_event){ {0,0}, EV_KEY, lps->intro, 1 }; intro = 1; } else if (c == '2' && intro) { *p++ = (struct input_event){ {0,0}, EV_KEY, lps->intro, 0 }; intro = 0; } else if ( (pc = index(map, c)) ) { i = pc - map; DBG(2, "char %c maps to %d\n", c, i); *p++ = (struct input_event){ {0,0}, EV_KEY, i, 1 }; *p++ = (struct input_event){ {0,0}, EV_KEY, i, 0 }; } return (p - kbbuf) * sizeof(*p); } static int is_kindle3(void) { /* if all 3 /dev/input/event[012] are open then we are on Kindle3 */ return (lps->kpad.fdin != -1 && lps->fw.fdin != -1 && lps->vol.fdin != -1); } /* * compare two key entries. Sorting is by length and then by string. * One-byte entries are case-sensitive, other are case-insensitive. * ecmp1() is used for the initial sorting (removing duplicates) * and breaks ties looking at the type (privileging short sequences) */ static int ecmp(const void *_l, const void *_r) { const struct key_entry *l = _l, *r = _r; int d = l->namelen - r->namelen; if (d != 0) return d; return (l->namelen == 1) ? (int)l->name[0] - (int)r->name[0] : strncasecmp(l->name, r->name, l->namelen); } static int ecmp1(const void *_l, const void *_r) { const struct key_entry *l = _l, *r = _r; int d = ecmp(l, r); return d ? d : l->type - r->type; } /* * maps a keydef to the correct key_entry, returns NULL if not found. */ static struct key_entry *lookup_key(const char *key, int len) { struct key_entry l, *k; if (*key == ' ') { len = 0; key = "Space"; } l.name = (char *)key; l.namelen = len ? len : strlen(key); k = bsearch(&l, lps->e, lps->nentries, sizeof(l), ecmp); if (!k) DBG(0, "entry '%.*s' not found\n", len, key); return k; } /* * Take an action entry and "compile" it, replacing the left size with * sequence of event codes, and setting len1 to the length. * The sequence on the right is left unchanged. */ static void compile_action(struct entry *k) { char *src; uint8_t *dst; int len ; if (k->len1) /* already compiled */ return; dst = (uint8_t *)k->key; DBG(2, "sequence %s :\n", k->key); /* * on the left hand side only entries of type KT_SEND are allowed, * with a special case for single chars which are case-insensitive */ for (src = k->key; *src; src += len) { struct key_entry *e; char c = tolower(*src), *cp = src; /* defaults... */ len = strcspn(src, " \t"); if (len == 0) { len = 1; continue; } if (len == 1) cp = &c; e = lookup_key(cp, len); if (e == NULL) { DBG(0, "%.*s key not found\n", len, src); break; } if (e->type != KT_SEND && e->type != KT_FW) { DBG(0, "%.*s key not valid as hotkey\n", len, src); break; } DBG(2, "\t%.*s becomes %d\n", len, src, e - lps->e); *dst++ = e->code; } k->len1 = dst - (uint8_t *)k->key; DBG(2, "\taction %s\n", k->value ); } /* * Helper function that, given "N = a b c d ..." appends to lps.e[] * the key_entry sections for the keydefs on the right side. * lps.nentries points to the next free slot. */ static int build_seq(struct section *sec) { const struct entry *k; struct key_entry *e = lps->e + lps->nentries; if (sec == NULL) { DBG(0, "section not found\n"); return 1; } DBG(2, "exploring section %p\n", sec); for (k = cfg_find_entry(sec, NULL); k; k = k->next) { int l; char *s = k->key; DBG(2, "found %s = %s\n", k->key, k->value); e->type = KT_SEND; /* normal */ e->code = atoi(s); if ( index("sfv", *s) ) { /* shift fiveway volume */ e->type = (*s == 's') ? KT_SHIFT : (*s == 'f' ? KT_FW : KT_VOL); e->code = atoi(s+1); } else if (!strncasecmp(s, "row", 3)) { e->type = KT_SYM; /* row */ e->ysteps = atoi(s+3); e->code = 0; } s = k->value; while ( (l = strcspn(s, " \t")) || *s ) { if (l == 0) { s++; continue; } if (*s == '\\') { s++; l--; } e->name = s; e->namelen = l; e++; e[0] = e[-1]; e->code++; /* prepare next entry */ s += l; } } lps->nentries = e - lps->e; DBG(1, "done %d entries\n", lps->nentries); return 0; } /* fetch a string, int or key name from the config file, * and store the value in dst. type can be * 's' to store a string; * 'i' to store an int; * 'k' to store a keycode (lookup the value on the right); */ static int setVal(struct section *sec, const char *key, int type, void *dst) { struct key_entry *e; const struct entry *k = cfg_find_entry(sec, key); if (!k) return 1; switch (type) { case 's': /* string */ *(char **)dst = k->value; break; case 'i': /* int */ *(int *)dst = strtol(k->value, NULL, 0) ; break; case 'k': /* keycode */ e = lookup_key(k->value, strlen(k->value)); if (e == NULL || (e->type == KT_ALT || e->type == KT_SHIFT)) { DBG(0, "Warning: no code for %s %s\n", key, k->value) ; return 1; } *(int *)dst = e->code ; break; } return 0; } /* set dst with the code of the key called 'key' */ static int setKey(const char *key, int *dst) { struct key_entry *e = lookup_key(key, strlen(key)); if (e) *dst = e->code; return (e ? 0 : 1); } /* * reinitialize. */ static int launchpad_init(char *path) { struct section *sec ; int i; struct key_entry *e; memset(lps, 0, (char *)&lps->savearea - (char *)lps); /* load initial values */ lps->script_path = ""; lps->hot_interval = 700; lps->key_delay = 50; lps->refresh_delay = 100; lps->kpad.fdin = lps->fw.fdin = lps->vol.fdin = -1; if (path == NULL) path = lps->cfg_name; lps->db = cfg_read(path, lps->basedir, NULL); if ( lps->db == NULL) { DBG(0, "%s -- not found or bad\n", path) ; return -1 ; } /* load file identifiers */ sec = cfg_find_section(lps->db, "Settings"); if (!sec) { DBG(0, "section Settings not found\n") ; return -1; } /* load system-independent values */ setVal(sec, "HotInterval", 'i', &lps->hot_interval); setVal(sec, "ScriptDirectory", 's', &lps->script_path); setVal(sec, "InterKeyDelay", 'i', &lps->key_delay); setVal(sec, "RefreshDelay", 'i', &lps->refresh_delay); setVal(sec, "KpadIn", 's', &lps->kpad.namein); setVal(sec, "KpadOut", 's', &lps->kpad.nameout); setVal(sec, "FwIn", 's', &lps->fw.namein); setVal(sec, "FwOut", 's', &lps->fw.nameout); setVal(sec, "VolIn", 's', &lps->vol.namein); setVal(sec, "VolOut", 's', &lps->vol.nameout); /* try open files so we know on what system we are */ i = O_RDONLY | O_NONBLOCK; lps->kpad.fdin = open(lps->kpad.namein, i); lps->fw.fdin = open(lps->fw.namein, i); lps->vol.fdin = open(lps->vol.namein, i); DBG(2, "open %s %s %s gives %d %d %d\n", lps->kpad.namein, lps->fw.namein, lps->vol.namein, lps->kpad.fdin, lps->fw.fdin, lps->vol.fdin); if (lps->kpad.fdin == -1 && lps->fw.fdin == -1 && lps->vol.fdin) { DBG(0, "no input available, exiting...\n") ; return -1; } i = O_WRONLY | O_NONBLOCK; lps->kpad.fdout = open(lps->kpad.nameout, i) ; lps->fw.fdout = open(lps->fw.nameout, i); lps->vol.fdout = open(lps->vol.nameout, i); /* ignore errors on output */ /* load keymap entries (system-dependent) */ build_seq(cfg_find_section(lps->db, "inkeys")); build_seq(cfg_find_section(lps->db, is_kindle3() ? "inkeys-k3" : "inkeys-dx")); DBG(2, "sort sequences\n"); /* sort using the extended comparison function */ qsort(lps->e, lps->nentries, sizeof(*e), ecmp1); /* now remove duplicates, keeping the shortest sequences */ for (e = lps->e, i = 0; i < lps->nentries - 1; i++, e++) { if (ecmp(e, e+1) == 0) { DBG(1, "dup %3d for ty %d code %3d y %3d l %d %.*s\n", i, e->type, e->code, e->ysteps, e->namelen, e->namelen, e->name); e[1].type = 255; } } /* second pass, bubble up all duplicate elements */ for (e = lps->e, i = 0; i < lps->nentries; i++, e++) { if (e->type == 255) { lps->nentries--; *e = lps->e[lps->nentries]; } } /* sort again, this time using ecmp */ qsort(lps->e, lps->nentries, sizeof(*e), ecmp); /* build the 'by_code' array, used in output */ memset(lps->by_code, 0, sizeof(lps->by_code)); DBG(2, "--- dump events by name ---\n"); for (e = lps->e, i = 0; i < lps->nentries; i++, e++) { if (e->type == KT_SEND || e->type == KT_FW) lps->by_code[e->code] = e; DBG(2, "%3d ty %d code %3d y %3d l %d %.*s\n", i, e->type, e->code, e->ysteps, e->namelen, e->namelen, e->name); } DBG(2, "--- debugging -- dump events by code ---\n"); for (i=0; i < 256; i++) { e = lps->by_code[i]; if (!e) continue; DBG(2, "%3d ty %d code %3d y %3d l %d %.*s\n", i, e->type, e->code, e->ysteps, e->namelen, e->namelen, e->name); } /* load parameters that depend on the key mapping */ setVal(sec, "Introducer", 'k', &lps->intro); setVal(sec, "Trailer", 'k', &lps->trailer); setVal(sec, "TermEnd", 'k', &lps->term_end); setVal(sec, "TermEsc", 'k', &lps->term_esc); setVal(sec, "TermCtrl", 'k', &lps->term_ctrl); setVal(sec, "TermShift", 'k', &lps->term_shift); setVal(sec, "TermSym", 'k', &lps->term_sym); setVal(sec, "TermFn", 'k', &lps->term_fn); lps->xsym = 1; /* position of initial symbol */ lps->ysym = 1; setKey("Sym", &lps->sym); setKey("Left", &lps->fw_left); setKey("Right", &lps->fw_right); setKey("Up", &lps->fw_up); setKey("Down", &lps->fw_down); setKey("Select", &lps->fw_select); setKey("Del", &lps->del); /* translate actions into event sequences */ sec = cfg_find_section(lps->db, "Actions"); if (sec) { struct entry *k; k = lps->actions = (struct entry *)cfg_find_entry(sec, NULL); for (; k; k = k->next) compile_action(k); } return 0 ; } /* locate a valid hotkey sequence */ static const struct entry *find_action(uint8_t *pseq, int len) { const struct entry *k; for (k = lps->actions; k; k = k->next) { if (len == k->len1 && !bcmp(k->key, pseq, len)) { DBG(2, "found action %s\n", k->value); return k; } } return NULL ; } static char *get_file_contents(const char *path) { int fd ; char *p = NULL ; unsigned long flen ; fd = open(path, O_RDONLY); if (fd < 0) { DBG(0, "Can't open kindle script file %s\n", path); return NULL; } flen = lseek(fd, 0, SEEK_END) ; lseek(fd, 0, SEEK_SET) ; p = calloc(1, flen+1); if (p == NULL) { DBG(0, "Can't allocate %lu bytes\n", flen); } else if (read(fd, p, flen) != flen) { DBG(0, "Can't read %lu bytes from %s\n", flen, path); free(p); p = NULL; } close(fd); return p; } /* record additional entries to send to the kindle. They will * be actually sent later to avoid blocking. */ static void send_event(uint8_t code, uint8_t mode) { ds_append(&lps->pending, &code, 1); ds_append(&lps->pending, &mode, 1); } /* the actual send_event handler */ void send_event1(uint8_t code, uint8_t mode) { char tmpbuf[32]; int len = sprintf(tmpbuf, "send%s %d\n", mode == KT_SHIFT ? "shift" : "", code) ; int fd = (mode == KT_FW) ? lps->fw.fdout : (mode == KT_VOL) ? lps->vol.fdout : lps->kpad.fdout ; if (fd < 0) return; DBG(1, "mode %d %s", mode, tmpbuf); write(fd, tmpbuf, len) ; } /* * Send a key-entry to the kindle, possibly expand the SYM entries */ static void send_key_entry(struct key_entry *e) { int i; if (e == NULL) return; if (e->type != KT_SYM) { send_event(e->code, e->type); return; } DBG(2, "symbol %.*s at x %d y %d\n", e->namelen, e->name, e->code, e->ysteps); send_event(lps->sym, KT_SEND); i = e->code; if (i < lps->xsym) { /* left */ while (i++ < lps->xsym) send_event(lps->fw_left, KT_FW); } else if (i > lps->xsym) { while (i-- > lps->xsym) send_event(lps->fw_right, KT_FW); } i = e->ysteps; if (i < lps->ysym) { /* up */ while (i++ < lps->ysym) send_event(lps->fw_up, KT_FW); } else if (i > lps->ysym) { while (i-- > lps->ysym) send_event(lps->fw_down, KT_FW); } send_event(lps->fw_select, KT_FW); send_event(lps->sym, KT_SEND); } static void send_key(const char *p, int len) { send_key_entry(lookup_key(p, len)); } /* send an ascii string to the kindle */ static void send_ascii_string(const char *p, int len) { DBG(2, "%.*s\n", len, p); for ( ; len > 0 && *p; len--, p++) { if (*p == '\\' && p[1]) { p++ ; len--; } send_key(p, 1); } }; /* * send a sequence of keywords and strings * start with a DEL to enter input mode. */ static void process_script(char *p) { int i, l ; DBG(1, "%s\n", p); send_event(lps->del, KT_SEND); for (; *p ; p += l) { /* get the symbol or string length if in quotes */ if (*p == '"' || *p == '\'') { for (l=1; p[l] && p[l] != p[0]; l++) { if (p[l] == '\\' && p[l+1]) l++; } if (p[l] == p[0]) l++; } else l = strcspn(p, " \t\r\n"); DBG(2, "substring %p %.*s\n", p, l, p); if (l == 0) { l = strspn(p, " \t\r\n"); DBG(2, "whitespace %p %.*s\n", p, l, p); continue; } i = l; switch(*p) { case '\'': /* apostrophe, ignore final char */ i--; if (p[i] == '\'') i--; send_key(p+1, i); break ; case '"': i--; if (p[i] == '"') i--; send_ascii_string(p+1, i) ; break ; default: send_ascii_string(p, l) ; break ; } } } struct terminal *shell_find(const char *name); static void print_help(void); static int execute_action(const struct entry *k) { char *tmp = NULL, *p = k->value ; char *must_free = NULL ; int l; DBG(1, "%s\n", p); switch(*p) { case '!': /* exec a shell command */ if (!strncmp(p+1, "terminal", 8)) { struct terminal *t = shell_find(p+1); DBG(0, "start %s got %p\n", p+1, t); if (t == NULL) return 1; lps->fb = fb_open(); /* also mark terminal mode */ if (lps->fb) { /* if success, input is for us */ pixmap_t *pix = &lps->fb->pixmap; int l = pix->width * pix->height * pix->bpp / 8; lps->curterm = t; ds_reset(lps->save_pixmap); ds_append(&lps->save_pixmap, pix->surface, l); print_help(); capture_input(1) ; // set a timeout to popup the terminal gettimeofday(&lps->screen_due, NULL); } return 0; } DBG(1, "call system %s\n", p+1); return system(p+1); case '@': /* take keys from file, then as above */ asprintf(&tmp, "%s/%s", lps->script_path, p+1); DBG(1, "opening %s\n", tmp); must_free = p = get_file_contents(tmp); if (!must_free) return 1; p = skipws(p); /* remove initial send_string and trailing DEL */ if (strstr(p, "send_string") == p) p += strlen("send_string"); trimws(p, NULL); l = strlen(p); if (!strcasecmp("'del'", p + l - 5)) p[l-5] = '\0'; process_script(p); break; case '#': /* send keys as specified */ process_script(p+1); break ; default: /* send keys immediately */ process_script(p) ; break ; } if (must_free) free(must_free); DBG(1, "sent %d keys\n", ds_len(lps->pending)/2); gettimeofday(&lps->keys_due, NULL); return 0 ; } /* block or unblock input events to the kindle. * If we detect the initiator, we block events, and release them * after we are done. Setting capture mode also creates a timeout * upon which we will unblock. */ static void capture_input(int capture) { capture = capture ? 1 : 0 ; /* normalize */ if (capture) { gettimeofday(&lps->hotkey_due, NULL); timeradd_ms(&lps->hotkey_due, lps->hot_interval, &lps->hotkey_due); } else { timerclear(&lps->hotkey_due); } #ifndef __FreeBSD__ if (lps->kpad.fdin != -1 && ioctl(lps->kpad.fdin, EVIOCGRAB, capture)) perror("Capture kbd input:"); if (lps->fw.fdin != -1 && ioctl(lps->fw.fdin, EVIOCGRAB, capture)) perror("Capture fw input:"); if (lps->vol.fdin != -1 && ioctl(lps->vol.fdin, EVIOCGRAB, capture)) perror("Capture k3_vol input:"); #endif } /* process a hotkey sequence if found */ static void call_hotkey(int mode) { const struct entry *act ; int i ; DBG(1, "%s\n", mode ? "direct" : "timeout"); timerclear(&lps->hotkey_due); if (!lps->hotkey_mode) return; capture_input(0) ; lps->hotkey_mode = 0; if (lps->hot_seq_len == 0) return; ds_reset(lps->pending); act = find_action(lps->hot_seq, lps->hot_seq_len) ; if (act) { DBG(1, "found hotkey sequence for %s\n", act->value) ; execute_action(act); } else { DBG(0, "Unknown hotkey sequence entered len %d: ", lps->hot_seq_len) ; /* must send the kindle all keys we stole. */ for (i = 0; i < lps->hot_seq_len; i++) { send_event(lps->hot_seq[i], lps->hot_seq_dev[i]); } } lps->hot_seq_len = 0 ; } static void curterm_end(void) { int l = ds_len(lps->save_pixmap); DBG(0, "exit from terminal mode\n"); if (l && lps->fb) { pixmap_t *p = &lps->fb->pixmap; memcpy(p->surface, ds_data(lps->save_pixmap), l); ds_reset(lps->save_pixmap); fb_update_area(lps->fb, UMODE_PARTIAL, 0, 0, p->width, p->height, NULL); } fb_close(lps->fb); lps->curterm = NULL; lps->fb = NULL; capture_input(0); } /* * pass keys to the terminal code, conversion etc. will happen there */ static void process_term(struct input_event *ev, int mode) { char k[16]; struct key_entry *e = lps->by_code[ev->code]; /* simulate ctrl, shift, sym keys */ static int ctrl = 0; static int shift = 0; static int sym = 0; static int fn = 0; DBG(1, "process event %d %d e %p %.*s for terminal\n", ev->value, ev->code, e, e ? e->namelen : 3, e ? e->name : "---"); if (e == NULL) /* unknown event */ return; memset(k, 0, sizeof(k)); if (ev->value == 1 || ev->value == 2) { /* press */ #define E_IS(e, s) ((e)->namelen == strlen(s) && !strncasecmp((e)->name, s, (e)->namelen)) if (ev->code == lps->term_end) // ignore here, handle on release return; if (ev->code == lps->term_shift) shift = 1; else if (ev->code == lps->term_ctrl) ctrl = 1; else if (ev->code == lps->term_sym) sym = 1; else if (ev->code == lps->term_fn) fn = 1; else if (ev->code == lps->term_esc) k[0] = 0x1b; /* escape */ else if (fn) { /* map chars into escape sequences */ const char *fnk[] = { "q\e[[A", // F1 "w\e[[B", // F2 "e\e[[C", // F3 "r\e[[D", // F4 "t\e[[E", // F5 "y\e[17~", // F6 "u\e[18~", // F7 "i\e[19~", // F8 "o\e[20~", // F9 "p\e[21~", // F10 "l\e[23~", // F11 "D\e[24~", // F12 NULL }; int i; char c = ' '; if (e->namelen == 1) c = e->name[0]; else if (E_IS(e, "Del")) c = 'D'; for (i = 0; fnk[i]; i++) { if (fnk[i][0] == c) { strcpy(k, fnk[i]+1); break; } } DBG(0, "function %s\n", k); } else if (sym) { /* translate. The first row in the table contains * the base characters, and the other * two are the mappings with SYM and SYM-SHIFT */ const char *t[] = { "qazuiopklD.SE", "`\t<-=[];'\\,./", "~\t>_+{}:\"|<>?" }; char *p; if (e->namelen == 1) k[0] = e->name[0]; else if (E_IS(e, "Del")) k[0] = 'D'; else if (E_IS(e, "Sym")) k[0] = 'S'; else if (E_IS(e, "Enter")) k[0] = 'E'; p = index(t[0], k[0]); if (p == NULL) return; /* invalid */ k[0] = t[shift+1][p - t[0]]; if (k[0] == '\t' && shift) strcpy(k, "\e[Z"); // backtab } else if (e->namelen == 1) { k[0] = e->name[0]; if (isalpha(k[0])) { if (shift) // shift overrides control k[0] += 'A' - 'a'; else if (ctrl) k[0] += 1 - 'a'; } else if (isdigit(k[0])) { if (shift) // shift overrides control k[0] = ")!@#$%^&*("[k[0] - '0']; else if (ctrl) k[0] += 1 - 'a'; } } else if (E_IS(e, "Enter")) k[0] = 13; else if (E_IS(e, "Space")) k[0] = ' '; else if (E_IS(e, "Del")) k[0] = 0x7f; else if (E_IS(e, "Up")) /* PgUp if shift pressed */ strcpy(k, shift ? "\e[5~" : "\e[A"); else if (E_IS(e, "Down")) /* PgDown if shift pressed */ strcpy(k, shift ? "\e[6~" : "\e[B"); else if (E_IS(e, "Right")) strcpy(k, "\e[C"); else if (E_IS(e, "Left")) strcpy(k, "\e[D"); } else if (ev->value == 0) { /* release */ if (ev->code == lps->term_end) { curterm_end(); return; } if (ev->code == lps->term_shift) shift = 0; else if (ev->code == lps->term_ctrl) ctrl = 0; else if (ev->code == lps->term_sym) sym = 0; else if (ev->code == lps->term_fn) fn = 0; } if (lps->curterm) term_keyin(lps->curterm->the_shell, k); } /* * print a buffer at x, y. If attr, use attributes array * Wrap after 'cols'. */ static void print_buf(int x0, int y0, int cols, int cur, const uint8_t *buf, int len, const uint8_t *attr, int bg0) { int i, x = x0, y = y0; pixmap_t char_pixmap; for (i=0; i < len; i++) { unsigned char cc = buf[i]; unsigned char bg = attr ? attr[i] : (bg0 << 2); bg = (bg & 0x38) >> 2; /* background color */ bg = bg | (bg << 4); if ( i == cur ) bg |= 0x88; get_char_pixmap(lps->fb->font, cc, &char_pixmap) ; pix_blt(&lps->fb->pixmap, x, y, &char_pixmap, 0, 0, -1, -1, bg) ; x += char_pixmap.width; if ( (i+1) % cols == 0) { x = x0; y += char_pixmap.height; } } fb_update_area(lps->fb, UMODE_PARTIAL, x0, y0, cols*(char_pixmap.width), y - y0, NULL) ; DBG(2, "end\n"); } static void print_help(void) { const uint8_t help[] = "\ === keyboard mapping =================================\ !~ @ # $ % ^ &_ *+ ({ )} Fn \ 1` 2 3 4 5 6 7- 8= 9[ 0] \ \ <-- : \" | \ A-> K; L' del\\ \ \ > < > ? \ Z< ., Sy. En/ \ \ Ctrl Sym "; int l = sizeof(help); print_buf(20, 420, l/11, -1, help, l, NULL, 0x8); } /* * update the screen. We know the state is 'modified' so we * don't need to read it, just notify it and fetch data. * XXX to optimize the code we could store a copy of the prev * window so we only update smaller regions of the screen. */ void process_screen(void) { struct term_state st = { .flags = TS_MOD, .modified = 0}; uint8_t *d; #define XOFS 0 /* horizontal offset */ #define YOFS 0 /* vertical offset */ timerclear(&lps->screen_due); if (!lps->curterm || !lps->fb) return; term_state(lps->curterm->the_shell, &st); d = (unsigned char *)st.data; print_buf(XOFS, YOFS, st.cols, st.cur, d, st.rows * st.cols, d + st.rows * st.cols, 0); } /* * Process an input event from the kindle. 'mode' is the source */ static void process_event(struct input_event *ev, int mode) { static int npressed = 0 ; /* keys currently pressed */ static int got_intro = 0 ; /* we saw the introducer */ if (ev == NULL) { /* SYNC */ npressed = 0; lps->hot_seq_len = 0 ; got_intro = 0 ; return; } if (ev->type != EV_KEY) return; DBG(2, "event ty %d val %d code %d got_intro %d npress %d seqlen %d\n", ev->type, ev->value, ev->code, got_intro, npressed, lps->hot_seq_len); /* ignore autorepeat events, ev->value == 2. */ if (lps->fb) { process_term(ev, mode); return; } if (ev->value == 1) { /* key pressed */ npressed += 1 ; if (lps->hotkey_mode == 0) { got_intro = (npressed == 1 && ev->code == lps->intro); } else { if (ev->code == lps->trailer) { /* sequence complete, try it */ call_hotkey(1); } else { int i = lps->hot_seq_len++; lps->hot_seq_dev[i] = mode ; lps->hot_seq[i] = ev->code ; if (i == MAXSEQ - 1) call_hotkey(1); } } } else if (ev->value == 0) { /* key released */ if (npressed > 0) /* don't go out of sync */ npressed --; if (npressed == 0 && ev->code == lps->intro && got_intro) { got_intro = 0; capture_input(1) ; /* block input to the kindle */ lps->hotkey_mode = 1; DBG(1, "-- start hotkey mode\n"); } } } static void hup_handler(int x) { lps->got_signal = 1 ; /* reinit */ } static void int_handler(int x) { lps->got_signal = 2 ; /* exit */ } static void fd_close(int *fd) { if (*fd == -1) return; close(*fd); *fd = -1; } static void free_terminals(void) { struct terminal *t; curterm_end(); while ( (t = lps->allterm) ) { lps->allterm = t->next; term_kill(t->the_shell, 9); free(t); } } void term_dead(struct sess *s) { struct terminal **t, *cur; for (t = &lps->allterm; (cur = *t); t = &(*t)->next) { if (cur->the_shell != s) continue; DBG(0, "terminal %s is dead\n", cur->name); *t = cur->next; if (lps->curterm == cur) curterm_end(); memset(cur, 0, sizeof(*cur)); free(cur); return; } DBG(0, "could not find dead terminal %p\n", s); } /* * find or create a shell with the given name. The name string * is copied in the descriptor so it can be preserved on reboots. */ struct terminal *shell_find(const char *name) { struct terminal *t; int l = strlen(name) + 1; for (t = lps->allterm; t; t = t->next) { if (!strcmp(name, t->name)) return t; } t = calloc(1, sizeof(*t) + l); if (!t) { DBG(0, "could not allocate session for %s\n", name); return t; } strcpy(t->name, name); t->the_shell = term_new("/bin/sh", t->name, 25, 80, term_dead); if (!t->the_shell) { free(t); return NULL; } t->next = lps->allterm; lps->allterm = t; return t; } /* * prepare for a restart or for final exiting */ static void launchpad_deinit(int restart) { DBG(0, "called, restart %d\n", restart); lps->got_signal = 0 ; // XXX should remove the pending sessions from the scheduler ? curterm_end(); lps->pending = ds_free(lps->pending); signal(SIGINT, SIG_DFL) ; signal(SIGTERM, SIG_DFL) ; signal(SIGHUP, SIG_DFL) ; if (!restart) free_terminals(); lps->hotkey_mode = 0; fd_close(&lps->kpad.fdin); fd_close(&lps->fw.fdin); fd_close(&lps->vol.fdin); fd_close(&lps->kpad.fdout); fd_close(&lps->fw.fdout); fd_close(&lps->vol.fdout); if (lps->db) { cfg_free(lps->db) ; lps->db = NULL ; } } int launchpad_start(void); /* * callback for select. * We have only one session so ignore _s */ int handle_launchpad(void *_s, struct cb_args *a) { int fds[3] = { lps->kpad.fdin, lps->fw.fdin, lps->vol.fdin }; int i, j, ev; DBG(2, "fds %d %d %d\n", lps->kpad.fdin, lps->fw.fdin, lps->vol.fdin); DBG(2, "term %p sh %p hotkey_due %d pend %d\n", lps->fb, lps->curterm, (int)lps->hotkey_due.tv_usec, ds_len(lps->pending) ); if (lps->kpad.fdin < 0) { /* dead */ if (a->run == 0) return 0; /* try to restart or terminate ? */ launchpad_deinit(0); return 1; } if (a->run == 0) { /* create screen refresh timeout if needed */ if (lps->fb && lps->curterm && term_state(lps->curterm->the_shell, NULL) && !timerisset(&lps->screen_due)) timeradd_ms(&a->now, lps->refresh_delay, &lps->screen_due); /* Record pending timeouts */ timersetmin(&a->due, &lps->screen_due); timersetmin(&a->due, &lps->hotkey_due); timersetmin(&a->due, &lps->keys_due); /* if we have keys to send, ignore input events */ if (ds_len(lps->pending) > 0) return 0; for (i=0; i < 3; i++) { if (fds[i] >= 0) FD_SET(fds[i], a->r); if (fds[i] > a->maxfd) a->maxfd = fds[i]; } return 1; } if (timerdue(&lps->hotkey_due, &a->now)) call_hotkey(0); if (lps->got_signal == 1) { launchpad_deinit(1); launchpad_start(); return 0; } if (lps->got_signal == 2) { launchpad_deinit(0); return 0; } ev = 0; if (ds_len(lps->pending) == 0) { struct input_event kbbuf[2]; for (j = 0; j < sizeof(fds) / sizeof(fds[0]) ; j++) { int l = sizeof(struct input_event); int n; if (fds[j] < 0 || !FD_ISSET(fds[j], a->r)) continue; ev = 1; /* got an event */ DBG(1, "reading on %d\n", fds[j]); #ifdef __FreeBSD__ n = host_event(fds[j], kbbuf, l); #else n = read(fds[j], kbbuf, l* 2) ; #endif DBG(2, "got %d bytes from %d\n", n, fds[j]); for (i = 0; i < 2 && n >= l; i++, n -= l) { process_event(kbbuf + i, j) ; } } } /* test pending again, could have been set above */ if (ds_len(lps->pending) > 0) { if (timerdue(&lps->keys_due, &a->now)) { uint8_t *p = (uint8_t *)ds_data(lps->pending); struct timeval k = { 0, lps->key_delay * 1000 }; send_event1(p[0], p[1]); ds_shift(lps->pending, 2); if (ds_len(lps->pending) > 0) timeradd(&a->now, &k, &lps->keys_due); else timerclear(&lps->keys_due); DBG(1, "sending key, left %d\n", ds_len(lps->pending)/2); } return 0; } if (timerdue(&lps->screen_due, &a->now)) { process_screen(); return 0; } if (ev == 0) { /* timeout ? resync ? */ process_event(NULL, 0); } return 0; } int launchpad_parse(int *ac, char *av[]) { int i ; lps = __me.app->data; DBG(0, "Launchpad start routine\n"); memset(lps, 0, sizeof(*lps)); /* copy the full config name into lps->basedir */ i = sizeof(lps->basedir) - strlen(".ini") - 1; if (readlink ("/proc/self/exe", lps->basedir, i) == -1) strncpy(lps->basedir, av[0], i) ; strcat(lps->basedir, ".ini"); /* dirname() may or may not truncates the argument, so we * enforce the truncation and append a '/' */ i = strlen( dirname(lps->basedir) ); lps->basedir[i] = '\0'; lps->cfg_name = lps->basedir + i + 1; lps->cfg_name = "launchpad.ini"; // XXX DBG(1, "inipath is %s ini_name %s\n", lps->basedir, lps->cfg_name); if (*ac > 2 && !strcmp(av[1], "--cfg")) lps->cfg_name = av[2]; return 0; } int launchpad_start(void) { new_sess(0, -2, handle_launchpad, NULL); signal(SIGINT, int_handler); signal(SIGTERM, int_handler); signal(SIGHUP, hup_handler); process_event(NULL, 0); /* reset args */ if (!launchpad_init(NULL)) return 0; DBG(0, "init routine failed, exiting\n"); launchpad_deinit(0) ; return 0 ; } struct app lpad = { .parse = launchpad_parse, .start = launchpad_start, .data = &lpad_desc}; screen.c000644 000423 000000 00000006567 11476051326 012762 0ustar00luigiwheel000000 000000 /* * (C) 2010 Andy * * fbscreen interface routines */ #include #include #include #include #include #include #include #include #include #include #include "pixop.h" #include "screen.h" typedef unsigned char u8 ; #include "linux/einkfb.h" #include "font.h" fbscreen_t *fb_open(void) { struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; static fbscreen_t fb ; // XXX non reentrant memset(&fb, 0, sizeof(fb)) ; /* Open the file for reading and writing */ fb.fd = open("/dev/fb0", O_RDWR); if (fb.fd < 0) { printf("Error: cannot open framebuffer device.\n"); return NULL; } /* Get fixed screen information */ if (ioctl(fb.fd, FBIOGET_FSCREENINFO, &finfo)) /* non fatal */ printf("Error reading fixed screen information.\n"); /* Get variable screen information */ if (ioctl(fb.fd, FBIOGET_VSCREENINFO, &vinfo)) { printf("Error reading variable screen information.\n"); /* assume we are on K3, if so */ vinfo.xres=600; vinfo.yres=800; vinfo.bits_per_pixel=4 ; } /* Figure out the size of the screen in bytes */ fb.screensize = (vinfo.xres * vinfo.yres * vinfo.bits_per_pixel) / 8; /* Map the device to memory. * We need MAP_SHARED or updates will not be sent. */ fb.pixmap.surface = mmap(NULL, fb.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0); if (fb.pixmap.surface == ((void*) -1)) { close(fb.fd) ; printf("Error: failed to mmap framebuffer\n"); return NULL; } fb.pixmap.width = vinfo.xres ; fb.pixmap.height = vinfo.yres ; fb.pixmap.bpp = vinfo.bits_per_pixel; fb.font = &font_pixmap; return &fb; } void fb_close(fbscreen_t *fb) { if (!fb) return; if ((fb->fd != -1) && (fb->pixmap.surface) && (fb->screensize != 0)) { munmap(fb->pixmap.surface, fb->screensize); close(fb->fd); } fb->fd = -1 ; fb->screensize = 0 ; if (fb->pixmap.surface) memset(&fb->pixmap, 0, sizeof(pixmap_t)) ; fb->pixmap.surface = NULL; } void fb_update_area(fbscreen_t *fb, int mode, int x0, int y0, int w, int h, void *pbuf) { update_area_t ua; int ret; c_truncate(&x0, &w, fb->pixmap.width); c_truncate(&y0, &h, fb->pixmap.height); ua.x1 = x0 ; ua.y1 = y0 ; ua.x2 = x0 + w ; ua.y2 = y0 + h ; ua.which_fx = mode ; ua.buffer = pbuf ; if (w == 0 || h == 0) return; ret = ioctl(fb->fd, FBIO_EINK_UPDATE_DISPLAY_AREA, &ua); if (ret) { fprintf(stderr, "%s @%d %d %d x %d error %d\n", __FUNCTION__, x0, y0, w, h, errno); perror("error: "); } } int fb_char_at(fbscreen_t *fb, const struct font *font, int x, int y, char c, int bg) { pixmap_t pix; if (font == NULL) font = fb->font; get_char_pixmap(font, c, &pix) ; pix_blt(&fb->pixmap, x, y, &pix, 0, 0, -1, -1, bg) ; return 0; } const struct font *fb_getfont(const char *name) { return &font_pixmap; } int get_char_pixmap(const struct font *font, int code, pixmap_t *ppx) { int bytesperchar; if (font == NULL) font = &font_pixmap; bytesperchar = (font->width * font->bpp + 7)/8 * font->height; code &= 0xff ; if (code < font->code_first || code > font->code_last) code = font->code_first ; ppx->width = font_pixmap.width ; ppx->height = font_pixmap.height ; ppx->bpp = font_pixmap.bpp ; ppx->surface = (font->pixmap + (code-font->code_first)*bytesperchar) ; return code ; } pixop.c000644 000423 000000 00000012672 11476210514 012630 0ustar00luigiwheel000000 000000 /* * (C) 2010 Andy * * pixmap routines */ #include #include #include #include //#include #include #include #include #include #include "pixop.h" /* * XXX all the routines here should consider the rounding * due to pixmaps not using the full 8 bits. */ // fill rectangle in pixmap "dst" with color "color" // bx, by = upper-left coord in dst pixmap (pixels) // wd, height = width and height of rectangle (pixels) int pix_fill(pixmap_t* dst, int bx, int by, int width, int height, int color) { unsigned char *dp; int dst_stride; // dst pixmap width in bytes int fill_stride; // fill width in bytes int n; if (dst == NULL) return 0; c_truncate(&bx, &width, dst->width); c_truncate(&by, &height, dst->height); if (width <= 0 || height <= 0) return 0; dp = dst->surface; switch (dst->bpp) { case 4: // 4 bits/pixel, 2 pixels per byte color &= 0x0F; color |= (color << 4); dst_stride = (dst->width + 1)/2; fill_stride = (width + 1)/2; bx /= 2; // first byte offset in row dp += by*dst_stride; // start row dp += bx; // first pixel to fill break; default: fprintf(stderr, "unsupported pix_fill depth %d\n", dst->bpp); return 0; } for (n = 0; height-- > 0; dp += dst_stride, n += fill_stride) memset(dp, color, fill_stride); return width*height; // num of pixels actually filled } /* transfer pixmap "src:sx,sy (width:height)" to pixmap "dst: dx, dy" * bg, if non-zero, is OR-ed to every byte in the dst region. */ int pix_blt(pixmap_t* dst, int dx, int dy, pixmap_t* src, int sx, int sy, int width, int height, int bg) { unsigned char *dstp, *srcp; int dst_stride, src_stride; int i, j, n_bytes; if (dst == NULL || src == NULL) return 0; if (width < 0) { width = src->width; height = src->height; } #ifdef DEBUG int s_dx = dx, s_dy = dy, s_sx = sx, s_sy = sy, s_width = width, s_height = height; #define M(a) do { if (a != s_ ## a) \ fprintf(stderr, #a " modified from %d to %d\n", s_ ## a, a); \ while (0) #else #define M(a) #endif c_truncate(&sx, &width, src->width); c_truncate(&sy, &height, src->height); c_truncate(&dx, &width, dst->width); c_truncate(&dy, &height, dst->height); M(dx); M(dy); M(sx); M(sy); M(width); M(height); #ifdef DEBUG fprintf(stderr, "src: %dx%d dst: %dx%d\n", src->width, src->height, dst->width, dst->height); fprintf(stderr, "copy: %dx%d@%d+%d -> %d+%d\n\n", width, height, sx, sy, dx, dy); #endif if (height <= 0 || width <= 0) { // fprintf(stderr, "aborting copy\n"); return 0; } dst_stride = (dst->width*dst->bpp + 7)/8; // dst width in bytes src_stride = (src->width*src->bpp + 7)/8; // src width in bytes if (0 && dst->bpp == src->bpp) { for (i = 8, j=1; i > 0; i >>= 1, j <<=1) { if (dst->bpp == i && dx % j == 0 && sx % j == 0) goto fast; } } #if 1 /* * Non optimized code, in case bpp or aligment do not match. * Assumption: the sample on the left is on the LSbits of a byte. * * Algorithm: accumulate samples in a variable, then update destination. * We keep two 16-bit windows for both src and dst. * We need a byte and bit offset pointer in both. * The bpp adaptation is done simply by scaling according to * the difference in max values. */ /* base positions in bytes */ dstp = dst->surface + dy*dst_stride + dx*dst->bpp/8; srcp = src->surface + sy*src_stride + sx*src->bpp/8; uint16_t srcmask = ( (1<bpp) - 1); uint16_t dstmask = ( (1<bpp) - 1); for (i = 0; i < height; i++) { uint8_t srcofs = (sx*dst->bpp % 8); uint8_t dstofs = (dx*dst->bpp % 8); uint8_t *sp = srcp, *dp = dstp; uint16_t sd = sp[0] + (sp[1]<<8); uint16_t dd = dp[0] + (dp[1]<<8); for (j = 0; j < width; j++) { uint16_t x = (sd >> srcofs) & srcmask; // XXX potentially extend/reduce size if (src->bpp != dst->bpp) /* scale */ x = x * ( (1<bpp) - 1) / ( (1<bpp) - 1); /* clear destination and update */ x |= bg; dd &= ~(dstmask << dstofs); dd |= (x << dstofs); /* advance source */ srcofs += src->bpp; if (srcofs >= 8) { srcofs -= 8; sp++; sd = (sd >>8) + (sp[1] << 8); } /* advance destination */ dstofs += dst->bpp; if (dstofs >= 8) { dstofs -= 8; dp[0] = dd & 0xff; /* write back */ dp++; dd = (dd >>8) + (dp[1] << 8); } } /* final write */ dp[0] = dd & 0xff; dp[1] = (dd >> 8); dstp += dst_stride; srcp += src_stride; } #endif fast: /* if we get here, data is byte-aligned */ dx = dx*dst->bpp/8; // horz byte offset, truncated sx = sx*src->bpp/8; // horz byte offset, truncated dstp = dst->surface + dy*dst_stride + dx; srcp = src->surface + sy*src_stride + sx; n_bytes = width *dst->bpp/8; // truncated for (i = 0; i < height; i++) { memcpy(dstp, srcp, n_bytes); if (bg) { for (j=0; j< n_bytes; j++) dstp[j] |= bg; } dstp += dst_stride; srcp += src_stride; } return width*height; // num of pixels transferred } void pix_invert(pixmap_t *p) { int nbytes ; unsigned char *tmp ; if (!p) return; nbytes = (p->width+1 /2) * (p->height) ; for (tmp = p->surface ; nbytes--; tmp++) *tmp = ~(*tmp) ; } pixmap_t * pix_alloc(int w, int h) { int size = ((w+1)/2)*h + sizeof(pixmap_t) ; pixmap_t * p = (pixmap_t *)calloc(1, size); if (p) { p->width = w ; p->height = h ; p->surface = (unsigned char *)(p + 1); } return p ; } void pix_free(pixmap_t *p) { if (p) free(p) ; } ajaxterm.css000644 000423 000000 00000003404 11467257362 013657 0ustar00luigiwheel000000 000000 /* * $Id: ajaxterm.css 7726 2010-11-12 15:52:28Z luigi $ */ body { font-size: 8pt; background-color: #888; } #term { float: left; } .kindle { background-color: white; color: black; } pre.stat { margin: 0px; padding: 4px; display: block; font-family: monospace; white-space: pre; background-color: black; border-top: 1px solid black; color: white; } pre.stat span { padding: 0px; } pre.stat .on { background-color: #080; font-weight: bold; color: white; cursor: pointer; } pre.stat .off { background-color: #888; font-weight: bold; color: white; cursor: pointer; } pre.term { margin: 0px; padding: 4px; display: block; font-family: monospace; white-space: pre; background-color: #fff; border-top: 1px solid white; color: #000; } /* foreground/background colors used for color terminals. * XXX should provide a better set for greyscale */ pre.term span.f0 { color: #000; } pre.term span.f1 { color: #b00; } pre.term span.f2 { color: #0b0; } pre.term span.f3 { color: #bb0; } pre.term span.f4 { color: #00b; } pre.term span.f5 { color: #b0b; } pre.term span.f6 { color: #0bb; } pre.term span.f7 { color: #bbb; } pre.term span.f8 { color: #666; } pre.term span.f9 { color: #f00; } pre.term span.f10 { color: #0f0; } pre.term span.f11 { color: #ff0; } pre.term span.f12 { color: #00f; } pre.term span.f13 { color: #f0f; } pre.term span.f14 { color: #0ff; } pre.term span.f15 { color: #fff; } pre.term span.b0 { background-color: #000; } pre.term span.b1 { background-color: #b00; } pre.term span.b2 { background-color: #0b0; } pre.term span.b3 { background-color: #bb0; } pre.term span.b4 { background-color: #00b; } pre.term span.b5 { background-color: #b0b; } pre.term span.b6 { background-color: #0bb; } pre.term span.b7 { background-color: #bbb; } ajaxterm.html000644 000423 000000 00000001720 11466545543 014032 0ustar00luigiwheel000000 000000 Ajaxterm - Luigi Rizzo version
ajaxterm.js000644 000423 000000 00000020355 11477240222 013473 0ustar00luigiwheel000000 000000 /* * $Id: ajaxterm.js 7996 2010-12-06 14:58:07Z luigi $ * * setHTML works around an IE bug that requires content to be installed twice * (and still without working handlers) */ function setHTML(el, t) { if (!el) return; el.innerHTML = t; el.innerHTML = el.innerHTML; } ajaxterm={}; ajaxterm.Terminal = function(id, width, height, keylen, sid) { if (!width) width=80; if (!height) height=25; if (!keylen) keylen=16; var ie = (window.ActiveXObject) ? 1 : 0; var webkit = (navigator.userAgent.indexOf("WebKit") >= 0) ? 1 : 0; if (!sid) { /* generate a session ID if not supplied */ sid = ''; var alphabet = 'abcdefghijklmnopqrstuvwxyz'; var l = alphabet.length; for (var i=0; i < keylen; i++) sid += alphabet.charAt(Math.round(Math.random()*l)); } /* query0 is the base URL for a query */ var query0 = "s=" + sid + "&w=" + width + "&h=" + height; var query1 = query0 + "&c=1&k="; /* current query */ var timeout; /* callback for the update request */ var error_timeout; /* the error callback */ var keybuf = ''; /* keys to be transmitted */ var sending = 0; /* set when we have a pending refresh request */ var refresh_pending = 0; /* set when we have a pending refresh request */ /* elements in the top bar */ var div = document.getElementById(id); var dstat = document.createElement('pre'); /* status line */ var opt_get = document.createElement('a'); var opt_color = document.createElement('a'); var sdebug = document.createElement('span'); var dterm = document.createElement('div'); init(); debug('Session: ' + sid); return; function debug(s) { setHTML(sdebug, s); } function error() { debug("Connection lost at "+((new Date).getTime())); } function opt_add(opt,name) { opt.className = 'off'; setHTML(opt, ' '+name+' '); dstat.appendChild(opt); dstat.appendChild(document.createTextNode(' ')); } function do_get(event) { /* toggle get/post */ opt_get.className = (opt_get.className == 'off') ? 'on' : 'off'; debug('GET ' + opt_get.className); } function do_color(event) { var o = opt_color.className = (opt_color.className == 'off')?'on':'off'; query1 = query0 + (o=='on' ? "&c=1" : "") + "&k="; debug('Color '+opt_color.className); } /* we always want a pending update for refresh, * plus we want to send one when new data are around. */ function update() { if (keybuf == '') { /* outstanding pure refresh ? */ if (refresh_pending) return; refresh_pending = 1; } else { /* outstanding data */ if (sending) return; sending=1; } var r=new XMLHttpRequest(); r.tosend = keybuf; keybuf = ''; var query=query1 + r.tosend; if (opt_get.className=='on') { r.open("GET","u?"+query,true); if (ie) { // force a refresh r.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); } } else { r.open("POST","u",true); } r.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); r.onreadystatechange = function () { if (r.readyState!=4) return; if (error_timeout) window.clearTimeout(error_timeout); if (r.status!=200) { debug("Connection error, status: "+r.status + ' ' + r.statusText); return; } if (r.tosend) { sending = 0; debug('got ack for ' + r.tosend); } else { refresh_pending = 0; } if(ie) { var responseXMLdoc = new ActiveXObject("Microsoft.XMLDOM"); responseXMLdoc.loadXML(r.responseText); de = responseXMLdoc.documentElement; } else { de=r.responseXML.documentElement; } if (de.tagName=="pre" || de.tagName=="p") { setHTML(dterm, unescape(r.responseText)); } timeout=window.setTimeout(update, 100); /* next refresh */ } if (error_timeout) window.clearTimeout(error_timeout); error_timeout=window.setTimeout(error,25000); r.send ( (opt_get.className=='on') ? null : query ); } function queue(s) { keybuf += s; window.clearTimeout(timeout); timeout=window.setTimeout(update,10); // 10ms between keys } function keypress(ev, which) { if (!ev) ev = window.event; if (!which) which = ev.which; else if (which == -1) which = 0; s = "kp kC=" + ev.keyCode + " w=" + ev.which + " sh=" + ev.shiftKey + " ct=" + ev.ctrlKey + " al=" + ev.altKey; debug(s); var kc; var k = ""; if (ev.keyCode) kc = ev.keyCode; if (which) kc = which; if (0 && ev.altKey) { /* ALT-char ==> ESC + char */ if (kc >= 65 && kc <= 90) kc += 32; if (kc >= 97 && kc <= 122) k = String.fromCharCode(27) + String.fromCharCode(kc); } else if (ev.ctrlKey || ev.altKey) { if (kc >= 65 && kc <= 90) k = String.fromCharCode(kc - 64); // Ctrl-A..Z else if (kc >= 97 && kc <= 122) k = String.fromCharCode(kc - 96); // Ctrl-A..Z /* XXX check below, kc values do not match */ else if (kc == 54) k=String.fromCharCode(30); // Ctrl-^ else if (kc == 109) k=String.fromCharCode(31); // Ctrl-_ else if (kc == 219) k=String.fromCharCode(27); // Ctrl-[ else if (kc == 220) k=String.fromCharCode(28); // Ctrl-\ else if (kc == 221) k=String.fromCharCode(29); // Ctrl-] else if (kc == 219) k=String.fromCharCode(29); // Ctrl-] else if (kc == 219) k=String.fromCharCode(0); // Ctrl-@ } else if (which==0) { if (kc==9) k=String.fromCharCode(9); // Tab else if (kc==8) k=String.fromCharCode(127); // Backspace else if (kc==27) k=String.fromCharCode(27); // Escape else { if (kc==33) k="[5~"; // PgUp else if (kc==34) k="[6~"; // PgDn else if (kc==35) k="[4~"; // End else if (kc==36) k="[1~"; // Home else if (kc==37) k="[D"; // Left else if (kc==38) k="[A"; // Up else if (kc==39) k="[C"; // Right else if (kc==40) k="[B"; // Down else if (kc==45) k="[2~"; // Ins else if (kc==46) k="[3~"; // Del else if (kc==112) k="[[A"; // F1 else if (kc==113) k="[[B"; // F2 else if (kc==114) k="[[C"; // F3 else if (kc==115) k="[[D"; // F4 else if (kc==116) k="[[E"; // F5 else if (kc==117) k="[17~"; // F6 else if (kc==118) k="[18~"; // F7 else if (kc==119) k="[19~"; // F8 else if (kc==120) k="[20~"; // F9 else if (kc==121) k="[21~"; // F10 else if (kc==122) k="[23~"; // F11 else if (kc==123) k="[24~"; // F12 if (k.length) k=String.fromCharCode(27)+k; } } else { if (kc==8) k=String.fromCharCode(127); // Backspace else k=String.fromCharCode(kc); } if (k.length) queue( encodeURIComponent(k) ); /* javascript tricks to block propagation */ ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); if (ev.preventDefault) ev.preventDefault(); return false; } function keydown(ev) { if (!ie && !webkit) return; /* webkit and IE do not pass control key to keypress, so we * remap certain keys. Note that we cannot set ev.which=0 * because it is passed by reference and is not writable. */ if (!ev) ev = window.event; s="kd kC="+ev.keyCode+" w="+ev.which+" sh=" + ev.shiftKey+" ct="+ev.ctrlKey+" al="+ev.altKey; debug(s); /* keycodes to be mapped into keypress */ o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1, 113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1}; if (o[ev.keyCode] || ev.ctrlKey || ev.altKey) return keypress(ev, -1 /*ignore ev.which */); } function keyup(ev) { /* used to trap ESC and kindle keys */ if (!ie && !webkit) return; if (!ev) ev = window.event; s = "ku kC="+ev.keyCode+" w="+ev.which+" sh=" + ev.shiftKey+" ct="+ev.ctrlKey+" al="+ev.altKey; debug(s); /* kindle-specific, map left BACK to escape */ if (ev.keyCode == 33) queue("%1B"); return false; } function init() { opt_add(opt_color,'Colors'); opt_color.className = 'on'; opt_color.title = 'Toggle color or grey'; opt_add(opt_get,'GET'); opt_get.title = 'Toggle GET or POST methods'; dstat.appendChild(sdebug); dstat.className = 'stat'; div.appendChild(dstat); div.appendChild(dterm); if (opt_color.addEventListener) { opt_get.addEventListener('click',do_get,true); opt_color.addEventListener('click',do_color,true); } else { opt_get.attachEvent("onclick", do_get); opt_color.attachEvent("onclick", do_color); } document.onkeypress = keypress; document.onkeydown = keydown; document.onkeyup = keyup; timeout=window.setTimeout(update,100); } } Makefile000644 000423 000000 00000001666 11511644733 012772 0ustar00luigiwheel000000 000000 # $Id: Makefile 8169 2011-01-07 17:32:36Z luigi $ CC=/home/luigi/arm-2008q3/bin/arm-none-linux-gnueabi-gcc STRIP=/home/luigi/arm-2008q3/bin/arm-none-linux-gnueabi-strip CFLAGS = -O1 -Wall -Werror -g # files to publish PUB= $(HEADERS) $(ALLSRCS) ajaxterm.* Makefile README myts.arm launchpad.ini keydefs.ini HEADERS = config.h dynstring.h font.h myts.h pixop.h screen.h terminal.h HEADERS += linux/ ALLSRCS= myts.c terminal.c dynstring.c cp437.c http.c ALLSRCS += config.c launchpad.c ALLSRCS += screen.c pixop.c # ALLSRCS += sip.c SPLIT=1 ifeq ($(SPLIT),) SRCS= myts.c else SRCS= $(ALLSRCS) CFLAGS += -DSPLIT endif CFLAGS += -I. OBJS := $(strip $(patsubst %.c,%.o,$(strip $(SRCS)))) myts.arm: $(OBJS) $(CC) $(CFLAGS) -o myts.arm $(OBJS) -lutil $(OBJS): myts.h terminal.o: terminal.h tgz: $(PUB) tar cvzf /tmp/kiterm.tgz --exclude .svn $(PUB) clean: rm -rf myts.arm *.o *.core # conversion # hexdump -e '"\n\t" 8/1 "%3d, "' # DO NOT DELETE README000644 000423 000000 00000012232 11477240222 012175 0ustar00luigiwheel000000 000000 kiterm -- A kindle (or browser) based terminal This package, kiterm, is made of three components: 1. an application launcher for the kindle, which intercepts hotkey sequences and can run commands. This is compatible with the 'launchpad' program. 3. a terminal for the kindle, which uses the two parts above, and simple framebuffer routines, to run a full terminal. 3. a rewritten version of the AjaxTerm program, which permits shell access through a browser just using Javascript. This part is present only for historical reasons. To use the program, you are expected to have shell access to the kindle, and then: - copy 'myts.arm, launchpad.ini and keydefs.ini' on the kindle all in the same directory; - edit the 'launchpad.ini' to adapt it to your needs; - launch the program in background, e.g. "./myts.arm &" The program intercepts keypresses, and upon some of the hotkey sequences defined in launchpad.ini it executes relevant actions. Among these, you can define "!terminal xxx" actions, where xxx are arbitrary strings. In this case, launchpad will launch a new shell window named xxx (or reconnect to an existing one if any) and present a terminal window on the screen. To exit from a terminal press "Left<" (page back on the top left ; this is configurable). The keyboard is mapped as follows: A..Z, space, ., DEL, ENTER as their label ALT+Q..P digits Left> ESC Left< exit from terminal mode Shift acts as "shift" Aa acts as "control" BACK special keys, as follows (same layout as on a regular key; use shift fo key BACK BACK+SHIFT q ` ~ a TAB backtab z < > u - _ i = + o [ { p ] } k ; : l ' " DEL \ | . , < sym . > enter / ? ~` 5way Arrows arrow keys 5way up/dn+shift PgUp/PgDown The font is 8x16 cp437 taken from freebsd. As is it fits 75 columns. To get 80 columns we need to use a 7px font (too much ?) or implement horizontal scrolling. !~ @ # $ % ^ &_ *+ ({ )} 1` 2 3 4 5 6 7- 8= 9[ 0] <-- : " | A -> K; L' del\ > < > ? Z< ., Sy. En/ --- Web-based interface ---- This part is there only for historical reasons or if you want to have shell access using an external browser. KiTerm uses some simple javascript on the client to access a server in charge of forking shells (and keeping them alive) and pass tty data across the HTTP connection. This approach is especially useful on the kindle, where running an xterm or a shell in console mode is challenging. Instead, the browser can be used for this. The original AjaxTerm used a Python script, with the usual bloat of libraries, to implement the backend. I have completely reimplemented the backend in C, using a single process that handles multiple connections and forks shells as desired. The javascript has also been heavily simplified, removing unnecessary libraries. The tarball includes: + this README + myts.c source code for the server + dynstring.[ch] my library for dynamic strings + myts.arm the server compiled for the kindle + ajaxterm.{html,js,css}, html files To use the program you must run the server from the directory where the javascript files are, and then launch a browser to http://localhost:8022/ On the kindle, ALT maps to CTRL, and the ESC key is the "page back" key on the left of the screen. Similar mappings should be necessary on handheld devices. PROTOCOL The protocol is very simple -- requests have the form /u?s=xxx&c=1&r=1&w=NN&h=NN&k=... where s (mandatory) is the session id (alpha chars), w and h represent the geometry (only used when creating a new terminal), k (optional) contains keypresses. c (optional) is set when requesting color output, XXX unimplemented r (optional) forces a refresh XXX unimplemented The response is XML/UTF8 consisting of a block if no updates are available, or
...
with the entire screen dump if something has changed. Colors (including the cursor) are implemented by ... where X and Y are the foreground and background colors. TODO: At this stage the program is still a bit experimental in that it still needs work on two areas, namely process management and terminal emulation. In particular: + complete ANSI control code emulation not all ANSI sequences are recognised, though most things work (top, vi, ...). The missing sequences mostly refer to color handling. + reconnect to existing sessions at the moment each session uses a random key so if the browser dies or disconnects, you cannot reach the existing session anymore + session termination shells remain alive until the server terminates. I should implement a way to explicitly kill a session or connect to one of the existing ones. + resource limiting should expire sessions for which we do not receive a connection for more than some time (minutes?) Should also prevent more than M sessions from the same IP === References === http://antony.lesuisse.org/software/ajaxterm/ wget http://antony.lesuisse.org/ajaxterm/files/Ajaxterm-0.10.tar.gz tar zxvf Ajaxterm-0.10.tar.gz cd Ajaxterm-0.10 ./ajaxterm.py myts.arm000755 000423 000000 00000551006 11511644742 013030 0ustar00luigiwheel000000 000000 ELF(4X4 (&#pTTxTx444444`````a wlllHHH Qtd/lib/ld-linux.so.3GNUCH<.A-F?*98D(71G/5B> &C+!;, 4:E3@   $#"%)02' 6=dčHЍz܍dC?Tt   $$0<tHFT``lxsWddQd̎ ؎d%pNi|X `n,048DP3Px\8Uh tQW01Pȏtԏdx`P0\-(uY.4@LXpdpPa|`8;(84\ĐАXܐ0libutil.so.1__gmon_start___Jv_RegisterClassesforkptylibc.so.6strcasestrsocketstrcpyexitstrncmpinet_atonperrorconnectinet_ntoastrncpysignalputslistenselectreallocabortkillstrspnstrtolmmapcallocstrlendirnamememsetstrstrstrcspn__errno_locationbindreadshutdownvsnprintflseekmemcpysetsockoptstrcasecmpraiseasprintf__ctype_b_locsscanfstderrioctlsystemmunmapwait3gethostbynamereadlinkindexexecvpstrncasecmp__fxstatstrncatgettimeofdaybcopycloseopenstrchrfprintfqsortaccept__ctype_tolower_locbsearchfcntlbcmpstrcmp__libc_start_mainwritefreeGLIBC_2.4 ii \9ii \| Y8hlptx|     !"#$%&'()* +,-./ 0$1(2,3044586<7@9D:H;L<P=T>X?\@`AdBhClDpEtFxG@--kƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌ|ƏʌtƏʌlƏʌdƏʌ\ƏʌTƏʌLƏʌDƏʌ<Əʌ4Əʌ,Əʌ$ƏʌƏʌƏʌ ƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌ|ƏʌtƏʌlƏʌdƏʌ\ƏʌTƏʌLƏʌDƏʌ<Əʌ4Əʌ,Əʌ$ƏʌƏʌƏʌ ƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌƏʌ$  --0-8.SS0 0Q/6,h  0S00/Y @-0S0S3/h@-àL080OCId000A30a0L/C R0S/0R 0R  R  R/ P0S/P 0R/P/O-SMp$J?K?N?O?001 0410 p0S0 p0S J??(1 `V0 0SP `PP0S``$0S H4@@4 ?B8c$#B20b" cD1? " bD3c00 00 p@TP PP@00 P  81S8!@T  !(10b(1$!,10b,1S=9 =,1(10C(1(1dSd0(1S,(0S  t"@2 ?B8c$#B20b" cD1?"( , bD3cJ?08 0P JU,0 p0S0 p0S0S 5!@1 ?B8c$#B20b" cD1?" bD3ciP@P UPU T0S Lx> ?B8c$#B20b" cP0x?,< bD3c0<2/82P+0SL>=L= ?B8c$#B20b" cP0?,< bD3cp82<2(10(1(10(1820CQ00C0a<2/.000bc<<"R%0SL<L< ?B8c$#B20b" cP0?,P< bD3c-0<282R0SL(<L$< ?B8c$#B20b" cP0$?,<@ bD3c82<2Q0D<2<"R%0SLx;Lt; ?B8c$#B20b" cP0t?,< bD3c0<2n82Rj0SL}:L: ?B8c$#B20b" cP0?,< bD3c82<2EQl [Q;P0\0X0T00SL[AL:L : ?B8c$#B20b" cP0 ?, bD3c8Q@ p Pf 0S9 dQ D P0SL<9L89 ?B8c$#B20b" cP08?, bD3cJ<Q  T00\ X0 4L|> ?B8c$#B20b" cP0?,< bD3cC82<2(1@0(1R0 SO<P$0SL?L8? ?B8c$#B20b" cP0d?,t< bD3c0<2&82P#0SL?L3 ?B8c$#B20b" cP0?,< bD3c82<2<4"L2QQ b<"R$0SLD3L(3 ?B8c$#B20b" cP0?,< bD3c0<2&82R#0SLd2L2 ?B8c$#B20b" cP0\?,X<@ bD3c82<2^ P( `0@S (1  T<"0-0S0T"<2T"82< P20420CS <20<2D2S (1@0(1<"82R!0SL H1L,1 ?B8c$#B20b" cP0?, bD3cA0<2 pY.&P0S" 00SL0L|0 ?B8c$#B20b" cP0P?d`T bD3cdЍ 8E.MbOXYSV[\k0VjD[A-MP`0S 0S  0S 3/ 40S33 ?B8c$#B20b" c0?B  bD3c0S  1 1 1$0S    12 12 1S2T ($ UpP!20SJO22 ?B8c$#B20b" c0? bD3c,$0W"T20S*<242 ?B8c$#B20b" c0? $  bD3c\(1$00g$0@2 1S2a ~P eP$`10SH1@1 ?B8c$#B20b" c0?,($ bD3c!00200> 00S00 ?B8c$#B20b" c0l? x bD3c0@2Ѝ\kYE.MbdV|[tVs[w[V\L\p@-P@(1 P 0S `0[S<PO00$ ( b($p|\0S/0S/P$/0S/0S/XcP/P0C/P/000S00/p@-@p3P Q`a`P  000  8000 ppp@-@PP `P0S *T@1O"P@ppp@-@P@00p@-`@PPpP0P% Td000QPT 0d0 V 0 0000 00 ppp@-P`P @T QP 0UPp epp@-`P@TD!Pp-G- M,`P0000 p/p@0S 0P# Q PPe 0U0 S S0ATP 000\ p  ЍG Ѝ/p@-@PY@ $p@-P JO-4M2(020S F2 2?A8cA20a  c$0\?T(@ lD3cxeR 0S S S   S S 0`0S0,0Q 0S P&S0 1, Q P00S @@ 0010 T0pPQ0S) 1 @$0 U P /A(bA  a " l? P bL3c`㜀pᘠp (@T  (P0`(0,@D0l4($ 4Ѝ\kYE.Mb\\\\\`kO-MPp10S11 ?B8c$#B20b" c 0X?PLH bD3cWD44`@ P0`3 W5pGP0( P @ r 4 <0PP 0000 APX%pGWP½Ѝ\kYE.Mb\d]]`o]]]]0@-M00  00P00S 00 ?B8c$#B20b" c 0?| bD3c=@0@@@T00P$0 @00Ѝ0Dk`o\kYE.Mb]]V]^p@-P@0Qp4+Pp02 b 00000p ^@-00  PP 0 00:0<0A- M0`00S+0P0#0/Cxb43C" c20bpc@0#OCCdN 00?0p04"4 0H0000P 0@@@T0  Ѝ`o\kYE.Mb ]0^`0@-,M00P0S     12 1_ 2 1S2V \10S 8D1 <1 ?B8c$#B20b" c0?} bD3cl(00! 0 0$ 0 P#00S" 0 |0 ?B8c$#B20b" c0P?H~@ bD3c<, 1,Ѝ0\kYE.Mb]`^^`O-,M PsP P&` ;T =$P0`$0 sR0S$P wR0S$ 0hS0S$ 0cS0S$ kR0S$p rR0S @T n P0` 0$@0S 0Sj,`XT2@T PDr0P P0 @T 2p`P1000 0`PAY0S" @ R 0P  00+R %Rda000 R00(` !0SZ+P&00S00 ?B8c$#B20b" c0?x bD3cEL0 0 0 0,Ѝ@0$0UceXc^Dk_ _,`o(_\kYE.Mb(]H_O-Mp`0S,0S  0S     12 1(VP  0R$ 0RR    12 12 1S2  0 , cP >0Sx>x> ?B8c$#B20b" c|0?B P, bD3cU000$|=0Sxgd=x \=?A8cA20a  c|00?(,,  lD3c00,PP00 0R"<0Sx:<x< ?B8c$#B20b" c|0|? bD3cn00hW UTQ U0Sz4PZc  ;0S#x;x@; ?B8c$#B20b" c|0?, j  bE3c+,0 00j SA/ QPR \^ ^ Q 0S S S   S S 00S000S 㜊 @Q 0S S S   S S 00S000S 00P0090Sxu9x9 ?B8c$#B20b" c|0h?tc P bD3c00 lP 0/S 0uS0S g0GS0ES0TS 0S  PQPU 0S ?S &S  ?S &S 000S p800S0/Si 0S  .S0.S4X` 0 S0/S 8R@7PWP KPWE700L 07pW7 L0'07PU@0S S0 0@Y d P0 PU 0S S @&FL0RV6PF 0B 2 1S2k t60S$ 0( 0, 00 04 08 0< 0@ 00p0!( 6&P , (0So @p 9YK@00WT @X P5!R 0 0tP `  P X <p,\Q (0, WL40S#x44Px,40/Cb43C" c20bc|@3OCCd`440A?x 0H hV 430S#xx3Pxp3#0/Cxb43C" c20bpc|@@3OCCd3u3030 00S @`3d0  c 30C   lP[00020S xh2x`2 ?B8c$#B20b" c|04?  bD3c 0RP200c00010S!xy1x1 ?B8c$#B20b" c|0x?,0a  bD3c 0s510SxO1x0 ?B8c$#B20b" c|0? bD3chu0000S 0P 0C0e0S0Ѝ00W @\kYE.Mb0]1_3_<]c_```,`q0`Xcl````o``0`8`4\`,`4ataaaa`kub bbb0aH] bPb XbX]bbbP/p@-PP@ @Q T P @Tpp@-PPQ@@ @Q T P @Tp@-@P Pp@-PPp@T 00P 00P|@TwpO-`Q`V9 @5@Ppܰ\Q0V- p!U "Q'QPP0'Q"Q0 P p ;Q T#QWp P0 p W0p0@VW @00@Tc@-@P  @TcG-`PPQ2 P/ 0S, @Xp \X 00SppX nP 0=S=X  00R000 v@O-$M@ P60SD6@<<&<60T   0 SP00*P0.0C0S  0zP 50S`5@%5X P p PB `` R  U 40S,40$4$00 R  `40Sڈ4`$0`匔 JP0  0@)A 0;S S #SK[SHPP`P@00p P00]T 0S30#00SX300|l#0t gP  P  30S300(#0^00000Sڸ2"0NPP@ @0S  h2 00x"07TU_ 020Sn$200`8"0'e0S1P@4"0$EP0Sڴ1@!0  3[ 0S.p1!0' `P 0S4100H!0`P 00S 000@!000`P@@T 0S00Sڌ0 0  RX00SL0H N?Z X0S $Ѝ\kY\c00 ?B8c$#B20b" c0\?TB PD bD3cq$Ѝ,00P`Y\kYE.Mbf8jhjE-$MpP Q {10S$11 ?B8c$#B20b" c0?& p bD3c,dA08 0 S P`@  P<SS P`C@e  P<S0 <P P`p@  P<SP P`@dp@e$  P<S<@0( {08 w$Ѝ\kYE.Mb$fpjY@-MP`00Sw00 ?B8c$#B20b" c0?B P bD3cV0S p\S@0S`F@8`FVP0SЍ\kYE.Mb4f~jO-$M`20S122 ?B8c$#B20b" c0|?t)Bh bD3ce\204  R  842` cPMp60S6 6?A8cA20a  c0t? p lD3cWs DV@V PlVk  000T@A|U0 l /A N50St5t5 ?B8c$#B20b" c0H?d` bD3c^(50< ,040Ss44 ?B8c$#B20b" c0? bD3c `P!440SJ44 ?B8c$#B20b" c0?0,( bD3c~ P pP!t30SF\3\3 ?B8c$#B20b" c00?pt"p bD3cN( U 20S22 ?B8c$#B20b" c0?" bD3c&z @O@PP0010S&1P1#0/Chb43C" c20b`c@1OCCd10 I1010 0T1 0 1 1 ?B8c$#B20b" c0?@, bD3c0 <S @P0 I@ <St0 0<<00S@Trp Ѝ\kY8n@nE.MbfjYfHn%tnfnnnpc of)0o1lo3ooo)pLpG-pMp`P9  , <0S980S*d8d@8 ?B8c$#B20b" ch0呓?  \ȟ X bE3c-,8 <S 0<10P80S(d7dh Uw@@p7 ?B8c$#B20b" c7哑? P@p  bL3cU 0T0X 0\ 0` 0 0BS07 <<P D<P 6 E H<P 6 ? L<P 6 9 P<P 6 3 @<P0T0. 60SO F000S0 Sh PD Q 0S  0STrQ50Sd@5d 5?A8cA20a  ch0?T lD3cr<50S; dd5@T00T0 T`( VPD0T0  NPS0T0 T DPE0T0d@T[P |40p1 d00T0 ST40S4T0@T#0@T@' 00  40S 0DT030S`0DT0  30S40T0y30S`0DT0sT` P 0T0h  P 0T0` T| P0T0V Tt P 3 TX3XRET< P2 T 3 R4T P2T0* T( P2T0 RH2 <<P6D<P  2  H<P 2  L<P 1  P<P 1 10<Sn Tj 0S)1   <S R ,<R`1 T 0<RbM0<,!00|00 ,Q@R=S;0 R B 00S2 00,<R,0 0S( @0 0 0<00Sdp0dh0哜 ?B8c$#B20b" ch0<?4 bD3c"pЍY\kYE.Mbf#Xpp gRpgppPglt$q`qhj,q0q4q < ?T< 20X< 20\< e0C`   0 P!\?0S%4sD?4? ?B8c$#B20b" c80?B bD3cP,!>0S4L>4> ?B8c$#B20b" c80T?TiT bD3c ]0,8i >00, s ; 00,i >00,i > 00,s >0,s >00,s >0,s >00,s 2=0,ls 2=0@` h @p x @  <0S)4<4 <?A8cA20aB@c80|?|`p hx| dE3c;Ph<s'x<s$<S! <0SP4;4; ?B8c$#B20b" c80? bD3cJd 7l TZ`t 1| ` , 0 P h<s x<s <sPL:0S4X:4: ?B8c$#B20b" c80? bD3cTI0 9 00CS=`p44,P*0S& !@4 9?A8cA20a  c80? @@  lE3cK pH8 00CW`,8Q@P 00S 0A00 !00 ^ 087 +80S484d8 ?B8c$#B20b" c808?8 bD3c7 0S=`p4l0S0֕<10`0S& @4< ?B8c$#B20b" c80p?p @@   bE3cp6 0W`70S4a646 ?B8c$#B20b" c80?$  bD3c <1 `V) 0S& 9@44< ?B8c$#B20b" c80? @@ L bE3ccp WD0,8k > 00, k >0, k > 00,k 1=0,k 1=00,k 1=00,k 1= 00,k >0 ,0,tYdTT ODK8F(A<0 P` @ PY 0S/0S4#43 ?B8c$#B20b" c80?CP bD3cP@T 01?00S S S  0S S S`R V?pP""0S4W242 ?B8c$#B20b" c80?hLB PD bD3c0S"T"0S41<242 ?B8c$#B20b" c80?B P bD3cdy!0S#4 14 ?B8c$#B20b" c80\?DIB P8a bD3c;00K?Y Xc\gqqq rr(r8rHrPrXr`rhrprxrrrrrsX0stsss,t8t@tHtPt\thtptltXqPq,q0C8#880P4P!x h0/.000b0/.000bP00 0$08#,@ 0$08#x0<Y88#(@ 0`T 60CA (08#88%  %("x0X 0H<  < 04)48#0PU0EPp04'48#xp0Zp'404@@4@tPT, ,0 0 0 S0$@1 P @0h S0( 1 p0 S0Q`x0p x\ U 000 U`tV @ tpDЍG-@P pP? `Q@V@Z 0VdUpP\ PWp0\ peZ#W!  R $00?À0?`"?P@@0<  OP@DTjY4xQ  aB Qp 00`BSoq /oo @ r S?C S?C S>C S>C S=C  S=C S?0123456789;%5d.%03d [%-14.14s %4d] +++ now PARM %s %d;%d;%dABCDGHJKPXdghlmr%5d.%03d [%-14.14s %4d] ANSI sequence (%d)(%d) %d %d %d cmd %d( ESC-[%.*s) %5d.%03d [%-14.14s %4d] a1 %d a2 %d %5d.%03d [%-14.14s %4d] setattr fg %d %5d.%03d [%-14.14s %4d] setattr bg %d %5d.%03d [%-14.14s %4d] scroll region to %d, %d %5d.%03d [%-14.14s %4d] -- at %4d ANSI sequence (%d) %d %d %d ( ESC-[%c%.*s) ()>=H%5d.%03d [%-14.14s %4d] other ESC-%.*s ()%5d.%03d [%-14.14s %4d] enter graphics at %d %5d.%03d [%-14.14s %4d] exit graphics at %d %5d.%03d [%-14.14s %4d] unrecognised ESC ( %c H=>%5d.%03d [%-14.14s %4d] non ANSI sequence %d ESC-%c %5d.%03d [%-14.14s %4d] --- ouch, overflow on c %d %5d.%03d [%-14.14s %4d] ----- leftover stuff ESC [%s] %5d.%03d [%-14.14s %4d] poll %p %s %5d.%03d [%-14.14s %4d] error writing to keyboard %5d.%03d [%-14.14s %4d] short write to keyboard %d out of %d %5d.%03d [%-14.14s %4d] --- shell read error, dead %d %5d.%03d [%-14.14s %4d] got %d bytes for %s ABCDbuild_map437%5d.%03d [%-14.14s %4d] cp437 is %s same%5d.%03d [%-14.14s %4d] fields %s %s -none-http_parsehttp_inithttp_starthandle_listenu_modehandle_httpparse_msgbuild_responsehttp_write%5d.%03d [%-14.14s %4d] http parse routine --unsafe--cmd--port--addrcannot parse address%5d.%03d [%-14.14s %4d] http init routine 127.0.0.1login0123456789abcdef0123456789ABCDEF%5d.%03d [%-14.14s %4d] listen on %s:%d cmd %s %5d.%03d [%-14.14s %4d] listening socket %5d.%03d [%-14.14s %4d] listen failed HTTP/1.1 200 OK Content-Type: text/html

Active sessions

%2d %s

HTTP/1.1 400 fork failed %5d.%03d [%-14.14s %4d] /* no modifications, wait before reply */ %5d.%03d [%-14.14s %4d] read %p returns %d %s %5d.%03d [%-14.14s %4d] buf [%s] %5d.%03d [%-14.14s %4d] --- XXX input buffer full Content-length:%d%5d.%03d [%-14.14s %4d] content length = %d, body len %d %5d.%03d [%-14.14s %4d] %s %s +++ request body [%s] POST/u?invalid pathname/ajaxterm.htmlopen failedmmap failedtext/plainHTTP/1.1 200 OK Content-Type: %s Content-Length: %d HTTP/1.1 200 OK Content-Type: text/plain Resource %s : %s
HTTP/1.1 200 OK
Content-Type: text/xml; charset=cp437;

%s
 %c%%%02x%5d.%03d [%-14.14s %4d] done %d chars at %p %s
%5d.%03d [%-14.14s %4d] response %s %5d.%03d [%-14.14s %4d] written1 %d/%d %5d.%03d [%-14.14s %4d] written2 %d/%d %5d.%03d [%-14.14s %4d] reply complete html text/htmlhtm text/htmljs text/javascriptcss text/csscfg_readcfg_parse [%-14.14s %4d] %s %s/%s[%-14.14s %4d] error opening %s [%-14.14s %4d] cannot read file %s size %d [%-14.14s %4d] start, db %p content %.50s ... -_[%-14.14s %4d] invalid section name %s %c [%-14.14s %4d] start section %s [%-14.14s %4d] cannot allocate section %s [%-14.14s %4d] key name pair = [%-14.14s %4d] after parse name next p %p %d [%-14.14s %4d] cannot parse name %s [%-14.14s %4d] key [%s] val [%s] include[%-14.14s %4d] processing include %s [%-14.14s %4d] key val outside section, ignore [%-14.14s %4d] replace val %s [%-14.14s %4d] cannot allocate key %s [%-14.14s %4d] END db %p [%-14.14s %4d] can't create db structure print_buflookup_keysend_key_entrysend_ascii_stringprocess_scriptcurterm_endterm_deadbuild_seqsetValhost_eventlaunchpad_deinitlaunchpad_parseshell_findcall_hotkeyfind_actionexecute_actionget_file_contentsprocess_eventprocess_termvvw www$w,w4w K; L' del\ > < > ? Z< ., Sy. En/ Ctrl Sym %5d.%03d [%-14.14s %4d] entry '%.*s' not found Space%5d.%03d [%-14.14s %4d] symbol %.*s at x %d y %d %5d.%03d [%-14.14s %4d] %.*s %5d.%03d [%-14.14s %4d] %s %5d.%03d [%-14.14s %4d] substring %p %.*s %5d.%03d [%-14.14s %4d] whitespace %p %.*s Capture kbd input:Capture fw input:Capture k3_vol input:%5d.%03d [%-14.14s %4d] exit from terminal mode %5d.%03d [%-14.14s %4d] terminal %s is dead %5d.%03d [%-14.14s %4d] could not find dead terminal %p %5d.%03d [%-14.14s %4d] section not found %5d.%03d [%-14.14s %4d] exploring section %p %5d.%03d [%-14.14s %4d] found %s = %s sfvrow%5d.%03d [%-14.14s %4d] done %d entries %5d.%03d [%-14.14s %4d] Warning: no code for %s %s %5d.%03d [%-14.14s %4d] char %c maps to %d %5d.%03d [%-14.14s %4d] called, restart %d %5d.%03d [%-14.14s %4d] Launchpad start routine /proc/self/exe.inilaunchpad.ini%5d.%03d [%-14.14s %4d] inipath is %s ini_name %s --cfg%5d.%03d [%-14.14s %4d] could not allocate session for %s /bin/shtimeoutdirect%5d.%03d [%-14.14s %4d] found action %s %5d.%03d [%-14.14s %4d] found hotkey sequence for %s terminal%5d.%03d [%-14.14s %4d] start %s got %p %5d.%03d [%-14.14s %4d] call system %s %5d.%03d [%-14.14s %4d] opening %s %5d.%03d [%-14.14s %4d] Can't open kindle script file %s %5d.%03d [%-14.14s %4d] Can't allocate %lu bytes %5d.%03d [%-14.14s %4d] Can't read %lu bytes from %s 'del'%5d.%03d [%-14.14s %4d] sent %d keys %5d.%03d [%-14.14s %4d] Unknown hotkey sequence entered len %d: send_string%5d.%03d [%-14.14s %4d] event ty %d val %d code %d got_intro %d npress %d seqlen %d ---%5d.%03d [%-14.14s %4d] process event %d %d e %p %.*s for terminal Del%5d.%03d [%-14.14s %4d] function %s EnterUp[5~Down[6~RightLeft%5d.%03d [%-14.14s %4d] -- start hotkey mode )!@#$%^&*(%5d.%03d [%-14.14s %4d] %s -- not found or bad Settings%5d.%03d [%-14.14s %4d] section Settings not found HotIntervalScriptDirectoryInterKeyDelayRefreshDelayKpadInKpadOutFwInFwOutVolInVolOut%5d.%03d [%-14.14s %4d] open %s %s %s gives %d %d %d %5d.%03d [%-14.14s %4d] no input available, exiting... inkeysinkeys-k3inkeys-dx%5d.%03d [%-14.14s %4d] sort sequences %5d.%03d [%-14.14s %4d] dup %3d for ty %d code %3d y %3d l %d %.*s %5d.%03d [%-14.14s %4d] --- dump events by name --- %5d.%03d [%-14.14s %4d] %3d ty %d code %3d y %3d l %d %.*s %5d.%03d [%-14.14s %4d] --- debugging -- dump events by code --- IntroducerTrailerTermEndTermEscTermCtrlTermShiftTermSymTermFnSelectActions%5d.%03d [%-14.14s %4d] sequence %s : %5d.%03d [%-14.14s %4d] %.*s key not found %5d.%03d [%-14.14s %4d] %.*s key not valid as hotkey %5d.%03d [%-14.14s %4d] %.*s becomes %d %5d.%03d [%-14.14s %4d] action %s %5d.%03d [%-14.14s %4d] init routine failed, exiting send%s %d %5d.%03d [%-14.14s %4d] mode %d %sshift%5d.%03d [%-14.14s %4d] fds %d %d %d %5d.%03d [%-14.14s %4d] term %p sh %p hotkey_due %d pend %d %5d.%03d [%-14.14s %4d] reading on %d %5d.%03d [%-14.14s %4d] got %d bytes from %d %5d.%03d [%-14.14s %4d] sending key, left %d qazuiopklD.SE` <-=[];'\,./~ >_+{}:"|<>?q[[Aw[[Be[[Cr[[Dt[[Ey[17~u[18~i[19~o[20~p[21~l[23~D[24~fb_update_area%s @%d %d %d x %d error %d error: /dev/fb0Error: cannot open framebuffer device.Error reading fixed screen information.Error reading variable screen information.Error: failed to mmap framebufferunsupported pix_fill depth %d `D9 ,T`dh f \(dTooolp 0x00 0x0000 NULL 0x01 0x263A ☺ While Smiling Face 0x02 0x263B ☻ Black Smiling Face 0x03 0x2665 ♥ Black Heart Suit 0x04 0x2666 ♦ Black Diamond Suit 0x05 0x2663 ♣ Black Club Suit 0x06 0x2660 ♠ Black Spades Suit 0x07 0x2022 • Bullet 0x08 0x25D8 ◘ Inverse Bullet 0x09 0x25CB ○ White Circle 0x0A 0x25D9 ◙ Inverse White Circle 0x0B 0x2642 ♂ Male Sign 0x0C 0x2640 ♀ Female Sign 0x0D 0x266A ♪ Eighth Note 0x0E 0x266B ♫ Beamed Eighth Note 0x0F 0x263C ☼ White Sun With Rays 0x10 0x25BA ► Black Right-Pointing Pointer 0x11 0x25C4 ◄ Black Left-Pointing Pointer 0x12 0x2195 ↕ Up Down Arrow 0x13 0x203C ‼ Double Exclamation Mark 0x14 0x00B6 ¶ Pilcrow Sign 0x15 0x00A7 § Section Sign 0x16 0x25AC ▬ Black Rectangle 0x17 0x21A8 ↨ Up Down Arrow With Base 0x18 0x2191 ↑ Upwards Arrow 0x19 0x2193 ↓ Downwards Arrow 0x1A 0x2192 → Rightwards Arrow 0x1B 0x2190 ← Leftwards Arrow 0x1C 0x221F ∟ Right Angle 0x1D 0x2194 ↔ Left Right Arrow 0x1E 0x25B2 ▲ Black Up-Pointing Triangle 0x1F 0x25BC ▼ Black Down-Pointing Triangle 0x7F 0x2302 ⌂ House 0x80 0x00C7 Ç Latin Capital Letter C With Cedilla 0x81 0x00FC ü Latin Small Letter U With Diaeresis 0x82 0x00E9 é Latin Small Letter E With Acute 0x83 0x00E2 â Latin Small Letter A With Circumflex 0x84 0x00E4 ä Latin Small Letter A With Diaeresis 0x85 0x00E0 à Latin Small Letter A With Grave 0x86 0x00E5 å Latin Small Letter A With Ring Above 0x87 0x00E7 ç Latin Small Letter C With Cedilla 0x88 0x00EA ê Latin Small Letter E With Circumflex 0x89 0x00EB ë Latin Small Letter E With Diaeresis 0x8A 0x00E8 è Latin Small Letter E With Grave 0x8B 0x00EF ï Latin Small Letter I With Diaeresis 0x8C 0x00EE î Latin Small Letter I With Circumflex 0x8D 0x00EC ì Latin Small Letter I With Grave 0x8E 0x00C4 Ä Latin Capital Letter A With Diaeresis 0x8F 0x00C5 Å Latin Capital Letter A With Ring Above 0x90 0x00C9 É Latin Capital Letter E With Acute 0x91 0x00E6 æ Latin Small Ligature Ae 0x92 0x00C6 Æ Latin Capital Ligature Ae 0x93 0x00F4 ô Latin Small Letter O With Circumflex 0x94 0x00F6 ö Latin Small Letter O With Diaeresis 0x95 0x00F2 ò Latin Small Letter O With Grave 0x96 0x00FB û Latin Small Letter U With Circumflex 0x97 0x00F9 ù Latin Small Letter U With Grave 0x98 0x00FF ÿ Latin Small Letter Y With Diaeresis 0x99 0x00D6 Ö Latin Capital Letter O With Diaeresis 0x9A 0x00DC Ü Latin Capital Letter U With Diaeresis 0x9B 0x00A2 ¢ Cent Sign 0x9C 0x00A3 £ Pound Sign 0x9D 0x00A5 ¥ Yen Sign 0x9E 0x20A7 ₧ Peseta Sign 0x9F 0x0192 ƒ Latin Small Letter F With Hook 0xA0 0x00E1 á Latin Small Letter A With Acute 0xA1 0x00ED í Latin Small Letter I With Acute 0xA2 0x00F3 ó Latin Small Letter O With Acute 0xA3 0x00FA ú Latin Small Letter U With Acute 0xA4 0x00F1 ñ Latin Small Letter N With Tilde 0xA5 0x00D1 Ñ Latin Capital Letter N With Tilde 0xA6 0x00AA ª Feminine Ordinal Indicator 0xA7 0x00BA º Masculine Ordinal Indicator 0xA8 0x00BF ¿ Inverted Question Mark 0xA9 0x2310 ⌐ Reversed Not Sign 0xAA 0x00AC ¬ Not Sign 0xAB 0x00BD ½ Vulgar Fraction One Half 0xAC 0x00BC ¼ Vulgar Fraction One Quarter 0xAD 0x00A1 ¡ Inverted Exclamation Mark 0xAE 0x00AB « Left-Pointing Double Angle Quotation Mark 0xAF 0x00BB » Right-Pointing Double Angle Quotation Mark 0xB0 0x2591 ░ Light Shade 0xB1 0x2592 ▒ Medium Shade 0xB2 0x2593 ▓ Dark Shade 0xB3 0x2502 │ Box Drawings Light Vertical 0xB4 0x2524 ┤ Box Drawings Light Vertical And Left 0xB5 0x2561 ╡ Box Drawings Vertical Single And Left Double 0xB6 0x2562 ╢ Box Drawings Vertical Double And Left Single 0xB7 0x2556 ╖ Box Drawings Down Double And Left Single 0xB8 0x2555 ╕ Box Drawings Down Single And Left Double 0xB9 0x2563 ╣ Box Drawings Double Vertical And Left 0xBA 0x2551 ║ Box Drawings Double Vertical 0xBB 0x2557 ╗ Box Drawings Double Down And Left 0xBC 0x255D ╝ Box Drawings Double Up And Left 0xBD 0x255C ╜ Box Drawings Up Double And Left Single 0xBE 0x255B ╛ Box Drawings Up Single And Left Double 0xBF 0x2510 ┐ Box Drawings Light Down And Left 0xC0 0x2514 └ Box Drawings Light Up And Right 0xC1 0x2534 ┴ Box Drawings Light Up And Horizontal 0xC2 0x252C ┬ Box Drawings Light Down And Horizontal 0xC3 0x251C ├ Box Drawings Light Vertical And Right 0xC4 0x2500 ─ Box Drawings Light Horizontal 0xC5 0x253C ┼ Box Drawings Light Vertical And Horizontal 0xC6 0x255E ╞ Box Drawings Vertical Single And Right Double 0xC7 0x255F ╟ Box Drawings Vertical Double And Right Single 0xC8 0x255A ╚ Box Drawings Double Up And Right 0xC9 0x2554 ╔ Box Drawings Double Down And Right 0xCA 0x2569 ╩ Box Drawings Double Up And Horizontal 0xCB 0x2566 ╦ Box Drawings Double Down And Horizontal 0xCC 0x2560 ╠ Box Drawings Double Vertical And Right 0xCD 0x2550 ═ Box Drawings Double Horizontal 0xCE 0x256C ╬ Box Drawings Double Vertical And Horizontal 0xCF 0x2567 ╧ Box Drawings Up Single And Horizontal Double 0xD0 0x2568 ╨ Box Drawings Up Double And Horizontal Single 0xD1 0x2564 ╤ Box Drawings Down Single And Horizontal Double 0xD2 0x2565 ╥ Box Drawings Down Double And Horizontal Single 0xD3 0x2559 ╙ Box Drawings Up Double And Right Single 0xD4 0x2558 ╘ Box Drawings Up Single And Right Double 0xD5 0x2552 ╒ Box Drawings Down Single And Right Double 0xD6 0x2553 ╓ Box Drawings Down Double And Right Single 0xD7 0x256B ╫ Box Drawings Vertical Double And Horizontal Single 0xD8 0x256A ╪ Box Drawings Vertical Single And Horizontal Double 0xD9 0x2518 ┘ Box Drawings Light Up And Left 0xDA 0x250C ┌ Box Drawings Light Down And Right 0xDB 0x2588 █ Full Block 0xDC 0x2584 ▄ Lower Half Block 0xDD 0x258C ▌ Left Half Block 0xDE 0x2590 ▐ Right Half Block 0xDF 0x2580 ▀ Upper Half Block 0xE0 0x03B1 α Greek Small Letter Alpha 0xE1 0x00DF ß Greek Capital Letter Beta / Latin Small Letter Esset 0xE2 0x0393 Γ Greek Capital Letter Gamma 0xE3 0x03C0 π Greek Small Letter Pi 0xE4 0x03A3 Σ Greek Capital Letter Sigma 0xE5 0x03C3 σ Greek Small Letter Sigma 0xE6 0x00B5 µ Greek Small Letter Mu 0xE7 0x03C4 τ Greek Small Letter Tau 0xE8 0x03A6 Φ Greek Capital Letter Phi 0xE9 0x0398 Θ Greek Capital Letter Theta 0xEA 0x03A9 Ω Greek Capital Letter Omega 0xEB 0x03B4 δ Greek Small Letter Delta 0xEC 0x221E ∞ Infinity 0xED 0x03C6 φ Greek Small Letter Phi 0xEE 0x03B5 ε Greek Small Letter Epsilon 0xEF 0x2229 ∩ Intersection 0xF0 0x2261 ≡ Identical To 0xF1 0x00B1 ± Plus-Minus Sign 0xF2 0x2265 ≥ Greater-Than Or Equal To 0xF3 0x2264 ≤ Less-Than Or Equal To 0xF4 0x2320 ⌠ Top Half Integral 0xF5 0x2321 ⌡ Bottom Half Integral 0xF6 0x00F7 ÷ Division Sign 0xF7 0x2248 ≈ Almost Equal To 0xF8 0x00B0 ° Degree Sign 0xF9 0x2219 ∙ Bullet Operator 0xFA 0x00B7 · Middle Dot 0xFB 0x221A √ Square Root 0xFC 0x207F ⁿ Superscript Latin Small Letter N 0xFD 0x00B2 ² Superscript Two 0xFE 0x25A0 ■ Black Square 0xFF 0x00A0     No-Break Space bcc,c`l<do..1234567890....qwertyuiop....asdfghjkl.....zxcvbnm,ZGCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2  0!,X) 0l\N|d YlLLFhJ ?timeradd_mstimersetmintimerduemainloopmain new_sess5 opensock, verbose> __mez all_appst +term_nameterm_findoterm_killterm_state term_newhandle_shellterm_keyin!ds_datads_lends_size#ds_resetHds_shiftds_create(ds_appendds_truncateds_adjustdsprintf=ds_refds_free*)}bbuild_map437jmap437i 0Spnew_clientChandle_listen9u_modehandle_httphttp_app(desc:http\Ny cfg_section_namecfg_find_entry^cfg_find_sectioncfg_find_valcfg_freeWtrimwsskipws cfg_readY)term_deadhost_eventmlaunchpad_parse$process_screenashell_find#launchpad_start&send_event1&handle_launchpad)lpadl fb_getfont=get_char_pixmapfb_char_at fb_update_area fb_close. fb_openQzzpix_invertpix_freepix_alloc6pix_bltepix_fill t0HsCuintg>8a-lo>G|$- Z# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&Z#8 *Z#< ,z#@ 0>#D 1L#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L%#h 0 NZ#l SP#p >  # p# Z#    'F G# H#7D: K:# J N# 7e e )h G>  R #  #  , 2> 40 ]U  ! % #s f  ߖ# I #  #  U#app @ V A# ) B# C#end D#  E#ZZZ_ MInow N#due O#r PI#w QI# RZ#run SZ#J5 VZ`Zuu W  X#app Y#cb ZO#arg [# fd \Z#{f h9  i9#app j#  k#  l# cur m#  nZ#{GsrcFPmsFZdstFROL]dstN2curNP0VZL]dstUcnowUZmenZ s(ps rJ~ wJ} a!__i0"AI(!__i0"AI nowPp nowPĕ@!__i0"AIĕؕd!__i0"AI` nowP nowP# nowP$c 8TZP %Z%c;!app9aYiZw#"opth{ &h" "Z#0"5%"% '7Px5 % ZfdZcbOFargds0$ now`$c DT\Zx sa[!@udp[Z% [Z fd]ZT i^Zs|(D\ now`T&;`>$c PT ' ' ' )))\*9Z\k*v:Dk)=f)9=f z *>j '3,t0HsCuintg>8a-lo>G|$- Z# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&Z#8 *Z#< ,z#@ 0>#D 1L#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L%#h 0 NZ#l SP#p >  # p# Z#    'F# G# H#7DE KE# #U N. p 17app @ V A# ) B# C#end D#  E#ZZZ_ M^now N#due O#r P^#w Q^# RZ#run SZ#U5 VouZ W  X#app Y#cb Zd#arg [# fd \Z#{ hN  iN#app j#  k#  l# cur m#  nZ# >okv$ ?  @Z# 5 AZ#  AZ#  AZ# cur AZ#pid BZ#cb C# D#  E# b P  ># ( ># 9 ># X !>#>Gj J)Y8XT U# V#pidWZ#cbX# [Z# S\Z#$ C]#( ^Z# $_Z# q`# cZ# cZ# cZ#curdZ# 5eZ# _fZ# jZ# |jZ# >qp# s#  /]s(OFo esT5%%Z0sigZ sh!vZ0D "#ptrD ;$shX$retZZ%\3 $nowX&c\Vo'Y #sh" Z#lenZ$xV%ȞH $now`&cVs4 cmd  (ZFZdcb(lZ(lnZws XsU%؟T nowP% nowP% nowP%< nowP%Ȣ av P&c$V  '4N #sh$pU)lZ*Z +shн+s,Z)xӲ-Ӳ- Ӳ)cmdӸ-fӸ)nZ)a1Z)a2Z)a3Z./ )now/ )now/ )now/% )now/6 )now/H (now/Z (now/l (now/~ (now/ (now / (now/ (now/ (now/ (now/8 (iZ(arg / (now/ (now/) (now0(now/T (dst(lZ/f (now/x (now/ (now/ (now&cqsho(lqZ/G(nows/Y(noww&ctV=Z>sh(sZ(lZ/(now/(now&cVZ _s af sh %\Cnow`?X6 79+ %;:`;L`?jX6|79 89 %,;`|;`&cdV!HwZ,L"v<#kvZ@shxx \ L q a p v  `      AAA\A 3ZAv pV,d106b1mlen;m#p8-l  |$- # # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&#8 *#< ,#@ 0#D 1#F 2#G 6.#H ?#P H#X "I#\ )J#` 0K#d 7Lm#h 0 N#l SP4#p=+  #> #p##.D'Ji`pB,L]sA%GDL]sF%ppHD6j]si%s]#sr%x]Hbufw%PuT/d%Nnlpp Tbufm %%!%(5"buf%H![bufzdZlenѢ kӢ!buf$!LHMbufli.l #$buf%m%!$fmtD$apO&res'k'!HH=buffmtD9()resP)apOX*8 ~ǢX+P,_,S,G,;,/*h-j.v.!'Y%HlpXDlenX<"dZ%Zpp[!clmsb%//ylt0HsCuintg>8a-lo>G|$- Z# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&Z#8 *Z#< ,z#@ 0>#D 1L#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L%#h 0 NZ#l SP#p >  # p# Z#    'F G# H# 1zgp 3!*[__sz__s<zb__s<FzZlZcaͲ(bͲT$nowH~iZvicԲԸPԸ Ը  0nowHHϸPϸ ϸz`x T!c\    " #$U$%%%\%3Z j &Z`kO 3l|} d106btGHsCuintg>8x9+6 G GY \Gk G-l>GoC 2| $ - q# ,# },# ,# ,# U,# ,# #,# ,# ,#$ ,#(  ,#, \"7#0 $=#4 u&q#8 *q#< ,#@ 0U#D 1c#F 2C#G 6S#H ?#P H#X "I#\ )J#` 0K#d 7L<#h 0 Nq#l SPY#p  > 7 7# p=# q#9 2S 2i'o2  z  {#  |#  F  G#  H # 7 D  K#  N NG U G R# G# 2W 3r  ,2U4G]rU}  %# s # I# # #app@Q V AW# ) B~# CW#endDW# E#qQqrrxq,] _ MnowN#dueO#rP#wQ# Rq#runSq#5Vq   Wd Xd#appYj#cbZ#arg[# fd\q# h i#appjj# kd# ld# curmd# nq#j>k v$?| @q# 5Aq# Aq# Aq# curAq#pidBq#cbC# D,# E,# d| d e,# fx# N gq#  hq# ix#1=gp 3!* > X%8 &# 'U# Z )# . -# .# {/# 0# 1# "2U#(  4#, 8#0 ;!#4 u Ft#8 Gt#@ Ht#H ) U\#P 3 V\#T <F G# Hq#posIq#lenIq#dueJ# shKd#( a L #, M%# D Pq# Qq# mapR,# 2  `8 saa# bq#cmdc,# dq#EqX Ji < __siq< < __si<qq< <$ __si<qqFq<[,\ __sx2z,, __sx<22z,,, __sx<22F2z,,= q8  qa 8 =  ql`r !acr"cx#qW$ %nowP$ #,X&opt,' 5<<$LX 5'<'<$ht> 5+<+<$n ;,U(8 ,)K $ 5/</<* &h0 #+c\ q`L,sa$ %nowh+c]-jwk.cir.srcik/hexki0pliPx1 <!fd q!cb !arg -&sK8  @q<`^C%saAV$`2%nowC`*2;CU+c ]1Qq`P!_s!a %sa`%lG}&fdq%sU$P%nowT$%nowT+c]3x,94sw,/srcy,/dsty,/czq5 qP`!.ssM6g ,k7s,7k,8#qj8q8q 9 q0cur,}$7p,87p2,p7iq8d'V929P29 2:$ )C )7 ;$ )C )7 ; MqM2PM2 M2C:)w )k < CV) ) ) < ) ) ) ) < iA_qs,lqBs C,nowC,nowC,now+cSX]3~ q4ss4reti/st/modqCz/srci9y N/iqCk/ccN9q,nowC,now +c>H]1" q`|3!_s_!a &s $Px&l.q$|%now1@$ ;%now3@(x8);0@@,@g@<@/@@@ @ E"@$FF*<<$FF*<<$HG/@$T(GA@'w. 2S C 2h X 2} mGXCC iLJ X\M =M =M\ =M3qMvppNJp ,M4 O g doO) gL`o u  c |usHCuintg>8V-zld|t3,2, $- O# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&O#8 *O#< ,o#@ 0,#D 1A#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L#h 0 NO#l SP#p  >  # p# O#  ' 1Kgp 3!* * +#key,# -# .# K 1 :# ;# C<# % 2  H # JI# J#t H__sQ O $__s#, #O6 #O% 0__s/, /O6 /O@ /O1[__szl__s<z__s<Fz} X|]secW"  kO"Osj" j #klOTU K ]8>#db\ ]# \{#s^# y8h#dbx #secx# x$sz;$k|OY$ Ghw$WpF $sHTkI$J Y$ sX$ endX%! ZO%" [!l [% P$& pOC&#" Q" Q" Q$ a&n p& sep&%c&%q&&lOW' O (db (p) *cur" + *c" *key*val+g ""P" + ,,-+B ,E,9,--Q-^,,,,--"5ڞ"ڞ./c* HcZ  & $' c'old 'db Z0nOlenO'fdO>(0buf1  1 1:42a pp3n6 ,4(,5`6[7(57(70)6U7)#4---84,,#4-/c? 8V-zld>zGz|1  g   p 3   !   *   & t3 F_G#H#7zDH# _ Nj  O1%,2, $ - O# #} # #  #U #  ## # #  #$ #( #,\ "#0 $#4u &O#8 *O#< ,o#@ 0,#D 1A#F 2#G 6#H ?#P H#X" I#\) J#`0 K#d7 L+#h0 NO#lS P#p >  #p # O#    'OO   , O  { 6#s  #  #  +#  app @V A#) B# C#end D#  E#OO _ Mhnow N6#due O6#r Ph#w Qh# RO#run SO#5 VyO   W X#app Y#cb Zn#arg [# fd \O#  hX iX#app j# k# l# cur m# nO# *+#key,# -# .# ^d1b>   k v$?e@O#5AO#AO#AO# curAO#pidBO#cbCq# D#E# qe ; / O# O#bpp O## %b w .OO# O#/O#O# bppO## $fdO#(O#O# O# ## .qO  k  h   P#  Q# R#sS# T#[ U# Yh / Z#k [# \O#]O# a b # c# d #h &nm sO#etm # u} #dbz #{#}|# ~O#~O#O# O#O#O# O#O#cO#delO#symO#" O#FO# O# O#ZO#D O# O#>O#OO## #fw# #vol# #3 #fb ## 6#6#6# ## O# O#8  #  #@  #  #  # #"O#" } %     O   + __s !O"+ +Q __s !<O!O"+ + __s !<O!O!FO"+t + __s !Q O"+ $+ __s# !, #O!6 #O"%+ 0+m __s/ !, /O!6 /O!@ /O"1+EO!J #xE]$xDOP#qJ]$xIOP%OX)5&_l)&_r)'l5)'r5*'dO*;(%OX|(*&_lG*&_rZ*)l5U)r5T'dOm**?|*+ >*+1 >** *,x0O+,y0OX++O+,curO+$buf,lenO+-B,bg0O+.iO,/xOV/yOW0yH1.cc%7,.bg%J,10/now6@2c ) f *](s,=0cN{3lO Nh =*O(L,|,fdN,%O  L,&key -&lenO;-)l`'k Y-1<)now6X2c(f4VA eU 3iWO503now_62c($f*5wl-,pv -,lenvO-6x7 89-8P:#X* }.,p| 3.,len|Og.1X/now~6`2c(4f* . ,p..iO..lO.1ly/now6P;0""P" ;H/now6P1" " " 1</now6P2c)Hf<O!/l,key @/,dst^/.e |/*6 $/+ O/* 3$//l4OV1P/now66h183p82c!)Xf=dT /,sc"0/teW/cure U1Xf/nowi6`1$ /nowq6`2c(df < 1OT  l01 ,sec010/k27W.e3 01  /now66P1  !/now96P1  .l;O0.s<1;`c/now=6P>mX d ?}7>m  B7>m  E7?x"I"PI" I@ I78 7, 7 ?AD 1 H  /now[6P2c(pf=( ^<fO R1,sece1}1,keye 1+seO1,dste1.eg 1/kh7V1D/noww6`2c(|fB O 2&fdOI2CI \2&lOz2'c2'pc2'p3'iOM31X\D~O10)now6dEOY)map=(2c](f64 W3tX *  k3m+ O31<4/now6h>L\8L932c(fF O3$,ac3,av43iO18/now6`1x/now+6`1 "5-+"-+2c(f= T94[/stT.d[e4Fy Tx4+ x 4/tz U3l{O1|"5~+"~+18/now6h2c(fG 7P! [ lenO3k75?3now62c)fGO+ k73tmp3p"3lO53now653t 53now6H3pix3lO53now653now653now62c)fGq "!! 3fd#O3p$"#%:5|3now)653now1653now362c)f* T"4+1 O4.act75.iOI51h/now6\>#Q77 ?A#8:2\1,n/now%6\IP&7b?9lg59x59"6A;@: \I+X+7=?p9IV6AT9^61h:\1 :o\8T:\1lA:\1<W:\1Hm:\?961:\8,AA1 (!/now(6\2c)f4+ G evF!1 FO3kH3eI 5!3nowP65U3fnkf3itO3cuH3now65o3t3p0%KOZ0LOZ/symMOZ/fnNO Z2c6) g  *c T",60!,ev7+1 OG71"L#, /now!6T>`#)& 77?:D9p7;0 :&A29<78%<&:GT1#($ :T?H :ZT9d71@** .i1O71+x+ /now?6T0Z OY0OY2c;)fGL OC"!3sec13iO3e 5!3now65!3now65!3now65!3now65!3now65!3now65!3now65!3now65"3now65""3now652"3k 2c(\gJ O4 # k3src3dst[3lenO5"3now 65#3e 3c3cp5""~O5N#""P" 5#7 7 HA 50#78 7, 7 HAD H7 7| 7p 7d HA 5`#3now65r#3now!6H3now$65#3now(62c(lgF 4O,=8&I0!x :%KB!@8? 9N!^89Z!89d!8; $:"L1855#$:"L;( 5$:!L134K$:!LLC"1D11D00q$:!L1`/0$:!L1,h-$:s!L1-.$:!L1\11$:!L;@ $:!L?X 9'"A96P"(8<7^"?p Ah"9t"_99"}9; %9"99"99"9; ~%A"A"A"@ 78 7, 7 ? AD 1`99%:S#L19t:%:e#L8:;:s#L1H88%:"L8x<<:#L1==&/now<6L2c@)|g=F=? :&+ E9:+1 Eb:0HGH.lenHO:.fdJO:1,>>&/nowN6@2cr(gFO?LF:(,_s;,a2;/fds(L.iOP;/jOW.evOy;1@??>'/now6D1?@['/now6D1`BD'0I -(8`BC3lO.nO;1BC'/now6D88CC/now6D18V-zld|t3$-i O# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&O#8 *O#< ,o#@ 0,#D 1A#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L#h 0 NO#l SP#p >  # p# O#p  i  '1%,2,43I DDid# :# # s# # n# #$ q#& #( #, :#0 #4 {#8 #<     M # # *# # ]# # [# # # b# #red# #, a#8 #D #P R#T #X /#\ #` #d <#h h#l #p #t #x Q#| # # # #  ; ; / O#  O#bpp O# ;# %b  OO#  O# /O# O# bppO# ;#$  fd O# ( O#  O#  O#  A#   # L  uU4 -z, O ɽx1 O#y1 O#x2 O#y2 O# < U#  ӽ#O `ofslen>OO.LFXF]. ~;4LuOXFF;.; O<ppxD<EOA!uOF`Gb< fbs <s.<xtO<ytO<ct=bgtOpixvAX\`GxH%= fbZ Q=1 [Oo=x0[O=y0[O=w[O>h[O5>J[T>ua]Pret^OxGG`   GGa   !c TwHKxHI>. fbJ >f IhJ>z "uM~"[&~fb k z % #?" "! L$$$\vhJlQGsHCuintg>8V-zld|t3$-i O# # }# # # U# # ## # #$ #(  #, \"#0 $#4 u&O#8 *O#< ,o#@ 0,#D 1A#F 2#G 6#H ?#P H#X "I#\ )J#` 0K#d 7L#h 0 NO#l SP#p >  # p# O#p  i  '1%,2,; 4 / O#  O#bpp O# 4# %b tofstlent>OOhJJ]pĹ>OQtmp4P:JJ>pݹ?JJ.?6wOM?hOk? Opӹ?BOJ@P?_dst@?dx@O?dy@Oc@srcA@sxAO@syAO(A/AOhAAOAbgAOAC4BC4`B-DOBDOBiEOBjEOBEO=CHOD%[CE $ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/  : ;  : ; (  : ;  : ; I8 ' I' II.? : ; ' @: ; I : ; I&I.? : ; ' @ .? : ; ' I@ .? : ; ' I@ 4: ; I4: ; I 4: ; I !4: ; I"4: ; I# U$4I4  %: ; I& '&I( : ; )4: ; I? < *4: ; I?  % : ; I$ > $ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ &I : ;  : ;  : ; I8 ' I' II : ; ( '  : ; .? : ;' I@ : ;I.? : ;' I@: ;I4: ;I  4: ;I 4: ;I!.? : ; ' I@": ; I#: ; I$4: ; I % &4I4  '.: ; ' @(4: ;I)4: ; I*.: ; ' I +: ; I,: ; I-4: ; I. : ;/ 0 1.: ;' I@2 : ;3 U44: ;I51UX Y617 U841941: 1;41 <4: ;I =.: ;' I >: ;I?1X Y@4: ; IA4: ; I? < % : ; I I : ;  : ; I8  : ; I8 $ > $ >  $ >  : ;I8   I8 4 : ; I!I/ &I&!I.: ; ' I@ : ; I.? : ; ' I@ 4: ; I.? : ; ' @ : ; I .? : ;' I@: ;I 4: ;I.: ; ' I@: ; I 4: ; I!.? : ; ' I@"4: ; I#.: ;' I $: ;I%: ;I&4: ;I'4: ;I()4: ; I * U+1UX Y ,1-41.41/4: ; I? < % : ; I$ > $ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/  : ; ( .? : ;' I : ;I: ;I4: ;I .? : ; ' I@: ; I4: ; I 4: ; I  U U4: ; I1UX Y 141 41!4I4  "&I#!I/$4: ; I %4: ; I? < &4: ; I?  % : ; I I< $ > $ > $ >   : ;  : ;I8 : ; : ; I8 I!I/ &I : ;  : ; (  : ;  : ; I8 ' I' II'  : ; !I/.? : ;' I : ;I: ;I4: ;I  .: ;' I@!: ;I": ;I#4: ;I $ %4: ;I &4: ;I' U(1X Y)1* +4I4  ,4: ;I-.: ; ' @.: ; I/4: ; I04: ; I 1.? : ;' I@24: ;I3.: ; ' I 4: ; I5.? : ; ' I@6: ; I74: ; I84: ; I94: ; I:1UX Y ; U<41=1UX Y >1X Y ?1X Y @41A.: ;' I B : ;C D E 1F4G41 H1UX YI1X YJ1K1UX YL4: ; I M4: ; I? < N4: ;I?  O4: ; I?  % $ > $ > : ; I$ >   I&I  : ;  : ;I8 : ; : ; I8 I!I/  : ; (  : ; I8 .? : ;' I : ;I: ;I4: ;I .? : ;' I@ : ;I&I.? : ;' I@: ;I4: ;I 4: ;I.? : ;' @.? : ; ' I@ : ; I!4: ; I"4: ; I# $.: ; ' I@%4: ; I&4: ; I '.: ; ' I (: ; I): ; I*4: ; I+ ,1-41. /4I4  04: ;I1 : ;2 31X Y415 U641 74181X Y 94: ; I? < % $ > $ > : ; I$ >   I : ;  ( I !I/ &I  : ;  : ; I8  : ; 5I : ;I8 : ; &' I : ;  : ; I8 ' I' I<  : ; !I : ; !I/.? : ;' I  : ;I!: ;I"4: ;I#.: ;' @ $: ;I %.: ; ' I@&: ; I'4: ; I(&I)4: ; I *.: ;' @+: ;I,: ;I-: ;I .4: ;I/4: ;I 04: ;I 1 24I4  34: ;I4.: ;' 5 61X Y718 941:41 ; U<.: ;' I@=.? : ;' @>1X Y? U@1UX YA41B.? : ; ' I@C: ; ID4: ; IE4: ; I F.? : ;' I@G.: ;' I H I1UX YJ.: ; ' I K1L1X YM4: ; I? < N4: ;I?  % $ > $ > : ; I$ >   I : ;  : ;I8 : ; : ; I8 I !I/ &I : ; I8  : ; ( .: ; ' : ; I: ; I.? : ; ' I@ : ; I&I.? : ; ' I@: ; I4: ; I: ; I 4: ; I .? : ; ' @4: ; I1X Y  1!4I4  "4: ; I #!I/$4: ; I? < % $ > $ > : ; I$ >   I : ;  : ;I8 : ; : ; I8 I !I/  : ; I8 .: ; ' : ; I: ; I.? : ; ' @ : ; I4: ; I 4: ; I .? : ; ' @.? : ; ' I@4: ; I4: ; I: ; I4: ; I : ; 1X Y 1  U!4: ; I"1X Y #4: ; I? <   /usr/home/luigi/arm-2008q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/bits/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/netinetmyts.cstddef.htypes.hlibio.hstdio.htime.hselect.hsockaddr.hsocket.hstdint.hin.hmyts.h/j/&kK$.9fQJ$ggLg-BKK0//K!)mgKghKI0/KJ!ggD!KBhH/K/0x.L//*0 rf.2)vJga/g/gggy. fL~ֽKLgKKF///gK/ fKgiKjiK Jh& /usr/home/luigi/arm-2008q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/bits/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/systerminal.cstddef.htypes.hlibio.hstdio.htime.hselect.hstdint.hmyts.hterminal.hioctl-types.h fMkp0KL{Jih/PKKLKKLKKLKKKKM^KHjhjFKFK//KKK///0KKghK//JgBKLgL/{KK. jHL2Kg1/K}J0BBKN`nKKK/g/Jg-0/Kg-0/Lg/gLdk!KI0gKK-0gLgLdkg-Vnf@KD @KDUf4gK-lHKI0I0KLggggI0ggKgghI0I0I0!!I0gKMKe0Ke0Ke0KhgZhgKiKgKgKgBFKggxfgggghDKgD׻׻׻ڟ\YD~JXLB1+IT) ,KBـKTDKT f׻׻gLL}Jh0FJz.f,zNhKKFgFPlfgFBLdy.0LFzgRXith&ן/-gKF KKig .v.?BDesXfKg2ZiK& /usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/bits/usr/home/luigi/arm-2008q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include./linuxlinuxscreen.cpixop.htypes.hstddef.hlibio.hstdio.hstdint.hfb.hscreen.heinkfb.hfont.hLFiLh0gKK>a//`f./MjhK9../MjhK.z//KK/NKZLZ/L!/LKKg!FfOwKMLKKNKKgKKh;J /usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/include/bits/usr/home/luigi/arm-2008q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/include/usr/home/luigi/arm-2008q3/bin/../arm-none-linux-gnueabi/libc/usr/includepixop.cpixop.htypes.hstddef.hlibio.hstdio.hstdint.hhJLKf/KqJh///N~.KK JEJK1JDJ/jg2JCJK3JBJ/jg?Jv OJ_.=Z"L"KKKgKKK0j/K/].M=Y/Gggecl/L~JLy./MjhK+x./MjhK,/hK/gh/cJLg | `D \ LT(pD$D @DD(P(DD($x$D DX | XDD 0lDD@ DD8$D DH4pD(`$D$D DD0D | ,, ,L4 , , ,$,D,TpD,(D,D,TD,4D,,HD D,D8 ,H$D,lD | $D$DX | $lD$D8 `0D D \DPD <$DD8`D D8$PD$DP (`D$D | |PD\D80DhdD$D( (D D $D$DH |  HDX$D|PD D(D$D \D D($DL4DD8 @DD@DD0$ D$DH 4DD$dDD(DD0$T @D$DH  lDD0 DD0 DD( DD0DD@TtDD(  DD8$T" D D$,D$Dh =TDDP(?DD$D | LF  XFD FpDD@ `GDD@ xHD IhDD | @ hJ<@ JD@ J@D$@ JHD$Dh @ @P,D  | lQ  | S SlD _IO_read_ptr_chain_shortbuf__s1_IO_buf_basetimerduelpadlong long unsigned intin_addr_tcb_argslong long int_fileno_IO_read_end__quad_tmaxfd__s2_len/usr/ports-luigi/webtty_cur_columnSOCK_STREAMshort int_old_offset__resultnextsmainloopGNU C 4.3.2sin_zeroSOCK_RDMfd_sets_addruint16_tcb_fn__bsx__arr__suseconds_t_IO_write_ptr__FUNCTION___sbuf__metimeradd_msshort unsigned intsin_addr_posmyts.c_IO_save_basestdin_locktimevalstdoutmy_argsoptvalsin_familytmp_sessopensocktv_sec_IO_write_end_IO_lock_t_IO_FILE__off_t__s1_len_IO_markersin_portsa_family_markers__socket_typeunsigned char_IO_buf_end__fd_mask_flags2_vtable_offseterrorSOCK_PACKETtv_usecuint32_thttp_appsockaddrverboseargc_next__off64_t_IO_read_base_IO_save_end__pad1__pad2__pad3__pad4__pad5__time_tsa_family_t_unused2stderrargvSOCK_DGRAMsockaddr_intimersetmin_IO_backup_basesa_dataSOCK_RAWall_appsSOCK_SEQPACKETmain_IO_write_basenew_sessin_port_t__fds_bitsterm_keyboardkf_autowrappagelenpage_scrollslenka_fg_shiftmodifiedcur_attrkf_privterm_findka_bgnowrapmarkTS_NAMEterm_newscroll_bottomeraseka_bg_shiftterm_screenterm_killkf_graphicsrowsspospagescroll_topnotfoundkseqmy_sesskf_dographiccurcolhandle_shellka_fgTS_MODpage_appendws_colterm_namews_xpixelkeysterm_keyinklenws_ypixelwinsizekf_nocursorterm_statedo_csiparmws_rowTS_CBkflagskf_insertuint8_tterminal.ckf_wrappedspecialcols__dynstr_helperwantds_resetds_free__va_listds_sizedynstr_make_spacenewbufds_refrecsizeds_len__gnuc_va_listds_adjustdynstring.c__dynstrneedusedds_shift__resds_datads_appenddsprintfmax_len__apnew_lends_truncateinit_lends_createds_readonly_IScntrl_ISgraph_ISpunct__strsep_3c__cp__r2_ISdigitcp437.c_ISblank_ISalnum_ISspace__reject1__reject3__r1cp437__strsep_1c_ISlower_ISxdigit__retval__reject2_ISprint_ISupper__strsep_2cbuild_map437__r0_ISalpha__reject__u_quad_tst_ctimst_blksizest_blocksuse_spanSHUT_RDWR__gid_tst_mtimunescaperefresh__dev_thttp.cquery_argsatoi__nptrhandle_listenhttp_writeclen__blksize_tst_uidh_aliasesst_rdevadd_digitparse_msggetmime__mode_th_addr_listhttp_deschttp_initresourcehostentmethodst_gidh_namereplyh_lengthSHUT_RDst_sizehttp_start__unused4__unused5fstat__blkcnt_th_addrtype__ino_tinbufbodysuffixwrite_donebuild_response__fdSHUT_WR__strcspn_c1__strcspn_c2__strcspn_c3st_nlinkst_devtimespecunsafebody_lenhttp_timeoutu_modecolorhttp_parsenew_clienttv_nsechandle_httpst_mode__uid_tlsufffilepmime_typeslresst_ino__statbuf__nlink_tst_atimcfg_section_namecfg_find_entrycfg_parselen1skipwsin_quotecfg_freecfg_find_sectioncfg_find_valkcurparse_namegood__a0__a1__a2__strspn_c2immediatebasedirconfig__accept1__accept2__accept3trimws__acceptcfg_readconfig.clast_ws__strspn_c1__strspn_c3sectionsvaluehotkey_modecapturebuild_seq__u16terminalis_kindle3alltermhot_seq_lenterm_shiftprint_bufcall_hotkeycode_lasthot_intervalcurterm_endprocess_termhot_seqsaveareakbbuflookup_keynpressedprocess_eventget_file_contents__invalid_size_argument_for_IOCsend_ascii_stringprocess_screenfw_selectfree_terminalsxsymlaunchpad_startprocess_scriptnamelenKT_VOLthe_shellfdinlaunchpad_parsenameincapture_inputterm_fnlaunchpad_initystepspixmap_tnameoutlaunchpad.ccfg_namepseqinput_eventlpad_descrestartby_codelaunchpad_deinitfind_actionfw_righthot_seq_devpendingscreen_duehost_eventcur_xcur_ysurfacefw_downiodesclp_statewidthsend_keykey_delaytmpbufrefresh_delayprint_helpKT_SHIFTk_typehup_handlerfdoutsend_key_entrysetKeyhandle_launchpadecmp1hotkey_duesend_eventactionssetValgot_signalecmpfbscreen_tfbscreenysymexecute_action__s32nentriesflenscreensizecurtermpixmap_strterm_esccode_firstterm_symtrailerKT_FWint_handlerscript_pathKT_ALTshell_findsend_event1kpadterm_deadfw_upsave_pixmapkeys_dueKT_SYMtimefw_leftKT_SENDmust_freefd_closegot_introcompile_actionheightterm_ctrlmsb_rightfx_maskleft_marginfb_closevsync_lenyres_virtualright_marginvinfoaccellower_marginaccel_flagsfx_typeline_lengthvmoderotatebufferxres_virtualgrayscalepixelsfb_bitfieldreservedfb_fix_screeninfofx_update_fullsmem_startfb_char_atfx_update_partialbound__u8__u32update_area_tyresbits_per_pixelypanstepfx_flashxpanstepnonstdxoffsetmmio_startsmem_lenfx_noneywrapstepfb_var_screeninfoxresscreen.cmmio_lenupper_marginfb_getfonttransppixclockfb_update_areafont_pixmapfx_buf_is_maskwhich_fxbytespercharactivatefinfobluefb_openvisualget_char_pixmapc_truncategreensyncyoffsettype_auxfx_inverthsync_lensrcofsfastpixop.cpix_bltpix_invertn_bytessrc_stridesrcpdstofspix_allocdstppix_freenbytesdstmaskdst_stridefill_stridesrcmaskpix_fill]`}$Q`pPp\`QPRRQ\]}$}0P0pZpPZUHLU0UVSVS|VTTTU0PTtTTT$}V]}}(P}QX,TTTT,TTP hPhxPPP]}}(PUQtTTRVSWPPP]}  }  Z  YX \P P $]$x} 8P8xVx|]|}xPxQQPP]}}PPPQW]}}80P0U4Q4X,R,W]} } P YQXRVSW\\]}PT ] }$h+}$P$h+V,Q, W Z U Z4U4|Z|!U!"Z"#U#%Z%)W)x*Zx*|*W|**Z*$+W$+0+U0+h+Z4xXxQ X 0 Q0 X Q | X| Q  X 4 Q4 XXh+X4DPD}<|*P|*+}<+h+P4}88L8}8LLLh+}84L}4LH}4Hp}4pH}4H }4 HT}4T H h+}44}S8p8<S<p}SpS<p<l}lRp(R(p}p}p } (p(,S,8p8X}Xp}p4}4<p<@S@LpLp}pp$}$pT}T p h+}4}lp}pl`}` l h+}4p}phh+}4TT0|T)<*T`*|*T+$+T4U8|U)|*U+$+U4XXX !X)|*X+$+Xh+l+]l+p+}p+0}0h++P++P++P<,T,P,,P//Ph++Q++U++Q+@.U/0Ux++V++P+0V,4.W/0W//QX./X/0X00]00}0 0P`0h0P00Q00U00T0 0P 00T PP (P08P@HPLTPT\P`dPdlPptP](}P(TQ (QR R(,],}(8P8U(8Q8TtP]}PP]}PUQVRTQ]}PVQUU]}PVQURTQQ ] $} $(},(}8HPHVHHXLdPxPPP  PLXSSQS S@LZLPUU ] @},P,@T0Q0@U4<P@D]DX}@PPPTP]}$}$P8`PP(Q8dQQp8},P},\}(\lll}(l\PlTPTTPQRQR`Q`dRWSWS8WDWlTTT]}$}8$PPP Q UVUVT<TP\PP]} $} $(](}$@P@U$8Q8T]}P\Q^RSP]}}8\R]} }8 P<\P(Q<DQ,PP]}$ }P YQQHdQQ Q|UT U UHWHpTpWW T 0 W0 \ T\ d Sd W S \ T\ W TZXUXDZD|U|ZT UT Z U Z U } 0 T0 } }  0 X0 } } $l$H} H lHT T|U UpT VSSS@ }\ ` d` } d ] }$ } P4 @ P P $ Q$ W Q WW0W  V P V < U4<P<P\}\p}}@ }DlDX}Xdld} Z Q ZQ R $Q$<R<Q$ZZ0Z$Y$PQPTXT|Q|RQRQXdYdU Y HUHYUYURURLULPYP|U| XU Y XUXt X U\\ \^^ ^H }R}LPUUUUtU0UTSTSTTTT T0TtT0@ThT4TdT$TP(P(0S0@P@LSLP\P \[ [[U UUtU0U ,Y,PPPXYX`P`YPY YY$0Z0`T`pSpTZ Z0ZR8R`pR|RRRP4pPPPPPYT(Y(XTXYW0WXtXP P]`}<PX\P$Q$0U08Q8`U`d]d}`PP`pQpUQUxTT]}PQQRTPPPP]P}PPU$P(4PPT]Tl}(P`P`xXxTSTSX S T(X(<S<XTX`X`dSdlTP`Q`lVUYXUXlYWZXWXlZlp]p}lxPxT]} PUQVPtRT|Z|T]}$d }PT8 < T T d TQd }Rd} d ` } ` } ` d } UUUU(\U8 U d U} }<h< } h d }T}p}8 p8 D }D d pV(d VtT(T8 < T d T} l }8 l8 } l d }`< T d T04]4x}0DP0pQ8t\@pQDlPx|]|}xPxQP]} }P}Q}]}$}PL}`(>8>P$CC},CCPCC},CC`(849W499^9l?WlB$CWCCW$809V09:T:P?VlBpBV|B$CVCCV<>$CYCCYH>$CZCCZH>$CVCCVH>$CWCCWH>$C}?CC}?H>\?U\?h?Ph?$CUCCUCC]CC}C(E}CCPCCSDDSCCQCDVDDQD(EVDDWD(EWDDU$D(DU4DDUD(EU(E,E],E0E}$0ElL}(EdEPFFP(E@EQ@ElLYHIZIJTJlLZtHITIJWJ`JTKlLTH\KVKlLVP ]} P 4Q48\8PRP\ 8R8T]}}PVQPRWSXS]},}P,PQ,Q,R,8\8xVx\,VDSD`T`lRlTR,T44,UDD,W,,0]0},8P8T]}}P<@]@P}<LPPT]T}PpPpTPlQlU|P]}$}P} T} Q}P}`P`PP}RQRRS}L}UT}TUU4T4HQHTTD}D$} 8}8(d,dW,},`},`TT}0d}0<d<XX\\tPX}4XVVZ\[R[[TUU}8ll<X`U}<}<\[|YdWR R]} PPPQTVDTDVTVTR,U,8\8dUdp\pUUUSZWQYYp\RU\UXXVV ,D$h*0+h+ !0+h+ x 0+h+!|lp L `(4P*+$+0+,,,.0.4.//T./8DL 8@T<@lT`8<P8@D@D@D@D@D8LP8<P|8<P|8<h|P\44  4 ,@8   x8  PPP\DDDD`p$(p0`$(0X$(0X$(0X,,@hlLP<0<0L\@<P88L\@<P8\<P@Lt0T $tXdL@4 8 $tXdL@4 ( 4 D p\\\L &''L ''''x&&%h&%%!% !! !! &h&x&&#%''#,$''$%\$$@$P$ !!!L")`+4// /$/....\.t.4.L..$.x-.-t-,-,,,,p+,+`+p+\,l,,-\-,-,,,,t2$CCCt22CC<>$C$>0>D8>h788,7d7777 766l56X5`5D5L538523;<CC\:h::,;0888X88,>0><>$CH>>h?C>`?>`?h?pB>? ?L?>? ?L?>? ?L?A.aeabi$ARM10TDMI .symtab.strtab.shstrtab.interp.note.ABI-tag.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.ARM.exidx.eh_frame.init_array.fini_array.jcr.dynamic.got.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_ranges.ARM.attributes44#HH 1hh47 ?fGo To @c TT l dd ( u p P{D,T,4T4 $pTxT \x\``ddhhll\\$d_YYYz^[ ~\M`c(,D 5008U@K1FK Yp/iH%? 84HhTd    ,T 4TTx\x`dhl\Y !"   <  ,T H  4T 0T )h6D D \ LY[dd` `  ``     @ P \ x \ 8T DT PT      |   t   4p 4 `$     x 0 T    `  ( V %V7$V I0V [ ? F  f  f $f04fBHfTXf fdf xpf |ff fff f f ff,f> g Pg4g[Pg f\gxlg|gg g4ZYYYYYZ ZZ Z%LF TF XF F F dH xH HJ .Tw@L@ kS k$[hJ dQ @ lQ ctQ r S xS  T \xh\d`l    d  p$Dk)80 6čHFЍW܍djS zP Ih  T t  0l   2JH : D$Y\ka0t,T z`oP( <tHT`` lx S"  ! J * ( 1 C U J@ _  i p r ` ~ XF `k 4T d d d  ̎ ؎d p  / Y= =T I [ @P, d  m  S"  H$ X xH `G ` ,0 \x  8  ' DPF lQ  O Px_ l Fp w \8 h  H o t Sl o `  P   (  \ % 09 L ` p $ y P Tt ȏt ԏ d x hd P ?D  Y 03 o> 4 H   S L4 [ X e S  u LT ~  \ o l `  ( \ T Y4@(L<P CXpU ^ idz| pPLF  Y|`8Tx((lQ 5x$ >doC P4bĐrАhJ<  ܐ0@  , call_gmon_start$a$dinit.ccrtstuff.c__JCR_LIST____do_global_dtors_auxcompleted.5877__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrymyts.c__FUNCTION__.4188__FUNCTION__.4153__FUNCTION__.4117terminal.cerasepage_scrollpage_append__FUNCTION__.4206__FUNCTION__.4239__FUNCTION__.4867__FUNCTION__.4578__FUNCTION__.4289special.4574__FUNCTION__.4818__FUNCTION__.4760__FUNCTION__.4788dynstring.cds_readonlydynstr_make_spacecp437.c__FUNCTION__.3728cp437http.chttp_parsehttp_initadd_digithttp_start__FUNCTION__.5225__FUNCTION__.5198__FUNCTION__.5425__FUNCTION__.5164__FUNCTION__.4368__FUNCTION__.4694__FUNCTION__.4806__FUNCTION__.4632__FUNCTION__.5116mime_typesconfig.cparse_name__FUNCTION__.4492__FUNCTION__.4371launchpad.chup_handlerint_handlerecmpecmp1send_eventprint_bufprint_helpfd_closelookup_keysend_keysend_ascii_stringprocess_scriptsetKeycapture_inputcurterm_endbuild_seqsetVallaunchpad_deinitcall_hotkeyprocess_event__FUNCTION__.6730__FUNCTION__.5794__FUNCTION__.6278__FUNCTION__.6334__FUNCTION__.6353__FUNCTION__.6579__FUNCTION__.6855__FUNCTION__.5912__FUNCTION__.6007__FUNCTION__.5691__FUNCTION__.6916__FUNCTION__.7070__FUNCTION__.6894__FUNCTION__.6542__FUNCTION__.6195__FUNCTION__.6445__FUNCTION__.6220__FUNCTION__.6791__FUNCTION__.6607C.145.6639C.148.6652__FUNCTION__.6048__FUNCTION__.5818__FUNCTION__.7148__FUNCTION__.6258__FUNCTION__.6945map.5683lpad_desclpsintro.5682npressed.6788got_intro.6789shift.6603ctrl.6602sym.6604fn.6605screen.c__FUNCTION__.3982font_pixmappixelsfb.3942pixop.c.divsi3_nodiv0shiftelf-init.c__FRAME_END____JCR_END___GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startopen@@GLIBC_2.4qsort@@GLIBC_2.4process_screenhttp_app__mecfg_find_valmmap@@GLIBC_2.4abort@@GLIBC_2.4connect@@GLIBC_2.4__libc_csu_finistrcasestr@@GLIBC_2.4cfg_find_entryfb_open_start__libc_start_main@@GLIBC_2.4all_appsinet_ntoa@@GLIBC_2.4signal@@GLIBC_2.4cfg_readterm_state__gmon_start___Jv_RegisterClassespix_bltterm_killvsnprintf@@GLIBC_2.4verbosestrncpy@@GLIBC_2.4_finihttpnew_sesssystem@@GLIBC_2.4strchr@@GLIBC_2.4strcasecmp@@GLIBC_2.4dirname@@GLIBC_2.4ds_sizelisten@@GLIBC_2.4calloc@@GLIBC_2.4__aeabi_idiv0memset@@GLIBC_2.4pix_freeskipwsexecvp@@GLIBC_2.4perror@@GLIBC_2.4pix_allocterm_namemainloophandle_httpget_char_pixmapmap437_IO_stdin_usedfree@@GLIBC_2.4read@@GLIBC_2.4write@@GLIBC_2.4__data_startgettimeofday@@GLIBC_2.4accept@@GLIBC_2.4bsearch@@GLIBC_2.4launchpad_parse__bss_start__send_event1socket@@GLIBC_2.4pix_fillds_shiftinet_aton@@GLIBC_2.4__aeabi_ldiv0ioctl@@GLIBC_2.4ds_refbcopy@@GLIBC_2.4fb_closefb_update_areastrlen@@GLIBC_2.4sscanf@@GLIBC_2.4__exidx_endds_appendmemcpy@@GLIBC_2.4term_dead__ctype_tolower_loc@@GLIBC_2.4__divsi3bcmp@@GLIBC_2.4__dso_handlefb_char_atstrtol@@GLIBC_2.4strcpy@@GLIBC_2.4dsprintf__end__strncat@@GLIBC_2.4__libc_csu_init__bss_end__timeradd_msraise@@GLIBC_2.4new_clienttrimwsds_createcfg_find_sectionasprintf@@GLIBC_2.4forkpty@@GLIBC_2.4shutdown@@GLIBC_2.4bind@@GLIBC_2.4ds_resetstrstr@@GLIBC_2.4shell_findselect@@GLIBC_2.4wait3@@GLIBC_2.4close@@GLIBC_2.4strncasecmp@@GLIBC_2.4cfg_free__ctype_b_loc@@GLIBC_2.4handle_launchpad__bss_startfprintf@@GLIBC_2.4_bss_end__ds_adjusthost_eventds_dataterm_find__aeabi_idivmodtimerduehandle_shellputs@@GLIBC_2.4_endds_freehandle_listenfcntl@@GLIBC_2.4readlink@@GLIBC_2.4timersetminds_truncatestderr@@GLIBC_2.4lseek@@GLIBC_2.4munmap@@GLIBC_2.4__fxstat@@GLIBC_2.4u_modestrspn@@GLIBC_2.4term_newterm_keyinindex@@GLIBC_2.4lpadcfg_section_namestrcspn@@GLIBC_2.4fb_getfont_edatastrncmp@@GLIBC_2.4kill@@GLIBC_2.4gethostbyname@@GLIBC_2.4realloc@@GLIBC_2.4__exidx_startsetsockopt@@GLIBC_2.4__aeabi_idivopensockdescbuild_map437strcmp@@GLIBC_2.4exit@@GLIBC_2.4__errno_location@@GLIBC_2.4pix_invertds_lensprintf@@GLIBC_2.4main_initlaunchpad_startlaunchpad.ini000644 000423 000000 00000006763 11510415325 013765 0ustar00luigiwheel000000 000000 ;;; $Id$ ;;; the launchpad transparently scans keypad/fiveway/volume keystrokes ;;; until the user presses and releases the hot sequence INTRODUCER key. ;;; This enters hotkey mode, where keystrokes are captured and not passed ;;; to the Kindle up to the pressure of the TRAILER key, or a idle time ;;; of HOTINTERVAL millisecond. ;;; At this point capture is released, and captured keys are compared with ;;; existing ACTIONS. In case of a match, we execute the action, otherwise ;;; input is transferred back to the kindle. ;;; This config file is split into [sections] with generic configuration ;;; being in [SETTINGS], actions in [ACTIONS], keystroke definitions ;;; in [INKEYS], [INKEYS-DX] and [INKEYS-K3]. ;;; configuration can be included with an 'include = filename' line. [Settings] Introducer = Shift Trailer = Enter ; terminal key configuration TermEnd = Left< TermEsc = Left> TermCtrl = aA TermSym = Back ; so we can map other keys TermShift = Shift TermFn = Menu HotInterval = 1000 InterKeyDelay = 50 RefreshDelay = 50 ScriptDirectory = ./scripts #KpadIn = /dev/stdin KpadIn = /dev/input/event0 FwIn = /dev/input/event1 VolIn = /dev/input/event2 KpadOut = /proc/keypad FwOut = /proc/fiveway VolOut = /proc/volume include = keydefs.ini ;;; actions are defined below as = ;;; one action definition per text line. ;;; ;;; is a blank separated list of key symbolic names. See keydefs.ini for details. ;;; describes the action to execute on a particular hotkey sequence. ;;; Currently three type of action supported depending on the first character of the ;;; command string: ;;; '!' -- shell command. The command string excluding the leading '!' is sent to the ;;; system shell, exactly as it was typed from the console. ;;; '@' -- Kindle Framework script. The command string excluding the leading '@' is interpreted ;;; as a name of a special script containing command information obeying format of ;;; the known hotkeys package. The main purpose of these scripts is to simplify ;;; entering special symbols into kindle Framework search box ;;; '#' -- Kindle Framework key sequence. Similar to the above, but doesn't require ;;; external script. ;;; all other command strings are interpreted as a sequence of a send_key commands. The contents of these ;;; commands gets interpreted and sent as a sequence of simulated keystrokes to the input subsystem. ;;; Such commands consist of the space-separated tokens, which can be symbolic key names and/or ;;; ascii strings enclosed in quotes (") ;;; ;;; Note: to correctly accept a kindle key sequence beginning with a special ;;; symbol, the Framework search box should be brought up, if not already. ;;; Press the 'Del' key on Kindle in order to bring the search box up ;;; [Actions] z = "testing luigi@foo.bar; me-12+55" 'Enter' F B = !/mnt/us/FBReader/goqt.sh FBReader & A F = !/etc/init.d/framework restart ; ;Dot = @SHIFT-DOT.sh ; D = #';' "debugOn" shift D = #';' "debugOff" N = #"~usbNetwork" T = !terminal 1 shift T = !terminal 2 # refresh content of /mnt/us/documents shift R = !dbus-send --system /default com.lab126.powerd.resuming int32:1 & # set/reset 'connected' flag C = !dbus-send --system /default com.lab126.wifid.cmConnected & D = !dbus-send --system /default com.lab126.wifid.cmDisconnected & keydefs.ini000644 000423 000000 00000003426 11476412350 013457 0ustar00luigiwheel000000 000000 ;;; input key definitions is in one generic section [INKEYS], ;;; plus system-specific ones ([INKEYS-DX], INKEYS-K3]) which are ;;; used depending on the system. ;;; Definitions are of the form Code = Name .... ;;; CODE is a number optionally preceded by s, f, v to indicate ;;; that the corresponding names on the right are meant to be sent ;;; with sendshift (s), or on /proc/fiveways (f) or /proc/volume (v) ;;; In case of multiple names, codes are assigned sequentially. ;;; Special case, the code ROWn where n is a number correspond ;;; to row in the 'Symbol' menu. ;;; NAME is the symbolic name of the key, used in actions. ;;; Single-char names correspond to ascii chars and are case sensitive. ;;; other names are case insensitive. ;;; use \\ to protect special chars (space, ; and #) ;;; # is a valid comment only before a '=' [INKEYS] ; generic codes, for all platforms ; ascii keys 2 = 1 2 3 4 5 6 7 8 9 0 ; Alt + Row 1, not on kindle3 16 = q w e r t y u i o p ; Row 1 30 = a s d f g h j k l ; Row 2 44 = z x c v b n m ; Row 3 ; function keys 139 = Menu 14 = Del 52 = . 126 = Sym 28 = Enter 42 = Shift ; alt pressure and release is only reported after the next keypress 56 = Alt 57 = ' ' 57 = Space 190 = aA 102 = Home 158 = Back f103 = Up f108 = Down f105 = Left f106 = Right f194 = Select v114 = Vol- v115 = Vol+ 193 = Left< 104 = Left> 109 = Right< 191 = Right> [inkeys-dx] ; symbols for the kindle dx graphite ROW0 = \" ' @ - + * ^ ( ) < > ROW1 = ? , ! / = # | { } ` ~ ROW2 = & : . \; _ % $ [ ] \\ [inkeys-k3] ; symbols for the kindle3 ROW0 = : < > \" ? { } | ` ~ GBp Euro ROW1 = \; , . ' / [ ] \\ oQ cQ ~! ~? ROW2 = ! @ # $ % ^ & * ( ) _ + ROW3 = 1 2 3 4 5 6 7 8 9 0 - =