#include #include #include #include #include #include #include #include static const DirectFBKeySymbolNames(m_symbols); static IDiVine *m_divine; static int m_x; static int m_y; static int m_sin16_16[360 * 16]; static inline int sin_16_16( int deg16_16 ) { return m_sin16_16[ (deg16_16 >> 12) % (360 * 16) ]; } static inline int cos_16_16( int deg16_16 ) { return m_sin16_16[ ((deg16_16 + 90 * 65536) >> 12) % (360 * 16) ]; } typedef void (*HandlerProcess)( FILE *stream ); typedef struct { HandlerProcess process; } Handler; static void process_button( FILE *stream ) { DFBInputEvent event; event.flags = DIEF_NONE; if (fgetc(stream) == '+') event.type = DIET_BUTTONPRESS; else event.type = DIET_BUTTONRELEASE; event.button = fgetc(stream) - '0'; m_divine->SendEvent( m_divine, &event ); } static Handler m_button = { .process = process_button }; static void process_motion( FILE *stream ) { DFBInputEvent event; event.flags = DIEF_AXISABS; event.type = DIET_AXISMOTION; event.axis = fgetc(stream) - 'x'; if (fscanf( stream, "%d", &event.axisabs ) != 1) return; switch (event.axis) { case DIAI_X: m_x = event.axisabs; break; case DIAI_Y: m_y = event.axisabs; break; default: break; } m_divine->SendEvent( m_divine, &event ); } static Handler m_motion = { .process = process_motion }; static void process_motion_special( FILE *stream ) { int i, ms, ex, ey, _x = m_x, _y = m_y; int count = 1; int step = 36; DFBInputEvent event; if (fscanf( stream, "%d", &ms ) != 1) return; while (!feof(stream)) { switch (fgetc(stream)) { case 'c': if (fscanf( stream, "%d", &count ) != 1) return; break; case 's': if (fscanf( stream, "%d", &step ) != 1) return; break; case 'o': if (fscanf( stream, "%d", &ex ) != 1) return; for (i=0; i<=360*count; i+=step) { event.flags = DIEF_AXISABS | DIEF_FOLLOW; event.type = DIET_AXISMOTION; event.axis = DIAI_X; event.axisabs = _x = m_x + ((ex * cos_16_16( (i % 360) << 16 )) >> 16) - ex; m_divine->SendEvent( m_divine, &event ); event.flags = DIEF_AXISABS; event.type = DIET_AXISMOTION; event.axis = DIAI_Y; event.axisabs = _y = m_y + ((ex * sin_16_16( (i % 360) << 16 )) >> 16); m_divine->SendEvent( m_divine, &event ); usleep( ms * 1000 ); } m_x = _x; m_y = _y; break; case 'l': if (fscanf( stream, "%d,%d", &ex, &ey ) != 2) return; for (i=0; iSendEvent( m_divine, &event ); event.flags = DIEF_AXISABS; event.type = DIET_AXISMOTION; event.axis = DIAI_Y; event.axisabs = _y = m_y + ey * i; m_divine->SendEvent( m_divine, &event ); usleep( ms * 1000 ); } m_x = _x; m_y = _y; break; default: return; } } } static Handler m_motion_special = { .process = process_motion_special }; static void process_pause( FILE *stream ) { int ms = 0; fscanf( stream, "%d", &ms ); usleep( ms * 1000 ); } static Handler m_pause = { .process = process_pause }; static void process_text( FILE *stream ) { int ms = 0; bool leading = true; fscanf( stream, "%d", &ms ); while (!feof( stream )) { int c = fgetc( stream ); if (c == ' ' && leading) continue; if (c == '\n') break; m_divine->SendSymbol( m_divine, c ); leading = false; usleep( ms * 1000 ); } } static Handler m_text = { .process = process_text }; static void process_text_special( FILE *stream ) { int i, ms = 0; char buf[31]; fscanf( stream, "%d", &ms ); while (!feof( stream )) { switch (fgetc( stream )) { case '\n': return; case 'b': m_divine->SendSymbol( m_divine, DIKS_BACKSPACE ); break; case 'd': m_divine->SendSymbol( m_divine, DIKS_DELETE ); break; case 'r': m_divine->SendSymbol( m_divine, DIKS_RETURN ); break; case 'C': switch (fgetc( stream )) { case 'l': m_divine->SendSymbol( m_divine, DIKS_CURSOR_LEFT ); break; case 'r': m_divine->SendSymbol( m_divine, DIKS_CURSOR_RIGHT ); break; case 'u': m_divine->SendSymbol( m_divine, DIKS_CURSOR_UP ); break; case 'd': m_divine->SendSymbol( m_divine, DIKS_CURSOR_DOWN ); break; } break; case 'S': fscanf( stream, "%30s", buf ); for (i=0; m_symbols[i].symbol != DIKS_NULL; i++) { if (!strcasecmp( buf, m_symbols[i].name )) { m_divine->SendSymbol( m_divine, m_symbols[i].symbol ); break; } } break; } usleep( ms * 1000 ); } } static Handler m_text_special = { .process = process_text_special }; static Handler *m_handlers[] = { ['b'] = &m_button, ['m'] = &m_motion, ['M'] = &m_motion_special, ['p'] = &m_pause, ['t'] = &m_text, ['T'] = &m_text_special }; int main( int argc, char *argv[] ) { DFBResult ret; int c; FILE *stream; DiVineInit( &argc, &argv ); if (argc > 1) { if (!strcmp( argv[1], "--help" ) || argc > 2) { fprintf( stderr, "Spooky - DiVine event generator\n" "\n" " Usage: spooky [filename]\n" "\n" "Reads from stdin unless filename is given." "\n" "Commands in stream:\n" " Code Description Arguments & Options Examples\n" " b Press/release button +/-