displayMgr/src/displayMgr.c File Reference

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "liberdm/erdm.h"
#include "liberdm/erdmServer.h"
#include "liberdm/erdminternal.h"
#include "config.h"
#include "displayEinkTypes.h"
#include "liberdm/display.h"
#include <liberipc/eripc.h>
#include <liberipc/eripcbusyd.h>
#include <liberipc/eripccontentlister.h>

Go to the source code of this file.

Classes

struct  _dmWaveforms

Defines

#define MILLION   1000000
#define N_FILENAME   1024
#define UD_FBSIZE   786432
#define BUFFERSIZE   1024
#define ERDMG_LOGGING_ON   0
#define ERDMG_WARNING_ON   1
#define ERDMG_ERROR_ON   1
#define ERDMG_LOGPRINTF(x, args...)   do {} while (0)
#define ERDMG_WARNPRINTF(x, args...)   fprintf(stderr, "(W)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)
#define ERDMG_ERRORPRINTF(x, args...)   fprintf(stderr, "(E)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)
#define min(x, y)   (((x)<(y))?(x):(y))
#define max(x, y)   (((x)>(y))?(x):(y))
#define WAVEFORM_SIZE   (128*1024)
#define FBIO_IOCTL_BASE   'v'
#define FBIO_DISPLAY   _IOW(FBIO_IOCTL_BASE, 1, struct display_update_info)
#define FBIO_ERASE_WHITE   _IOW(FBIO_IOCTL_BASE, 2, struct display_update_info)
#define FBIO_DRAWPIXELS   _IOW(FBIO_IOCTL_BASE, 3, struct transfer_buffer)
#define FBIO_DRAW_BRUSH   _IOW(FBIO_IOCTL_BASE, 4, struct brush_draw_info)
#define FBIO_REDRAW   _IOW(FBIO_IOCTL_BASE, 5, struct display_update_info)
#define FBIO_UPLOAD_WAVEFORM   _IOC(_IOC_WRITE, FBIO_IOCTL_BASE, 6, WAVEFORM_SIZE)
#define FBIO_DISPLAYPARTIAL   0xfff

Typedefs

typedef struct _dmWaveforms dmWaveforms_t

Functions

void displayHelp ()
int uploadWaveform (int fbDev, char *szFilename)
int main (int argc, char **argv)

Variables

static dmWaveforms_t waveforms []


Define Documentation

#define BUFFERSIZE   1024

Definition at line 61 of file displayMgr.c.

#define ERDMG_ERROR_ON   1

Definition at line 65 of file displayMgr.c.

#define ERDMG_ERRORPRINTF ( x,
args...   )     fprintf(stderr, "(E)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)

Definition at line 80 of file displayMgr.c.

#define ERDMG_LOGGING_ON   0

Definition at line 63 of file displayMgr.c.

#define ERDMG_LOGPRINTF ( x,
args...   )     do {} while (0)

Definition at line 70 of file displayMgr.c.

#define ERDMG_WARNING_ON   1

Definition at line 64 of file displayMgr.c.

#define ERDMG_WARNPRINTF ( x,
args...   )     fprintf(stderr, "(W)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)

Definition at line 74 of file displayMgr.c.

#define FBIO_DISPLAY   _IOW(FBIO_IOCTL_BASE, 1, struct display_update_info)

Definition at line 92 of file displayMgr.c.

#define FBIO_DISPLAYPARTIAL   0xfff

Definition at line 100 of file displayMgr.c.

#define FBIO_DRAW_BRUSH   _IOW(FBIO_IOCTL_BASE, 4, struct brush_draw_info)

Definition at line 95 of file displayMgr.c.

#define FBIO_DRAWPIXELS   _IOW(FBIO_IOCTL_BASE, 3, struct transfer_buffer)

Definition at line 94 of file displayMgr.c.

#define FBIO_ERASE_WHITE   _IOW(FBIO_IOCTL_BASE, 2, struct display_update_info)

Definition at line 93 of file displayMgr.c.

#define FBIO_IOCTL_BASE   'v'

Definition at line 91 of file displayMgr.c.

#define FBIO_REDRAW   _IOW(FBIO_IOCTL_BASE, 5, struct display_update_info)

Definition at line 96 of file displayMgr.c.

#define FBIO_UPLOAD_WAVEFORM   _IOC(_IOC_WRITE, FBIO_IOCTL_BASE, 6, WAVEFORM_SIZE)

Definition at line 97 of file displayMgr.c.

#define max ( x,
 )     (((x)>(y))?(x):(y))

