Hi Micah,

I'm tracing a bug in my program.
I got very often the 2 following errors (not at the same time):

*** PicoGUI ERROR (HANDLE) : Bad handle for widget text property

This one appear when I close a popup -> I think that could occure when refresh
of the background


*** PicoGUI ERROR (INTERNAL) : Invalid widget in widget_set

This one occure when I come back from a vforked app to my finder.
And I think as before when refresh of the bkg.

The most strange is that the errors doesn't occure when using XCopilot or the pc
but only on the ChipSlice module... ??

Do you have any clue?
Could you tell me more about the signification of this errors?
Thanks in advance

Philippe



---------8<-----------------------------------------------------------
/* $Id: sd_toolbar.c,v 1.7 2001/04/08 18:42:53 philippe Exp $
 * 
 * sd_toolbar.c - Toolbar main app for SMARTDATA demo V0.4.
 *                Derived from omnibar.c
 *
 * Author: Philippe Ney <[EMAIL PROTECTED]>
 * Copyright (C) 2001 SMARTDATA <www.smartdata.ch>
 *
 * omnibar.c - hopefully this will grow into a general interface
 *             for starting and manipulating applications, but
 *             for now it's pretty simple.
 *             Copyright (C) 2000, 2001 Micah Dowty
 *             <[EMAIL PROTECTED]>
 *
 * PicoGUI small and efficient client/server GUI
 * Copyright (C) 2000 Micah Dowty <[EMAIL PROTECTED]>
 *
 * 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.
 * 
 * 
 */

#include <sys/types.h>   /* For making directory listings */

#include <signal.h>      /* for SIGKILL */

#include <unistd.h>      /* for vfork */
#include <linux/wait.h>  /* for WNOHANG */

#include <time.h>        /* For clock */

#include <malloc.h>      /* Dynamic memory is used for the array */


#include <picogui.h>


#define DEBUG
#ifdef DEBUG
# define DPRINTF printf
#else
# define DPRINTF __dummy__
static inline __dummy__(const char* fmt, ...) {}
#endif

#ifdef UCLINUX
static const char* PATH="/opt/desktop/";
#else
static const char*
PATH="/home/philippe/SourceForge_dev/pc/cli_c/demos/data_finder/";
#endif

pghandle wClock;
pid_t    pid;
char     path[100];
pghandle wGridbox,wRow,wButton;
int      iIsFinderDisplayed;
int      theme=0;


/*
 * define the grid of the button for the Finder
 * a 'NULL' define a new line and a double 'NULL' for the end of the grid
 * (this is due to the algo for grid construction)
 */
static char *buttongrid[] = {
  NULL,"ToDo","Web","Games",
  NULL,"Calculator","Mail","Expenses",
  NULL,"Adresses","Calendar","Notes",
  NULL,NULL
};



/* initialisation of variables */
int Init(void) {
  iIsFinderDisplayed = 0;
  return 0;
}


