tizen 2.3 release
[framework/system/deviced.git] / src / display / enhance.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <dirent.h>
24 #include <sys/types.h>
25 #include <device-node.h>
26 #include <sys/un.h>
27 #include <stdarg.h>
28 #include <vconf.h>
29 #include <vconf-keys.h>
30 #include "core.h"
31 #include "core/devices.h"
32 #include "core/log.h"
33 #include "core/common.h"
34 #include "proc/proc-handler.h"
35 #include "device-interface.h"
36
37 #define VCONFKEY_ENHANCE_MODE           "db/private/sysman/enhance_mode"
38 #define VCONFKEY_ENHANCE_SCENARIO       "db/private/sysman/enhance_scenario"
39 #define VCONFKEY_ENHANCE_TONE           "db/private/sysman/enhance_tone"
40 #define VCONFKEY_ENHANCE_OUTDOOR        "db/private/sysman/enhance_outdoor"
41 #define VCONFKEY_ENHANCE_PID            "memory/private/sysman/enhance_pid"
42
43 #ifndef VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT
44 #define VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT    "db/setting/auto_display_adjustment"
45 #endif
46
47 #define SETTING_NAME    "setting"
48 #define CLUSTER_HOME    "cluster-home"
49 #define BROWSER_NAME    "browser"
50
51 #define SIGNAL_GLOVEMODE_ON     "GloveModeOn"
52 #define SIGNAL_GLOVEMODE_OFF    "GloveModeOff"
53
54 enum lcd_enhance_type{
55         ENHANCE_MODE = 0,
56         ENHANCE_SCENARIO,
57         ENHANCE_TONE,
58         ENHANCE_OUTDOOR,
59         ENHANCE_MAX,
60 };
61
62 struct enhance_entry_t{
63         int pid;
64         int type[ENHANCE_MAX];
65 };
66
67 static Eina_List *enhance_ctl_list;
68 static struct enhance_entry_t default_enhance;
69
70 int get_glove_state(void)
71 {
72         int ret, val;
73
74         ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
75         if (ret < 0) {
76                 return ret;
77         }
78         return val;
79 }
80
81 void switch_glove_key(int val)
82 {
83         int ret, exval;
84
85         ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, &exval);
86         if (ret < 0 || exval != val) {
87                 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
88                 if (ret < 0)
89                         _E("fail to set touch key glove mode");
90                 else
91                         _D("glove key mode is %s", (val ? "on" : "off"));
92         }
93 }
94
95 static void broadcast_glove_mode(int state)
96 {
97         broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
98             (state ? SIGNAL_GLOVEMODE_ON : SIGNAL_GLOVEMODE_OFF), NULL, NULL);
99 }
100
101 static int check_default_process(int pid, char *default_name)
102 {
103         char exe_name[PATH_MAX];
104         if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
105                 _E("fail to check cmdline: %d (%s)", pid, default_name);
106                 return -EINVAL;
107         }
108         if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
109                 return -EINVAL;
110         }
111         return 0;
112 }
113
114 static void restore_enhance_status(struct enhance_entry_t *entry)
115 {
116         int ret;
117         int scenario;
118         static int pid;
119
120         if (pid == entry->pid)
121                 return;
122
123         pid = entry->pid;
124
125         ret = device_get_property(DEVICE_TYPE_DISPLAY,
126                 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO, &scenario);
127         if (ret != 0) {
128                 _E("fail to get status");
129                 return;
130         }
131         if (entry->type[ENHANCE_SCENARIO] == scenario)
132                 goto restore_enhance;
133
134         _D("clear tone and outdoor");
135         device_set_property(DEVICE_TYPE_DISPLAY,
136                 PROP_DISPLAY_IMAGE_ENHANCE_TONE, 0);
137         device_set_property(DEVICE_TYPE_DISPLAY,
138                 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR, 0);
139
140 restore_enhance:
141         _D("restore [%d:%d:%d:%d]",
142                 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
143                 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
144
145         device_set_property(DEVICE_TYPE_DISPLAY,
146                 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
147                 entry->type[ENHANCE_MODE]);
148         device_set_property(DEVICE_TYPE_DISPLAY,
149                 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
150                 entry->type[ENHANCE_SCENARIO]);
151         device_set_property(DEVICE_TYPE_DISPLAY,
152                 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
153                 entry->type[ENHANCE_TONE]);
154         device_set_property(DEVICE_TYPE_DISPLAY,
155                 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
156                 entry->type[ENHANCE_OUTDOOR]);
157 }
158
159 static int find_entry_from_enhance_ctl_list(int pid)
160 {
161         Eina_List *n;
162         Eina_List *next;
163         struct enhance_entry_t* entry;
164         char exe_name[PATH_MAX];
165
166         EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
167                 if (entry != NULL && entry->pid == pid && get_cmdline_name(entry->pid, exe_name, PATH_MAX) == 0) {
168                         _D("find enhance list");
169                         restore_enhance_status(entry);
170                         return 1;
171                 }
172         }
173         return 0;
174 }
175
176 static void remove_entry_from_enhance_ctl_list(int pid)
177 {
178         Eina_List *n;
179         Eina_List *next;
180         struct enhance_entry_t *entry;
181         char exe_name[PATH_MAX];
182
183         if (pid <= 0)
184                 return;
185
186         EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
187                 if (entry != NULL &&
188                     (get_cmdline_name(entry->pid, exe_name, PATH_MAX) != 0 || (entry->pid == pid))) {
189                         _D("remove enhance list");
190                         enhance_ctl_list = eina_list_remove(enhance_ctl_list, entry);
191                         free(entry);
192                 }
193         }
194 }
195
196 static int check_entry_to_enhance_ctl_list(int pid)
197 {
198         int oom_score_adj;
199         if (pid <= 0)
200                 return -EINVAL;
201
202         if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
203                 _E("fail to get adj value of pid: %d (%d)", pid);
204                 return -EINVAL;
205         }
206
207         switch (oom_score_adj) {
208         case OOMADJ_FOREGRD_LOCKED:
209         case OOMADJ_FOREGRD_UNLOCKED:
210                 if (!find_entry_from_enhance_ctl_list(pid))
211                         return -EINVAL;
212                 return 0;
213         case OOMADJ_BACKGRD_LOCKED:
214         case OOMADJ_BACKGRD_UNLOCKED:
215                 remove_entry_from_enhance_ctl_list(pid);
216                 return -EINVAL;
217         case OOMADJ_SU:
218                 if (check_default_process(pid, CLUSTER_HOME) != 0)
219                         return 0;
220                 return -EINVAL;
221         default:
222                 return 0;
223         }
224 }
225
226 static void update_enhance_status(struct enhance_entry_t *entry, int index)
227 {
228         char exe_name[PATH_MAX];
229         int type;
230
231         if (index == ENHANCE_MODE)
232                 type = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
233         else if (index == ENHANCE_SCENARIO)
234                 type = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
235         else if (index == ENHANCE_TONE)
236                 type = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
237         else if (index == ENHANCE_OUTDOOR)
238                 type = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
239         else {
240                 _E("abnormal type is inserted(%d)", index);
241                 return;
242         }
243
244         _I("[ENHANCE(%d)] %d", index, entry->type[index]);
245         device_set_property(DEVICE_TYPE_DISPLAY, type, entry->type[index]);
246 }
247
248 static int change_default_enhance_status(int pid, int index, int val)
249 {
250         Eina_List *n, *next;
251         struct enhance_entry_t *entry;
252         char exe_name[PATH_MAX];
253
254         if (check_default_process(pid, SETTING_NAME) != 0)
255                 return -EINVAL;
256         default_enhance.pid = pid;
257         default_enhance.type[index] = val;
258         switch (index) {
259         case ENHANCE_MODE:
260                 vconf_set_int(VCONFKEY_ENHANCE_MODE, val);
261                 EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
262                         if (!entry)
263                                 continue;
264                         entry->type[index] = default_enhance.type[index];
265                 }
266                 break;
267         case ENHANCE_SCENARIO:
268                 vconf_set_int(VCONFKEY_ENHANCE_SCENARIO, val);
269                 break;
270         case ENHANCE_TONE:
271                 vconf_set_int(VCONFKEY_ENHANCE_TONE, val);
272                 break;
273         case ENHANCE_OUTDOOR:
274                 vconf_set_int(VCONFKEY_ENHANCE_OUTDOOR, val);
275                 break;
276         default:
277                 _E("input index is abnormal value");
278                 return -EINVAL;
279         }
280         update_enhance_status(&default_enhance, index);
281         return 0;
282 }
283
284 static int add_entry_to_enhance_ctl_list(int pid, int index, int val)
285 {
286         int find_node = 0;
287         Eina_List *n, *next;
288         struct enhance_entry_t *entry;
289         struct enhance_entry_t *entry_buf;
290         int oom_score_adj;
291
292         if (pid <= 0)
293                 return -EINVAL;
294
295         EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
296                 if (entry != NULL && entry->pid == pid) {
297                         find_node = 1;
298                         break;
299                 }
300         }
301
302         entry_buf = malloc(sizeof(struct enhance_entry_t));
303         if (!entry_buf) {
304                 _E("Malloc failed");
305                 return -EINVAL;
306         }
307
308         if (find_node) {
309                 memcpy(entry_buf, entry, sizeof(struct enhance_entry_t));
310                 entry_buf->type[index] = val;
311                 remove_entry_from_enhance_ctl_list(pid);
312         } else {
313                 memset(entry_buf, 0, sizeof(struct enhance_entry_t));
314                 entry_buf->type[ENHANCE_MODE] = default_enhance.type[ENHANCE_MODE];
315                 entry_buf->pid = pid;
316                 entry_buf->type[index] = val;
317         }
318
319         enhance_ctl_list = eina_list_prepend(enhance_ctl_list, entry_buf);
320         if (!enhance_ctl_list) {
321                 _E("eina_list_prepend failed");
322                 return -EINVAL;
323         }
324
325         if (get_oom_score_adj(entry_buf->pid, &oom_score_adj) < 0) {
326                 _E("fail to get adj value of pid: %d (%d)", pid);
327                 return -EINVAL;
328         }
329         return 0;
330 }
331
332 static void enhance_control_pid_cb(keynode_t *in_key, void *data)
333 {
334         int pid;
335
336         if (vconf_get_int(VCONFKEY_ENHANCE_PID, &pid) != 0)
337                 return;
338
339         if (check_entry_to_enhance_ctl_list(pid) == 0)
340                 return;
341
342         restore_enhance_status(&default_enhance);
343 }
344
345 static void enhance_auto_control_cb(keynode_t *in_key, void *data)
346 {
347         int val;
348
349         if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) != 0) {
350                 _E("fail to get %s", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
351                 return;
352         }
353
354         _I("set auto adjust screen tone (%d)", val);
355         device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
356         device_set_property(DEVICE_TYPE_DISPLAY,
357                 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
358                 default_enhance.type[ENHANCE_MODE]);
359 }
360
361 static void init_colorblind_status(void)
362 {
363         struct color_blind_info info;
364         char *str, *it;
365         int val, cnt, cmd, ret, sum;
366         unsigned int color[9];
367
368         /* get the status if colorblind is ON or not */
369         if (vconf_get_bool(VCONFKEY_SETAPPL_COLORBLIND_STATUS_BOOL, &val) != 0)
370                 return;
371
372         if (!val) {
373                 _D("color blind status is FALSE");
374                 return;
375         }
376
377         /* get the value of color blind */
378         str = vconf_get_str(VCONFKEY_SETAPPL_COLORBLIND_LAST_RGBCMY_STR);
379         if (!str)
380                 return;
381
382         cnt = strlen(str)/4 - 1;
383         if (cnt != 8)
384                 return;
385
386         /* token the color blind value string to integer */
387         sum = 0;
388         for (it = str+cnt*4; cnt >= 0 && it; --cnt, it -= 4) {
389                 color[cnt] = strtol(it, NULL, 16);
390                 sum += color[cnt];
391                 *it = '\0';
392                 _D("color[%d] : %d", cnt, color[cnt]);
393         }
394
395         /* ignore colorblind when all of value is invalid */
396         if (!sum)
397                 return;
398
399         cnt = 0;
400         info.power = val;
401         info.RrCr = color[cnt++];
402         info.RgCg = color[cnt++];
403         info.RbCb = color[cnt++];
404         info.GrMr = color[cnt++];
405         info.GgMg = color[cnt++];
406         info.GbMb = color[cnt++];
407         info.BrYr = color[cnt++];
408         info.BgYg = color[cnt++];
409         info.BbYb = color[cnt++];
410
411         /* write to the kernel node */
412         cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
413         ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, (int)&info);
414         if (ret < 0)
415                 _E("fail to set color blind value : %d", ret);
416 }
417
418 static void reset_default_enhance_status(struct enhance_entry_t *entry)
419 {
420         _D("reset [%d:%d:%d:%d]",
421                 entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
422                 entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
423
424         device_set_property(DEVICE_TYPE_DISPLAY,
425                 PROP_DISPLAY_IMAGE_ENHANCE_MODE,
426                 entry->type[ENHANCE_MODE]);
427         device_set_property(DEVICE_TYPE_DISPLAY,
428                 PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
429                 entry->type[ENHANCE_SCENARIO]);
430         device_set_property(DEVICE_TYPE_DISPLAY,
431                 PROP_DISPLAY_IMAGE_ENHANCE_TONE,
432                 entry->type[ENHANCE_TONE]);
433         device_set_property(DEVICE_TYPE_DISPLAY,
434                 PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
435                 entry->type[ENHANCE_OUTDOOR]);
436 }
437
438 static void init_default_enhance_status(void)
439 {
440         int val;
441
442         memset(&default_enhance, 0, sizeof(struct enhance_entry_t));
443
444         if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) == 0) {
445                 _I("set auto adjust screen tone (%d)", val);
446                 device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
447         }
448
449         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT,
450                 (void *)enhance_auto_control_cb, NULL) < 0) {
451                 _E("failed to set : KEY(%s)", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
452         }
453
454         if (vconf_get_int(VCONFKEY_ENHANCE_MODE, &val) == 0 && val >= 0) {
455                 default_enhance.type[ENHANCE_MODE] = val;
456         }
457         if (vconf_get_int(VCONFKEY_ENHANCE_SCENARIO, &val) == 0 && val >= 0) {
458                 default_enhance.type[ENHANCE_SCENARIO] = val;
459         }
460         if (vconf_get_int(VCONFKEY_ENHANCE_TONE, &val) == 0 && val >= 0) {
461                 default_enhance.type[ENHANCE_TONE] = val;
462         }
463         if (vconf_get_int(VCONFKEY_ENHANCE_OUTDOOR, &val) == 0 && val >= 0) {
464                 default_enhance.type[ENHANCE_OUTDOOR] = val;
465         }
466         reset_default_enhance_status(&default_enhance);
467 }
468
469 int changed_enhance_value(int pid, int prop, int val)
470 {
471         int index;
472
473         index = prop - PROP_DISPLAY_IMAGE_ENHANCE_MODE;
474
475         if (change_default_enhance_status(pid, index, val) == 0)
476                 return 0;
477         if (add_entry_to_enhance_ctl_list(pid, index, val) == 0)
478                 return 0;
479
480         _E("fail to set enhance (p:%d,t:%d,v:%d)", pid, index, val);
481         return -EINVAL;
482 }
483
484 int set_enhance_pid(int pid)
485 {
486         return vconf_set_int(VCONFKEY_ENHANCE_PID, pid);
487 }
488
489 static DBusMessage *edbus_getenhancesupported(E_DBus_Object *obj, DBusMessage *msg)
490 {
491         DBusMessageIter iter;
492         DBusMessage *reply;
493         int cmd, val, ret;
494
495         cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_INFO, DEFAULT_DISPLAY);
496         ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
497         if (ret >= 0)
498                 ret = val;
499
500         _I("get imange enhance supported %d, %d", val, ret);
501
502         reply = dbus_message_new_method_return(msg);
503         dbus_message_iter_init_append(reply, &iter);
504         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
505         return reply;
506 }
507
508 static DBusMessage *edbus_getimageenhance(E_DBus_Object *obj, DBusMessage *msg)
509 {
510         DBusMessageIter iter;
511         DBusMessage *reply;
512         int type, prop, cmd, val, ret;
513
514         dbus_message_iter_init(msg, &iter);
515         dbus_message_iter_get_basic(&iter, &type);
516
517         _I("get image enhance type %d", type);
518
519         switch (type) {
520         case ENHANCE_MODE:
521                 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
522                 break;
523         case ENHANCE_SCENARIO:
524                 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
525                 break;
526         case ENHANCE_TONE:
527                 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
528                 break;
529         case ENHANCE_OUTDOOR:
530                 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
531                 break;
532         default:
533                 ret = -EINVAL;
534                 goto error;
535         }
536
537         cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
538         ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
539         if (ret >= 0)
540                 ret = val;
541
542 error:
543         reply = dbus_message_new_method_return(msg);
544         dbus_message_iter_init_append(reply, &iter);
545         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
546         return reply;
547 }
548
549 static DBusMessage *edbus_setimageenhance(E_DBus_Object *obj, DBusMessage *msg)
550 {
551         DBusMessageIter iter;
552         DBusMessage *reply;
553         int type, prop, cmd, val, ret;
554         pid_t pid;
555
556         ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &type, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
557         if (!ret) {
558                 _I("there is no message");
559                 ret = -EINVAL;
560                 goto error;
561         }
562
563         _I("set image enhance type %d, %d", type, val);
564
565         switch (type) {
566         case ENHANCE_MODE:
567                 prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
568                 break;
569         case ENHANCE_SCENARIO:
570                 prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
571                 break;
572         case ENHANCE_TONE:
573                 prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
574                 break;
575         case ENHANCE_OUTDOOR:
576                 prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
577                 break;
578         default:
579                 ret = -EINVAL;
580                 goto error;
581         }
582
583         cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
584         ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
585
586         /* notify to deviced with the purpose of stroing latest enhance value */
587         pid = get_edbus_sender_pid(msg);
588         changed_enhance_value(pid, prop, val);
589
590 error:
591         reply = dbus_message_new_method_return(msg);
592         dbus_message_iter_init_append(reply, &iter);
593         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
594         return reply;
595 }
596
597 static DBusMessage *edbus_getenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
598 {
599         int ret;
600         int val;
601         DBusMessageIter iter;
602         DBusMessage *reply;
603
604         ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
605         if (ret < 0) {
606                 val = -1;
607         }
608
609         reply = dbus_message_new_method_return(msg);
610         dbus_message_iter_init_append(reply, &iter);
611         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
612         return reply;
613 }
614
615 static DBusMessage *edbus_setenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
616 {
617         DBusMessageIter iter;
618         DBusMessage *reply;
619         int val, exval, ret;
620
621         ret = dbus_message_get_args(msg, NULL,
622                         DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
623         if (!ret) {
624                 _I("there is no message");
625                 ret = -EINVAL;
626                 goto error;
627         }
628
629         if (!val)
630                 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
631         if (ret < 0)
632                 _E("fail to off touch key glove mode");
633
634         ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &exval);
635         if (ret < 0 || exval != val)
636                 ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, val);
637         if (ret < 0) {
638                 _E("fail to set touch screen glove mode (%d)", val);
639                 goto error;
640         }
641         broadcast_glove_mode(val);
642
643 error:
644         reply = dbus_message_new_method_return(msg);
645         dbus_message_iter_init_append(reply, &iter);
646         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
647         return reply;
648 }
649
650 static const struct edbus_method edbus_methods[] = {
651         { "getimageenhance",  "i",   "i", edbus_getimageenhance },      /* deprecated */
652         { "setimageenhance", "ii",   "i", edbus_setimageenhance },      /* deprecated */
653         { "GetEnhanceSupported", NULL, "i", edbus_getenhancesupported },
654         { "GetImageEnhance",  "i",   "i", edbus_getimageenhance },
655         { "SetImageEnhance", "ii",   "i", edbus_setimageenhance },
656         { "GetEnhancedTouch",    NULL,   "i", edbus_getenhancedtouch },
657         { "SetEnhancedTouch",     "i",   "i", edbus_setenhancedtouch },
658 };
659
660 static void enhance_init(void *data)
661 {
662         int ret;
663
664         ret = register_edbus_method(DEVICED_PATH_DISPLAY,
665                     edbus_methods, ARRAY_SIZE(edbus_methods));
666         if (ret < 0)
667                 _E("Failed to register edbus method! %d", ret);
668
669         if (vconf_notify_key_changed(VCONFKEY_ENHANCE_PID,
670                 (void *)enhance_control_pid_cb, NULL) < 0) {
671                 _E("failed to set : KEY(%s)", VCONFKEY_ENHANCE_PID);
672         }
673
674         init_default_enhance_status();
675         init_colorblind_status();
676 }
677
678 static const struct device_ops enhance_device_ops = {
679         .priority = DEVICE_PRIORITY_NORMAL,
680         .name     = "enhance",
681         .init     = enhance_init,
682 };
683
684 DEVICE_OPS_REGISTER(&enhance_device_ops)