Definition at line 86 of file displayMgr.c.

#define MILLION   1000000

Copyright (C) 2005-2008 iRex Technologies B.V. All rights reserved.

Definition at line 41 of file displayMgr.c.

#define min ( x,
 )     (((x)<(y))?(x):(y))

Definition at line 85 of file displayMgr.c.

#define N_FILENAME   1024

Definition at line 58 of file displayMgr.c.

#define UD_FBSIZE   786432

Definition at line 59 of file displayMgr.c.

#define WAVEFORM_SIZE   (128*1024)

Definition at line 89 of file displayMgr.c.


Typedef Documentation

typedef struct _dmWaveforms dmWaveforms_t


Function Documentation

void displayHelp (  ) 

Definition at line 116 of file displayMgr.c.

00117 {
00118     printf("Usage: displayMgr -<option> <argument>\n");
00119     printf("  no arguments : start server process (local access only)\n");
00120     printf("  -a : allow messages to be sent from any host (starts server process)\n");
00121     printf("  -h : display this message\n");
00122     // printf("  -d <filename> : dump framebuffer to filename\n");
00123     printf("  -p : disable partial update\n");
00124     printf("  -w <filename> : load waveform from filename\n");
00125 }

int main ( int  argc,
char **  argv 
)

Definition at line 172 of file displayMgr.c.

