Initialize Tizen 2.3
[apps/home/mobileprint.git] / mobileprint / app / mobileprint.c
1 /*
2 *       Mobileprint
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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
22 #include <app.h>
23 #include <ui-gadget.h>
24 #include <Ecore_X.h>
25 #include <utilX.h>
26 #include <X11/Xatom.h>
27 #include <X11/Xutil.h>
28 #include <utilX.h>
29 #include "mobileprint.h"
30 #include "pts_main_view.h"
31
32 #define _GNU_SOURCE
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <linux/unistd.h>
37 #include <errno.h>
38
39 /*Global variable */
40 pts_appdata_t g_mobile_print_app_data;
41
42 pts_appdata_t *pts_get_appdata()
43 {
44         return &g_mobile_print_app_data;
45 }
46
47 /*
48 * delete the main window
49 */
50 static void _win_del(void *data, Evas_Object *obj, void *event)
51 {
52         PTS_TRACE_BEGIN;
53         app_efl_exit();
54         PTS_TRACE_END;
55 }
56
57 /*
58 * the response callback when quit the main function
59 */
60 void main_quit_cb(void *data, Evas_Object *obj,
61                                   const char *emission, const char *source)
62 {
63         PTS_TRACE_BEGIN;
64         app_efl_exit();
65         PTS_TRACE_END;
66 }
67
68 /*
69 * create the main window
70 */
71 static Evas_Object *_create_win(const char *name)
72 {
73         PTS_TRACE_BEGIN;
74         PTS_RETV_IF(name == NULL, NULL, "name is NULL");
75
76         Evas_Object *eo = NULL;
77         int w = 0;
78         int h = 0;
79
80         const int rots[4] = { APP_DEVICE_ORIENTATION_0,
81                         APP_DEVICE_ORIENTATION_90,
82                         APP_DEVICE_ORIENTATION_180,
83                         APP_DEVICE_ORIENTATION_270 };
84
85         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
86         PTS_RETV_IF(eo == NULL, NULL, "Failed to elm_win_add");
87
88         elm_win_autodel_set(eo, EINA_TRUE);
89         elm_win_title_set(eo, name);
90
91         elm_win_borderless_set(eo, EINA_TRUE);
92         elm_win_indicator_mode_set(eo, ELM_WIN_INDICATOR_SHOW);
93
94         elm_win_alpha_set(eo, EINA_TRUE);
95         elm_win_conformant_set(eo, EINA_TRUE);
96         evas_object_smart_callback_add(eo, "delete,request", _win_del, NULL);
97
98         ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
99         evas_object_resize(eo, w, h);
100
101         /* Register a list of rotation angles that mobileprint supports */
102         if (elm_win_wm_rotation_supported_get(eo))
103                 elm_win_wm_rotation_available_rotations_set(
104                                 eo, rots, 4);
105
106         PTS_TRACE_END;
107         return eo;
108 }
109
110 /*
111 * callback function for device rotation
112 */
113 static void _rot_changed_cb(void *data, Evas_Object *obj, void *event)
114 {
115         pts_appdata_t *ad = (pts_appdata_t*)data;
116         int rot;
117
118         PTS_TRACE_BEGIN;
119
120         rot = elm_win_rotation_get(ad->win);
121
122
123         if (NULL != ad->list_info.active_printer) {
124                 if (NULL != ad->size_popup_info.size_popup) {
125                         PTS_DEBUG("Found size popup. Let's resize it");
126                         if (rot == APP_DEVICE_ORIENTATION_0
127                                         || rot == APP_DEVICE_ORIENTATION_180)
128                                 evas_object_size_hint_min_set(
129                                         ad->size_popup_info.size_popup_box,
130                                         400 * elm_config_scale_get(),
131                                         ad->size_popup_info
132                                                 .size_popup_portrait_height);
133                         else
134                                 evas_object_size_hint_min_set(
135                                         ad->size_popup_info.size_popup_box,
136                                         400 * elm_config_scale_get(),
137                                         ad->size_popup_info
138                                                 .size_popup_landscape_height);
139                 }
140                 else if (NULL != ad->size_popup_info.custom_popup) {
141                         PTS_DEBUG("Found custom popup. Let's resize It");
142                         if (rot == APP_DEVICE_ORIENTATION_0
143                                         || rot == APP_DEVICE_ORIENTATION_180)
144                                 evas_object_size_hint_min_set(
145                                         ad->size_popup_info.custom_popup_box,
146                                         400 * elm_config_scale_get(),
147                                         ad->size_popup_info
148                                                 .custom_popup_portrait_height);
149                         else
150                                 evas_object_size_hint_min_set(
151                                         ad->size_popup_info.custom_popup_box,
152                                         400 * elm_config_scale_get(),
153                                         ad->size_popup_info
154                                                 .custom_popup_landscape_height);
155                 }
156         }
157         else if (NULL != ad->list_info.printer_list_popup) {
158                 PTS_DEBUG("Found printer list popup. Let's resize it");
159                 if (rot == APP_DEVICE_ORIENTATION_0
160                                 || rot == APP_DEVICE_ORIENTATION_180)
161                         evas_object_size_hint_min_set(
162                                 ad->list_info.printer_list_popup_box,
163                                 PRINTER_LIST_POPUP_W * elm_config_scale_get(),
164                                 ad->list_info
165                                         .printer_list_popup_portrait_height);
166                 else
167                         evas_object_size_hint_min_set(
168                                 ad->list_info.printer_list_popup_box,
169                                 PRINTER_LIST_POPUP_LN_W
170                                         * elm_config_scale_get(),
171                                 ad->list_info
172                                         .printer_list_popup_landscape_height);
173         }
174
175         PTS_TRACE_END;
176 }
177
178 /*
179 * this callback function is called
180 * at the start of the application.
181 */
182 static bool _app_create(void *user_data)
183 {
184         PTS_TRACE_BEGIN;
185         PTS_RETV_IF(user_data == NULL, false, "user_data is NULL");
186
187         pts_appdata_t *ad = (pts_appdata_t *)user_data;
188         char *name = NULL;
189
190         /* create window */
191         app_get_name(&name);
192         ad->win = _create_win(name);
193         PTS_RETV_IF(ad->win == NULL, false, "ad->win is NULL");
194
195         evas_object_smart_callback_add(ad->win, "wm,rotation,changed",
196                         _rot_changed_cb, ad);
197
198         UG_INIT_EFL(ad->win, UG_OPT_INDICATOR_ENABLE);
199
200         PTS_IF_FREE_MEM(name);
201
202         PTS_TRACE_END;
203         return true;
204 }
205
206 /*
207 * this callback function is called once after
208 * the main loop of application exits.
209 */
210 static void _app_terminate(void *user_data)
211 {
212         PTS_TRACE_BEGIN;
213 #if 0
214         pts_appdata_t *ad = (pts_appdata_t *)user_data;
215
216         PTS_RET_IF(ad == NULL, "data is NULL");
217
218         if (ad->ugd->main_layout) {
219                 PTS_DEBUG("ad->lymain is not NULL");
220                 //evas_object_del(ad->ugd->main_layout);
221         }
222
223         if (ad->win) {
224                 PTS_DEBUG("ad->lymain is not NULL");
225                 //evas_object_del(ad->ugd->root_win);
226         }
227 #endif
228
229         pts_util_remove_tmp_files("/tmp/mobileprint/");
230
231         PTS_TRACE_END;
232 }
233
234 /*
235 * this callback function is called each time the application
236 * is completely obscured by another application and becomes
237 * invisible to the user.
238 */
239 static void _app_pause(void *user_data)
240 {
241         PTS_TRACE_BEGIN;
242         pts_appdata_t *ad = (pts_appdata_t *)user_data;
243         PTS_RET_IF(ad == NULL,"ad is NULL");
244         if (ad->noti_info.job_spooling_list == NULL && ad->noti_info.dummy_noti_id == 0) {
245                 PTS_DEBUG("Without active job spooling, mobileprint will terminate when moved background.");
246                 app_efl_exit();
247         } else {
248                 PTS_DEBUG("Active job spooling list is existed. So don't terminate mobileprint.");
249         }
250         PTS_TRACE_END;
251 }
252
253 /*
254 * this callback function is called each time the application
255 * becomes visible to the user.
256 */
257 static void _app_resume(void *user_data)
258 {
259         PTS_TRACE_BEGIN;
260         PTS_TRACE_END;
261 }
262
263 static Eina_Bool _simple_exit(void *data)
264 {
265         PTS_TRACE_BEGIN;
266         elm_exit();
267         PTS_TRACE_END;
268         return ECORE_CALLBACK_CANCEL;
269 }
270
271 void load_main_view(void *userdata)
272 {
273         PTS_TRACE_BEGIN;
274
275         pts_appdata_t *ad = pts_get_appdata();
276         //pts_core_data_t *ugd  = ad->ugd;
277
278         // XXX - show main view after set active/default printer
279         pts_create_main_view(ad);
280         // XXX - disable to fix blink problem
281         //elm_win_resize_object_add(ugd->root_win, ugd->main_layout);
282         edje_object_signal_callback_add(elm_layout_edje_get(ad->main_info.main_layout),
283                                                                         "EXIT", "*", main_quit_cb, NULL);
284
285         pts_main_view_update_printer_label(ad);
286         pts_main_view_rotate_image(ad, app_get_device_orientation());
287
288         evas_object_show(ad->main_info.main_layout);
289         evas_object_show(ad->main_info.root_win);
290         PTS_TRACE_END;
291 }
292
293 /*
294 * load the app
295 */
296 static void __app_load_data(pts_appdata_t *ad, pts_printing_data_t *pt_files)
297 {
298         PTS_TRACE_BEGIN;
299         PTS_RET_IF(ad == NULL, "ad is NULL");
300         PTS_RET_IF(ad->win == NULL, "ad->win is NULL");
301         PTS_RET_IF(pt_files == NULL, "pt_files is NULL");
302
303         int ret;
304         if (pts_util_supported_arch() != EINA_TRUE) {
305                 pts_util_show_error_popup(ad->win, _("IDS_COM_POP_UNSUPPORTED"));
306                 ecore_timer_add(1, (Ecore_Task_Cb)_simple_exit, (void *)ad);
307                 return;
308         }
309
310         if (ad->main_info.root_win == NULL) {
311                 ad->main_info.root_win = ad->win;
312         }
313
314         ret = pt_init(__pts_event_cb, ad);
315         PTS_RET_IF(ret != PT_ERR_NONE,"pt_init error");
316
317         //TODO: Remove this after ecore fix max thread  number problem.
318         ecore_thread_max_set(4);
319
320         /*
321          * prepare load print files
322          */
323         pts_main_view_load_printing_data(ad, pt_files);
324
325         ad->search_info.print_search_mode = PTS_SEARCH_INITIAL;
326         ad->search_info.selection_done_cb = load_main_view;
327         ad->search_info.print_search_popup_parent = ad->main_info.root_win;
328         ad->search_info.printer_search_user_data = NULL;
329         pts_search_printer(ad);
330
331         PTS_TRACE_END;
332 }
333
334 static Eina_Bool show_dummy_noti_popup(service_h *service, void *user_data, pts_printing_data_t *printing_data)
335 {
336 //noti_mode:
337         PTS_TRACE_BEGIN;
338         pts_appdata_t *ad = (pts_appdata_t *)user_data;
339         PTS_RETV_IF(ad == NULL, EINA_FALSE, "ad is NULL");
340         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
341
342         int ret = -1;
343         char *value = NULL;
344
345         ret = service_get_extra_data(*service, SERVICE_FILES, &value);
346         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
347
348         char *files = strdup(value);
349         PTS_RETV_IF(files == NULL, EINA_FALSE, "failed to strdup. files is NULL");
350         PTS_DEBUG("files[%s]", files);
351
352         ret = service_get_extra_data(*service, SERVICE_PAGE_COUNT, &value);
353         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
354
355         int page_count = atoi(value);
356         PTS_DEBUG("page_count[%d]", page_count);
357         __pts_print_dummy_popup(ad, files, page_count);
358
359         evas_object_raise(ad->win);
360
361         PTS_TRACE_END;
362         return EINA_TRUE;
363 }
364
365 static Eina_Bool show_progress_noti_popup(service_h *service, void *user_data)
366 {
367 //noti_mode:
368         PTS_TRACE_BEGIN;
369         pts_appdata_t *ad = (pts_appdata_t *)user_data;
370         PTS_RETV_IF(ad == NULL, EINA_FALSE, "ad is NULL");
371         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
372
373         int ret = -1;
374         char *value = NULL;
375
376         ret = service_get_extra_data(*service, SERVICE_JOB_ID, &value);
377         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
378
379         if (NULL != value) {
380                 int job_id = atoi(value);
381                 PTS_DEBUG("job_id[%d]", job_id);
382                 ret = service_get_extra_data(*service, SERVICE_PAGE_COUNT, &value);
383                 PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
384                 int page_count = atoi(value);
385                 PTS_DEBUG("page_count[%d]", page_count);
386                 __pts_print_progress_popup(ad, job_id, page_count);
387         }
388
389         evas_object_raise(ad->win);
390
391         PTS_TRACE_END;
392         return EINA_TRUE;
393 }
394
395 static Eina_Bool get_extra_data_by_single_content(service_h *service, void *user_data, pts_printing_data_t *printing_data)
396 {
397         PTS_TRACE_BEGIN;
398         pts_appdata_t *ad = (pts_appdata_t *)user_data;
399         PTS_RETV_IF(ad == NULL, EINA_FALSE,  "ad is NULL");
400         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
401
402         Eina_Bool bret = EINA_FALSE;
403         int ret = -1;
404         char *value = NULL;
405         char *uri_temp = NULL;
406
407         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_TYPE, &value);
408         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the type of print files failed!, errno: %d", ret);
409
410         bret = _pts_printing_data_set_type(value, printing_data);
411         PTS_IF_FREE_MEM(value);
412         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set type");
413
414         bret = _pts_printing_data_set_files_count("1", printing_data);
415         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set files count");
416
417         ret = service_get_uri(*service, &value);
418         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the uri failed!, errno: %d", ret);
419
420         uri_temp = (char *)pt_utils_filename_from_URI(value);
421         PTS_IF_FREE_MEM(value);
422         PTS_RETV_IF(uri_temp == NULL, EINA_FALSE, "uri_temp is NULL");
423         bret = _pts_printing_data_set_request_files((const char **)&uri_temp, 1, printing_data);
424         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set request_files");
425
426         __app_load_data(ad, printing_data);
427         evas_object_raise(ad->win);
428
429         PTS_TRACE_END;
430         return EINA_TRUE;
431 }
432
433 static Eina_Bool get_extra_data_by_multi_contents(service_h *service, void *user_data, pts_printing_data_t *printing_data)
434 {
435         PTS_TRACE_BEGIN;
436         pts_appdata_t *ad = (pts_appdata_t *)user_data;
437         PTS_RETV_IF(ad == NULL, EINA_FALSE,  "ad is NULL");
438         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
439         PTS_RETV_IF(printing_data == NULL, EINA_FALSE, "printing_data is NULL");
440
441         Eina_Bool bret = EINA_FALSE;
442         int ret = -1;
443         int length = 0;
444         char *value = NULL;
445         char **filesname = NULL;
446
447         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_COUNT, &value);
448         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the count of print files failed!, errno: %d", ret);
449
450         bret = _pts_printing_data_set_files_count(value, printing_data);
451         PTS_IF_FREE_MEM(value);
452         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set files count");
453
454         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_TYPE, &value);
455         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the type of print files failed!, errno: %d", ret);
456
457         bret = _pts_printing_data_set_type(value, printing_data);
458         PTS_IF_FREE_MEM(value);
459         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set type");
460
461         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_CURRENT_INDEX, &value);
462         if (ret == SERVICE_ERROR_NONE) {
463                 bret = _pts_printing_data_set_index(value, printing_data);
464                 PTS_IF_FREE_MEM(value);
465                 PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set current index");
466         } else {
467                 PTS_DEBUG("get the current index of print files failed!, errno: %d", ret);
468         }
469
470         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_FOLDER_NAME, &value);
471         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
472
473         bret = _pts_printing_data_set_directory(value, printing_data);
474         PTS_IF_FREE_MEM(value);
475         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set directory");
476
477         ret = service_get_extra_data_array(*service, SERVICE_PRINT_FILES_FILES_NAME, &filesname, &length);
478         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
479
480         bret = _pts_printing_data_set_request_files((const char **) filesname, length, printing_data);
481         PTS_IF_FREE_MEM(filesname);
482         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set request files");
483
484         __app_load_data(ad, printing_data);
485         evas_object_raise(ad->win);
486
487         return EINA_TRUE;
488 }
489
490 /*
491 * this callback function is called when other application
492 * send the launch request to the application.
493 */
494 static void _app_service(service_h service, void *user_data)
495 {
496         PTS_TRACE_BEGIN;
497         pts_appdata_t *ad = (pts_appdata_t *)user_data;
498         PTS_RET_IF(ad == NULL, "ad is NULL");
499         PTS_RET_IF(ad->win == NULL, "ad->win is NULL");
500
501         int ret = -1;
502         char    *value = NULL;
503         pts_printing_data_t printing_data;
504         service_h reply_service;
505         Eina_Bool is_success = EINA_FALSE;
506
507         memset(&printing_data, 0, sizeof(printing_data));
508         service_create(&reply_service);
509
510         ret = service_get_extra_data(service, SERVICE_LAUNCH_TYPE, &value);
511         if (ret == SERVICE_ERROR_KEY_NOT_FOUND) {
512                 ret = service_get_extra_data(service, SERVICE_PRINT_FILES_COUNT, &value);
513                 if (ret == SERVICE_ERROR_NONE) {
514                         PTS_DEBUG("***** APP_SERVICE MODE(MULTI) *****");
515                         is_success = get_extra_data_by_multi_contents(&service, user_data, &printing_data);
516                 } else if (ret == SERVICE_ERROR_KEY_NOT_FOUND) {
517                         PTS_DEBUG("***** APP_SERVICE MODE(SINGLE) *****");
518                         is_success = get_extra_data_by_single_content(&service, user_data, &printing_data);
519                 } else {
520                         PTS_DEBUG("SERVICE_PRINT_FILES_COUNT ERROR(%d) ", ret);
521                 }
522         } else if (ret == SERVICE_ERROR_NONE) {
523                 PTS_DEBUG("SERVICE_LAUNCH_TYPE : %s", value);
524                 if (!strcmp(value, LAUNCH_FROM_DUMMY_NOTI)) {
525                         PTS_DEBUG("***** DUMMY NOTI MODE *****");
526                         is_success = show_dummy_noti_popup(&service, user_data, &printing_data);
527                 } else if (!strcmp(value, LAUNCH_FROM_PROGRESS_NOTI)) {
528                         PTS_DEBUG("***** NOTI MODE *****");
529                         is_success = show_progress_noti_popup(&service, user_data);
530                 } else {
531                         PTS_DEBUG("SERVICE_LAUNCH_TYPE ERROR(%s) ", value);
532                 }
533         } else if (ret == SERVICE_ERROR_OUT_OF_MEMORY
534                            || ret == SERVICE_ERROR_INVALID_DATA_TYPE
535                            || ret == SERVICE_ERROR_INVALID_PARAMETER) {
536                 PTS_DEBUG("APP_SERVICE ERROR(%d)", ret);
537         } else {
538                 PTS_DEBUG("***** Undefined *****");
539         }
540         PTS_IF_FREE_MEM(value);
541
542         if (is_success == EINA_TRUE) {
543                 service_reply_to_launch_request(reply_service, service, SERVICE_RESULT_SUCCEEDED);
544         } else {
545                 service_reply_to_launch_request(reply_service, service, SERVICE_RESULT_FAILED);
546                 pts_util_show_error_popup(ad->win, IDS_PRT_41);
547                 ecore_timer_add(1, (Ecore_Task_Cb)_simple_exit, (void *)ad);
548         }
549         PTS_TRACE_END;
550         return;
551 }
552
553 /*
554 * the main function
555 */
556 int main(int argc, char *argv[])
557 {
558         PTS_TRACE_BEGIN;
559         pts_appdata_t *pts_appdata = pts_get_appdata();
560
561         app_event_callback_s event_callback;
562
563         event_callback.create                                   = _app_create;
564         event_callback.terminate                                = _app_terminate;
565         event_callback.pause                                    = _app_pause;
566         event_callback.resume                                   = _app_resume;
567         event_callback.service                                  = _app_service;
568         event_callback.low_memory                               = NULL;
569         event_callback.low_battery                              = NULL;
570         event_callback.device_orientation               = NULL;
571         event_callback.language_changed                 = NULL;
572         event_callback.region_format_changed    = NULL;
573
574         memset(pts_appdata, 0x00, sizeof(pts_appdata_t));
575
576         PTS_TRACE_END;
577         return app_efl_main(&argc, &argv, &event_callback, pts_appdata);
578 }