#include "cdk.h" #include static void segvTrap (int sig); static boolean validObjType(EObjectType type) { switch (type) { case vALPHALIST: case vBUTTONBOX: case vCALENDAR: case vDIALOG: case vENTRY: case vFSELECT: case vGRAPH: case vHISTOGRAM: case vITEMLIST: case vLABEL: case vMARQUEE: case vMATRIX: case vMENTRY: case vMENU: case vRADIO: case vSCALE: case vSCROLL: case vSELECTION: case vSLIDER: case vSWINDOW: case vTEMPLATE: case vVIEWER: return TRUE; default: return FALSE; } } void *_newCDKObject(unsigned size, CDKFUNCS *funcs) { void *result = malloc(size); memset(result, 0, sizeof(CDKOBJS)); ((CDKOBJS *)result)->fn = funcs; return result; } /* * This creates a new CDK screen. */ CDKSCREEN *initCDKScreen(WINDOW *window) { CDKSCREEN *screen = (CDKSCREEN *)malloc (sizeof(CDKSCREEN)); int x; /* Set signal trap handlers. */ signal (SIGSEGV, segvTrap); signal (SIGBUS, segvTrap); /* Set up basic curses settings. */ noecho(); cbreak(); /* Initialize the CDKSCREEN pointer. */ screen->objectCount = 0; screen->window = window; for (x=0; x < MAX_OBJECTS; x++) { screen->object[x] = 0; screen->cdktype[x] = vNULL; } /* OK, we are done. */ return (screen); } /* * This registers a CDK object with a screen. */ void registerCDKObject (CDKSCREEN *screen, EObjectType cdktype, void *object) { /* Set some basic vars. */ int objectNumber = screen->objectCount; CDKOBJS *obj = (CDKOBJS *)object; /* rubik fix. objects have to be registered only if it hasn't been * already registered */ int i,present; //rubik present = 0; for (i=0;iobjectCount;i++) { if (screen->object[i]==obj) present=1; } if (present == 0) { /* end rubik fix */ screen->object[objectNumber] = obj; if (validObjType(cdktype)) { //rubik: FIXME here should check if the object is already //registered... unless it is the first time an object is //being registrated on a screen. (obj)->screenIndex = objectNumber; (obj)->screen = screen; screen->cdktype[objectNumber] = cdktype; screen->objectCount++; } } } /* * This removes an object from the CDK screen. */ void unregisterCDKObject (EObjectType cdktype, void *object) { /* Declare some vars. */ CDKSCREEN *screen; int Index, x; if (validObjType(cdktype)) { CDKOBJS *obj = (CDKOBJS *)object; if ((obj)->screen != NULL) { //rubik: if already unregistered don't do anything screen = (obj)->screen; Index = (obj)->screenIndex; (obj)->screen=NULL; //rubik /* * If this is the last object -1 then this is the last. If not * we have to shuffle all the other objects to the left. */ //rubik: check if there is at least 1 object registered if (screen->objectCount > (Index -1)) { for (x=Index; x < screen->objectCount-1; x++) { cdktype = screen->cdktype[x+1]; screen->cdktype[x] = cdktype; screen->object[x] = screen->object[x+1]; (screen->object[x])->screenIndex = x; } } /* Clear out the last widget on the screen list. */ x = screen->objectCount--; screen->object[x] = 0; screen->cdktype[x] = vNULL; } } } /* * This 'brings' a CDK object to the top of the stack. */ void raiseCDKObject (EObjectType cdktype, void *object) { CDKOBJS *swapobject; EObjectType swaptype; int swapindex; int toppos; if (validObjType(cdktype)) { CDKOBJS *obj = (CDKOBJS *)object; CDKSCREEN *parent = obj->screen; toppos = parent->objectCount - 1; swapobject = parent->object[toppos]; swaptype = parent->cdktype[toppos]; swapindex = (obj)->screenIndex; (obj)->screenIndex = toppos; parent->object[toppos] = obj; parent->cdktype[toppos] = cdktype; (swapobject)->screenIndex = swapindex; parent->object[swapindex] = swapobject; parent->cdktype[swapindex] = swaptype; } } /* * This 'lowers' an object. */ void lowerCDKObject (EObjectType cdktype, void *object) { CDKOBJS *swapobject; EObjectType swaptype; int swapindex; int toppos; if (validObjType(cdktype)) { CDKOBJS *obj = (CDKOBJS *)object; CDKSCREEN *parent = obj->screen; toppos = 0; swapobject = parent->object[toppos]; swaptype = parent->cdktype[toppos]; swapindex = (obj)->screenIndex; (obj)->screenIndex = toppos; parent->object[toppos] = obj; parent->cdktype[toppos] = cdktype; (swapobject)->screenIndex = swapindex; parent->object[swapindex] = swapobject; parent->cdktype[swapindex] = swaptype; } } /* * This calls refreshCDKScreen. (made consistent with widgets) */ void drawCDKScreen (CDKSCREEN *cdkscreen) { refreshCDKScreen (cdkscreen); } /* * This refreshes all the objects in the screen. */ void refreshCDKScreen (CDKSCREEN *cdkscreen) { int objectCount = cdkscreen->objectCount; int x; /* Refresh the screen. */ touchwin (cdkscreen->window); wrefresh (cdkscreen->window); /* We just call the drawObject function. */ for (x=0; x < objectCount; x++) { CDKOBJS *obj = cdkscreen->object[x]; if (validObjType (cdkscreen->cdktype[x])) obj->fn->drawObj(obj, obj->box); } } /* * This clears all the objects in the screen. */ void eraseCDKScreen (CDKSCREEN *cdkscreen) { int objectCount = cdkscreen->objectCount; int x; /* We just call the drawObject function. */ for (x=0; x < objectCount; x++) { if (validObjType (cdkscreen->cdktype[x])) { cdkscreen->object[x]->fn->eraseObj(cdkscreen->object[x]); } } /* Refresh the screen. */ wrefresh (cdkscreen->window); } /* * This destroys a CDK screen. */ void destroyCDKScreen (CDKSCREEN *screen) { if (screen) { free (screen); } } /* * This is added to remain consistent. */ void endCDK(void) { /* Turn echoing back on. */ echo(); /* Turn off cbreak. */ nocbreak(); /* End the curses windows. */ endwin(); #ifdef HAVE_XCURSES XCursesExit(); #endif } /* * This is the function called when we trap a SEGV or a BUS error. */ static void segvTrap (int sig) { static int nested; if (!nested++) { endCDK(); printf ("core dumped. your fault! (signal %d)\n", sig); } abort(); }