00173 {
00174     int     fDump = 0;
00175     int     fLocal = 1;
00176     int     fDisablePartialUpdate = 0;
00177     int     fWaveFile = 0;
00178     int     nArg = 1;
00179     char    szDumpFile[N_FILENAME];
00180     char    szWaveFile[N_FILENAME];
00181     int     nRet;
00182 
00183     // eink var's
00184     int     ret;
00185     int     fbDev;
00186 
00187     int     sockfd;
00188     struct sockaddr_in clientAdr;
00189     socklen_t len;
00190     int     n;
00191 
00192     char    buffer[BUFFERSIZE];
00193     uDmCommand dmCommand;
00194     unsigned long sleepTimeUSeconds = 0;
00195 
00196     erClientChannel_t contentListerChannel;
00197     int               first_update = 1;
00198 
00199     // Options follow the pattern
00200     // -option <argument>
00201     // -option
00202     while (nArg < argc)
00203     {
00204         if (argv[nArg][0] == '-')
00205         {
00206             switch (argv[nArg][1])
00207             {
00208             case 'h':
00209                 displayHelp();
00210                 return 0;
00211                 break;
00212 
00213             case 'a':
00214                 fLocal = 0;
00215                 nArg++;
00216                 break;
00217 
00218             case 'd':
00219                 fDump = 1;
00220                 // To what file ?
00221                 if (++nArg >= argc)
00222                 {
00223                     // Not enough arguments supplied.
00224                     ERDMG_ERRORPRINTF("Supply a filename after option -d");
00225                     displayHelp();
00226                     return -1;
00227                 }
00228                 else
00229                 {
00230                     strncpy(szDumpFile, argv[nArg], N_FILENAME);
00231                     nArg++;
00232                 }
00233                 break;
00234 
00235             case 'p':
00236                 fDisablePartialUpdate = 1;
00237                 nArg++;
00238                 break;
00239 
00240             case 'w':
00241                 fWaveFile = 1;
00242                 // To what file ?
00243                 if (++nArg >= argc)
00244                 {
00245                     // Not enough arguments supplied.
00246                     ERDMG_ERRORPRINTF("Supply a filename after option -w");
00247                     displayHelp();
00248                     return -1;
00249                 }
00250                 else
00251                 {
00252                     strncpy(szWaveFile, argv[nArg], N_FILENAME);
00253                     nArg++;
00254                 }
00255                 break;
00256 
00257             default:
00258                 ERDMG_ERRORPRINTF("Option %s not known.", argv[nArg]);
00259                 displayHelp();
00260                 return -1;
00261             }
00262         }
00263         else
00264         {
00265             ERDMG_ERRORPRINTF("Argument supplied not proceded by option.");
00266             displayHelp();
00267             return -1;
00268         }
00269     }
00270 
00271 
00272     ERDMG_WARNPRINTF("ePaper daemon (%s)", PACKAGE_STRING);
00273 
00274     if (fDump == 1)
00275         ERDMG_WARNPRINTF("File dumping set to file %s", szDumpFile);
00276     if (fLocal == 1)
00277         ERDMG_WARNPRINTF("Display Manager is accessible to local processes only.");
00278     if (fWaveFile == 1)
00279         ERDMG_WARNPRINTF("Loading waveforms from file %s", szWaveFile);
00280 
00281 #ifdef __arm__
00282     fbDev = open("/dev/fb0", O_RDWR);
00283     if (fbDev == -1)
00284     {
00285         ERDMG_ERRORPRINTF("Error opening framebufferdevice. # mknod /dev/fb0 c 29 0");
00286         return -1;
00287     }
00288 
00289     // Load waveforms
00290     if (fWaveFile == 1)
00291     {
00292         nRet = uploadWaveform(fbDev, szWaveFile);
00293         if (nRet != 0)
00294         {
00295             ERDMG_ERRORPRINTF("Failed to upload waveform, continuing anyway");
00296         }
00297     }
00298 #endif
00299 
00300     initServer(&sockfd, fLocal);    
00301         // setup the client channel of contentlister    
00302         ret = erIpcStartClient(ER_CONTENTLISTER_CHANNEL, &contentListerChannel);
00303         if (ret != 0)
00304         ERDMG_ERRORPRINTF("erIpcStartClient returned %d", ret);
00305     while (1)
00306     {
00307         fd_set  readset;
00308         struct timeval timeout;
00309         char    szClientIP[INET_ADDRSTRLEN + 1];
00310         struct timeval tvStart;
00311         struct timeval tvEnd;
00312         long    timediff;
00313         uDmCommand dmCmdDpy;
00314         uDmCommand dmCmdDpyPartial;
00315         eDmCommandCode commandCode;
00316         struct coordinates coordFinal;
00317         int     nx1, ny1, nx2, ny2;
00318         int     x1, y1, x2, y2;
00319         struct display_update_info displayUpdateInfo;
00320         struct partial_display_update_info partialDisplayUpdateInfo;
00321 
00322         if (sleepTimeUSeconds > 0)
00323         {
00324             // We know the eInk display is busy. We just sleep.
00325             ERDMG_LOGPRINTF("Going to sleep for %ld micro seconds", sleepTimeUSeconds);
00326             usleep(sleepTimeUSeconds);
00327             sleepTimeUSeconds = 0;
00328         }
00329 
00330         // The first call is a blocking call.
00331         len = sizeof(clientAdr);
00332         n = recvfrom(sockfd, buffer, BUFFERSIZE, 0, (struct sockaddr *) &clientAdr, &len);
00333         buffer[n] = '\0';
00334         if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00335         {
00336             ERDMG_LOGPRINTF("Message %s received from %s.", buffer, szClientIP);
00337         }
00338         nRet = dmMessageParser(buffer, &dmCommand);
00339         if (nRet != 0)
00340         {
00341             ERDMG_ERRORPRINTF("Skipping an invalid command");
00342             continue;
00343         }
00344 
00345         // Blank display before the first display update,
00346         // this reduces ghosting from startup screen.
00347         if (first_update)
00348         {
00349             first_update = 0;
00350 
00351             ERDMG_LOGPRINTF("Erase to white for first update");
00352             displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00353             displayUpdateInfo.sequence = 0;
00354 #ifdef __arm__
00355             if ((ret = ioctl(fbDev, FBIO_ERASE_WHITE, &displayUpdateInfo)))
00356             {
00357                 ERDMG_ERRORPRINTF("Error sending FBIO_ERASE_WHITE: %x", ret);
00358             }
00359 #else
00360             ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_ERASE_WHITE)");
00361 #endif
00362         }
00363 
00364         commandCode = dmCommand.dmCmdGeneric.cmd;
00365         switch (commandCode)
00366         {
00367         case dmCcDisplay:
00368             dmCmdDpy = dmCommand;
00369             break;
00370 
00371         case dmCcDisplayPartial:
00372             dmCmdDpyPartial = dmCommand;
00373             break;
00374 
00375         default:
00376             ;  // ignore
00377         }
00378 
00379         // Depending on the priority of the request we adapt the timeout that will be
00380         // used in the select of the while loop.
00381         switch (dmCommand.dmCmdGeneric.priority)
00382         {
00383         case dmCmdPriorLow:
00384             timediff = 1500 * 1000;
00385             break;
00386 
00387         case dmCmdPriorHigh:
00388             timediff = 100 * 1000;
00389             break;
00390 
00391         case dmCmdPriorUrgent:
00392             timediff = 0;
00393             break;
00394 
00395         case dmCmdPriorNormal:
00396         default:
00397             timediff = 500 * 1000;
00398             break;
00399         }
00400         //g_assert(timediff < MILLION);
00401         
00402         gettimeofday(&tvEnd, NULL);
00403         tvEnd.tv_usec += timediff;
00404         if (tvEnd.tv_usec > MILLION)
00405         {
00406             tvEnd.tv_usec -= MILLION;
00407             tvEnd.tv_sec  += 1;
00408         }
00409 
00410         while (1)  // loop exits with break statement
00411         {
00412             FD_ZERO(&readset);
00413             FD_SET(sockfd, &readset);
00414 
00415             gettimeofday(&tvStart, NULL);
00416             if (tvEnd.tv_usec < tvStart.tv_usec)
00417             {
00418                 tvEnd.tv_usec += MILLION;
00419                 tvEnd.tv_sec  -= 1;
00420             }
00421             if (tvEnd.tv_sec < tvStart.tv_sec)
00422             {
00423                 timeout.tv_usec = 0;
00424                 timeout.tv_sec  = 0;
00425             }
00426             else
00427             {
00428                 timeout.tv_usec = tvEnd.tv_usec - tvStart.tv_usec;
00429                 timeout.tv_sec  = tvEnd.tv_sec  - tvStart.tv_sec;
00430             }
00431             ERDMG_LOGPRINTF("timeout [%ld:%06ld]", timeout.tv_sec, timeout.tv_usec);
00432             
00433             if ((select(sockfd + 1, &readset, NULL, NULL, &timeout) == -1) && (errno != EINTR))
00434             {
00435                 perror("Select Failed");
00436             }
00437             else
00438             {
00439                 if (FD_ISSET(sockfd, &readset))
00440                 {
00441                     len = sizeof(clientAdr);
00442                     n = recvfrom(sockfd, buffer, BUFFERSIZE, 0, (struct sockaddr *) &clientAdr, &len);
00443                     buffer[n] = '\0';
00444                     if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00445                     {
00446                         ERDMG_LOGPRINTF("Message %s received from %s.", buffer, szClientIP);
00447                     }
00448                     nRet = dmMessageParser(buffer, &dmCommand);
00449                     if (nRet != 0)
00450                     {
00451                         ERDMG_ERRORPRINTF("Skipping an invalid command");
00452                         continue;
00453                     }
00454                     // If we already plan to do a full display update, ignore the partial display update.
00455                     if (commandCode == dmCcDisplay)
00456                     {
00457                         // Update the priority
00458                         //   A higher value corresponds to a higher priority
00459                         if ((int) dmCmdDpy.dmCmdDisplay.priority < (int) dmCommand.dmCmdDisplay.priority)
00460                         {
00461                             dmCmdDpy.dmCmdDisplay.priority = dmCommand.dmCmdDisplay.priority;
00462                         }
00463                         // Update the quality
00464                         //   A higher value corresponds to a faster waveform (slowest waveforms should take precedence)
00465                         if ((int) dmCmdDpy.dmCmdDisplay.qual > (int) dmCommand.dmCmdDisplay.qual)
00466                         {
00467                             dmCmdDpy.dmCmdDisplay.qual = dmCommand.dmCmdDisplay.qual;
00468                         }
00469                     }
00470                     else if (commandCode == dmCcDisplayPartial)
00471                     {
00472                         if (dmCommand.dmCmdGeneric.cmd == dmCcDisplay)
00473                         {
00474                             // A full screen update supersedes a partial screen update.
00475                             commandCode = dmCcDisplay;
00476                             dmCmdDpy = dmCommand;
00477                         }
00478                         else if (dmCommand.dmCmdGeneric.cmd == dmCcDisplayPartial)
00479                         {
00480                             // Merge the two rectangles.
00481                             int     x1Up, y1Up;
00482                             int     x1Down, y1Down;
00483                             int     x2Up, y2Up;
00484                             int     x2Down, y2Down;
00485 
00486                             x1Down = dmCmdDpyPartial.dmCmdDisplayPartial.xDown;
00487                             y1Down = dmCmdDpyPartial.dmCmdDisplayPartial.yDown;
00488                             x1Up = dmCmdDpyPartial.dmCmdDisplayPartial.xUp;
00489                             y1Up = dmCmdDpyPartial.dmCmdDisplayPartial.yUp;
00490 
00491                             x1Up = min(x1Up, x1Down);
00492                             y1Up = min(y1Up, y1Down);
00493                             x1Down = max(x1Up, x1Down);
00494                             y1Down = max(y1Up, y1Down);
00495 
00496                             x2Down = dmCommand.dmCmdDisplayPartial.xDown;
00497                             y2Down = dmCommand.dmCmdDisplayPartial.yDown;
00498                             x2Up = dmCommand.dmCmdDisplayPartial.xUp;
00499                             y2Up = dmCommand.dmCmdDisplayPartial.yUp;
00500 
00501                             x2Up = min(x2Up, x2Down);
00502                             y2Up = min(y2Up, y2Down);
00503                             x2Down = max(x2Up, x2Down);
00504                             y2Down = max(y2Up, y2Down);
00505 
00506                             // The actual merge (TODO: determine qual)
00507                             commandCode = dmCcDisplayPartial;
00508                             dmCmdDpyPartial.dmCmdDisplay.cmd = commandCode;
00509                             dmCmdDpyPartial.dmCmdDisplay.priority = dmCmdPriorNormal;
00510                             dmCmdDpyPartial.dmCmdDisplay.qual = dmQFull;
00511                             dmCmdDpyPartial.dmCmdDisplayPartial.xUp = min(x1Up, x2Up);
00512                             dmCmdDpyPartial.dmCmdDisplayPartial.yUp = min(y1Up, y2Up);
00513                             dmCmdDpyPartial.dmCmdDisplayPartial.xDown = max(x1Down, x2Down);
00514                             dmCmdDpyPartial.dmCmdDisplayPartial.yDown = max(y1Down, y2Down);
00515                         }
00516                     }
00517                     else
00518                     {
00519                         commandCode = dmCommand.dmCmdGeneric.cmd;
00520                         switch (commandCode)
00521                         {
00522                         case dmCcDisplay:
00523                             dmCmdDpy = dmCommand;
00524                             break;
00525 
00526                         case dmCcDisplayPartial:
00527                             dmCmdDpyPartial = dmCommand;
00528                             break;
00529                         default:
00530                             ;  // ignore
00531                         }
00532                     }
00533                 }
00534                 else
00535                 {
00536                     ERDMG_LOGPRINTF("Nothing more pending.");
00537                     break;  // exit while (1)
00538                 }
00539             }
00540         }
00541 
00542         switch (commandCode)
00543         {
00544         case dmCcDisplay:
00545             dmCommand = dmCmdDpy;
00546             break;
00547 
00548         case dmCcDisplayPartial:
00549             dmCommand = dmCmdDpyPartial;
00550             break;
00551 
00552         default:
00553             ;  // ignore
00554         }
00555 
00556         switch (dmCommand.dmCmdGeneric.cmd)
00557         {
00558         case dmCcDisplay:
00559             displayUpdateInfo.sequence = 0;
00560             switch (dmCommand.dmCmdDisplay.qual)
00561             {
00562               case dmQFull:
00563                 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00564                 break;
00565               case dmQBW:
00566                 displayUpdateInfo.waveform = WAVEFORM_FAST_BLACK_WHITE;
00567                 ERDMG_LOGPRINTF("Selected BW waveform");
00568                 break;
00569               case dmQTyping:
00570                 displayUpdateInfo.waveform = WAVEFORM_TYPING;
00571                 ERDMG_LOGPRINTF("Selected Typing waveform");
00572                 break;
00573               default:
00574                 ;  // ignore
00575             }
00576             ERDMG_LOGPRINTF("Before ioctl");
00577             gettimeofday(&tvStart, NULL);
00578 #ifdef __arm__
00579             // if ((ret = ioctl(fbDev, FBIO_DISPLAY, NULL)))
00580             if ((ret = ioctl(fbDev, FBIO_DISPLAY, &displayUpdateInfo)))
00581             {
00582                 ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAY: %x", ret);
00583             }
00584 #else
00585             ERDMG_LOGPRINTF("(Dummy) ioctl(fbDev, FBIO_DISPLAY, NULL)");
00586 #endif
00587             gettimeofday(&tvEnd, NULL);
00588             timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00589             ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00590             sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00591                         // send "clCcDisplayUpdated" signal to contentlister
00592             clDisplayUpdated(contentListerChannel);                     
00593             break;
00594 
00595         case dmCcDisplayPartial:
00596             // Transform coordinates
00597 /* 'coord' should be the native coords, while gtk is rotated
00598  * gtk.x = 768 - native.y
00599  * gtk.y = native.x
00600  *
00601  * native.x = gtk.y
00602  * native.y = 768 - gtk.x
00603  */
00604             if (fDisablePartialUpdate == 1)
00605             {
00606                 ERDMG_LOGPRINTF("Before ioctl (PARTIAL UPDATE DISABLED: FULL UPDATE INSTEAD)");
00607                 displayUpdateInfo.sequence = 0;
00608                 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00609                 gettimeofday(&tvStart, NULL);
00610 #ifdef __arm__
00611                 // if ((ret = ioctl(fbDev, FBIO_DISPLAY, NULL)))
00612                 if ((ret = ioctl(fbDev, FBIO_DISPLAY, &displayUpdateInfo)))
00613                 {
00614                     ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAY: %x", ret);
00615                 }
00616 #else
00617                 ERDMG_LOGPRINTF("(Dummy) ioctl(fbDev, FBIO_DISPLAY, NULL)");
00618 #endif
00619                 gettimeofday(&tvEnd, NULL);
00620                 timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00621                 ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00622                 sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00623             }
00624             else
00625             {
00626                 partialDisplayUpdateInfo.sequence = 0;
00627                 partialDisplayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00628 
00629                 nx1 = dmCommand.dmCmdDisplayPartial.yUp;
00630                 ny1 = SCREEN_WIDTH - dmCommand.dmCmdDisplayPartial.xUp;
00631                 nx2 = dmCommand.dmCmdDisplayPartial.yDown;
00632                 ny2 = SCREEN_WIDTH - dmCommand.dmCmdDisplayPartial.xDown;
00633 
00634                 // Have the rectangle properly defined. 
00635                 // (x1,y1) = upper left in native coordinates
00636                 // (x2,y2) = lower right in native coordinates
00637                 x1 = min(nx1, nx2);
00638                 y1 = min(ny1, ny2);
00639                 x2 = max(nx1, nx2);
00640                 y2 = max(ny1, ny2);
00641 
00642                 // Make everything a multiple of four. The rectangle should not become smaller. (Except if it is adjacent to border)
00643                 // Avoid partial redrawing adjacent to border (don't know whether we need this..)
00644                 x2 += 4;
00645                 y2 += 4;
00646 
00647                 x1 = (x1 < 4) ? 4 : (x1 - (x1 % 4));
00648                 y1 = (y1 < 4) ? 4 : (y1 - (y1 % 4));
00649                 x2 = (x2 > (SCREEN_HEIGHT - 4)) ? (SCREEN_HEIGHT - 4) : (x2 - (x2 % 4));
00650                 y2 = (y2 > (SCREEN_WIDTH - 4)) ? (SCREEN_WIDTH - 4) : (y2 - (y2 % 4));
00651 
00652                 // Here the type becomes unsigned.
00653                 coordFinal.x1 = x1;
00654                 coordFinal.y1 = y1;
00655                 coordFinal.x2 = x2;
00656                 coordFinal.y2 = y2;
00657 
00658                 partialDisplayUpdateInfo.coord = coordFinal;
00659 
00660                 ERDMG_LOGPRINTF("Before ioctl. PartialUpdate((%d,%d):(%d,%d))", coordFinal.x1, coordFinal.y1, coordFinal.x2, coordFinal.y2);
00661                 gettimeofday(&tvStart, NULL);
00662 #ifdef __arm__
00663                 // if ((ret = ioctl(fbDev, FBIO_DISPLAYPARTIAL, &coordFinal)))
00664                 if ((ret = ioctl(fbDev, FBIO_DISPLAYPARTIAL, &partialDisplayUpdateInfo)))
00665                 {
00666                     ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAYPARTIAL: %x", ret);
00667                 }
00668 #else
00669                 ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_DISPLAYPARTIAL, &coordFinal)");
00670 #endif
00671                 gettimeofday(&tvEnd, NULL);
00672                 timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00673                 ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00674                 sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00675             }
00676             break;
00677 
00678         case dmCcDump:
00679             ERDMG_ERRORPRINTF("%d not implemented.", (int) dmCommand.dmCmdGeneric.cmd);
00680             sleepTimeUSeconds = 0;
00681             break;
00682 
00683         case dmCcEraseToWhite:
00684             displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00685             displayUpdateInfo.sequence = 0;
00686             ERDMG_LOGPRINTF("erase to white");
00687 #ifdef __arm__
00688             if ((ret = ioctl(fbDev, FBIO_ERASE_WHITE, &displayUpdateInfo)))
00689             {
00690                 ERDMG_ERRORPRINTF("Error sending FBIO_ERASE_WHITE: %x", ret);
00691             }
00692 #else
00693             ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_ERASE_WHITE)");
00694 #endif
00695             sleepTimeUSeconds = 0;
00696             break;
00697 
00698         default:
00699             ;  // ignore
00700         }
00701     }
00702 
00703     return 0;
00704 }