int btnHandler(struct pgEvent *evt) {
  char appPath[100];
  char *c = (char *)pgGetPayload(evt->from);
  int  status;

  sprintf(appPath,"%s%s/%s.app",PATH,c,c);

  pgLeaveContext();
  iIsFinderDisplayed = 0;


  pid = vfork();
  printf("vfork -> child pid: %i\n",pid);
  switch(pid) {
  case -1:                       /* error */
    printf("vfork failed\n");
    exit(1);
    break;
  case 0:                        /* child */
DPRINTF("%s -- 1\n",__FUNCTION__);
    execlp(appPath,appPath,NULL);
    pgMessageDialogFmt("Error",0,"There was an error starting the\nfollowing
program:\n%s",appPath);
    exit(1);
  }
DPRINTF("%s -- 2\n",__FUNCTION__);
  /*
   * here we are in the parent so we have to reload the theme because the child
   * will load the default theme
   */
  strcpy(appPath,PATH);
  switch(theme) {
  case 0:
    strcat(appPath,"_Preferences/skins/sd_simple.th");
    break;
  case 1:
    strcat(appPath,"_Preferences/skins/sd_mono.th");
    break;
  case 2:
    strcat(appPath,"_Preferences/skins/sd_3D.th");
    break;
  default:
    strcat(appPath,"_Preferences/skins/sd_simple.th");
    break;
  }
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgLoadTheme(pgFromFile(appPath));
DPRINTF("%s -- 4\n",__FUNCTION__);
  return 0;
}




/*----------------------------------------------------------------------------*/
/* Popup window for contrast changes and theme chooser                        */
/*----------------------------------------------------------------------------*/

/* Exit popup button */
int btnExitPopup(struct pgEvent *evt) {
  char themePath[100];

DPRINTF("%s -- 1\n",__FUNCTION__);
  pgLeaveContext();
DPRINTF("%s -- 2\n",__FUNCTION__);
  strcpy(themePath,PATH);
  switch(theme) {
  case 0:
    strcat(themePath,"_Preferences/skins/sd_simple.th");
    break;
  case 1:
    strcat(themePath,"_Preferences/skins/sd_mono.th");
    break;
  case 2:
    strcat(themePath,"_Preferences/skins/sd_3D.th");
    break;
  default:
    strcat(themePath,"_Preferences/skins/sd_simple.th");
    break;
  }
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgLoadTheme(pgFromFile(themePath));
DPRINTF("%s -- 4\n",__FUNCTION__);
  return 0;
}

int btnMoreContrast(struct pgEvent *evt) {
  int i;
  pghandle *label = (pghandle *) evt->extra;
   
DPRINTF("%s -- 1\n",__FUNCTION__);
  i = atoi(pgGetString(pgGetWidget(*label,PG_WP_TEXT)));
DPRINTF("%s -- 2\n",__FUNCTION__);
  if(i<10) i++;
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgReplaceTextFmt(*label,"%i",i);
  printf("More Contrast: %i\n",i);
  return 0;
}
int btnLessContrast(struct pgEvent *evt) {
  int i;
  pghandle *label = (pghandle *) evt->extra;
   
DPRINTF("%s -- 1\n",__FUNCTION__);
  i = atoi(pgGetString(pgGetWidget(*label,PG_WP_TEXT)));
DPRINTF("%s -- 2\n",__FUNCTION__);
  if(i>0) i--;
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgReplaceTextFmt(*label,"%i",i);
  printf("Less Contrast\n");
  return 0;
}

int btnLoadSimpleSkin(struct pgEvent *evt) {
  char themePath[100];

DPRINTF("%s -- 1\n",__FUNCTION__);
  strcpy(themePath,PATH);
DPRINTF("%s -- 2\n",__FUNCTION__);
  strcat(themePath,"_Preferences/skins/sd_simple.th");
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgLoadTheme(pgFromFile(themePath));
DPRINTF("%s -- 4\n",__FUNCTION__);
  theme=0;
  return 0;
}
int btnLoadMonoSkin(struct pgEvent *evt) {
  char themePath[100];

DPRINTF("%s -- 1\n",__FUNCTION__);
  strcpy(themePath,PATH);
DPRINTF("%s -- 2\n",__FUNCTION__);
  strcat(themePath,"_Preferences/skins/sd_mono.th");
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgLoadTheme(pgFromFile(themePath));
DPRINTF("%s -- 4\n",__FUNCTION__);
  theme=1;
  return 0;
}
int btnLoad3DSkin(struct pgEvent *evt) {
  char themePath[100];

DPRINTF("%s -- 1\n",__FUNCTION__);
  strcpy(themePath,PATH);
DPRINTF("%s -- 2\n",__FUNCTION__);
  strcat(themePath,"_Preferences/skins/sd_3D.th");
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgLoadTheme(pgFromFile(themePath));
DPRINTF("%s -- 4\n",__FUNCTION__);
  theme=2;
  return 0;
}

/* Prefs popup */
int btnPrefs(struct pgEvent *evt) {
  pghandle wPopup;
  pghandle wPopupTb;
  pghandle wContrastTextBox;
  pghandle wContrastLevel;
  pghandle wSkinTitleBox;
  pghandle wSkinTypesBox;
  char path[150];

DPRINTF("%s -- 1\n",__FUNCTION__);
  /* Create a Context for the popup */
  pgEnterContext();

DPRINTF("%s -- 2\n",__FUNCTION__);
  wPopup = pgNewPopup(150,170);

DPRINTF("%s -- 3\n",__FUNCTION__);
  wPopupTb = pgNewWidget(PG_WIDGET_TOOLBAR,0,0);
  pgSetWidget(PGDEFAULT,PG_WP_SIDE,PG_S_BOTTOM,0);
  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_INSIDE,wPopupTb);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("Exit"),
              PG_WP_SIDE,PG_S_LEFT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnExitPopup,NULL); /* handler */
  
