int PG_VideoInit(_THIS, SDL_PixelFormat *vformat) { /* Connect to the PicoGUI server. No way to process command line args yet, * but since this is based on SHM it's not important to be able to specify * a remote PicoGUI server. * * FIXME: Another nitpick about the current client lib is there's no * clean way to indicate that command line args are not available. */ pgInit(0,(char**)""); this->hidden->mi = *pgGetVideoMode(); /* Create a picogui application and canvas. We'll populate the canvas later. */ this->hidden->wApp = pgRegisterApp(PG_APP_NORMAL,"SDL",0); this->hidden->wCanvas = pgNewWidget(PG_WIDGET_CANVAS,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE, PG_S_ALL, 0); PG_InitEvents(this); /* Determine the screen depth. * We change this during the SDL_SetVideoMode implementation... * Round up to the nearest Bytes per pixel */ vformat->BitsPerPixel = this->hidden->mi.bpp; vformat->BytesPerPixel = this->hidden->mi.bpp >> 3; if (this->hidden->mi.bpp & 7) vformat->BytesPerPixel++; /* We're done! */ return(0); }
int main(int argc, char **argv) { int c; unsigned long i,number = 1000000; unsigned int gremlin = 0; time_t start,now,last=0,eta=0; struct pgmodeinfo mi; char spinner[] = "/-\\|"; char stats[80]; int cx,cy; /* Cursor position */ /* Init and get video mode */ pgInit(argc,argv); mi = *pgGetVideoMode(); /* Process command line */ while ( (c = getopt(argc,argv,"g:n:")) != -1 ) switch (c) { case 'g': gremlin = atoi(optarg); break; case 'n': number = atol(optarg); break; default: /* Help */ puts("PicoGUI gremlin (pgui.sourceforge.net)\n\n" "usage pgserver [-g gremlin] [-n number]\n\n" " g gremlin : Specify a gremlin number to repeat previous results\n" " Defaults is derived from the current time\n" " n number : Specify the number of iteratons\n" " Default is a large number\n" "\n" " PicoGUI gremlin is similar to the PalmOS program of similar name.\n" " It feeds random events to the server, acting as a relentles but\n" " quite unintelligent beta tester."); exit(1); } /* Initialize to a (sometimes) predictable state */ if (!gremlin) gremlin = time(NULL) & 0xFFFFF ; srand(gremlin); printf("Summoning gremlin #%lu for %lu frobs...\n",gremlin,number); /* Start the clock */ start = time(NULL); /* The gremlin loop */ for (i=0;i<number;i++) { /* Get the time and calculate the ETA */ now = time(NULL) - start; if (i && now>last) { /* Only update ETA every second to prevent round errors * causing wild fluctuation */ eta = (number * now / i) - now; last = now; } /* Use unbuffered output or it looks bad */ write(1,stats,sprintf(stats,"\r %c --- #%-10lu ---" " Running %02d:%02d:%02d ---" " Remaining %02d:%02d:%02d ", spinner[(i>>6)&3],i+1,now/3600,(now%3600)/60, now%60,eta/3600,(eta%3600)/60,eta%60)); /* Move the mouse */ cx = rand() % mi.xres; cy = rand() % mi.yres; sendPointerInput(PG_TRIGGER_MOVE,cx,cy,0); pgUpdate(); /* Clickski! */ if ((rand()%100) < 80) { sendPointerInput(PG_TRIGGER_DOWN,cx,cy,1); pgUpdate(); /* Drag */ if ((rand()%100) < 5) { cx = rand() % mi.xres; cy = rand() % mi.yres; sendPointerInput(PG_TRIGGER_MOVE,cx,cy,1); pgUpdate(); } sendPointerInput(PG_TRIGGER_UP,cx,cy,0); pgUpdate(); } /* Some common keys */ if ((rand()%100) < 5) { sendKeyInput(PG_TRIGGER_KEYDOWN,PGKEY_y,0); pgUpdate(); sendKeyInput(PG_TRIGGER_KEYUP,PGKEY_y,0); sendKeyInput(PG_TRIGGER_CHAR,'y',0); pgUpdate(); } if ((rand()%100) < 2) { sendKeyInput(PG_TRIGGER_KEYDOWN,PGKEY_n,0); pgUpdate(); sendKeyInput(PG_TRIGGER_KEYUP,PGKEY_n,0); sendKeyInput(PG_TRIGGER_CHAR,'n',0); pgUpdate(); } if ((rand()%100) < 30) { sendKeyInput(PG_TRIGGER_KEYDOWN,PGKEY_TAB,0); pgUpdate(); sendKeyInput(PG_TRIGGER_KEYUP,PGKEY_TAB,0); pgUpdate(); } if ((rand()%100) < 5) { sendKeyInput(PG_TRIGGER_KEYDOWN,PGKEY_SPACE,0); pgUpdate(); sendKeyInput(PG_TRIGGER_KEYUP,PGKEY_SPACE,0); pgUpdate(); } /* Wait */ if ((rand()%100) < 20) usleep(1000); } printf("\nDone. Remember to check for memory leaks with CTRL-ALT-M!\n"); return 0; }
int main(int argc, char **argv) { struct pgEvent *evt; pghandle wApply,wClose,sTmp,wToolbar; pghandle wXres,wYres,wBpp,wRotate,wPopup; struct pgmodeinfo mi; char buf[20]; pgInit(argc,argv); wPopup = pgDialogBox("Set Video Mode"); /******** Take care of such niceties... */ wToolbar = pgNewWidget(PG_WIDGET_TOOLBAR,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_BOTTOM, 0); wApply = pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_INSIDE,wToolbar); pgSetWidget(PGDEFAULT, PG_WP_TEXT,pgNewString("Apply"), 0); wClose = pgNewWidget(PG_WIDGET_BUTTON,0,0); pgSetWidget(PGDEFAULT, PG_WP_TEXT,pgNewString("Close"), 0); /******** Mode options */ /* For now just make boxes, we'll fill them in later */ wXres = pgNewWidget(PG_WIDGET_BOX,PG_DERIVE_AFTER,wToolbar); pgSetWidget(PGDEFAULT,PG_WP_TRANSPARENT,1,0); wYres = pgNewWidget(PG_WIDGET_BOX,0,0); pgSetWidget(PGDEFAULT,PG_WP_TRANSPARENT,1,0); wBpp = pgNewWidget(PG_WIDGET_BOX,0,0); pgSetWidget(PGDEFAULT,PG_WP_TRANSPARENT,1,0); wRotate = pgNewWidget(PG_WIDGET_CHECKBOX,0,0); pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString("Rotation"),0); /* Fill in the boxes */ wXres = pgNewWidget(PG_WIDGET_FIELD,PG_DERIVE_INSIDE,wXres); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_SIZE,50, PG_WP_SIZEMODE,PG_SZMODE_PERCENT, 0); pgNewWidget(PG_WIDGET_LABEL,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_TEXT,pgNewString("Width:"), 0); wYres = pgNewWidget(PG_WIDGET_FIELD,PG_DERIVE_INSIDE,wYres); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_SIZE,50, PG_WP_SIZEMODE,PG_SZMODE_PERCENT, 0); pgNewWidget(PG_WIDGET_LABEL,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_TEXT,pgNewString("Height:"), 0); wBpp = pgNewWidget(PG_WIDGET_FIELD,PG_DERIVE_INSIDE,wBpp); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_SIZE,50, PG_WP_SIZEMODE,PG_SZMODE_PERCENT, 0); pgNewWidget(PG_WIDGET_LABEL,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_TEXT,pgNewString("BPP:"), 0); /******** Run a tiny event loop */ /* Big loop setting modes... */ for (;;) { /* Get actual mode info, put it in the widgets. * Not the best way, but for now pgReplaceTextFmt doesn't work on * field widgets because their handle handling is different :) * The field copies our string to an internal buffer so we don't need * to keep the handle around. Note that a server bug (listed in my * todo file) will cause a server segfault if pgReplaceText is used! */ mi = *pgGetVideoMode(); sprintf(buf,"%d",mi.xres); sTmp = pgNewString(buf); pgSetWidget(wXres,PG_WP_TEXT,sTmp,0); pgDelete(sTmp); sprintf(buf,"%d",mi.yres); sTmp = pgNewString(buf); pgSetWidget(wYres,PG_WP_TEXT,sTmp,0); pgDelete(sTmp); sprintf(buf,"%d",mi.bpp); sTmp = pgNewString(buf); pgSetWidget(wBpp,PG_WP_TEXT,sTmp,0); pgDelete(sTmp); pgSetWidget(wRotate,PG_WP_ON,mi.flags & PG_VID_ROTATE90,0); /* Small event loop waiting for an apply */ for (;;) { evt = pgGetEvent(); /* Done yet? */ if (evt->from == wClose) return 0; /* Any PG_WE_ACTIVATE causes apply, this covers clicking the apply * button or pressing enter in a field. Specifically exclude * clicking the rotate checkbox */ if (evt->type == PG_WE_ACTIVATE && evt->from != wRotate) break; } /* Set mode based on widget values */ pgSetVideoMode(atoi(pgGetString(pgGetWidget(wXres,PG_WP_TEXT))), atoi(pgGetString(pgGetWidget(wYres,PG_WP_TEXT))), atoi(pgGetString(pgGetWidget(wBpp,PG_WP_TEXT))), pgGetWidget(wRotate,PG_WP_ON) ? PG_FM_ON : PG_FM_OFF, PG_VID_ROTATE90); } return 0; }
int main(int argc, char **argv) { SDL_Surface *surf; SDL_Event evt; struct pgmodeinfo mi; int scale = 1; int ox=0,oy=0,btnstate=0; static union pg_client_trigger trig; pghandle cursor; /* Don't need an app, but a connection would be nice... */ pgInit(argc,argv); mi = *pgGetVideoMode(); /* Create a cursor for this input device */ cursor = pgNewCursor(); /* If the server is especially low resolution, magnify it */ if (mi.xres < 300 || mi.yres < 300) { if (mi.xres > mi.yres) scale = 300/mi.xres; else scale = 300/mi.yres; } if (scale<1) scale = 1; /* Start up SDL */ if (SDL_Init(SDL_INIT_VIDEO)) { printf("Error initializing SDL: %s\n",SDL_GetError()); return 1; } /* Set a video mode to match the server's _physical_ resolution */ surf = SDL_SetVideoMode(mi.xres*scale,mi.yres*scale,8,0); if (!surf) { printf("Error setting video mode: %s\n",SDL_GetError()); return 1; } SDL_EnableUNICODE(1); /* Time to wait! Most PicoGUI apps spend their time waiting in a * pgEventLoop, but we don't even have one... */ while (SDL_WaitEvent(&evt)) { switch (evt.type) { case SDL_MOUSEMOTION: evt.motion.x /= scale; evt.motion.y /= scale; /* Skip false moves (like dragging outside the window edge) * and ignore moves we can't keep up with */ if ((evt.motion.x==ox) && (evt.motion.y==oy)) break; if (SDL_PollEvent(NULL)) break; trig.content.type = PG_TRIGGER_MOVE; trig.content.u.mouse.x = ox = evt.motion.x; trig.content.u.mouse.y = oy = evt.motion.y; trig.content.u.mouse.btn = btnstate = evt.motion.state; trig.content.u.mouse.cursor_handle = cursor; pgInFilterSend(&trig); break; case SDL_MOUSEBUTTONDOWN: evt.button.x /= scale; evt.button.y /= scale; trig.content.type = PG_TRIGGER_DOWN; trig.content.u.mouse.x = ox = evt.button.x; trig.content.u.mouse.y = oy = evt.button.y; trig.content.u.mouse.btn = btnstate |= 1 << (evt.button.button-1); trig.content.u.mouse.cursor_handle = cursor; pgInFilterSend(&trig); break; case SDL_MOUSEBUTTONUP: evt.button.x /= scale; evt.button.y /= scale; trig.content.type = PG_TRIGGER_UP; trig.content.u.mouse.x = ox = evt.button.x; trig.content.u.mouse.y = oy = evt.button.y; trig.content.u.mouse.btn = btnstate &= ~(1 << (evt.button.button-1)); trig.content.u.mouse.cursor_handle = cursor; pgInFilterSend(&trig); break; case SDL_KEYDOWN: if (evt.key.keysym.unicode) { trig.content.type = PG_TRIGGER_CHAR; trig.content.u.kbd.key = evt.key.keysym.unicode; trig.content.u.kbd.mods = evt.key.keysym.mod; pgInFilterSend(&trig); } trig.content.type = PG_TRIGGER_KEYDOWN; trig.content.u.kbd.key = evt.key.keysym.sym; trig.content.u.kbd.mods = evt.key.keysym.mod; pgInFilterSend(&trig); break; case SDL_KEYUP: trig.content.type = PG_TRIGGER_KEYUP; trig.content.u.kbd.key = evt.key.keysym.sym; trig.content.u.kbd.mods = evt.key.keysym.mod; pgInFilterSend(&trig); break; case SDL_QUIT: SDL_Quit(); return 0; break; } pgFlushRequests(); } SDL_Quit(); return 0; }
int main(int argc, char** argv) { pgcolor color; struct pgmodeinfo mi; int i; pghandle ttl_box; /* init PicoGUI client */ pgInit(argc,argv); pgRegisterApp(PG_APP_NORMAL, argv[0], 0); /* create the title */ ttl_box = pgNewWidget(PG_WIDGET_BOX,0,0); ttl_text = pgNewWidget(PG_WIDGET_LABEL, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_TEXT, pgNewString("wclock"), 0); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_RIGHT, PG_WP_TEXT, pgNewString("?"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_set); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_LEFT, PG_WP_TEXT, pgNewString(">"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_right); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_LEFT, PG_WP_TEXT, pgNewString("<"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_left); /* create the main context */ main_window = pgNewWidget(PG_WIDGET_CANVAS, PG_DERIVE_AFTER, ttl_box); pgBind(PGDEFAULT, PGBIND_ANY, &canvas_handler, NULL); /* init time zones */ init_zones(); /* activate mouse move, keyboard and focus events */ pgSetWidget(main_window, PG_WP_TRIGGERMASK, pgGetWidget(main_window, PG_WP_TRIGGERMASK) | PG_TRIGGER_MOVE | PG_TRIGGER_CHAR | PG_TRIGGER_KEYDOWN | PG_TRIGGER_KEYUP /* | PG_TRIGGER_ACTIVATE | PG_TRIGGER_DEACTIVATE */, 0); mi = *pgGetVideoMode(); width = mi.lxres; height = mi.lyres; /* Make a backbuffer bitmap */ world_bitmap = create_world_bitmap(); width = get_world_width(); height = get_world_height(); /* Set the clipping rectangle */ pgWriteCmd(main_window, PGCANVAS_GROP, 5, PG_GROP_SETCLIP, 0, 0, width, height + TIMEBAR_HEIGHT); /* Set to be always rendered */ pgWriteCmd(main_window, PGCANVAS_GROPFLAGS, 1, PG_GROPF_UNIVERSAL); /* Create contexts for the canvas itself and the back-buffer */ gfx_context = pgNewCanvasContext(main_window, PGFX_IMMEDIATE ); /* run all */ DPRINTF(">>> entering loop\n"); pgEventLoop(); return 0; }