00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032
00033
00034 #include <glib.h>
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <fcntl.h>
00039 #include <sys/ioctl.h>
00040 #include <sys/time.h>
00041 #include <arpa/inet.h>
00042 #include <string.h>
00043
00044
00045 #include <liberipc/eripc.h>
00046 #include <liberipc/eripc_support.h>
00047 #include <liberutils/display_utils.h>
00048
00049
00050 #include "log.h"
00051 #include "delta.h"
00052 #include "system.h"
00053 #include "tasks.h"
00054 #include "xwindow.h"
00055 #include "ipc.h"
00056
00057 #define UNUSED(x) (void)(x)
00058
00059
00060
00061
00062
00063
00064
00065 #define DMPORT 50555
00066 #define LOCALHOST 0x7f000001L // "127.0.0.1"
00067
00068 #define DM_MAXCHARONLINE 1024
00069 #define DM_CMD_NAME 128
00070 #define DM_ARGLENGTH 256
00071 #define DM_N_ARG 16
00072
00073
00074
00075
00076
00077 #define WAVEFORM_QUICK 6 // WAVEFORM_1BPP_IMAGE
00078 #define WAVEFORM_PARTIAL 9 // WAVEFORM_2BPP_IMAGE
00079 #define WAVEFORM_FULL 1 // WAVEFORM_4BPP_IMAGE
00080
00081
00082 #define DELTA_TIME_FULL 900*1000
00083
00084 #define DELTA_TIME_QUICK 50*1000
00085
00086 typedef enum
00087 {
00088 DM_INFO,
00089 DM_FORCE,
00090 DM_UNDEFINED
00091 } DMCommandCode;
00092
00093 typedef struct
00094 {
00095 int pid;
00096 int x, y;
00097 int w, h;
00098 int shouldIgnore;
00099 int isWindow;
00100 int windowType;
00101 char widgetType[64];
00102 int isFocus;
00103 } DMCommandInfo;
00104
00105 typedef struct
00106 {
00107 int pid;
00108 int takeControl;
00109 int hint;
00110 } DMCommandForce;
00111
00112 typedef struct
00113 {
00114 DMCommandCode cmd;
00115 DMCommandInfo info;
00116 DMCommandForce force;
00117 } DMCommand;
00118
00119 typedef struct
00120 {
00121 char name[DM_CMD_NAME];
00122 int cc;
00123 char arg[DM_N_ARG][DM_ARGLENGTH];
00124 int nArg;
00125 } erDmCmd_t;
00126
00127
00128
00129 typedef struct display_update_info DisplayUpdateInfo;
00130 typedef struct busy_info BusyInfo;
00131
00132
00133 #define CLIENT_IS_SPLASH_WIN (1<<0)
00134 #define CLIENT_FULLSCREEN_FLAG (1<<1)
00135 #define CLIENT_TITLE_HIDDEN_FLAG (1<<2)
00136 #define CLIENT_SHRUNK_FOR_TB_FLAG (1<<3)
00137 #define CLIENT_HELP_BUTTON_FLAG (1<<4)
00138 #define CLIENT_ACCEPT_BUTTON_FLAG (1<<5)
00139 #define CLIENT_DOCK_NORTH (1<<6)
00140 #define CLIENT_DOCK_SOUTH (1<<7)
00141 #define CLIENT_DOCK_EAST (1<<8)
00142 #define CLIENT_DOCK_WEST (1<<9)
00143 #define CLIENT_WANTS_MASK_FLAG (1<<10)
00144 #define CLIENT_IS_MODAL_FLAG (1<<11)
00145 #define CLIENT_BORDERS_ONLY_FLAG (1<<12)
00146 #define CLIENT_IS_MESSAGE_DIALOG (1<<14)
00147 #define CLIENT_IS_DESKTOP_FLAG (1<<15)
00148 #define CLIENT_NEW_FOR_DESKTOP (1<<16)
00149 #define CLIENT_DOCK_TITLEBAR (1<<17)
00150 #define CLIENT_CUSTOM_BUTTON_FLAG (1<<18)
00151 #define CLIENT_IS_MOVING (1<<19)
00152 #define CLIENT_DOCK_TITLEBAR_SHOW_ON_DESKTOP (1<<20)
00153 #define CLIENT_NO_FOCUS_ON_MAP (1<<21)
00154 #define CLIENT_IS_MINIMIZED (1<<23)
00155 #define CLIENT_TOOLBARS_MOVED_FOR_FULLSCREEN (1<<24)
00156 #define CLIENT_IS_TRANSIENT_FOR_ROOT (1<<25)
00157 #define CLIENT_HAS_URGENCY_FLAG (1<<26)
00158 #define CLIENT_HAS_ABOVE_STATE (1<<27)
00159 #define CLIENT_IS_MENU_DIALOG (1<<30)
00160 #define CLIENT_DELAY_MAPPING (1<<31)
00161
00162
00163 typedef enum
00164 {
00165 MBCLIENT_TYPE_DIALOG = (1<<1),
00166 MBCLIENT_TYPE_TOOLBAR = (1<<2),
00167 MBCLIENT_TYPE_PANEL = (1<<3),
00168 MBCLIENT_TYPE_TASK_MENU = (1<<4),
00169 MBCLIENT_TYPE_APP = (1<<5),
00170 MBCLIENT_TYPE_DESKTOP = (1<<6),
00171 MBCLIENT_TYPE_OVERRIDE = (1<<7),
00172 MBCLIENT_TYPE_ANY = (1<<8)
00173 } MBClientTypeEnum;
00174
00175
00176
00177
00178
00179
00180 #define N_FILENAME 1024
00181 #define BUFFERSIZE 1024
00182 #define BUSY_ANIMATION_SPEED 50
00183
00184 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00185 #define UPDATE_TIMEOUT_NORMAL_PORTRAIT 300
00186 #define UPDATE_TIMEOUT_NORMAL_LANDSCAPE 600
00187 #define UPDATE_TIMEOUT_KEY 24
00188 #define UPDATE_TIMEOUT_CURSOR 60
00189 #define UPDATE_TIMEOUT_TYPE 60
00190 #define UPDATE_TIMEOUT_SCRIBBLE 150
00191 #define UPDATE_AREA_CONTENT 744*806
00192 #define UPDATE_AREA_FULL 768*1024
00193 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00194 #define UPDATE_TIMEOUT_NORMAL_PORTRAIT 450
00195 #define UPDATE_TIMEOUT_NORMAL_LANDSCAPE 900
00196 #define UPDATE_TIMEOUT_KEY 40
00197 #define UPDATE_TIMEOUT_CURSOR 100
00198 #define UPDATE_TIMEOUT_TYPE 100
00199 #define UPDATE_TIMEOUT_SCRIBBLE 250
00200 #define UPDATE_AREA_CONTENT 1000*1010
00201 #define UPDATE_AREA_FULL 1024*1280
00202 #else
00203 #error Unhandled machine type
00204 #endif
00205
00206
00207
00208
00209
00210
00211 static int fbDev = 0;
00212 static int useSpecialWaveform = 0;
00213 static guint g_timeout = 0;
00214 static DMCommand DisplayCommand;
00215 static uint64_t deltaAvailableAgain = 0;
00216 static GSList *g_ignorelist = NULL;
00217
00218 static gboolean g_display_locked = FALSE;
00219
00220
00221 static gboolean locked_display (void) { return g_display_locked; }
00222 static void lock_display (void) { g_display_locked = TRUE; }
00223 static void unlock_display (void) { g_display_locked = FALSE; }
00224
00225
00226 static gint delta_update_display(DisplayUpdateInfo *displayUpdateInfo)
00227 {
00228
00229
00230 int ret = ioctl(fbDev, FBIO_DELTA_UPDATE_DISPLAY, displayUpdateInfo);
00231 if (ret != 0)
00232 {
00233 ERRORPRINTF("Error sending FBIO_DELTA_UPDATE_DISPLAY: %x", ret);
00234 }
00235 return ret;
00236 }
00237
00238
00239 static void display_update(gint waveform)
00240 {
00241 DisplayUpdateInfo displayUpdateInfo;
00242
00243 displayUpdateInfo.color = 0;
00244 displayUpdateInfo.waveform = waveform;
00245
00246 #if DMLOGGING_ON
00247 GTimeVal curtime;
00248 g_get_current_time(&curtime);
00249
00250 DMPPRINTF("\n\n%ld:%3ld update waveform %d\n",
00251 curtime.tv_sec, curtime.tv_usec / 1000,
00252 displayUpdateInfo.waveform);
00253 #endif
00254
00255
00256 delta_update_display(&displayUpdateInfo);
00257
00258
00259
00260 }
00261
00262 static void get_arguments(char *pChar, erDmCmd_t * pCmd, int nReqArgs)
00263 {
00264 int nArg;
00265 int i;
00266 char szToken[DM_MAXCHARONLINE];
00267
00268 for (nArg = 0; nArg < nReqArgs; nArg++)
00269 {
00270 i = 0;
00271 while (*pChar != '\0')
00272 {
00273 szToken[i] = '\0';
00274 if (*pChar == ',')
00275 {
00276 pChar++;
00277 break;
00278 }
00279 szToken[i] = *pChar++;
00280 i++;
00281 szToken[i] = '\0';
00282 }
00283 strcpy(pCmd->arg[nArg], szToken);
00284 }
00285 }
00286
00287 static gint parse_message(char *szCommand, erDmCmd_t * pCmd)
00288 {
00289 LOGPRINTF("entry");
00290
00291 int i;
00292 char *pChar;
00293 char szToken[DM_MAXCHARONLINE];
00294
00295 pCmd->cc = (int) DM_UNDEFINED;
00296 for (i = 0; i < DM_N_ARG; i++)
00297 {
00298 strcpy(pCmd->arg[i], "");
00299 }
00300
00301
00302 if (szCommand[0] != '!')
00303 {
00304 ERRORPRINTF("Command should start with \'!\'. (%s)", szCommand);
00305 return -1;
00306 }
00307
00308
00309 pChar = szCommand + 1;
00310 i = 0;
00311 while (*pChar != '\0')
00312 {
00313 szToken[i] = '\0';
00314 if (*pChar == ',')
00315 {
00316 pChar++;
00317 break;
00318 }
00319 szToken[i] = *pChar++;
00320 i++;
00321 szToken[i] = '\0';
00322 }
00323
00324
00325 if (!strcmp(szToken, "I"))
00326 {
00327 strcpy(pCmd->name, szToken);
00328 pCmd->cc = DM_INFO;
00329 pCmd->nArg = 10;
00330 }
00331 else if (!strcmp(szToken, "F"))
00332 {
00333 strcpy(pCmd->name, szToken);
00334 pCmd->cc = DM_FORCE;
00335 pCmd->nArg = 3;
00336 }
00337 else
00338 {
00339 return -1;
00340 }
00341
00342 if (pCmd->nArg > 0)
00343 {
00344 get_arguments(pChar, pCmd, pCmd->nArg);
00345 }
00346 return 0;
00347 }
00348
00349
00350 static uint64_t getCurrentTime()
00351 {
00352 struct timespec now;
00353
00354 clock_gettime(CLOCK_MONOTONIC, &now);
00355 u_int64_t now64 = now.tv_sec;
00356 now64 *= 1000000;
00357 now64 += (now.tv_nsec/1000);
00358 return now64;
00359 }
00360
00361 static gint parse_command(erDmCmd_t *pCmd, DMCommand *command)
00362 {
00363 switch (pCmd->cc)
00364 {
00365 case DM_INFO:
00366 command->cmd = DM_INFO;
00367 command->info.pid = atoi(pCmd->arg[0]);
00368 command->info.x = atoi(pCmd->arg[1]);
00369 command->info.y = atoi(pCmd->arg[2]);
00370 command->info.w = atoi(pCmd->arg[3]);
00371 command->info.h = atoi(pCmd->arg[4]);
00372 command->info.shouldIgnore = atoi(pCmd->arg[5]);
00373 command->info.isWindow = atoi(pCmd->arg[6]);
00374 command->info.windowType = atoi(pCmd->arg[7]);
00375 strcpy(command->info.widgetType,pCmd->arg[8]);
00376 command->info.isFocus = atoi(pCmd->arg[9]);
00377 break;
00378
00379 case DM_FORCE:
00380 command->cmd = DM_FORCE;
00381 command->force.pid = atoi(pCmd->arg[0]);
00382 command->force.takeControl = atoi(pCmd->arg[1]);
00383 command->force.hint = atoi(pCmd->arg[2]);
00384 break;
00385
00386 default:
00387 ERRORPRINTF("Undefined command");
00388 return -1;
00389 break;
00390 }
00391 return 0;
00392 }
00393
00394 static gboolean on_message_timeout(gpointer data)
00395 {
00396 LOGPRINTF("entry");
00397
00398 gint waveform = WAVEFORM_FULL;
00399
00400 if (useSpecialWaveform != 0)
00401 {
00402 waveform = useSpecialWaveform;
00403 }
00404
00405
00406 deltaAvailableAgain = getCurrentTime();
00407 if ((waveform == WAVEFORM_FULL) || (waveform == WAVEFORM_PARTIAL))
00408 {
00409 deltaAvailableAgain += DELTA_TIME_FULL;
00410 }
00411 else if (waveform == WAVEFORM_QUICK)
00412 {
00413 deltaAvailableAgain += DELTA_TIME_QUICK;
00414 }
00415
00416
00417 bzero(&DisplayCommand, sizeof(DMCommand));
00418 useSpecialWaveform = 0;
00419
00420
00421 display_update(waveform);
00422
00423
00424 return FALSE;
00425 }
00426
00427
00428 static gboolean ignore_pid(gint pid)
00429 {
00430
00431 return (g_slist_length(g_ignorelist) > 0);
00432 }
00433
00434
00435 static void ignore_pid_add(gint pid)
00436 {
00437 LOGPRINTF("entry [%d]", pid);
00438
00439 GSList *found = g_slist_find(g_ignorelist, (gconstpointer) pid);
00440 if (found == NULL)
00441 {
00442 LOGPRINTF("added [%d]", pid);
00443 g_ignorelist = g_slist_prepend(g_ignorelist, (gpointer) pid);
00444 }
00445 }
00446
00447
00448 static void ignore_pid_remove(gint pid)
00449 {
00450 LOGPRINTF("entry [%d]", pid);
00451 g_ignorelist = g_slist_remove(g_ignorelist, (gpointer) pid);
00452 }
00453
00454 static void schedule_update(gint delay, const char *rule)
00455 {
00456
00457 uint64_t now = getCurrentTime();
00458 #if DMLOGGING_ON
00459 guint prev_delay = delay;
00460 #endif
00461
00462
00463 if (((deltaAvailableAgain != 0) && ((now + delay*1000) < deltaAvailableAgain))
00464 && ((deltaAvailableAgain - DELTA_TIME_FULL) < now))
00465 {
00466 delay = (deltaAvailableAgain - now) / 1000;
00467 }
00468
00469
00470 if (g_timeout > 0) {
00471 DMPPRINTF("cancel t/o [%d]", g_timeout);
00472 g_source_remove(g_timeout);
00473 g_timeout= 0;
00474 }
00475 g_timeout = g_timeout_add(delay, on_message_timeout, NULL);
00476
00477 DMPPRINTF("set delay %d [was %d] (rule: %s) t/o [%d]", delay, prev_delay, rule, g_timeout);
00478 }
00479
00480
00481
00482 static void promote_waveform(gint waveform)
00483 {
00484 if (useSpecialWaveform == waveform)
00485 return;
00486
00487 switch (waveform)
00488 {
00489 case WAVEFORM_QUICK:
00490 if (useSpecialWaveform == 0)
00491 {
00492 useSpecialWaveform = waveform;
00493 }
00494 break;
00495
00496 case WAVEFORM_PARTIAL:
00497 if ((useSpecialWaveform == 0) || (useSpecialWaveform == WAVEFORM_QUICK))
00498 {
00499 useSpecialWaveform = waveform;
00500 }
00501 break;
00502
00503 case WAVEFORM_FULL:
00504 default:
00505 useSpecialWaveform = waveform;
00506 break;
00507 }
00508 }
00509
00510
00511
00512 static gint delta_vcom_set(gfloat vcom)
00513 {
00514 LOGPRINTF("entry");
00515
00516 glong vcom_int = 0;
00517 gint ret = 0;
00518
00519 if(vcom < -5)
00520 {
00521 vcom = -5;
00522 }
00523 else if(vcom > 5)
00524 {
00525 vcom = 5;
00526 }
00527
00528 vcom_int = (signed long)(1000 * vcom);
00529
00530 if ((ret=ioctl(fbDev, FBIO_DETA_VCOM_SET, &vcom_int)))
00531 {
00532 ERRORPRINTF("Error sending FBIO_DETA_VCOM_SET: %x",ret);
00533 }
00534
00535 return ret;
00536 }
00537
00538
00539 static void parse_gtk_messages(char* buffer)
00540 {
00541 #if DMLOGGING_ON
00542 GTimeVal oldtime = {0};
00543 #endif
00544 DMCommand command;
00545 erDmCmd_t cmd;
00546
00547 LOGPRINTF("entry");
00548
00549 bzero(&command, sizeof(command));
00550
00551 if ((parse_message(buffer, &cmd)==0) && (parse_command(&cmd, &command) == 0))
00552 {
00553 #if DMLOGGING_ON
00554 GTimeVal curtime;
00555 g_get_current_time(&curtime);
00556
00557 guint timediff = ((curtime.tv_sec - oldtime.tv_sec) * 1000) +
00558 ((curtime.tv_usec / 1000 ) - (oldtime.tv_usec / 1000));
00559 #endif
00560
00561 if (command.cmd == DM_FORCE)
00562 {
00563 DMCommandForce force = command.force;
00564
00565 DMPPRINTF("%ld:%3ld [%4d] checking msg: %d, %d, %d",
00566 curtime.tv_sec, curtime.tv_usec / 1000, timediff,
00567 force.pid, force.takeControl, force.hint);
00568
00569 if (force.takeControl > 0)
00570 {
00571 DMPPRINTF(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
00572 ignore_pid_add(force.pid);
00573 if (!locked_display())
00574 {
00575 DMPPRINTF("cancel pending update");
00576
00577 bzero(&DisplayCommand, sizeof(DMCommand));
00578 if (g_timeout > 0)
00579 {
00580 g_source_remove(g_timeout);
00581 g_timeout = 0;
00582 }
00583 }
00584 }
00585 else
00586 {
00587 DMPPRINTF("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
00588 ignore_pid_remove(force.pid);
00589 }
00590
00591 if (force.hint != DM_HINT_NONE)
00592 {
00593 gint update_delay = 50;
00594 switch (force.hint)
00595 {
00596 case DM_HINT_LOCK:
00597 lock_display();
00598 break;
00599 case DM_HINT_UNLOCK:
00600 unlock_display();
00601 break;
00602 case DM_HINT_FULL:
00603 useSpecialWaveform = WAVEFORM_FULL;
00604 break;
00605 case DM_HINT_SPLASH:
00606 update_delay = UPDATE_TIMEOUT_NORMAL_PORTRAIT;
00607 useSpecialWaveform = WAVEFORM_FULL;
00608 break;
00609 case DM_HINT_CURSOR:
00610 useSpecialWaveform = WAVEFORM_QUICK;
00611 break;
00612 case DM_HINT_PARTIAL:
00613 useSpecialWaveform = WAVEFORM_PARTIAL;
00614 break;
00615 case DM_HINT_KEY:
00616 update_delay = 20;
00617 useSpecialWaveform = WAVEFORM_QUICK;
00618 break;
00619 default:
00620 WARNPRINTF("unsupported display manager hint [%d]", force.hint);
00621 useSpecialWaveform = WAVEFORM_FULL;
00622 break;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 if ( !locked_display() || (force.hint == DM_HINT_SPLASH) )
00654 {
00655 schedule_update(update_delay, "forced by application");
00656 }
00657 }
00658 }
00659 else if (command.cmd == DM_INFO)
00660 {
00661 DMCommandInfo info = command.info;
00662 const gchar *rule = NULL;
00663 gboolean save = FALSE;
00664 gboolean trigger = FALSE;
00665 gboolean skip = FALSE;
00666 guint area_pending = DisplayCommand.info.w * DisplayCommand.info.h;
00667 gboolean is_portait = TRUE;
00668
00669 gboolean is_pending = (area_pending > 0) ? TRUE : FALSE;
00670 guint delay = is_portait ? UPDATE_TIMEOUT_NORMAL_PORTRAIT : UPDATE_TIMEOUT_NORMAL_LANDSCAPE;
00671 guint area = info.w * info.h;
00672
00673 if ((info.pid != -1) && ignore_pid(info.pid) &&
00674 (strcmp(info.widgetType,"erGtkBusyDialog") != 0) && (strcmp(info.widgetType,"GtkMessageDialog") != 0))
00675 {
00676
00677 skip = TRUE;
00678 }
00679
00680 DMPPRINTF("%ld:%3ld [%4d] %s pid [%d] %4dx%4d flags: i[%d] w[%d] t[%d] f[%d] %s",
00681 curtime.tv_sec, curtime.tv_usec / 1000, timediff, skip ? "SKIPPED" : "checking",
00682 info.pid, info.w, info.h, info.shouldIgnore,
00683 info.isWindow, info.windowType, info.isFocus,
00684 info.widgetType);
00685
00686
00687
00688
00689
00690 if (!is_pending && info.h == 32 &&
00691 strcmp(info.widgetType, "GtkEventBox") == 0)
00692 {
00693 rule = "statusbar";
00694 promote_waveform(WAVEFORM_PARTIAL);
00695 save = TRUE;
00696 }
00697
00698 if (!is_pending && strcmp(info.widgetType,"GtkEntry")==0)
00699 {
00700 rule = "keyboard entry";
00701 promote_waveform( WAVEFORM_QUICK);
00702 delay = UPDATE_TIMEOUT_TYPE;
00703 save = TRUE;
00704 }
00705
00706
00707
00708
00709
00710 if (!info.shouldIgnore ||
00711 (strcmp(info.widgetType,"HtmlView") == 0) ||
00712 (strcmp(info.widgetType,"GtkDrawingArea") == 0) ||
00713 (strcmp(info.widgetType,"GtkCalendar") == 0) ||
00714 (strcmp(info.widgetType,"GtkTreeView") == 0) ||
00715 (strcmp(info.widgetType,"GtkIconView") == 0) ||
00716 (strcmp(info.widgetType,"erGtkIconView") == 0) ||
00717 (strcmp(info.widgetType,"erGtkListView") == 0) ||
00718 (strcmp(info.widgetType,"erGtkNetworkList") == 0) ||
00719 (strcmp(info.widgetType,"WebKitWebView") == 0) ||
00720 (strcmp(info.widgetType,"GtkMenu") == 0) ||
00721 (strcmp(info.widgetType,"GtkProgressBar") == 0) )
00722 {
00723 if (!is_pending &&
00724 info.isFocus &&
00725 (area<UPDATE_AREA_CONTENT) &&
00726 ((strcmp(info.widgetType, "erGtkIconView") == 0) ||
00727 (strcmp(info.widgetType, "erGtkNetworkList") == 0) ||
00728 (strcmp(info.widgetType, "erGtkListView") == 0)) )
00729 {
00730 rule = "cursor";
00731 promote_waveform(WAVEFORM_QUICK);
00732 delay = is_portait ? UPDATE_TIMEOUT_CURSOR : 3*UPDATE_TIMEOUT_CURSOR;
00733 save = TRUE;
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 else if (area > area_pending)
00754 {
00755 if ((area * 3) < UPDATE_AREA_FULL)
00756 {
00757 promote_waveform(WAVEFORM_PARTIAL);
00758 rule = "paint, partial";
00759 }
00760 else
00761 {
00762 promote_waveform(WAVEFORM_FULL);
00763 rule = "paint, full";
00764
00765 if (is_portait && strcmp(info.widgetType,"GtkDrawingArea") == 0)
00766 {
00767 rule = "paint, full (UDS)";
00768 delay /= 2;
00769 }
00770 }
00771 save = TRUE;
00772 }
00773 else if (is_pending)
00774 {
00775 if (is_portait && strcmp(info.widgetType,"erGtkIconView") == 0)
00776 {
00777 delay /= 2;
00778 }
00779 rule = "delay";
00780 trigger = TRUE;
00781 }
00782 }
00783
00784
00785
00786
00787
00788 if (!is_pending && info.h == 29 &&
00789 ((strcmp(info.widgetType,"GtkMessageDialog")==0) ||
00790 (strcmp(info.widgetType,"GtkDialog")==0)))
00791 {
00792 rule = "button cursor";
00793 useSpecialWaveform = WAVEFORM_QUICK;
00794 delay = is_portait ? UPDATE_TIMEOUT_CURSOR : 2*UPDATE_TIMEOUT_CURSOR;
00795 save = TRUE;
00796 }
00797
00798 if (!is_pending && strcmp(info.widgetType,"erscribble")==0)
00799 {
00800 rule = "scribble";
00801 useSpecialWaveform = WAVEFORM_PARTIAL;
00802 delay = UPDATE_TIMEOUT_SCRIBBLE;
00803 save = TRUE;
00804 }
00805
00806
00807 if (is_pending &&
00808 (useSpecialWaveform != WAVEFORM_FULL) &&
00809 ( (strcmp(info.widgetType, "WebKitWebView")==0) ||
00810 (strcmp(info.widgetType, "GtkEntry")==0) ) )
00811 {
00812 rule = "entry speedup";
00813 save = FALSE;
00814 delay /= 2;
00815 trigger = FALSE;
00816 }
00817
00818
00819
00820
00821
00822 if (save)
00823 {
00824 DMPPRINTF("%ld:%3ld save area %d (rule: %s)", curtime.tv_sec, curtime.tv_usec / 1000, area, rule);
00825
00826 memcpy(&DisplayCommand, &command, sizeof(DMCommand));
00827 trigger = TRUE;
00828 }
00829
00830 if (trigger && !skip)
00831 {
00832 schedule_update(delay, rule);
00833 }
00834 }
00835 #if DMLOGGING_ON
00836 memcpy(&oldtime, &curtime, sizeof(GTimeVal));
00837 #endif
00838 }
00839 }
00840
00841
00842
00843 gboolean handle_gtk_socket(GIOChannel* source, GIOCondition condition, gpointer data)
00844 {
00845 UNUSED(data);
00846
00847 LOGPRINTF("entry");
00848
00849 if (condition != G_IO_IN) {
00850 WARNPRINTF("%s() UNKNOWN CONDITION (%d)", __func__, condition);
00851 return FALSE;
00852 }
00853
00854 gchar *buffer = NULL;
00855 gsize last_byte = 0;
00856 gsize bytes_read = 0;
00857 GError *error = NULL;
00858 g_io_channel_read_line(source, &buffer, &bytes_read, &last_byte, &error);
00859 buffer[last_byte] = '\0';
00860 if (error) {
00861 WARNPRINTF("GTK socket read failed: %s", error->message);
00862 g_error_free(error);
00863 } else {
00864 parse_gtk_messages(buffer);
00865 }
00866 g_free(buffer);
00867 return TRUE;
00868 }
00869
00870
00871 int main(int argc, char *argv[])
00872 {
00873 GMainLoop* gloop;
00874 g_type_init();
00875 gloop = g_main_loop_new(NULL, FALSE);
00876
00877
00878 fbDev = open("/dev/fb0", O_RDWR);
00879 if (fbDev == -1)
00880 {
00881 ERRORPRINTF("Cannot open framebufferdevice. # mknod /dev/fb0 c 29 0");
00882 return 0;
00883 }
00884
00885
00886 int sockfd = socket(PF_INET, SOCK_DGRAM, 0);
00887 if (sockfd == -1) {
00888 perror("Error invoking socket");
00889 return 0;
00890 }
00891 struct sockaddr_in server_addr;
00892 bzero(&server_addr, sizeof(struct sockaddr_in));
00893 server_addr.sin_family = AF_INET;
00894 server_addr.sin_port = htons(DMPORT);
00895 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00896 memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
00897
00898 int error = bind(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr));
00899 if (error) {
00900 perror("Error invoking bind");
00901 return 0;
00902 }
00903 GIOChannel* channel = g_io_channel_unix_new(sockfd);
00904 g_io_channel_set_encoding(channel, NULL, NULL);
00905 g_io_add_watch(channel, G_IO_IN|G_IO_PRI|G_IO_ERR, handle_gtk_socket, NULL);
00906
00907
00908 delta_vcom_set(-2.7);
00909
00910
00911 LOGPRINTF("before g_main_loop_run");
00912 g_main_loop_run(gloop);
00913 LOGPRINTF("after g_main_loop_run");
00914
00915 return 0;
00916 }
00917