DPRINTF("%s -- 4\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,wPopupTb);
  pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString(""),PG_WP_SIDE,PG_S_TOP,0);

DPRINTF("%s -- 5\n",__FUNCTION__);
  /* A box that contain title and level of contrast as label widgets */
  wContrastTextBox = pgNewWidget(PG_WIDGET_BOX,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,PG_WP_SIDE,PG_S_TOP,0);

DPRINTF("%s -- 6\n",__FUNCTION__);
  /* The title and level in label widgets */
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_INSIDE,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("Contrast: "),
              PG_WP_SIDE,PG_S_LEFT,
              0);
DPRINTF("%s -- 7\n",__FUNCTION__);
  wContrastLevel = pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("5"),
              PG_WP_SIDE,PG_S_LEFT,
              0);
DPRINTF("%s -- 8\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString(" "),
              PG_WP_SIDE,PG_S_LEFT,
              0);

DPRINTF("%s -- 9\n",__FUNCTION__);
  /* Buttons to change contrast level */
  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("+"),
              PG_WP_SIDE,PG_S_RIGHT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnMoreContrast,&wContrastLevel);

DPRINTF("%s -- 10\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("-"),
              PG_WP_SIDE,PG_S_RIGHT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnLessContrast,&wContrastLevel);


DPRINTF("%s -- 11\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,wContrastTextBox);
  pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString("_________________________"),0);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString(""),PG_WP_SIDE,PG_S_TOP,0);

DPRINTF("%s -- 12\n",__FUNCTION__);
  wSkinTitleBox = pgNewWidget(PG_WIDGET_BOX,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,PG_WP_SIDE,PG_S_TOP,0);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_INSIDE,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("Skins:"),
              PG_WP_SIDE,PG_S_LEFT,
              0);

DPRINTF("%s -- 13\n",__FUNCTION__);
  wSkinTypesBox = pgNewWidget(PG_WIDGET_BOX,PG_DERIVE_AFTER,wSkinTitleBox);
  pgSetWidget(PGDEFAULT,PG_WP_SIDE,PG_S_TOP,0);

  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_INSIDE,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("Simple"),
              PG_WP_SIDE,PG_S_LEFT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnLoadSimpleSkin,NULL);

DPRINTF("%s -- 14\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("Mono"),
              PG_WP_SIDE,PG_S_LEFT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnLoadMonoSkin,NULL);

DPRINTF("%s -- 15\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_BUTTON,PG_DERIVE_AFTER,0);
  pgSetWidget(PGDEFAULT,
              PG_WP_TEXT,pgNewString("3D"),
              PG_WP_SIDE,PG_S_LEFT,
              0);
  pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnLoad3DSkin,NULL);

DPRINTF("%s -- 16\n",__FUNCTION__);
  pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_AFTER,wSkinTypesBox);
  pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString("_________________________"),0);
  
DPRINTF("%s -- 17\n",__FUNCTION__);
  pgEventLoop();
  return 0;
}

