server/display.c

00001 /*
00002  * Copyright Ian Burnett 2005, 2006.
00003  *
00004  * This file is part of Ian's Interactive LCD controller (IILC).
00005  * 
00006  * IILC is free software; you can redistribute it and/or modify it under
00007  * the terms of the GNU General Public License as published by the Free
00008  * Software Foundation; either version 2 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * IILC is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00014  * for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with IILC; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
00019  */
00020 
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <string.h>
00024 
00025 #if !defined(_WIN32)
00026 #   include <time.h>
00027 #   include <unistd.h>
00028 #   include <termios.h>
00029 #   include <sys/select.h>
00030 #   include <sys/time.h>
00031 #   include <pthread.h>
00032 #   include <dlfcn.h>
00033 #endif
00034 
00035 #include "lcd.h"
00036 #include "trace.h"
00037 #include "display.h"
00038 #include "eventQueue.h"
00039 #include "module.h"
00040 #include "vector.h"
00041 #include "driver.h"
00042 #include "module2.h"
00043 
00044 /*
00045  * This file is the "display" module.
00046  */
00047 #define IILC_MODULE MODULE_TYPE_DISPLAY
00048 
00049 
00050 /*
00051  * Macros to convert fan speeds to and from an int value
00052  */
00053 
00054 #define FAN_SPEED_TO_INT(fan,percent)   (((fan & 0xFFFF) << 16) + (percent & 0x0000FFFF))
00055 #define FAN_ID_FROM_INT(val)            ((val & 0xFFFF0000) >> 16)
00056 #define FAN_SPEED_FROM_INT(val)         (val & 0x0000FFFF)
00057 
00058 
00059 
00060 /****************************************************************************/
00061 /****************************************************************************/
00062 /****************************************************************************/
00063 /****************************************************************************/
00064 /****************************************************************************/
00065 /****************************************************************************/
00066 /****************************************************************************/
00067 
00068 #define DRIVER_PRE_INVOKE(pDev, pfn) \
00069     ((pDev == NULL) ? ERR_BAD_PARAMETER \
00070         : ((pDev->pFnArray->pfn == NULL) ? ERR_NOT_IMPLEMENTED \
00071             : pthread_mutex_lock(&(pDev->mtxModule))))
00072 
00073 #define DRIVER_POST_INVOKE(pDev) pthread_mutex_unlock(&(pDev->mtxModule))
00074 
00075 /* Each platform has its own way of dealing with dynamic libraries */
00076 #if defined(_WIN32)
00077 #   define LIB_NAME_PREFIX
00078 #   define LIB_NAME_SUFFIX         ".dll"
00079 #   define DYNAMIC_LIB_HANDLE      HMODULE
00080 #else
00081 #   define LIB_NAME_PREFIX         "lib"
00082 #   define LIB_NAME_SUFFIX         ".so"
00083 #   define DYNAMIC_LIB_HANDLE      void *
00084 #endif
00085 
00086 
00087 
00088 typedef struct _tag_led_instance
00089 {
00091     COLOUR on;
00092 
00094     COLOUR off;
00095 
00097     unsigned int dutyCycle;
00098 
00100     unsigned int freq;
00101 
00103     int bLEDOn;
00104 
00106     //pfnGetLEDStatus pfn;
00107 
00109     void * context;
00110 
00112     int led_id;
00113 
00114 } LED_INSTANCE, * LPLED_INSTANCE;
00115 
00116 
00117 typedef struct _tag_display_set_fan_power
00118 {
00119     unsigned int fan_id;
00120 
00121     unsigned int fan_power;
00122 
00123 } FAN_POWER;
00124 
00125 typedef struct _tag_display_object_listener
00126 {
00128     LPMODULE pModule;
00129 
00131     unsigned int id;
00132 
00134     union
00135     {
00136         pfnDspCBFanSpeed FanSpeed;
00137         pfnDspCBKeyEvent KeyEvent;
00138         pfnDspCBTemp     Temp;
00139     }
00140     pfn;
00141 
00143     void * context;
00144 
00146     const char * pszName;
00147 }
00148 OBJECT_LISTENER, * LP_OBJECT_LISTENER;
00149 
00150 typedef struct _tag_display_temp_listener
00151 {
00153     unsigned int sensor_id;
00154 
00156     pfnDrvCBTemp pfn;
00157 
00159     void * context;
00160 
00162     const char * pszFanName;
00163 } 
00164 _TEMP_LISTENER, * LP_TEMP_LISTENER;
00165 
00166 typedef struct _tag_display_fan_listener
00167 {
00169     unsigned int fan_id;
00170 
00172     pfnDspCBFanSpeed pfn;
00173 
00175     void * context;
00176 
00178     const char * pszFanName;
00179 }
00180 FAN_LISTENER, * LPFAN_LISTENER;
00181 
00182 
00183 typedef struct _tag_display
00184 {
00186     DYNAMIC_LIB_HANDLE libraryHandle;
00187 
00189     LP_DRIVER_INSTANCE pDriver;
00190 
00192     char * pszPort;
00193 
00194     pthread_mutex_t mtxModule;
00195 
00196     struct
00197     {
00198         pfnDrvCBKeyEvent  KeyEvent;
00199 
00200         pfnDrvCBTemp TempReport;
00201 
00202         pfnDrvCBFanSpeed    FanSpeedReport;
00203 
00204     } pfn;
00205 
00207     LP_DRIVER_FN_ARRAY pFnArray;
00208 
00210     LP_DRIVER_FN_ARRAY pPrivateFnArray;
00211 
00212     struct
00213     {
00214         void * FanSpeedReport;
00215 
00216         void * KeyEvent;
00217 
00218         void * TempReport;
00219     
00220     } context;
00221 
00222     /* ----- Physical characteristics of the display ----- */
00223 
00224     /* Physical width of the device */
00225     unsigned int width;
00226 
00227     /* Physical height of the device */
00228     unsigned int height;
00229 
00230     /* Number of LEDs physically available on this display */
00231     unsigned int nLED;
00232 
00233     /* Number of fans physically available on this display */
00234     unsigned int nFans;
00235 
00237     unsigned int nTempSensors;
00238 
00239     /* ----- LEDs ----- */
00240 
00242     LPLED_INSTANCE * pLEDInstanceList;
00243 
00244     /* ----- Fans ----- */
00245 
00246     LPVECTOR pFanListeners;
00247 
00248     /* ----- Temperature sensors ----- */
00249 
00250     LPVECTOR pTempListeners;
00251 
00252     /* ----- LEDs ----- */
00253 
00254     pfnDrvCBKeyEvent pfnKeyListener;
00255 
00256     void * pKeyListenerCtxt;
00257 
00258 
00259     /* ----- Screen information ----- */
00260 
00262     int nScreenCurrent;
00263 
00265     LPVECTOR pScreenList;
00266 
00268     pthread_t * screenThreads;
00269 
00270     /* ----- Others ----- */
00271 
00272     /* The event queue around which the whole Tx loop rotates */
00273     LPEVENT_QUEUE    pEventQueue;
00274 
00275     /* ID of the Txthread */
00276     pthread_t        TxThreadID;
00277 }
00278 DISPLAY;
00279 
00280 
00281 /****************************************************************************/
00282 /****************************************************************************/
00283 /****************************************************************************/
00284 /****************************************************************************/
00285 /****************************************************************************/
00286 /****************************************************************************/
00287 /****************************************************************************/
00288 
00289 
00290 void * TxThread(void * arg);
00291 
00292 void * RenderThread(void * arg);
00293 
00294 
00295 int displayRefreshScreen(LPDISPLAY pDisplay);
00296 
00297 /*
00298 
00299 void displayCallbackKeyEvent(void * context, PACKET_KEY_EVENT event);
00300 */
00301 
00302 void displayCallbackFan(void * context, unsigned int fan, unsigned int rpm);
00303 
00304 void displayCallbackTemp(void * context, unsigned int sensor, double degc);
00305 
00306 /****************************************************************************/
00307 /****************************************************************************/
00308 /****************************************************************************/
00309 /****************************************************************************/
00310 /****************************************************************************/
00311 /****************************************************************************/
00312 /****************************************************************************/
00313 
00314 
00315 
00334 int displayCreate(const char * pszClass, const char * pszPort, LPDISPLAY * ppDisplay)
00335 {
00336     int rc = 0;
00337 
00338     LPDISPLAY pDisplay = NULL;
00339 
00340     pfnDriverCreate pfnCreate = NULL;
00341 
00342     char libraryName[512];
00343     char * dlError = NULL;
00344 
00345     IILC_TRACE_ENTRY(IILC_MODULE, T_displayCreate);
00346     traceDebug(IILC_TRACE_CONTEXT,
00347         "pszClass %p, pszPort %p, ppDisplay %p", pszClass, pszPort, ppDisplay);
00348 
00349     if (pszClass == NULL || pszPort == NULL || ppDisplay == NULL) {
00350         rc = ERR_BAD_PARAMETER;
00351         goto end_of_function;
00352     }
00353 
00354     traceDebug(IILC_TRACE_CONTEXT,
00355         "Creating display of type [%s] on port [%s]", pszClass, pszPort);
00356 
00357     /* Allocate the main memory */
00358     pDisplay = (LPDISPLAY) calloc(1, sizeof(DISPLAY));
00359 
00360     /* Take a copy of the port string */
00361     pDisplay->pszPort = (char *) calloc(strlen(pszPort)+1, sizeof(char));
00362     strcpy(pDisplay->pszPort, pszPort);
00363 
00364     /* Create the full module name */
00365     sprintf(libraryName, LIB_NAME_PREFIX "%s" LIB_NAME_SUFFIX, pszClass);
00366 
00367     /* Dynamically load the library */
00368 #if defined(_WIN32)
00369     pDisplay->libraryHandle = LoadLibrary(libraryName);
00370 #else
00371     pDisplay->libraryHandle = dlopen(libraryName, RTLD_NOW);
00372     dlError = dlerror();
00373 #endif
00374 
00375     /* Verify load worked */
00376     if (pDisplay->libraryHandle == NULL) {
00377         traceError(IILC_TRACE_CONTEXT, "Library load failed: %s", dlError);
00378         rc = ERR_INVALID_CONFIG;
00379         goto end_of_function;
00380     }
00381 
00382     /* Find the named entry point into the module */
00383 #if defined(_WIN32)
00384 #else
00385     dlerror();
00386     pfnCreate = (pfnDriverCreate) dlsym(pDisplay->libraryHandle, "driver_Create");
00387     dlError = dlerror();
00388 #endif
00389 
00390     if (pfnCreate == NULL) {
00391         traceError(IILC_TRACE_CONTEXT, "Failed loading module create function: %s", dlError);
00392         goto end_of_function;
00393     }
00394 
00395     /* Create a region of memory to hold the function pointers */
00396     pDisplay->pFnArray = (LP_DRIVER_FN_ARRAY) calloc(1, sizeof(DRIVER_FN_ARRAY));
00397     
00398     eventQueueCreate(&(pDisplay->pEventQueue));
00399 
00400     vectorCreate(&(pDisplay->pFanListeners));
00401     vectorCreate(&(pDisplay->pTempListeners));
00402     vectorCreate(&(pDisplay->pScreenList));
00403 
00404     /* Now call the module init routine */
00405     rc = (pfnCreate)(pDisplay->pszPort, pDisplay->pFnArray, &(pDisplay->pDriver));
00406     if (rc) {
00407         goto end_of_function;
00408     }
00409 
00410 
00411     /* Let it know which routine to use for fan callbacks */
00412     (pDisplay->pFnArray->SetCallbackFan)(pDisplay->pDriver, displayCallbackFan, pDisplay);
00413     (pDisplay->pFnArray->SetCallbackTemp)(pDisplay->pDriver, displayCallbackTemp, pDisplay);
00414 
00415     pDisplay->height = 4;
00416     pDisplay->width = 20;
00417 
00418     /* Assign to user area */
00419     *ppDisplay = pDisplay;
00420     
00421 end_of_function:
00422 
00423     IILC_TRACE_EXIT_RC(rc);
00424     return rc;
00425 }
00426 
00427 
00428 
00429 
00430 int displayDispose(LPDISPLAY * ppDisplay)
00431 {
00432     int rc = 0;
00433     LPDISPLAY pDev = NULL;
00434 
00435     if (ppDisplay == NULL) {
00436         goto end_of_function;
00437     }
00438 
00439     pDev = *ppDisplay;
00440 
00441     if (pDev->pszPort != NULL) {
00442         free(pDev->pszPort);
00443     }
00444 
00445     free(pDev);
00446 
00447 end_of_function:
00448 
00449     return rc;
00450 }
00451 
00452 
00453 
00454 
00455 
00456 int displayStart(LPDISPLAY pDisplay)
00457 {
00458     int rc = 0;
00459     EVENT evt;
00460 
00461     IILC_TRACE_ENTRY(IILC_MODULE, T_displayStart);
00462     traceDebug(IILC_TRACE_CONTEXT, "pDisplay %p", pDisplay);
00463 
00464     /* Start the underlying device */
00465     (pDisplay->pFnArray->Start)(pDisplay->pDriver);
00466 
00467     /* Spin off a transmit thread */
00468     rc = pthread_create(&(pDisplay->TxThreadID), NULL, TxThread, (void *) pDisplay);
00469     if (rc) {
00470         printf("pthread_create error: %s\n", strerror(errno));
00471         goto end_of_function;
00472     }
00473 
00474     /*
00475      * Enqueue some default actions
00476      */
00477 
00478     /* Create a display clear event */
00479     EVENT_INIT(evt, EVENT_SCREEN_CLEAR, NULL, 0);
00480     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00481 
00482     /* Poll each module for data */
00483     EVENT_INIT(evt, EVENT_POLL_MODULE, NULL, 0);
00484     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00485 
00486     /* Contrast to something useful */
00487     EVENT_INIT(evt, EVENT_SET_CONTRAST, NULL, 90);
00488     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00489 
00490     /* Set the backlight to 30% */
00491     EVENT_INIT(evt, EVENT_SET_BACKLIGHT, NULL, 30);
00492     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00493 
00494     /* Start fans 0 & 1 at 0% */
00495     EVENT_INIT(evt, EVENT_SET_FAN_STATE, NULL, FAN_SPEED_TO_INT(0, 50));
00496     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00497 
00498     EVENT_INIT(evt, EVENT_SET_FAN_STATE, NULL, FAN_SPEED_TO_INT(1, 50));
00499     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00500 
00501     /* Update the screen regularly */
00502     EVENT_INIT(evt, EVENT_SCREEN_REFRESH, NULL, 0);
00503     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00504 
00505     /* Repeatedly poll module 0 */
00506     EVENT_INIT(evt, EVENT_POLL_MODULE, NULL, 0);
00507     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00508 
00509 
00510 end_of_function:
00511 
00512     IILC_TRACE_EXIT_RC(rc);
00513     return rc;
00514 }
00515 
00516 
00532 int displayStop(LPDISPLAY pDisplay)
00533 {
00534     int rc = 0;
00535     int i  = 0;
00536     //int ret;
00537     EVENT evt;
00538     LPEVENT_QUEUE pEventQueue = pDisplay->pEventQueue;
00539 
00540     /* ----- Restore display to sensible state ----- */
00541 
00542     /* Switch fans back on */
00543     EVENT_INIT(evt, EVENT_SET_FAN_STATE, NULL, FAN_SPEED_TO_INT(0, 100));
00544     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00545 
00546     EVENT_INIT(evt, EVENT_SET_FAN_STATE, NULL, FAN_SPEED_TO_INT(1, 100));
00547     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00548 
00549     /* Stop fan reporting for all fans */
00550     for (i = 0; i < 4; i++) {
00551         EVENT_INIT(evt, EVENT_DISABLE_FAN_REPORT, NULL, i);
00552         eventQueueEnqueue(pEventQueue, &evt, 0);
00553     }
00554 
00555     /* Backlight off */
00556     EVENT_INIT(evt, EVENT_SET_BACKLIGHT, NULL, 0);
00557     eventQueueEnqueue(pEventQueue, &evt, 0);
00558 
00559 
00560     /* Terminate the Tx thread */
00561     EVENT_INIT(evt, EVENT_SHUTDOWN, NULL, 0);
00562     eventQueueEnqueue(pEventQueue, &evt, 0);
00563 
00564     /* Wait for the Tx thread to complete */
00565     pthread_join(pDisplay->TxThreadID, NULL);
00566 
00567     /* Shutdown the device itself */
00568     (pDisplay->pFnArray->Stop)(pDisplay->pDriver);
00569 
00570     /* Release this memory */
00571 //    free(pDisplay);
00572 
00573     /* Clear user's reference */
00574 //  pDisplay = NULL;
00575 
00576 //end_of_function:
00577 
00578     return rc;
00579 }
00580 
00581 typedef enum _tag_window_type
00582 {
00583     WINDOW_TYPE_TEXT,
00584     WINDOW_TYPE_SCROLL_TEXT,
00585     WINDOW_TYPE_WRAP_TEXT,
00586     WINDOW_TYPE_BAR,
00587     WINDOW_TYPE_LARGE_TEXT
00588 
00589 } WINDOW_TYPE;
00590 
00591 
00592 
00593 
00609 int displayAddFanReportListener(LPDISPLAY pDisplay, unsigned int fanId, LPMODULE pModule, const char * pszName)
00610 {
00611     int rc = 0;
00612     EVENT evt;
00613     LP_OBJECT_LISTENER pListener = NULL;
00614 
00615     /* Set the new data */
00616     pListener = (LP_OBJECT_LISTENER) malloc(sizeof(OBJECT_LISTENER));
00617     pListener->pModule      = pModule;
00618     pListener->id           = fanId;
00619     pListener->pszName      = pszName;
00620     vectorAdd(pDisplay->pFanListeners, pListener);
00621 
00622     /* Add an update for this fan to the event queue */
00623     EVENT_INIT(evt, EVENT_ENABLE_FAN_REPORT, NULL, fanId);
00624     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00625 
00626 //end_of_function:
00627 
00628     return rc;
00629 }
00630 
00631 int displayRemoveFanReportListener(LPDISPLAY pDisplay, LPMODULE pModule)
00632 {
00633     return 0;
00634 }
00635 
00636 int displayAddTempReportListener(LPDISPLAY pDisplay, unsigned int sensor_id, LPMODULE pModule, const char * pszReportAs)
00637 {
00638     int rc = 0;
00639     EVENT evt;
00640     LP_OBJECT_LISTENER pListener = NULL;
00641 
00642     /* Set the new data */
00643     pListener = (LP_OBJECT_LISTENER) malloc(sizeof(OBJECT_LISTENER));
00644     pListener->pModule   = pModule;
00645     pListener->id        = sensor_id;
00646     pListener->pszName   = pszReportAs == NULL ? NULL : strdup(pszReportAs);
00647     vectorAdd(pDisplay->pTempListeners, pListener);
00648 
00649     /* Add an update for this temp to the event queue */
00650     EVENT_INIT(evt, EVENT_ENABLE_TEMP_REPORT, NULL, sensor_id);
00651     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00652 
00653 //end_of_function:
00654 
00655     return rc;
00656 }
00657 
00658 int displayRemoveTempReportListener(LPDISPLAY pDisplay, pfnDspCBTemp pfnListener)
00659 {
00660     return 0;
00661 }
00662 
00663 int displayAddKeyEventListener(LPDISPLAY pDisplay, pfnDspCBKeyEvent pfnListener, void * context)
00664 {
00665 
00666     return 0;
00667 }
00668 
00669 
00670 
00674 void * TxThread(void * arg)
00675 {
00676     /* Grab our instance data from the arg ptr */
00677     LPDISPLAY pDisplay = (LPDISPLAY) arg;
00678     
00679     /* Vars used in this function */
00680     int running = 1;
00681     int rc = 0;
00682 
00683     /* Initialise convenient locals */
00684     LPEVENT_QUEUE pEventQueue = pDisplay->pEventQueue;
00685 
00686     /* Temp */
00687     char * longText = "This is a test";
00688     //char scrData[1024];
00689     int scrollPos = 0;
00690 
00691     IILC_TRACE_ENTRY(IILC_MODULE, T_TxThread);
00692 
00693     while (running)
00694     {
00695         /* Loop vars */
00696         EVENT evt;
00697 
00698         /* Flag to indicate we should keep the memory for the event (saves reallocing) */
00699         int iRequeueTime = -1; /* -1 == dispose of event */
00700 
00701         /* Wait for event dequeue */
00702         rc = eventQueueDequeue(pEventQueue, &evt);
00703         if (rc) {
00704             traceError(IILC_TRACE_CONTEXT, "Event dequeue failed");
00705             break;
00706         }
00707 
00708         traceDebug(IILC_TRACE_CONTEXT, "Dequeued event %d", evt.eType);
00709 
00710         /* Process */
00711         switch (evt.eType)
00712         {
00713         case EVENT_SHUTDOWN:
00714             running = 0;
00715             break;
00716 
00717         case EVENT_SCREEN_CLEAR:
00718 //            deviceClear(pDisplay->pDevice);
00719             break;
00720 
00721         case EVENT_SET_BACKLIGHT:
00722             (pDisplay->pFnArray->SetBacklight)(pDisplay->pDriver, (unsigned int) evt.iData);
00723             break;
00724 
00725         case EVENT_SET_CONTRAST:
00726             (pDisplay->pFnArray->SetContrast)(pDisplay->pDriver, (unsigned char) evt.iData);
00727             break;
00728 
00729         case EVENT_SCREEN_CHANGE:
00730 //            rc = displayAdvanceScreen(pDisplay);
00731             iRequeueTime = 5000;
00732             break;
00733 
00734         case EVENT_SCREEN_REFRESH:
00735             rc = displayRefreshScreen(pDisplay);
00736             iRequeueTime = 500;
00737             break;
00738 
00739         case EVENT_LED_UPDATE:
00740         {
00741             /* Convenience */
00742             LPLED_INSTANCE pLEDInst = pDisplay->pLEDInstanceList[evt.iData];
00743 
00744             printf("Updating LED %d status\n", evt.iData);
00745 
00746             /* Get current state and adjust output accordingly */
00747             if (pLEDInst->bLEDOn || pLEDInst->freq == 0) {
00748                 (pDisplay->pFnArray->SetLED)(pDisplay->pDriver, evt.iData,
00749                     pLEDInst->off.red, pLEDInst->off.green, pLEDInst->off.blue);
00750             }
00751             else {
00752                 (pDisplay->pFnArray->SetLED)(pDisplay->pDriver, evt.iData, 
00753                     pLEDInst->on.red, pLEDInst->on.green, pLEDInst->on.blue);
00754             }
00755 
00756             /* Calculate the requeue time */
00757             if (pLEDInst->freq == 0) {
00758                 iRequeueTime = 2000; /* Frequency of zero means always off */
00759             }
00760             else {
00761                 iRequeueTime = pLEDInst->bLEDOn ?
00762                     ((1000 * pLEDInst->dutyCycle) / pLEDInst->freq) :
00763                     ((1000 * (100 - pLEDInst->dutyCycle)) / pLEDInst->freq);
00764             }
00765 
00766             /* Toggle state and loop */
00767             pLEDInst->bLEDOn = ~(pLEDInst->bLEDOn);
00768             break;
00769         }
00770 
00771         /*
00772         case EVENT_POLL_LED_STATUS:
00773         {
00774             LPLED_INSTANCE pLEDInst = pDisplay->pLEDInstanceList[evt.iData];
00775 
00776             printf("Polling for LED %d status\n", evt.iData);
00777 
00778             * Get LED data from module *
00779             (pLEDInst->pfn)(pLEDInst->context, pLEDInst->led_id,
00780                 &(pLEDInst->on), &(pLEDInst->off),
00781                 &(pLEDInst->dutyCycle), &(pLEDInst->freq));
00782 
00783             * LEDs need only be updated every 2 seconds *
00784             iRequeueTime = 2000;
00785             break;
00786 
00787         }
00788         */
00789 
00790         case EVENT_POLL_MODULE:
00791         {
00792             break;
00793         }
00794 
00795         case EVENT_TEXT_SCROLL:
00796         {
00797             char tmpBuf[1024];
00798             size_t strLen = -1;
00799             int dispWidth = 20;
00800             
00801             /* Amount of string to end */
00802             strLen = strlen(&longText[scrollPos]);
00803 
00804             if (strLen > (unsigned int) dispWidth) {
00805                 sprintf(tmpBuf, "%.*s", dispWidth, &longText[scrollPos]);
00806             }
00807             else {
00808                 sprintf(tmpBuf, "%s %.*s", &longText[scrollPos], dispWidth - strLen - 1, longText);
00809             }
00810 
00811             /* Write to the display */
00812             (pDisplay->pFnArray->WriteText)(pDisplay->pDriver, 0, 1, tmpBuf, (unsigned int) strlen(tmpBuf));
00813 
00814             /* Scroll and check within bounds */
00815             scrollPos++;
00816             if ((unsigned int) scrollPos >= strlen(longText)) {
00817                 scrollPos = 0;
00818             }
00819 
00820             /* Keep event in memory and requeue for 50 msec time */
00821             iRequeueTime = 300;
00822             break;
00823         }
00824 
00825         case EVENT_KEY_PRESS:
00826             break;
00827 
00828         case EVENT_KEY_RELEASE:
00829             break;
00830 
00831         case EVENT_ENABLE_FAN_REPORT:
00832             (pDisplay->pFnArray->EnableFanReport)(pDisplay->pDriver, evt.iData);
00833             traceDebug(IILC_TRACE_CONTEXT, "Enabled fan reporting for %d", evt.iData);
00834             break;
00835 
00836         case EVENT_DISABLE_FAN_REPORT:
00837             (pDisplay->pFnArray->DisableFanReport)(pDisplay->pDriver, evt.iData);
00838             traceDebug(IILC_TRACE_CONTEXT, "Disabled fan reporting for %d", evt.iData);
00839             break;
00840 
00841         case EVENT_ENABLE_TEMP_REPORT:
00842             (pDisplay->pFnArray->EnableTempReport)(pDisplay->pDriver, evt.iData);
00843             traceDebug(IILC_TRACE_CONTEXT, "Enabled temp reporting for %d", evt.iData);
00844             break;
00845 
00846         case EVENT_DISABLE_TEMP_REPORT:
00847             (pDisplay->pFnArray->DisableTempReport)(pDisplay->pDriver, evt.iData);
00848             traceDebug(IILC_TRACE_CONTEXT, "Disabled temp reporting for %d", evt.iData);
00849             break;
00850 
00851         case EVENT_SET_FAN_STATE:
00852             (pDisplay->pFnArray->SetFanPower)(pDisplay->pDriver, 
00853                 FAN_ID_FROM_INT(evt.iData), FAN_SPEED_FROM_INT(evt.iData));
00854             iRequeueTime = 3000;
00855             break;
00856 
00857         default:
00858             printf("Unknown event type received (%d)\n", evt.eType);
00859             break;
00860         }
00861 
00862         /* Should we requeue this event? */
00863         if (iRequeueTime >= 0) {
00864             eventQueueEnqueue(pEventQueue, &evt, iRequeueTime);
00865         }
00866     }
00867 
00868 
00869 //end_of_function:
00870 
00871     IILC_TRACE_EXIT;
00872     return NULL;
00873 }
00874 
00875 
00876 int displayGetSize(LPDISPLAY pDisplay, int * width, int * height)
00877 {
00878     int rc = 0;
00879 
00880     *width = pDisplay->width;
00881     *height = pDisplay->height;
00882 
00883     return rc;
00884 }
00885 
00886 int displayScreenAdd(LPDISPLAY pDisplay, LPSCREEN pScreen)
00887 {
00888     int rc = 0;
00889     //LPSCREEN * pNewList = NULL;
00890     //pthread_t * pNewThreadList = NULL;
00891     //pthread_t newTid;
00892     EVENT evt;
00893 
00894     vectorAdd(pDisplay->pScreenList, pScreen);
00895 
00896     /* Remember to update us in the main Tx loop */
00897     EVENT_INIT(evt, EVENT_SCREEN_REFRESH, NULL, 0);
00898     eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
00899 
00900     return rc;
00901 }
00902 
00903 
00904 
00905 int displayRefreshScreen(LPDISPLAY pDisplay)
00906 {
00907     int rc = 0;
00908     unsigned int i = 0;
00909     //int nWindows = 0;
00910     LPSCREEN pScreen = NULL;
00911     int nScreenCount = 0;
00912     
00913     /* Buffer to draw to screen */
00914     char * pszScreen = NULL;
00915     char * ptrCurrent = NULL;
00916 
00917     /* Allocate some (2-D) memory */
00918     pszScreen = (char *) calloc(pDisplay->width * pDisplay->height, sizeof(char));
00919 
00920     /* If we have no screens, let the user know */
00921     vectorGetSize(pDisplay->pScreenList, &nScreenCount);
00922     if (nScreenCount == 0) {
00923         char * pszNoConfig = "No screens setup";
00924         strncpy(&pszScreen[0], pszNoConfig, strlen(pszNoConfig));
00925     }
00926     else {
00927         /* Get the current screen we are displaying */
00928         vectorGetElementAt(pDisplay->pScreenList, pDisplay->nScreenCurrent, (void **) &pScreen);
00929 
00930         /* Render this line into the current buffer */
00931         screenDoRender(pScreen, pszScreen);
00932     }
00933 
00934     /* Write all data to the screen */
00935     ptrCurrent = pszScreen;
00936     for (i = 0; i < pDisplay->height; i++) {
00937         rc = (pDisplay->pFnArray->WriteText)(pDisplay->pDriver, 0, i, ptrCurrent, pDisplay->width);
00938         ptrCurrent += pDisplay->width;
00939     }
00940 
00941     /* Release memory */
00942     if (pszScreen) free(pszScreen);
00943 
00944     return rc;
00945 }
00946 
00947 
00953 void displayCallbackTemp(void * context, unsigned int sensor, double degc)
00954 {
00955     int i = 0;
00956     int nCount = 0;
00957     LPDISPLAY pDisplay = (LPDISPLAY) context;
00958 
00959     IILC_TRACE_ENTRY(IILC_MODULE, T_displayCallbackTemp);
00960     traceDebug(IILC_TRACE_CONTEXT, "sensor %u, temp %f", sensor, degc);
00961 
00962     /* Iterate through all callbacks */
00963     vectorGetSize(pDisplay->pTempListeners, &nCount);
00964     for (i = 0; i < nCount; i++) {
00965 
00966         LP_OBJECT_LISTENER pListener;
00967 
00968         /* Get the next callback */
00969         vectorGetElementAt(pDisplay->pTempListeners, i, (void **) &pListener);
00970 
00971         /* Is this callback relevant for this sensor? */
00972         if (pListener->id != sensor) {
00973             continue; /* No - skip to next callback */
00974         }
00975 
00976         /* Yes - perform the callback */
00977         moduleReportTemp(pListener->pModule, sensor, degc, pListener->pszName);
00978     }
00979 
00980     IILC_TRACE_EXIT;
00981 }
00982 
00983 
00984 void displayCallbackFan(void * context, unsigned int fan, unsigned int rpm)
00985 {
00986     int i = 0;
00987     int nCount = 0;
00988     LPDISPLAY pDisplay = (LPDISPLAY) context;
00989 
00990     IILC_TRACE_ENTRY(IILC_MODULE, T_displayCallbackFan);
00991     traceDebug(IILC_TRACE_CONTEXT, "fan %u, rpm %u", fan, rpm);
00992 
00993     /* Iterate through all callbacks */
00994     vectorGetSize(pDisplay->pFanListeners, &nCount);
00995     for (i = 0; i < nCount; i++) {
00996 
00997         LP_OBJECT_LISTENER pListener;
00998 
00999         /* Get the next callback */
01000         vectorGetElementAt(pDisplay->pFanListeners, i, (void **) &pListener);
01001 
01002         /* Is this callback relevant for this fan? */
01003         if (pListener->id != fan) {
01004             continue; /* No - skip to next callback */
01005         }
01006 
01007         /* Yes - perform the callback */
01008         moduleReportFan(pListener->pModule, fan, rpm, pListener->pszName);
01009     }
01010 
01011     IILC_TRACE_EXIT;
01012 }
01013 
01014 
01028 int displaySetLEDController(LPDISPLAY pDisplay, unsigned int led_id, void * /* pfnGetLEDStatus */ pfn, void * context, int report_as_led)
01029 {
01030     int rc = 0;
01031     EVENT evt;
01032     LPLED_INSTANCE pInst = NULL;
01033 
01034     IILC_TRACE_ENTRY(IILC_MODULE, T_displaySetLEDController);
01035     traceDebug(IILC_TRACE_CONTEXT,
01036         "pDisplay " T_FMT_PTR ", led_id " T_FMT_INT ", pfn " T_FMT_PTR
01037         ", context " T_FMT_PTR ", report_as_led " T_FMT_INT,
01038         pDisplay, led_id, pfn, context, report_as_led);
01039 
01040     /* Sanity checks */
01041     if (pDisplay == NULL) {
01042         rc = ERR_BAD_PARAMETER;
01043         goto end_of_function;
01044     }
01045 
01046     if (led_id > pDisplay->nLED) {
01047         rc = ERR_BAD_PARAMETER;
01048         goto end_of_function;
01049     }
01050 
01051     /* Convenience */
01052     pInst = pDisplay->pLEDInstanceList[led_id];
01053 
01054     /* Clear and init memory */
01055     //pInst->     = pfn;
01056     pInst->context = context;
01057     pInst->led_id  = report_as_led;
01058 
01059     /* Are we setting up or removing a controller? */
01060     if (pfn != NULL) {
01061 
01062         /* Remember to query this LED */
01063         EVENT_INIT(evt, EVENT_POLL_LED_STATUS, NULL, led_id);
01064         eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
01065 
01066         /* Remember to update this LED */
01067         EVENT_INIT(evt, EVENT_LED_UPDATE, NULL, led_id);
01068         eventQueueEnqueue(pDisplay->pEventQueue, &evt, 0);
01069     }
01070 
01071 end_of_function:
01072 
01073     IILC_TRACE_EXIT;
01074     return 0;
01075 }

Generated on Mon Jul 17 01:36:11 2006 for IILC by  doxygen 1.4.6