Пример #1
0
void sysIdle(void) {
  FILE *f;
  char buf[50];
  int bat_raw, bat_percent;
  
  /* Get battery status */
  f = fopen("/proc/r39xxpm","r");
  if (f) {
    /* I don't think the format of /proc/r39xxpm is set in stone, so
     * this might break? Oh well, works for now. */
    fgets(buf,50,f);  /* CPU speed */
    fgets(buf,50,f);  /* Battery voltage */
    fclose(f);
    bat_raw = atoi(buf+9); /* Skip past "Battery: " */
    
    /* Translate to percent, assuming 259 (2.0 volts) is empty
     * and 402 (3.0 volts) is full. */
    bat_percent = ((bat_raw - 259) * 100) / 143;
    if (bat_percent < 0) bat_percent = 0;
    if (bat_percent > 100) bat_percent = 100;
    
    pgSetWidget(wBatt,PG_WP_VALUE,bat_percent,0);
    pgFlushRequests();
    pgSubUpdate(wBatt);  
  }
}
Пример #2
0
/* Put a request into the queue */
void _pg_add_request(s16 reqtype,void *data,u32 datasize) {
   
  struct pgrequest *newhdr;
  int padding;

  /* If this will overflow the buffer, flush it and send this packet
   * individually. This has two possible uses:
   *    - there are many packets in the buffer, so it flushes them 
   *    - this latest packet is very large and won't fit in the buffer
   *      anyway (a bitmap or long string for example)
   */
  if ((_pgreqbuffer_size + sizeof(struct pgrequest) + datasize) >
      PG_REQBUFSIZE) {

    struct pgrequest req;

    pgFlushRequests();

    /* Send this one */
    req.type = htons(reqtype);
    req.id = ++_pgrequestid;
    req.size = htonl(datasize);
    _pg_send(&req,sizeof(struct pgrequest));
    _pg_send(data,datasize);

#ifdef DEBUG
    printf("Forced buffer flush. New request: type = %d, size = %d\n",reqtype,datasize);
#endif

    _pg_getresponse(0);    
    return;
  } 

  padding = _pgreqbuffer_size & 3;  

  /* Pad the request buffer to a 32-bit boundary */
  if (padding) {
    padding = 4-padding;
    memset(_pgreqbuffer + _pgreqbuffer_size, 0, padding);
    _pgreqbuffer_size += padding;
  }
  
  /* Find a good place for the new header in the buffer and fill it in */
  newhdr = (struct pgrequest *) (_pgreqbuffer + _pgreqbuffer_size);
  _pgreqbuffer_count++;
  _pgreqbuffer_size += sizeof(struct pgrequest);
  _pgreqbuffer_lasttype = reqtype;
  newhdr->type = htons(reqtype);
  newhdr->id = ++_pgrequestid;
  newhdr->size = htonl(datasize);

#ifdef DEBUG
  printf("Added request: type = %d, size = %d\n",reqtype,datasize);
#endif

  /* Now the data */
  memcpy(_pgreqbuffer + _pgreqbuffer_size,data,datasize);
  _pgreqbuffer_size += datasize;  
}
Пример #3
0
struct pgEvent *pgGetEvent(void) {

  /* Run the idle handler here too, so it still gets a chance
   * even if we're flooded with events. */
  _pg_idle();

  /* Update before waiting for the user */
  pgUpdate();

  /* Wait for a new event */
  do {
     _pg_add_request(PGREQ_WAIT,NULL,0);
     pgFlushRequests();
  } while (_pg_return.type != PG_RESPONSE_EVENT);

  return &_pg_return.e.event;
}
Пример #4
0
/* There are many ways to create a menu in PicoGUI
 * (at the lowest level, using pgNewPopupAt and the menuitem widget)
 *
 * This creates a static popup menu from a "|"-separated list of
 * menu items, and returns the number (starting with 1) of the chosen
 * item, or 0 for cancel.
 */
int pgMenuFromString(char *items) {
  char *p;
  pghandle str;
  int ret;
  int i;

  if (!items || !*items) return 0;

  /* Create the menu popup in its own context */
  pgEnterContext();
  pgNewPopupAt(PG_POPUP_ATEVENT,PG_POPUP_ATEVENT,0,0);
  
  i=0;
  do {
    /* Do a little fancy stuff to make the string handle.
     * This is like pgNewString but we get to specify the 
     * length instead of having strlen() do it for us.
     */
    if (!(p = strchr(items,'|'))) p = items + strlen(items);
    _pg_add_request(PGREQ_MKSTRING,(void *) items,p-items);
    items = p+1;
    pgFlushRequests();
    str = _pg_return.e.retdata;

    /* Create each menu item */
    pgNewWidget(PG_WIDGET_MENUITEM,0,0);
    pgSetWidget(PGDEFAULT,
		PG_WP_TEXT,str,
		0);
    pgSetPayload(PGDEFAULT,++i);

  } while (*p);

  /* Run the menu */
  ret = pgGetPayload(pgGetEvent()->from);
  pgLeaveContext();
  return ret;
}
Пример #5
0
/*
 * Send a command to the virtual keyboard.
 * A virtual keyboard process is started if none is running.
 *
 * force       : 0 --> the command is ignored if a physical keyboard is present
 *               1 --> the command is always sent to the virtual keyboard
 */