/* Finder */
int btnFinder(struct pgEvent *evt) {
  char* s;
  int   i,status;
  char  imgPath[100],maskPath[100];

  if(iIsFinderDisplayed) return 0;

DPRINTF("%s -- 1\n",__FUNCTION__);
  if(pid) {
    kill(pid,SIGKILL);
//    printf("%s %s: KILL (SIGKILL) pid: %i\n",__FILE__,__FUNCTION__,pid);
    wait(&status);     /* to get the zombie process of the child */
  }


DPRINTF("%s -- 2\n",__FUNCTION__);
  /* Make panel */
  pgEnterContext();
DPRINTF("%s -- 3\n",__FUNCTION__);
  pgRegisterApp(PG_APP_NORMAL,"Finder Panel",0);

  /* Init widgets */
  wGridbox=0;wRow=0;wButton=0;

  /* Box widget that occupies ... */
DPRINTF("%s -- 4\n",__FUNCTION__);
  wGridbox = pgNewWidget(PG_WIDGET_BOX,0,0);
  pgSetWidget(PGDEFAULT,PG_WP_SIDE,PG_S_ALL,0); /* ... all the free space */

  /* The Finder panel */ 
  for (i=0;;i++) {
    s = buttongrid[i];
    if (s) {   /* Add a button to the row */
//      sprintf(imgPath,"%s%s/%s.pnm",PATH,s,s);
//      sprintf(maskPath,"%s%s/%s_mask.pnm",PATH,s,s);

DPRINTF("%s -- 5\n",__FUNCTION__);
      wButton = pgNewWidget(PG_WIDGET_FLATBUTTON,
                            wButton ? PG_DERIVE_AFTER : PG_DERIVE_INSIDE,
                            wButton ? wButton : wRow);
DPRINTF("Set widget: %s\n",s);
      pgSetWidget(PGDEFAULT,
                  PG_WP_TEXT,pgNewString(s),
//                  PG_WP_BITMAP,pgNewBitmap(pgFromFile(imgPath)),
//                  PG_WP_BITMASK,pgNewBitmap(pgFromFile(maskPath)),
                  PG_WP_SIZEMODE,PG_SZMODE_CNTFRACT,
                  PG_WP_SIZE,pgFraction(1,3),
                  0);
DPRINTF("%s setted\n",s);
      pgSetPayload(PGDEFAULT,(unsigned long) s);
      pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnHandler,NULL); /* handler */
    }
    else {     /* Add a row */
      if (!buttongrid[i+1])  /* Two consecutive NULLs, exit */
        break;
DPRINTF("%s -- 6\n",__FUNCTION__);
      wRow = pgNewWidget(PG_WIDGET_BOX,
                         wRow ? PG_DERIVE_AFTER : PG_DERIVE_INSIDE,
                         wRow ? wRow : wGridbox);
      pgSetWidget(PGDEFAULT,
                  PG_WP_TRANSPARENT,1,
                  PG_WP_SIDE,PG_S_BOTTOM,
                  PG_WP_SIZEMODE,PG_SZMODE_CNTFRACT,
                  PG_WP_SIZE,pgFraction(1,3),
                  0);
      wButton = 0;
    }
  }
  iIsFinderDisplayed = 1;
  return 0;
}


/* Called to update the clock */
void sysIdle(void) {
  time_t now;
  struct tm *tt;
  char ct[30];

  time(&now);            /* Get time */
  tt = localtime(&now);
  sprintf(ct,"%02i:%02i:%02i",tt->tm_hour,tt->tm_min,tt->tm_sec);
  pgReplaceText(wClock,ct);
  pgUpdate();
}


