1. Changed license year
[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         pts_appdata_t *ad = (pts_appdata_t *) data;
267         PTS_IF_FREE_MEM(ad);
268         elm_exit();
269         PTS_TRACE_END;
270         return ECORE_CALLBACK_CANCEL;
271 }
272
273 void load_main_view(void *userdata)
274 {
275         PTS_TRACE_BEGIN;
276
277         pts_appdata_t *ad = pts_get_appdata();
278         //pts_core_data_t *ugd  = ad->ugd;
279
280         // XXX - show main view after set active/default printer
281         pts_create_main_view(ad);
282         // XXX - disable to fix blink problem
283         //elm_win_resize_object_add(ugd->root_win, ugd->main_layout);
284         edje_object_signal_callback_add(elm_layout_edje_get(ad->main_info.main_layout),
285                                                                         "EXIT", "*", main_quit_cb, NULL);
286
287         pts_main_view_update_printer_label(ad);
288         pts_main_view_rotate_image(ad, app_get_device_orientation());
289
290         evas_object_show(ad->main_info.main_layout);
291         evas_object_show(ad->main_info.root_win);
292         PTS_TRACE_END;
293 }
294
295 /*
296 * load the app
297 */
298 static void __app_load_data(pts_appdata_t *ad, pts_printing_data_t *pt_files)
299 {
300         PTS_TRACE_BEGIN;
301         PTS_RET_IF(ad == NULL, "ad is NULL");
302         PTS_RET_IF(ad->win == NULL, "ad->win is NULL");
303         PTS_RET_IF(pt_files == NULL, "pt_files is NULL");
304
305         int ret;
306         if (pts_util_supported_arch() != EINA_TRUE) {
307                 pts_util_show_error_popup(ad->win, _("IDS_COM_POP_UNSUPPORTED"));
308                 ecore_timer_add(1, (Ecore_Task_Cb)_simple_exit, (void *)ad);
309                 return;
310         }
311
312         if (ad->main_info.root_win == NULL) {
313                 ad->main_info.root_win = ad->win;
314         }
315
316         ret = pt_init(__pts_event_cb, ad);
317         PTS_RET_IF(ret != PT_ERR_NONE,"pt_init error");
318
319         //TODO: Remove this after ecore fix max thread  number problem.
320         ecore_thread_max_set(4);
321
322         /*
323          * prepare load print files
324          */
325         pts_main_view_load_printing_data(ad, pt_files);
326
327         ad->search_info.print_search_mode = PTS_SEARCH_INITIAL;
328         ad->search_info.selection_done_cb = load_main_view;
329         ad->search_info.print_search_popup_parent = ad->main_info.root_win;
330         ad->search_info.printer_search_user_data = NULL;
331         pts_search_printer(ad);
332
333         PTS_TRACE_END;
334 }
335
336 static Eina_Bool show_dummy_noti_popup(service_h *service, void *user_data, pts_printing_data_t *printing_data)
337 {
338 //noti_mode:
339         PTS_TRACE_BEGIN;
340         pts_appdata_t *ad = (pts_appdata_t *)user_data;
341         PTS_RETV_IF(ad == NULL, EINA_FALSE, "ad is NULL");
342         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
343
344         int ret = -1;
345         char *value = NULL;
346
347         ret = service_get_extra_data(*service, SERVICE_FILES, &value);
348         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
349
350         char *files = strdup(value);
351         PTS_RETV_IF(files == NULL, EINA_FALSE, "failed to strdup. files is NULL");
352         PTS_DEBUG("files[%s]", files);
353
354         ret = service_get_extra_data(*service, SERVICE_PAGE_COUNT, &value);
355         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
356
357         int page_count = atoi(value);
358         PTS_DEBUG("page_count[%d]", page_count);
359         __pts_print_dummy_popup(ad, files, page_count);
360
361         evas_object_raise(ad->win);
362
363         PTS_TRACE_END;
364         return EINA_TRUE;
365 }
366
367 static Eina_Bool show_progress_noti_popup(service_h *service, void *user_data)
368 {
369 //noti_mode:
370         PTS_TRACE_BEGIN;
371         pts_appdata_t *ad = (pts_appdata_t *)user_data;
372         PTS_RETV_IF(ad == NULL, EINA_FALSE, "ad is NULL");
373         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
374
375         int ret = -1;
376         char *value = NULL;
377
378         ret = service_get_extra_data(*service, SERVICE_JOB_ID, &value);
379         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
380
381         if (NULL != value) {
382                 int job_id = atoi(value);
383                 PTS_DEBUG("job_id[%d]", job_id);
384                 ret = service_get_extra_data(*service, SERVICE_PAGE_COUNT, &value);
385                 PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
386                 int page_count = atoi(value);
387                 PTS_DEBUG("page_count[%d]", page_count);
388                 __pts_print_progress_popup(ad, job_id, page_count);
389         }
390
391         evas_object_raise(ad->win);
392
393         PTS_TRACE_END;
394         return EINA_TRUE;
395 }
396
397 static Eina_Bool get_extra_data_by_single_content(service_h *service, void *user_data, pts_printing_data_t *printing_data)
398 {
399         PTS_TRACE_BEGIN;
400         pts_appdata_t *ad = (pts_appdata_t *)user_data;
401         PTS_RETV_IF(ad == NULL, EINA_FALSE,  "ad is NULL");
402         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
403
404         Eina_Bool bret = EINA_FALSE;
405         int ret = -1;
406         char *value = NULL;
407         char *uri_temp = NULL;
408
409         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_TYPE, &value);
410         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the type of print files failed!, errno: %d", ret);
411
412         bret = _pts_printing_data_set_type(value, printing_data);
413         PTS_IF_FREE_MEM(value);
414         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set type");
415
416         bret = _pts_printing_data_set_files_count("1", printing_data);
417         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set files count");
418
419         ret = service_get_uri(*service, &value);
420         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the uri failed!, errno: %d", ret);
421
422         uri_temp = (char *)pt_utils_filename_from_URI(value);
423         PTS_IF_FREE_MEM(value);
424         PTS_RETV_IF(uri_temp == NULL, EINA_FALSE, "uri_temp is NULL");
425         bret = _pts_printing_data_set_request_files((const char **)&uri_temp, 1, printing_data);
426         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set request_files");
427
428         __app_load_data(ad, printing_data);
429         evas_object_raise(ad->win);
430
431         PTS_TRACE_END;
432         return EINA_TRUE;
433 }
434
435 static Eina_Bool get_extra_data_by_multi_contents(service_h *service, void *user_data, pts_printing_data_t *printing_data)
436 {
437         PTS_TRACE_BEGIN;
438         pts_appdata_t *ad = (pts_appdata_t *)user_data;
439         PTS_RETV_IF(ad == NULL, EINA_FALSE,  "ad is NULL");
440         PTS_RETV_IF(ad->win == NULL, EINA_FALSE, "ad->win is NULL");
441         PTS_RETV_IF(printing_data == NULL, EINA_FALSE, "printing_data is NULL");
442
443         Eina_Bool bret = EINA_FALSE;
444         int ret = -1;
445         int length = 0;
446         char *value = NULL;
447         char **filesname = NULL;
448
449         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_COUNT, &value);
450         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the count of print files failed!, errno: %d", ret);
451
452         bret = _pts_printing_data_set_files_count(value, printing_data);
453         PTS_IF_FREE_MEM(value);
454         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set files count");
455
456         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_TYPE, &value);
457         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get the type of print files failed!, errno: %d", ret);
458
459         bret = _pts_printing_data_set_type(value, printing_data);
460         PTS_IF_FREE_MEM(value);
461         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set type");
462
463         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_CURRENT_INDEX, &value);
464         if (ret == SERVICE_ERROR_NONE) {
465                 bret = _pts_printing_data_set_index(value, printing_data);
466                 PTS_IF_FREE_MEM(value);
467                 PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set current index");
468         } else {
469                 PTS_DEBUG("get the current index of print files failed!, errno: %d", ret);
470         }
471
472         ret = service_get_extra_data(*service, SERVICE_PRINT_FILES_FOLDER_NAME, &value);
473         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
474
475         bret = _pts_printing_data_set_directory(value, printing_data);
476         PTS_IF_FREE_MEM(value);
477         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set directory");
478
479         ret = service_get_extra_data_array(*service, SERVICE_PRINT_FILES_FILES_NAME, &filesname, &length);
480         PTS_RETV_IF(ret != SERVICE_ERROR_NONE, EINA_FALSE, "get extra data failed!, errno: %d", ret);
481
482         bret = _pts_printing_data_set_request_files((const char **) filesname, length, printing_data);
483         PTS_IF_FREE_MEM(filesname);
484         PTS_RETV_IF(bret == EINA_FALSE, EINA_FALSE, "Failed to set request files");
485
486         __app_load_data(ad, printing_data);
487         evas_object_raise(ad->win);
488
489         return EINA_TRUE;
490 }
491
492 /*
493 * this callback function is called when other application
494 * send the launch request to the application.
495 */
496 static void _app_service(service_h service, void *user_data)
497 {
498         PTS_TRACE_BEGIN;
499         pts_appdata_t *ad = (pts_appdata_t *)user_data;
500         PTS_RET_IF(ad == NULL, "ad is NULL");
501         PTS_RET_IF(ad->win == NULL, "ad->win is NULL");
502
503         int ret = -1;
504         char    *value = NULL;
505         pts_printing_data_t printing_data;
506         service_h reply_service;
507         Eina_Bool is_success = EINA_FALSE;
508
509         memset(&printing_data, 0, sizeof(printing_data));
510         service_create(&reply_service);
511
512         ret = service_get_extra_data(service, SERVICE_LAUNCH_TYPE, &value);
513         if (ret == SERVICE_ERROR_KEY_NOT_FOUND) {
514                 ret = service_get_extra_data(service, SERVICE_PRINT_FILES_COUNT, &value);
515                 if (ret == SERVICE_ERROR_NONE) {
516                         PTS_DEBUG("***** APP_SERVICE MODE(MULTI) *****");
517                         is_success = get_extra_data_by_multi_contents(&service, user_data, &printing_data);
518                 } else if (ret == SERVICE_ERROR_KEY_NOT_FOUND) {
519                         PTS_DEBUG("***** APP_SERVICE MODE(SINGLE) *****");
520                         is_success = get_extra_data_by_single_content(&service, user_data, &printing_data);
521                 } else {
522                         PTS_DEBUG("SERVICE_PRINT_FILES_COUNT ERROR(%d) ", ret);
523                 }
524         } else if (ret == SERVICE_ERROR_NONE) {
525                 PTS_DEBUG("SERVICE_LAUNCH_TYPE : %s", value);
526                 if (!strcmp(value, LAUNCH_FROM_DUMMY_NOTI)) {
527                         PTS_DEBUG("***** DUMMY NOTI MODE *****");
528                         is_success = show_dummy_noti_popup(&service, user_data, &printing_data);
529                 } else if (!strcmp(value, LAUNCH_FROM_PROGRESS_NOTI)) {
530                         PTS_DEBUG("***** NOTI MODE *****");
531                         is_success = show_progress_noti_popup(&service, user_data);
532                 } else {
533                         PTS_DEBUG("SERVICE_LAUNCH_TYPE ERROR(%s) ", value);
534                 }
535         } else if (ret == SERVICE_ERROR_OUT_OF_MEMORY
536                            || ret == SERVICE_ERROR_INVALID_DATA_TYPE
537                            || ret == SERVICE_ERROR_INVALID_PARAMETER) {
538                 PTS_DEBUG("APP_SERVICE ERROR(%d)", ret);
539         } else {
540                 PTS_DEBUG("***** Undefined *****");
541         }
542         PTS_IF_FREE_MEM(value);
543
544         if (is_success == EINA_TRUE) {
545                 service_reply_to_launch_request(reply_service, service, SERVICE_RESULT_SUCCEEDED);
546         } else {
547                 service_reply_to_launch_request(reply_service, service, SERVICE_RESULT_FAILED);
548                 pts_util_show_error_popup(ad->win, IDS_PRT_41);
549                 ecore_timer_add(1, (Ecore_Task_Cb)_simple_exit, (void *)ad);
550         }
551         PTS_TRACE_END;
552         return;
553 }
554
555 /*
556 * the main function
557 */
558 int main(int argc, char *argv[])
559 {
560         PTS_TRACE_BEGIN;
561         pts_appdata_t *pts_appdata = pts_get_appdata();
562
563         app_event_callback_s event_callback;
564
565         event_callback.create                                   = _app_create;
566         event_callback.terminate                                = _app_terminate;
567         event_callback.pause                                    = _app_pause;
568         event_callback.resume                                   = _app_resume;
569         event_callback.service                                  = _app_service;
570         event_callback.low_memory                               = NULL;
571         event_callback.low_battery                              = NULL;
572         event_callback.device_orientation               = NULL;
573         event_callback.language_changed                 = NULL;
574         event_callback.region_format_changed    = NULL;
575
576         memset(pts_appdata, 0x00, sizeof(pts_appdata_t));
577
578         PTS_TRACE_END;
579         return app_efl_main(&argc, &argv, &event_callback, pts_appdata);
580 }