Here is the call graph for this function:

int uploadWaveform ( int  fbDev,
char *  szFilename 
)

Definition at line 127 of file displayMgr.c.

00128 {
00129     FILE   *file = NULL;
00130     unsigned char *buffer = NULL;
00131     int     ret = 0;
00132 
00133     file = fopen(szFilename, "rb");
00134     if (!file)
00135     {
00136         ERDMG_ERRORPRINTF("Error opening file %s", szFilename);
00137         ret = -1;
00138         goto end;
00139     }
00140 
00141     buffer = (unsigned char *) malloc(WAVEFORM_SIZE);
00142     if (!buffer)
00143     {
00144         ERDMG_ERRORPRINTF("Out of memory");
00145         ret = -2;
00146         goto end;
00147     }
00148 
00149     if (fread(buffer, 1, WAVEFORM_SIZE, file) != WAVEFORM_SIZE)
00150     {
00151         ERDMG_ERRORPRINTF("Error reading file");
00152         ret = -3;
00153         goto end;
00154     }
00155 
00156     if ((ret = ioctl(fbDev, FBIO_UPLOAD_WAVEFORM, buffer)))
00157     {
00158         ERDMG_ERRORPRINTF("Error uploading waveform (err=0x%x)", ret);
00159         ret = -4;
00160         goto end;
00161     }
00162 
00163   end:
00164     if (buffer)
00165         free(buffer);
00166     if (file)
00167         fclose(file);
00168     return ret;
00169 }


Variable Documentation

Initial value:

 {
    {dmQFull,   1 * MILLION },
    {dmQBW,          100000 },
    {dmQTyping, 1 * MILLION }
}

Definition at line 110 of file displayMgr.c.


Generated on Sun Dec 14 17:14:18 2008 by  doxygen 1.5.6