/* Main program */
int main(int argc, char **argv) {
  pghandle fntLabel,fntLabelBold;
  char buf[20];
  int  i;
  int  help=0;
  int  toolbarside=0;
  char themePath[100];

  /* Parse args */
  for(i=1; i<argc; ++i) {

    if( argv[i][0]=='-' ) {
      const char* arg = &argv[i][1];

      if(!strcmp(arg, "-help") || !strcmp(arg, "?") || !strcmp(arg, "h"))
        help = 1;

      else if(!strcmp(arg, "r"))
        toolbarside = 1;

      else if(!strcmp(arg, "l"))
        toolbarside = 2;

      else if(!strcmp(arg, "s"))
        theme = 0;

      else if(!strcmp(arg, "m"))
        theme = 1;

      else if(!strcmp(arg, "d"))
        theme = 2;

      else {
        puts("%s: bad option");
        printf("Try `%s --help' for more information.\n", argv[0]);
        exit(1);
      }
    }
  }

  /* Help */
  if(help) {
    printf("Usage: %s [OPTION]...\n", argv[0]);
    puts("ChipSlice demo V0.4");
    puts("");
    puts("options:");
    puts("  -?, -h, --help  display this help");
    puts("  -r              create an empty toolbar at the right side");
    puts("  -l              create an empty toolbar at the left side");
    puts("  -s              launch app with theme sd_simple (default)");
    puts("  -m              launch app with theme sd_mono");
    puts("  -d              launch app with theme sd_3D");
    exit(0);
  }


  /*
   * if toolbarside is 0, we are in the parent, then vfork to create child
   * process that will launch the sided toolbars
   */
  if(toolbarside == 0) {
    pid_t  LeftTBpid,RightTBpid;
    long   ltimer;

    LeftTBpid = vfork();
    printf("vfork -> child pid: %i\n",LeftTBpid);
    switch(LeftTBpid) {
    case -1:     /* error */
      printf("vfork failed\n");
      exit(1);
      break;
    case 0:      /* child */
      execlp(argv[0],argv[0],"-l",NULL);
      pgMessageDialogFmt("Error",0,"There was an error starting the\nfollowing
program:\n%s",argv[0]);
      exit(1);
      break;
    }
    RightTBpid = vfork();
    printf("vfork -> child pid: %i\n",RightTBpid);
    switch(RightTBpid) {
    case -1:     /* error */
      printf("vfork failed\n");
      exit(1);
      break;
    case 0:      /* child */
      execlp(argv[0],argv[0],"-r",NULL);
      pgMessageDialogFmt("Error",0,"There was an error starting the\nfollowing
program:\n%s",argv[0]);
      exit(1);
      break;
    default:     /* parent */
      /*
       * delay to let the child construct the right toolbar otherwise, the
       * bottom right corner is taken by the main toolbar.
       */
      for(ltimer=0;ltimer<100;ltimer++) {
DPRINTF(".");
      }
      break;    
    }
  }

  /*
   * start of initialisations and graphical definitions
   */
  Init();
  pgInit(argc,argv);

  switch(toolbarside) {

  case 2:
    pgRegisterApp(PG_APP_TOOLBAR,"ToolBar",PG_APPSPEC_SIDE,PG_S_LEFT,0);
    pgEventLoop();
    return 0;
    break;

  case 1:
    pgRegisterApp(PG_APP_TOOLBAR,"ToolBar",PG_APPSPEC_SIDE,PG_S_RIGHT,0);
    pgEventLoop();
    return 0;
    break;

  case 0:
    strcpy(themePath,PATH);
    switch(theme) {
    case 0:
      strcat(themePath,"_Preferences/skins/sd_simple.th");
      break;
    case 1:
      strcat(themePath,"_Preferences/skins/sd_mono.th");
      break;
    case 2:
      strcat(themePath,"_Preferences/skins/sd_3D.th");
      break;
    default:
      strcat(themePath,"_Preferences/skins/sd_simple.th");
      break;
    }
    pgLoadTheme(pgFromFile(themePath));
    strcpy(themePath,PATH);
    strcat(themePath,"_Preferences/skins/sd_finder.th");
    pgLoadTheme(pgFromFile(themePath));

DPRINTF("%s -- 1\n",__FUNCTION__);
    pgRegisterApp(PG_APP_TOOLBAR,"ToolBar",
                  PG_APPSPEC_SIDE,PG_S_BOTTOM,
                  0);

DPRINTF("%s -- 2\n",__FUNCTION__);
    pgNewWidget(PG_WIDGET_BUTTON,0,0);
    pgSetWidget(PGDEFAULT,
                PG_WP_TEXT,pgNewString("Prefs"),
                0);
    pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnPrefs,NULL);

DPRINTF("%s -- 3\n",__FUNCTION__);
    pgNewWidget(PG_WIDGET_BUTTON,0,0);
    pgSetWidget(PGDEFAULT,
                PG_WP_TEXT,pgNewString("Finder"),
                0);
    pgBind(PGDEFAULT,PG_WE_ACTIVATE,&btnFinder,NULL);

DPRINTF("%s -- 4\n",__FUNCTION__);
    wClock = pgNewWidget(PG_WIDGET_LABEL,0,0);
    pgSetWidget(PGDEFAULT,
                PG_WP_SIDE,PG_S_RIGHT,
                PG_WP_TRANSPARENT,0,
                0);

    /* Call the Finder panel */
    btnFinder(NULL);

    /* Run it. */
    pgSetIdle(1000,&sysIdle);    /* This should make the clock run, but ... */
    pgEventLoop();
    return 0;
    break;
  }
}
   
/* The End */
---------8<-----------------------------------------------------------

_______________________________________________
Pgui-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/pgui-devel

Reply via email to