/* $Id: omnibar.c,v 1.2 2001/12/01 01:12:01 gork Exp $ * * omnibar.c - hopefully this will grow into a general interface * for starting and manipulating applications, but * for now it's pretty simple. * * PicoGUI small and efficient client/server GUI * Copyright (C) 2000 Micah Dowty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contributors: * * * */ #include /* For making directory listings */ #include #include #include /* For clock */ /* FIXME: Check for Mac OS X using autoconf */ #if (defined(__APPLE__) && defined(__MACH__)) // Mac OS X and Darwin #include #include #else #include #endif #include /* file IO for getting CPU load */ #include #include #ifdef CLOCK pghandle wClock; #endif pghandle wLoad; /********* Event handlers */ /* Applications menu * This whole thing's a kludge, I will write * something better (using custom menus) soon */ int btnAppMenu(struct pgEvent *evt) { pghandle *items; struct dirent *dent; int i,l; DIR *d; d = opendir("/pgui/apps"); /* FIXME : Count the items and allocate the array */ items = alloca(sizeof(pghandle) * 40); /* Enter a new context before making the handles */ pgEnterContext(); /* Make handles */ rewinddir(d); i = 0; while (dent = readdir(d)) { /* Skip all but applications */ l = strlen(dent->d_name); if (l<4) continue; if (dent->d_name[0] == '.') continue; /* Add item */ items[i++] = pgNewString(dent->d_name); } /* Run it */ i = pgMenuFromArray(items,i); /* Result? */ if (i) { char buf[80]; /* FIXME: Buffer overflow 'sploit waiting to happen! */ strcpy(buf,"/pgui/apps/"); strcat(buf,pgGetString(items[i-1])); if (!vfork()) { execlp(buf,buf,NULL); pgMessageDialogFmt("Error",0,"There was an error starting the\nfollowing program:\n%s",buf); exit(1); } } /* Free the server memory and destroy our menu */ pgLeaveContext(); closedir(d); return 0; } /* sdh: power off for psionw with appropriate kernel patch */ void psion_power_off() { FILE *fs = fopen("/proc/psionw/state", "w"); if (!fs) { fprintf(stderr, "Can't open /proc/psionw/state: %s\n", strerror()); return; } fprintf(fs, "0\n"); fclose(fs); return; } /* System menu */ int btnSysMenu(struct pgEvent *evt) { switch (pgMenuFromString("Power Off|About PicoGUI...|" "About Revol...|Quit PicoGUI...")) { case 1: psion_power_off(); break; case 2: /* Quick little about box */ pgMessageDialog("About PicoGUI", "Welcome to PicoGUI!\n" "This is a preview release (or a development\n" "version if you're a developer :)\n" "What you see may or may not represent the\n" "future of PicoGUI, it is just a test.\n" "For more information and the latest code, visit:\n" " http://pgui.sourceforge.net\n" "\n" "-- Micah",0); break; case 3: pgMessageDialog("About Revol", "Revol: Linux on the Psion Revo\n" "\n" "By Simon Howard\n" "\n" "http://fraggle.alkali.org/stuffage/revol/\n" "Feedback: sdh300@ecs.soton.ac.uk\n", 0); break; case 4: /* Beam us out! */ if (pgMessageDialog("Quit PicoGUI", "Quit PicoGUI?", PG_MSGBTN_YES | PG_MSGBTN_NO)==PG_MSGBTN_YES) exit(0); } } /* Called to update the clock and system load indicators */ void sysIdle(void) { time_t now; char *ct; char buf[50]; FILE *f; unsigned long cpu_user,cpu_nice,cpu_sys,cpu_idle; unsigned long crun,ctotal; static unsigned long ocrun = 0,octotal = 1; #ifdef CLOCK /* Get time */ time(&now); ct = ctime(&now); ct[strlen(ct)-1] = 0; /* Strip newline */ pgReplaceText(wClock,ct); pgSubUpdate(wClock); #endif /* Get CPU load */ f = fopen("/proc/stat","r"); fgets(buf,50,f); fclose(f); sscanf(buf,"cpu %lu %lu %lu %lu",&cpu_user,&cpu_nice,&cpu_sys,&cpu_idle); crun = cpu_user + cpu_sys; ctotal = crun + cpu_nice + cpu_idle; if (crun==ocrun || ctotal==octotal) return; /* Prevent SIGFPE */ pgSetWidget(wLoad,PG_WP_VALUE, (crun-ocrun) * 100 / (ctotal-octotal),0); ocrun = crun; octotal = ctotal; pgSubUpdate(wLoad); } /********* Main program */ int main(int argc, char **argv) { pghandle wLoadbox,fntLabel,fntLabelBold; pgInit(argc,argv); pgRegisterApp(PG_APP_TOOLBAR,"OmniBar",0); /* A font for our labels */ fntLabel = pgNewFont("Helvetica",8,0); fntLabelBold = pgNewFont("Helvetica",8,PG_FSTYLE_BOLD); /* Top-level widgets */ pgNewWidget(PG_WIDGET_BUTTON,0,0); pgSetWidget(PGDEFAULT, PG_WP_TEXT,pgNewString("Applications"), PG_WP_EXTDEVENTS,PG_EXEV_PNTR_DOWN, 0); pgBind(PGDEFAULT,PG_WE_PNTR_DOWN,&btnAppMenu,NULL); pgNewWidget(PG_WIDGET_BUTTON,0,0); pgSetWidget(PGDEFAULT, PG_WP_TEXT,pgNewString("System"), PG_WP_EXTDEVENTS,PG_EXEV_PNTR_DOWN, 0); pgBind(PGDEFAULT,PG_WE_PNTR_DOWN,&btnSysMenu,NULL); #ifdef CLOCK wClock = pgNewWidget(PG_WIDGET_LABEL,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_FONT,fntLabel, PG_WP_TRANSPARENT,0, 0); #endif wLoadbox = pgNewWidget(PG_WIDGET_BOX,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_RIGHT, PG_WP_SIZE,200, 0); /* Inside the load box */ pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_INSIDE,wLoadbox); pgSetWidget(PGDEFAULT, PG_WP_TEXT,pgNewString("CPU"), PG_WP_SIDE,PG_S_RIGHT, PG_WP_FONT,fntLabel, 0); wLoad = pgNewWidget(PG_WIDGET_INDICATOR,0,0); pgSetWidget(PGDEFAULT, PG_WP_SIDE,PG_S_ALL, 0); /* Run it. */ pgSetIdle(1000,&sysIdle); pgEventLoop(); return 0; } /* The End */