310651e167c150e4f844d42e5294b4ebf12ff98d
[apps/core/preloaded/print-service.git] / src / pt_job.c
1 /*
2 *  Printservice
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 #define _GNU_SOURCE
20 #include <string.h>
21 #include <math.h>
22 #include <cups/ipp.h>
23 #include <cups/ppd.h>
24
25 #include "pt_common.h"
26 #include "pt_debug.h"
27 #include "pt_optionmapping.h"
28
29 /**
30  *      This API let the app set page ranges option for active printer, if not find active printer, will use default printer
31  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
32  *      @param[in] ranges page range string
33  */
34 int pt_set_print_option_page_range(const char *ranges)
35 {
36         PRINT_SERVICE_FUNC_ENTER;
37         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
38         PT_RETV_IF(ranges == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
39
40         char buf[MAX_SIZE] = {0};
41         snprintf(buf, MAX_SIZE, "%s", ranges);
42         g_pt_info->num_options = cupsAddOption("page-ranges", buf, g_pt_info->num_options, &g_pt_info->job_options);
43         PT_DEBUG("num is %d", g_pt_info->num_options);
44         PT_DEBUG("options is %p", g_pt_info->job_options);
45
46         PRINT_SERVICE_FUNC_LEAVE;
47         return PT_ERR_NONE;
48 }
49
50 /**
51  *      This API let the app set copies option for active printer, if not find active printer, will use default printer
52  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
53  *      @param[in] copies the copy number
54  */
55 int pt_set_print_option_copies(int copies)
56 {
57         PRINT_SERVICE_FUNC_ENTER;
58         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
59         PT_RETV_IF(copies <= 0, PT_ERR_INVALID_PARAM, "Invalid argument");
60
61         char buf[MAX_SIZE] = {0};
62         snprintf(buf, MAX_SIZE, "%d", copies);
63         g_pt_info->num_options = cupsAddOption("copies", buf, g_pt_info->num_options, &g_pt_info->job_options);
64         PT_DEBUG("num is %d", g_pt_info->num_options);
65         PT_DEBUG("options is %p", g_pt_info->job_options);
66
67         PRINT_SERVICE_FUNC_LEAVE;
68         return PT_ERR_NONE;
69 }
70
71 /**
72  *      This API let the app set copies option for active printer, if not find active printer, will use default printer
73  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
74  *      @param[in] --
75  */
76 int pt_set_print_option_color(void)
77 {
78         PRINT_SERVICE_FUNC_ENTER;
79         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
80
81         ppd_choice_t *choi = pt_selected_choice(PT_OPTION_ID_GRAYSCALE, PT_ORIENTATION_PORTRAIT);
82         if (choi) {
83                 g_pt_info->num_options = cupsAddOption(choi->option->keyword, choi->choice, g_pt_info->num_options, &g_pt_info->job_options);
84         }
85
86         PT_DEBUG("num is %d", g_pt_info->num_options);
87         PT_DEBUG("options is %p", g_pt_info->job_options);
88         if (choi) {
89                 PT_DEBUG("%s=%s", choi->option->keyword, choi->choice);
90         }
91
92         PRINT_SERVICE_FUNC_LEAVE;
93         return PT_ERR_NONE;
94 }
95
96 int pt_set_print_option_paper_type(void)
97 {
98         PRINT_SERVICE_FUNC_ENTER;
99         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
100
101         ppd_choice_t *choi = pt_selected_choice(PT_OPTION_ID_PAPER, PT_ORIENTATION_PORTRAIT);
102         if (choi) {
103                 g_pt_info->num_options = cupsAddOption(choi->option->keyword, choi->choice, g_pt_info->num_options, &g_pt_info->job_options);
104         }
105
106         PT_DEBUG("num is %d", g_pt_info->num_options);
107         PT_DEBUG("options is %p", g_pt_info->job_options);
108         if (choi) {
109                 PT_DEBUG("%s=%s", choi->option->keyword, choi->choice);
110         }
111
112         PRINT_SERVICE_FUNC_LEAVE;
113         return PT_ERR_NONE;
114 }
115
116 int pt_set_print_option_quality(void)
117 {
118         PRINT_SERVICE_FUNC_ENTER;
119         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
120
121         ppd_choice_t *choi = pt_selected_choice(PT_OPTION_ID_QUALITY, PT_ORIENTATION_PORTRAIT);
122         if (choi) {
123                 g_pt_info->num_options = cupsAddOption(choi->option->keyword, choi->choice, g_pt_info->num_options, &g_pt_info->job_options);
124         }
125
126         PT_DEBUG("num is %d", g_pt_info->num_options);
127         PT_DEBUG("options is %p", g_pt_info->job_options);
128         if (choi) {
129                 PT_DEBUG("%s=%s", choi->option->keyword, choi->choice);
130         }
131
132         PRINT_SERVICE_FUNC_LEAVE;
133         return PT_ERR_NONE;
134 }
135
136 /**
137  *      This API let the app set paper size option for active printer, if not find active printer, will use default printer
138  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
139  *      @param[in] --
140  */
141 int pt_set_print_option_papersize(void)
142 {
143         PRINT_SERVICE_FUNC_ENTER;
144
145         ppd_choice_t *choi = pt_selected_choice(PT_OPTION_ID_PAPERSIZE, PT_ORIENTATION_PORTRAIT);
146         if (choi) {
147                 g_pt_info->num_options = cupsAddOption(choi->option->keyword, choi->choice, g_pt_info->num_options, &g_pt_info->job_options);
148         }
149
150         PT_DEBUG("num is %d", g_pt_info->num_options);
151         PT_DEBUG("options is %p", g_pt_info->job_options);
152         if (choi) {
153                 PT_DEBUG("%s=%s", choi->option->keyword, choi->choice);
154         }
155
156         PRINT_SERVICE_FUNC_LEAVE;
157         return PT_ERR_NONE;
158 }
159
160 /**
161  *      This API let the app set duplex option for active printer, if not find active printer, will use default printer
162  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
163  *      @param[in] papersize the paper size
164  */
165 int pt_set_print_option_duplex(pt_orientation_e orientation)
166 {
167         PRINT_SERVICE_FUNC_ENTER;
168
169         ppd_choice_t *choi = pt_selected_choice(PT_OPTION_ID_DUPLEX, orientation);
170         if (choi) {
171                 g_pt_info->num_options = cupsAddOption(choi->option->keyword, choi->choice, g_pt_info->num_options, &g_pt_info->job_options);
172         }
173
174         PT_DEBUG("num is %d", g_pt_info->num_options);
175         PT_DEBUG("options is %p", g_pt_info->job_options);
176         if (choi) {
177                 PT_DEBUG("%s=%s", choi->option->keyword, choi->choice);
178         }
179
180         PRINT_SERVICE_FUNC_LEAVE;
181         return PT_ERR_NONE;
182 }
183
184 /**
185  *      This API let the app set orientation option for active printer, if not find active printer, will use default printer
186  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
187  *      @param[in] orientation the orientation value(0:portrait, 1:landscape)
188  */
189 int pt_set_print_option_orientation(pt_orientation_e orientation)
190 {
191         PRINT_SERVICE_FUNC_ENTER;
192         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
193         PT_RETV_IF((orientation < PT_ORIENTATION_PORTRAIT) || (orientation > PT_ORIENTATION_LANDSCAPE)
194                            , PT_ERR_INVALID_PARAM, "Invalid argument");
195
196         if (orientation == PT_ORIENTATION_PORTRAIT) {
197                 g_pt_info->num_options = cupsAddOption("landscape", "off", g_pt_info->num_options, &g_pt_info->job_options);
198         } else if (orientation == PT_ORIENTATION_LANDSCAPE) {
199                 g_pt_info->num_options = cupsAddOption("landscape", "on", g_pt_info->num_options, &g_pt_info->job_options);
200         } else {
201                 PT_DEBUG("CUPS will do auto-rotate when landscape option is not specified");
202         }
203
204         PT_DEBUG("num is %d", g_pt_info->num_options);
205         PT_DEBUG("options is %p", g_pt_info->job_options);
206
207         PRINT_SERVICE_FUNC_LEAVE;
208         return PT_ERR_NONE;
209 }
210
211 /**
212  *      This API let the app set image fit for the page size, if not find active printer, will use default printer
213  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
214  */
215 int pt_set_print_option_scaleimage(pt_scaling_e scaling)
216 {
217         PRINT_SERVICE_FUNC_ENTER;
218         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
219
220         char scaling_option[MAX_SIZE] = {0};
221         char percent_size[MAX_SIZE] = {0};
222         switch (scaling) {
223         case PT_SCALING_2_PAGES:
224                 strcpy(scaling_option, "number-up");   // 2 pages in 1 sheet
225                 strcpy(percent_size, "2");
226                 break;
227         case PT_SCALING_4_PAGES:
228                 strcpy(scaling_option, "number-up");   // 4 pages in 1 sheet
229                 strcpy(percent_size, "4");
230                 break;
231         case PT_SCALING_FIT_TO_PAGE:
232         default:
233                 strcpy(scaling_option, "scaling");      // fit-to-paper
234                 strcpy(percent_size, "100");
235                 break;
236         }
237
238 // do not send number-up option to CUPS daemon.
239 // imagetoraster do not support number-up
240 // To print image to resolve OOM, apply number-up option to pdf in advance.
241         g_pt_info->num_options = cupsAddOption(scaling_option, percent_size, g_pt_info->num_options, &g_pt_info->job_options);
242         PT_DEBUG("num is %d", g_pt_info->num_options);
243         PT_DEBUG("options is %p", g_pt_info->job_options);
244         PT_DEBUG("scaling option:[%s %s]", scaling_option, percent_size);
245
246         PRINT_SERVICE_FUNC_LEAVE;
247         return PT_ERR_NONE;
248 }
249
250 /**
251  *      This API let the app set image fit for the page size, if not find active printer, will use default printer
252  *      @return   If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
253  */
254 int pt_set_print_option_imagesize(pt_imagesize_t *crop_image_info, const char *filepath, int res_x, int res_y)
255 {
256         PRINT_SERVICE_FUNC_ENTER;
257         PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
258         PT_RETV_IF(filepath == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
259
260         char imagesize_option[MAX_SIZE] = {0};
261         char ppi_value[MAX_SIZE] = {0};
262
263         int ppi = 128;
264         double divisor = 1;
265
266         switch (crop_image_info->imagesize) {
267         case PT_SIZE_5X7:                                       /** 13 cm X 18 cm */
268                 PT_DEBUG("selected PT_SIZE_5X7");
269                 divisor = 7.000;
270                 break;
271         case PT_SIZE_4X6:                                       /** 10 cm X 15 cm */
272                 PT_DEBUG("selected PT_SIZE_4X6");
273                 divisor = 6.000;
274                 break;
275         case PT_SIZE_3_5X5:                             /** 9 cm X 13 cm */
276                 PT_DEBUG("selected PT_SIZE_3_5X5");
277                 divisor = 5.000;
278                 break;
279         case PT_SIZE_WALLET:                            /** 6.4cm X 8.4 cm */
280                 PT_DEBUG("selected PT_SIZE_WALLET");
281                 divisor = 3.307;
282                 break;
283         case PT_SIZE_CUSTOM:
284                 PT_DEBUG("selected PT_SIZE_CUSTOM");
285                 if (crop_image_info->unit == 1) { // cm to inch
286                         crop_image_info->resolution_width = crop_image_info->resolution_width / 2.54;
287                         crop_image_info->resolution_height = crop_image_info->resolution_height / 2.54;
288                         crop_image_info->unit = 2;
289                         crop_image_info->ratio = crop_image_info->resolution_width / crop_image_info->resolution_height;
290                 }
291
292                 if (crop_image_info->resolution_width < crop_image_info->resolution_height) {
293                         divisor = crop_image_info->resolution_height;
294                 } else {
295                         divisor = crop_image_info->resolution_width;
296                 }
297                 break;
298         default:
299                 divisor = 1;
300                 PT_DEBUG("[ERROR] Undefined imagesize(%d)",crop_image_info->imagesize);
301                 return PT_ERR_INVALID_PARAM;
302         }
303
304         if (res_x < res_y) {
305                 ppi = (int) ceil((double)(res_y) / (double)divisor);
306         } else {
307                 ppi = (int) ceil((double)(res_x) / (double)divisor);
308         }
309         strcpy(imagesize_option, "ppi");
310         snprintf(ppi_value, MAX_SIZE, "%d", ppi);
311
312         g_pt_info->num_options = cupsAddOption(imagesize_option, ppi_value, g_pt_info->num_options, &g_pt_info->job_options);
313         PT_DEBUG("num is %d", g_pt_info->num_options);
314         PT_DEBUG("options is %p", g_pt_info->job_options);
315         PT_DEBUG("imagesize_option :[%s %s]", imagesize_option, ppi_value);
316
317         PRINT_SERVICE_FUNC_LEAVE;
318         return PT_ERR_NONE;
319 }