#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 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, | |||
| y | ) | (((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, | |||
| y | ) | (((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 struct _dmWaveforms dmWaveforms_t |
| 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 }

| 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 }
dmWaveforms_t waveforms[] [static] |
1.5.6