void send_command (struct keyboard_command * cmd, int force)
{
  if ( cmd && (!physical_keyboard_available () || force) )
    {
      pghandle kb;

      DPRINTF ("sending command: %d\n", cmd->type);
      cmd->type = htons (cmd->type);

      while ( !(kb = pgFindWidget (PG_KEYBOARD_APPNAME)) )
	{
	  DPRINTF ("'pgboard' not running, please start it ...\n");

	  sleep (2);
	}

      /* Send the user command */
      pgAppMessage (kb, pgFromMemory (cmd, sizeof (struct keyboard_command)));

      /* Flush PG_APPMSG requests */
      pgFlushRequests ();
    }
}
Пример #6
0
/* Wait for a new event, recieves the type code. This is used 
 * when an idle handler or other interruption is needed */
int _pg_recvtimeout(s16 *rsptype) {
  struct timeval tv;
  fd_set readfds;
  fd_set writefds;
  fd_set exceptfds;
  int result;
  struct pgrequest waitreq;
  struct pgrequest unwaitreq;
  char cruft[sizeof(struct pgresponse_ret) - sizeof(s16)];	/* Unused return packet */
   
  /* Set up a packet to send to put us back on the waiting list */
  waitreq.type = htons(PGREQ_WAIT);
  waitreq.size = 0;
   
  /* Set up a packet to send to take us off the waiting list */
  unwaitreq.type = htons(PGREQ_PING);
  unwaitreq.size = 0;
   
  while (1) {
     FD_ZERO(&readfds);
     FD_ZERO(&writefds);
     FD_ZERO(&exceptfds);
     FD_SET(_pgsockfd,&readfds);
     tv = _pgidle_period;
   
     /* don't care about writefds and exceptfds: */

     result = (*_pgselect_handler)(_pgsockfd+1,&readfds,&writefds,&exceptfds,
				   (tv.tv_sec + tv.tv_usec) ? &tv : NULL);
     if (result < 0)
       continue;

     /* Well, now we have something! */

     if (FD_ISSET(_pgsockfd, &readfds))   /* Got data from server */
	return _pg_recv(rsptype,sizeof(s16));
	
     /* If we get this far, it's not a return packet- it's either a pgIdle timeout or a
      * user-defined file descriptor added with pgCustomizeSelect. This code below needs
      * to safely suspend the event loop, call the appropriate handlers, then kickstart it
      * with a new 'wait' packet. This is only possible if we are currently waiting on a
      * response from the 'wait' packet. If it's something else, this will clobber the 
      * packet's return value and get the event loop out of sync. This is why
      * _pg_recvtimeout should only be used in event waits.
      */

     /* We'll need these */
     waitreq.id = ++_pgrequestid;
     unwaitreq.id = ++_pgrequestid;

     /* No event yet, but now we have a race condition. We need to tell the server
      * to take the client off the waiting list, but it's possible that before the command
      * reaches the server another event will already be on its way. Like any other request,
      * PGREQ_PING takes us off the waiting list. Wait for a return code: if it's an event,
      * Go ahead and return it. (There will still be a return packet on it's way, but
      * we skip that) If it's a return packet, ignore it and go on with the idle handler */
     _pg_send(&unwaitreq,sizeof(unwaitreq));
     if (_pg_recv(rsptype,sizeof(s16)))
       return 1;
     if ((*rsptype) == htons(PG_RESPONSE_EVENT))
       /* Important! We need to indicate to the caller that there's an extra
	* return packet on it's way after this event packet.
	*/
       return 2;
     _pg_recv(cruft,sizeof(cruft));
      
     /* At this point either it was a client-defined fd or a timeout.
	Either way we need to kickstart the event loop. */

     /* At this point, it's safe to make PicoGUI API calls. */
     if (_pgselect_bottomhalf)
       (*_pgselect_bottomhalf)(result,&readfds,&writefds,&exceptfds);
     _pg_idle();
     
     /* Clear the pipes... */
     pgFlushRequests();
     _pg_send(&waitreq,sizeof(waitreq));  /* Kickstart the event loop */
  }
}
Пример #7
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;
}
Пример #8
0
int evtMouse(struct pgEvent *evt) {
  struct key_entry *clickkey = NULL;
  static union pg_client_trigger trig;

  /* Ignore all but left mouse button */
  if (evt->e.pntr.chbtn != 1 && evt->type != PG_WE_PNTR_RELEASE)
    return 0;

  /* Figure out what (if anything) was clicked */
  clickkey = find_clicked_key (evt->e.pntr.x, evt->e.pntr.y);

  /* If we got this far, it was clicked */
  if (evt->type == PG_WE_PNTR_DOWN) {
    keydown = clickkey;

    if (clickkey) {
      if (clickkey->key) {
	trig.content.type = PG_TRIGGER_CHAR;
	trig.content.u.kbd.key = clickkey->key;
	trig.content.u.kbd.mods = clickkey->mods;
	pgInFilterSend(&trig);
      }
      if (clickkey->pgkey) {
	trig.content.type = PG_TRIGGER_KEYDOWN;
	trig.content.u.kbd.key = clickkey->pgkey;
	trig.content.u.kbd.mods = clickkey->mods;
	pgInFilterSend(&trig);
      }
      pgFlushRequests ();
    }
  }
  else {
    if (keydown!=clickkey) {
      xorKey(keydown);
      keydown = NULL;
      return 0;
    }
    else
      if (clickkey) {
	if (clickkey->pgkey) {
	  trig.content.type = PG_TRIGGER_KEYUP;
	  trig.content.u.kbd.key = clickkey->pgkey;
	  trig.content.u.kbd.mods = clickkey->mods;
	  pgInFilterSend(&trig);
	}
	pgFlushRequests ();
	if (clickkey->pattern) {
	  selectPattern (clickkey->pattern);
	  keydown = NULL;
	  return 0;
	}
      }
     
    keydown = NULL;
  }
   
  /* Flash the clicked key with an XOR'ed rectangle */
  xorKey(clickkey);

  return 0;
}