1. Changed license copyright year
[apps/core/preloaded/print-service.git] / src / pt_optionmapping.c
1 /*
2 *       Printservice
3 *
4 * Copyright 2012-2013  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 <ctype.h>
21 #include <stdbool.h>
22 #include "pt_debug.h"
23 #include "pt_common.h"
24 #include "pt_utils.h"
25 #include "pt_ppd.h"
26 #include "pt_optionmapping.h"
27
28 typedef ppd_choice_t *OPTIONCUBE[PT_QUALITY_MAX][PT_PAPER_MAX][PT_GRAYSCALE_MAX][PT_DUPLEX_MAX];
29
30 static int aQuality;
31 static int aPaper;
32 static int aColor;
33 static int aDuplex;
34 static int aPaperSize;
35 static ppd_option_t *paper_sizes;
36 static OPTIONCUBE *optionCube;
37 static char *aModelName;
38
39 int pt_get_print_option_default_papersize(void);
40
41 #include "pt_optionkeywords.c"
42
43 #ifdef PT_OPTIONCUBE_TEST_PRINT
44 static const char *papernames[] = {
45         "Plain  ",
46         "Glossy ",
47         "Photo  ",
48         "Any    "
49 };
50
51 static const char *qualitynames[] = {
52         "Draft    ",
53         "Standard ",
54         "High     ",
55         "Any      "
56 };
57
58 static const char *colornames[] = {
59         "Gray     ",
60         "Color    ",
61         "Any      "
62 };
63
64 #endif
65
66 static void parse_pagesize(ppd_option_t *opt)
67 {
68         int index;
69         paper_sizes = opt;
70         for (index = paper_sizes->num_choices-1; index > 0; --index)
71                 if (!strcasecmp(paper_sizes->choices[index].choice, paper_sizes->defchoice)) {
72                         break;
73                 }
74         aPaperSize = pt_get_print_option_default_papersize();
75         return;
76 }
77
78 static void parse_quality(ppd_option_t *opt)
79 {
80         int i;
81         for (i = opt->num_choices-1; i >= 0; i--) {
82                 const pt_choice_keyword *lookingup = pt_quality_words;
83                 while (lookingup->keyword != NULL) {
84                         if (strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
85                                 optionCube[0][lookingup->quality][lookingup->papertype][lookingup->grayscale][lookingup->duplex] = &opt->choices[i];
86                                 PT_DEBUG("quality choice found: %s - q:%d p:%d c:%d", lookingup->keyword, lookingup->quality, lookingup->papertype, lookingup->grayscale);
87                                 break;
88                         } else {
89                                 lookingup++;
90                         }
91                 }
92                 if ((strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) && (lookingup->keyword != NULL)) {
93                         if (lookingup->quality != PT_QUALITY_ANY) {
94                                 aQuality = lookingup->quality;
95                         }
96                         if (lookingup->papertype != PT_PAPER_ANY) {
97                                 aPaper = lookingup->papertype;
98                         }
99                 }
100         }
101
102         return;
103 }
104
105 static void parse_printquality(ppd_option_t *opt)
106 {
107         int i;
108         for (i = 0; i < opt->num_choices; i++) {
109                 if (strcasecmp("BestPhoto", opt->choices[i].choice) == 0) {
110                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
111                 } else if (strcasecmp("TextImage", opt->choices[i].choice) == 0) {
112                         optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
113                 } else if (strcasecmp("Draft", opt->choices[i].choice) == 0) {
114                         optionCube[0][PT_QUALITY_DRAFT][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
115                 }
116         }
117         // setup the default value:
118         if (strcasecmp("BestPhoto", opt->defchoice) == 0) {
119                 aQuality = PT_QUALITY_HIGH;
120         } else if (strcasecmp("Draft", opt->defchoice) == 0) {
121                 aQuality = PT_QUALITY_DRAFT;
122         } else {
123                 aQuality = PT_QUALITY_STANDARD;
124         }
125         return;
126 }
127
128 static void parse_economode(ppd_option_t *opt)
129 {
130         int i;
131         for (i = 0; i < opt->num_choices; i++) {
132                 if (strcasecmp("FALSE", opt->choices[i].choice) == 0) {
133                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
134                         aQuality = PT_QUALITY_HIGH;
135 //              } else if (strcasecmp("PrinterDefault", opt->choices[i].choice) == 0) {
136 //                      optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY] = &opt->choices[i];
137                 } else if (strcasecmp("TRUE", opt->choices[i].choice) == 0) {
138                         optionCube[0][PT_QUALITY_DRAFT][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
139                 }
140         }
141         // setup the default value:
142         if (strcasecmp("FALSE", opt->defchoice) == 0) {
143                 aQuality = PT_QUALITY_HIGH;
144         } else {
145                 aQuality = PT_QUALITY_DRAFT;
146         }
147         return;
148 }
149
150 static void parse_hpeconomode(ppd_option_t *opt)
151 {
152         int i;
153         for (i = 0; i < opt->num_choices; i++) {
154                 if (strcasecmp("False", opt->choices[i].choice) == 0) {
155                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
156                         aQuality = PT_QUALITY_HIGH;
157                 } else if (strcasecmp("PrinterDefault", opt->choices[i].choice) == 0) {
158                         optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
159                 } else if (strcasecmp("True", opt->choices[i].choice) == 0) {
160                         optionCube[0][PT_QUALITY_DRAFT][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
161                 }
162         }
163         // setup the default value:
164         if (strcasecmp("False", opt->defchoice) == 0) {
165                 aQuality = PT_QUALITY_HIGH;
166         } else if (strcasecmp("True", opt->defchoice) == 0) {
167                 aQuality = PT_QUALITY_DRAFT;
168         } else {
169                 aQuality = PT_QUALITY_STANDARD;
170         }
171         return;
172 }
173
174 static void parse_hpeconomic(ppd_option_t *opt)
175 {
176         int i;
177         for (i = 0; i < opt->num_choices; i++) {
178                 if (strcasecmp("FALSE", opt->choices[i].choice) == 0) {
179                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
180                         aQuality = PT_QUALITY_HIGH;
181 //              } else if (strcasecmp("PrinterDefault", opt->choices[i].choice) == 0) {
182 //                      optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY] = &opt->choices[i];
183                 } else if (strcasecmp("TRUE", opt->choices[i].choice) == 0) {
184                         optionCube[0][PT_QUALITY_DRAFT][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
185                 }
186         }
187         // setup the default value:
188         if (strcasecmp("FALSE", opt->defchoice) == 0) {
189                 aQuality = PT_QUALITY_HIGH;
190         } else {
191                 aQuality = PT_QUALITY_DRAFT;
192         }
193         return;
194 }
195
196 static void parse_hpclean(ppd_option_t *opt)
197 {
198         int i;
199         for (i = 0; i < opt->num_choices; i++) {
200                 if (strcasecmp("TRUE", opt->choices[i].choice) == 0) {
201                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
202                 } else if (strcasecmp("FALSE", opt->choices[i].choice) == 0) {
203                         optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
204                 }
205         }
206         // setup the default value:
207         if (strcasecmp("TRUE", opt->defchoice) == 0) {
208                 aQuality = PT_QUALITY_HIGH;
209         } else {
210                 aQuality = PT_QUALITY_STANDARD;
211         }
212         return;
213 }
214
215 static void parse_hpprintquality(ppd_option_t *opt)
216 {
217         int i;
218         for (i = 0; i < opt->num_choices; i++) {
219                 if (strcasecmp("FastRes1200", opt->choices[i].choice) == 0 ||
220                                 strcasecmp("1200x1200dpi", opt->choices[i].choice) == 0) {
221                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
222                 } else if (strcasecmp("600dpi", opt->choices[i].choice) == 0 ||
223                                    strcasecmp("600x600dpi", opt->choices[i].choice) == 0 ||
224                                    strcasecmp("ImageRet3600", opt->choices[i].choice) == 0) {
225                         optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
226                 }
227         }
228         // setup the default value:
229         if (strcasecmp("FastRes1200", opt->defchoice) == 0 || strcasecmp("1200x1200dpi", opt->defchoice)) {
230                 aQuality = PT_QUALITY_HIGH;
231         } else {
232                 aQuality = PT_QUALITY_STANDARD;
233         }
234         return;
235 }
236
237 static void parse_hpoutputquality(ppd_option_t *opt)
238 {
239         int i;
240         for (i = 0; i < opt->num_choices; i++) {
241                 if (strcasecmp("Best", opt->choices[i].choice) == 0) {
242                         optionCube[0][PT_QUALITY_HIGH][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
243                 } else if (strcasecmp("Normal", opt->choices[i].choice) == 0) {
244                         optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
245                 } else if (strcasecmp("Fast", opt->choices[i].choice) == 0) {
246                         optionCube[0][PT_QUALITY_DRAFT][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = &opt->choices[i];
247                 }
248         }
249         // setup the default value:
250         if (strcasecmp("Best", opt->defchoice) == 0) {
251                 aQuality = PT_QUALITY_HIGH;
252         } else if (strcasecmp("Fast", opt->defchoice) == 0) {
253                 aQuality = PT_QUALITY_DRAFT;
254         } else {
255                 aQuality = PT_QUALITY_STANDARD;
256         }
257         return;
258 }
259
260 static void parse_mediatype(ppd_option_t *opt)
261 {
262         int i;
263         aPaper = PT_PAPER_NORMAL;
264         for (i = opt->num_choices-1; i >= 0; i--) {
265                 const pt_choice_keyword *lookingup = pt_mediatype_words;
266                 while (lookingup->keyword != NULL) {
267                         if (strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
268                                 optionCube[0][lookingup->quality][lookingup->papertype][lookingup->grayscale][lookingup->duplex] = &opt->choices[i];
269                                 PT_DEBUG("mediatype choice found: %s - q:%d p:%d c:%d", lookingup->keyword, lookingup->quality, lookingup->papertype, lookingup->grayscale);
270                                 break;
271                         } else {
272                                 lookingup++;
273                         }
274                 }
275                 if ((strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) && (lookingup->keyword != NULL)) {
276                         if (lookingup->papertype != PT_PAPER_ANY) {
277                                 aPaper = lookingup->papertype;
278                         }
279                 }
280         }
281         return;
282 }
283
284 static void parse_resolution(ppd_option_t *opt)
285 {
286         int i;
287         int j = PT_RESOLUTION_HIGH;
288         ppd_choice_t *resolutions[PT_RESOLUTION_MAX];
289
290         for (i = 0; i < PT_RESOLUTION_MAX; i++) {
291                 resolutions[i] = NULL;
292         }
293
294         for (i = 0; i < opt->num_choices; i++) {
295                 const pt_resolution_keyword *lookingup = pt_resoultion_words;
296                 while(lookingup->keyword != NULL) {
297                         if(strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
298                                 resolutions[lookingup->weight] = &opt->choices[i];
299                                 break;
300                         } else {
301                                 lookingup++;
302                         }
303                 }
304         }
305
306         for (i = PT_QUALITY_HIGH; i >= PT_QUALITY_DRAFT; i--) {
307                 while(resolutions[j] == NULL && j >= 0) {
308                         j--;
309                 }
310                 if (j < 0) {
311                         break;
312                 }
313                 optionCube[0][i][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = resolutions[j];
314                 j--;
315         }
316
317         aQuality = PT_QUALITY_ANY;
318         for(i = PT_QUALITY_DRAFT; i < PT_QUALITY_ANY; i++) {
319                 if (optionCube[0][i][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] != NULL) {
320                         if ((strcasecmp(optionCube[0][i][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY]->choice, opt->defchoice) == 0)) {
321                                 aQuality = i;
322                                 break;
323                         }
324                 }
325         }
326 }
327
328 static void parse_ink(ppd_option_t *opt)
329 {
330         int i;
331         for (i = 0; i < opt->num_choices; i++) {
332                 if (strcasecmp("COLOR", opt->choices[i].choice) == 0) {
333                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
334                 } else if (strcasecmp("MONO", opt->choices[i].choice) == 0) {
335                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
336                 }
337         }
338         // setup the default value:
339         if (strcasecmp("COLOR", opt->defchoice) == 0) {
340                 aColor = PT_GRAYSCALE_COLOUR;
341         } else {
342                 aColor = PT_GRAYSCALE_GRAYSCALE;
343         }
344         return;
345 }
346
347 static void parse_color(ppd_option_t *opt)
348 {
349         int i;
350         for (i = 0; i < opt->num_choices; i++) {
351                 if (strcasecmp("Color", opt->choices[i].choice) == 0) {
352                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
353                 } else if (strcasecmp("Grayscale", opt->choices[i].choice) == 0) {
354                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
355                 } else if (strcasecmp("Mono", opt->choices[i].choice) == 0) {
356                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
357                 }
358         }
359         // setup the default value:
360         if (strcasecmp("Color", opt->defchoice) == 0) {
361                 aColor = PT_GRAYSCALE_COLOUR;
362         } else {
363                 aColor = PT_GRAYSCALE_GRAYSCALE;
364         }
365         return;
366 }
367
368 static void parse_hpcoloroutput(ppd_option_t *opt)
369 {
370         int i;
371         for (i = 0; i < opt->num_choices; i++) {
372                 if (strcasecmp("ColorPrint", opt->choices[i].choice) == 0) {
373                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
374                 } else if (strcasecmp("GrayscalePrint", opt->choices[i].choice) == 0) {
375                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
376                 }
377         }
378         // setup the default value:
379         if (strcasecmp("ColorPrint", opt->defchoice) == 0) {
380                 aColor = PT_GRAYSCALE_COLOUR;
381         } else {
382                 aColor = PT_GRAYSCALE_GRAYSCALE;
383         }
384         return;
385 }
386
387 static void parse_colormode(ppd_option_t *opt)
388 {
389         int i;
390         for (i = 0; i < opt->num_choices; i++) {
391                 if (strcasecmp("TRUE", opt->choices[i].choice) == 0) {
392                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
393                 } else if (strcasecmp("FALSE", opt->choices[i].choice) == 0) {
394                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
395                 }
396         }
397         // setup the default value:
398         if (strcasecmp("TRUE", opt->defchoice) == 0) {
399                 aColor = PT_GRAYSCALE_COLOUR;
400         } else {
401                 aColor = PT_GRAYSCALE_GRAYSCALE;
402         }
403         return;
404 }
405
406 static void parse_colormodel(ppd_option_t *opt)
407 {
408         int i;
409         for (i = 0; i < opt->num_choices; i++) {
410                 if (strcasecmp("BlackWhite", opt->choices[i].choice) == 0 ||
411                                 strcasecmp("CMYGray", opt->choices[i].choice) == 0 ||
412                                 strcasecmp("KGray", opt->choices[i].choice) == 0 ||
413                                 strcasecmp("Gray", opt->choices[i].choice) == 0 ||
414                                 strcasecmp("W", opt->choices[i].choice) == 0) {
415                         if (optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] == NULL) {
416                                 optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
417                         }
418                         if (strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) {
419                                 aColor = PT_GRAYSCALE_GRAYSCALE;
420                         }
421                 } else if (strcasecmp("CMYK", opt->choices[i].choice) == 0 ||
422                                    strcasecmp("Color", opt->choices[i].choice) == 0 ||
423                                    strcasecmp("RGBA", opt->choices[i].choice) == 0 ||
424                                    strcasecmp("RGB", opt->choices[i].choice) == 0) {
425                         if (optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] == NULL) {
426                                 optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
427                         }
428                         if (strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) {
429                                 aColor = PT_GRAYSCALE_COLOUR;
430                         }
431                 }
432         }
433
434         return;
435 }
436
437 static void parse_hpcolorasgray(ppd_option_t *opt)
438 {
439         int i;
440         for (i = 0; i < opt->num_choices; i++) {
441                 if (strcasecmp("False", opt->choices[i].choice) == 0 ||
442                         strcasecmp("Off", opt->choices[i].choice) == 0 ) {
443                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_COLOUR][PT_DUPLEX_ANY] = &opt->choices[i];
444                 } else if (strcasecmp("True", opt->choices[i].choice) == 0 ||
445                                         strcasecmp("HighQuality", opt->choices[i].choice) == 0 ||
446                                         strcasecmp("BlackInkOnly", opt->choices[i].choice) == 0) {
447                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
448                 }
449         }
450         // setup the default value:
451         if (strcasecmp("False", opt->defchoice) == 0 || strcasecmp("Off", opt->defchoice) == 0) {
452                 aColor = PT_GRAYSCALE_COLOUR;
453         } else {
454                 aColor = PT_GRAYSCALE_GRAYSCALE;
455         }
456         return;
457 }
458
459 static void parse_hpprintingrayscale(ppd_option_t *opt)
460 {
461         int i;
462         // XXX - It's a way to get gray print by black ink or sum of all inks.
463         for (i = 0; i < opt->num_choices; i++) {
464                 if (strcasecmp("GrayscalePrint", opt->choices[i].choice) == 0) {
465                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE][PT_DUPLEX_ANY] = &opt->choices[i];
466                         if (strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) {
467                                 aColor = PT_GRAYSCALE_GRAYSCALE;
468                         }
469                 } else if (strcasecmp("FullSetOfInks", opt->choices[i].choice) == 0) {
470                         // FIXME - Currently GrayscalePrint only used
471                         //optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_GRAYSCALE] = &opt->choices[i];
472                 }
473         }
474
475         return;
476 }
477
478 static void parse_cmandresolution(ppd_option_t *opt)
479 {
480         int i;
481         for (i = 0; i < opt->num_choices; i++) {
482                 const pt_choice_keyword *lookingup = pt_cmandresolution_words;
483                 while (lookingup->keyword != NULL) {
484                         if (strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
485                                 optionCube[0][lookingup->quality][lookingup->papertype][lookingup->grayscale][lookingup->duplex] = &opt->choices[i];
486                                 break;
487                         } else {
488                                 lookingup++;
489                         }
490                 }
491                 if ((strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) && (lookingup->keyword != NULL)) {
492                         aQuality = lookingup->quality;
493                         aColor = lookingup->grayscale;
494                 }
495         }
496         return;
497 }
498
499 static void parse_outputmode(ppd_option_t *opt)
500 {
501         int i;
502         for (i=0; i < opt->num_choices; i++) {
503                 const pt_choice_keyword *lookingup = pt_outputmode_words;
504                 while (lookingup->keyword != NULL) {
505                         if (strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
506                                 optionCube[0][lookingup->quality][lookingup->papertype][lookingup->grayscale][lookingup->duplex] = &opt->choices[i];
507                                 break;
508                         } else {
509                                 lookingup++;
510                         }
511                 }
512                 if ((strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) && (lookingup->keyword != NULL)) {
513                         aQuality = (lookingup->quality   != PT_QUALITY_ANY)   ? lookingup->quality   : aQuality;
514                         aPaper =   (lookingup->papertype != PT_PAPER_ANY)     ? lookingup->papertype : aPaper;
515                         aColor =   (lookingup->grayscale != PT_GRAYSCALE_ANY) ? lookingup->grayscale : aColor;
516                 }
517         }
518 }
519
520 static void parse_duplex(ppd_option_t *opt)
521 {
522         int i;
523         for(i=0; i < opt->num_choices; i++) {
524                 const pt_choice_keyword *lookingup = pt_duplex_words;
525                 while (lookingup->keyword != NULL) {
526                         if (strcasecmp(lookingup->keyword, opt->choices[i].choice) == 0) {
527                                 optionCube[0][lookingup->quality][lookingup->papertype][lookingup->grayscale][lookingup->duplex] = &opt->choices[i];
528                                 break;
529                         } else {
530                                 lookingup++;
531                         }
532                 }
533                 if ((strcasecmp(opt->choices[i].choice, opt->defchoice) == 0) && lookingup->keyword != NULL) {
534                         aDuplex = lookingup->duplex;
535                 }
536         }
537 }
538
539 /* KA: database with options and apropriate function */
540 static KeyActions KA[] = {
541         {
542                 "MediaType",
543                 parse_mediatype,
544                 pt_mediatype_words
545         },
546         {
547                 "HPEconoMode",
548                 parse_hpeconomode,
549                 NULL
550         },
551         {
552                 "Quality",
553                 parse_quality,
554                 pt_quality_words
555         },
556         {
557                 "PrintQuality",
558                 parse_printquality,
559                 NULL
560         },
561         {
562                 "Resolution",
563                 parse_resolution,
564                 NULL
565         },
566         {
567                 "OutputMode",
568                 parse_outputmode,
569                 NULL
570         },
571         {
572                 "EconoMode",
573                 parse_economode,
574                 NULL
575         },
576         {
577                 "HPEconomic",
578                 parse_hpeconomic,
579                 NULL
580         },
581         {
582                 "HPClean",
583                 parse_hpclean,
584                 NULL
585         },
586         {
587                 "HPPrintQuality",
588                 parse_hpprintquality,
589                 NULL
590         },
591         {
592                 "HPOutputQuality",
593                 parse_hpoutputquality,
594                 NULL
595         },
596         {
597                 "HPColorOutput",
598                 parse_hpcoloroutput,
599                 NULL
600         },
601         {
602                 "ColorModel",
603                 parse_colormodel,
604                 NULL
605         },
606         {
607                 "ColorMode",
608                 parse_colormode,
609                 NULL
610         },
611         {
612                 "Color",
613                 parse_color,
614                 NULL
615         },
616         {
617                 "Ink",
618                 parse_ink,
619                 NULL
620         },
621         {
622                 "CMAndResolution",
623                 parse_cmandresolution,
624                 NULL
625         },
626         {
627                 "HPColorAsGray",
628                 parse_hpcolorasgray,
629                 NULL
630         },
631         {
632                 "HPPrintInGrayscale",
633                 parse_hpprintingrayscale,
634                 NULL
635         },
636         {
637                 "Duplex",
638                 parse_duplex,
639                 pt_duplex_words
640         },
641         {       NULL, NULL, NULL}
642 };
643
644
645 static ppd_choice_t *quality_exists(int q)
646 {
647         ppd_choice_t *choi = NULL;
648
649         if (!optionCube[aPaperSize][q][aPaper][aColor][aDuplex]) {
650                 choi = optionCube[aPaperSize][q][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY];
651                 // choi == 1 is a special case: option doesn't exist in ppd file,
652                 // but it is allowed as a printer default setting, for ex.:
653                 // Standard quality as the only quality, a printer supports
654                 if (!choi && choi != (ppd_choice_t *)1) {
655                         choi = optionCube[aPaperSize][q][aPaper][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY];
656                 }
657                 if (!choi && choi != (ppd_choice_t *)1) {
658                         choi = optionCube[aPaperSize][q][PT_PAPER_ANY][aColor][PT_DUPLEX_ANY];
659                 }
660         }
661         return choi;
662 }
663
664 static ppd_choice_t *paper_exists(int p)
665 {
666         ppd_choice_t *choi = NULL;
667
668         if (!optionCube[aPaperSize][aQuality][p][aColor][aDuplex]) {
669                 choi = optionCube[aPaperSize][PT_QUALITY_ANY][p][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY];
670                 // choi == 1 is a special case: option doesn't exist in ppd file,
671                 // but it is allowed as printer default setting, for ex.:
672                 // Plain paper as the only and default paper type
673                 if (!choi && choi != (ppd_choice_t *)1) {
674                         choi = optionCube[aPaperSize][aQuality][p][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY];
675                 }
676                 if (!choi && choi != (ppd_choice_t *)1) {
677                         choi = optionCube[aPaperSize][PT_QUALITY_ANY][p][aColor][PT_DUPLEX_ANY];
678                 }
679         }
680         return choi;
681 }
682
683 static ppd_choice_t *color_exists(int c)
684 {
685         ppd_choice_t *choi = NULL;
686
687         if (!optionCube[aPaperSize][aQuality][aPaper][c][aDuplex]) {
688                 choi = optionCube[aPaperSize][PT_QUALITY_ANY][PT_PAPER_ANY][c][PT_DUPLEX_ANY];
689                 // choi == 1 is a special case: option doesn't exist in ppd file,
690                 // but it is allowed as printer default setting, for ex.:
691                 // Grayscale for black & white printer.
692                 if (!choi && choi != (ppd_choice_t *)1) {
693                         choi = optionCube[aPaperSize][aQuality][PT_PAPER_ANY][c][PT_DUPLEX_ANY];
694                 }
695                 if (!choi && choi != (ppd_choice_t *)1) {
696                         choi = optionCube[aPaperSize][PT_QUALITY_ANY][aPaper][c][PT_DUPLEX_ANY];
697                 }
698         }
699         return choi;
700 }
701
702 static ppd_choice_t *duplex_exists(int d)
703 {
704         ppd_choice_t *choi = NULL;
705         if (!optionCube[aPaperSize][aQuality][aPaper][aColor][d]) {
706                 choi = optionCube[aPaperSize][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_ANY][d];
707         }
708         return choi;
709 }
710
711 static void reset_option_cube(int num_sizes)
712 {
713         if (optionCube != NULL) {
714                 free(optionCube);
715         }
716         optionCube = calloc(num_sizes, sizeof(OPTIONCUBE));
717         // set current settings to their initial values
718         aColor = PT_GRAYSCALE_ANY;
719         aQuality = PT_QUALITY_ANY;
720         aPaper = PT_PAPER_ANY;
721         aDuplex = PT_DUPLEX_ANY;
722 }
723
724 static void check_defaults(ppd_file_t *ppd)
725 {
726         if (aColor == PT_GRAYSCALE_ANY) {
727                 PT_DEBUG("Color option not found!");
728                 ppd_attr_t *at = ppdFindAttr(ppd, "ColorDevice", NULL);
729                 if (at != NULL) {
730                         if (strcasecmp(at->text, "True") == 0) {
731                                 aColor = PT_GRAYSCALE_COLOUR;
732                         } else {
733                                 aColor = PT_GRAYSCALE_GRAYSCALE;
734                         }
735                         optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][aColor][PT_DUPLEX_ANY] = (ppd_choice_t *)1;
736                 } else {
737                         PT_DEBUG("Attribute ColorDevice not found! Check ppd file!");
738                 }
739         }
740         if (aQuality == PT_QUALITY_ANY) {
741                 PT_DEBUG("Qualtiy option not found!");
742                 optionCube[0][PT_QUALITY_STANDARD][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = (ppd_choice_t *)1;
743                 aQuality = PT_QUALITY_STANDARD;
744         }
745         if (aPaper == PT_PAPER_ANY) {
746                 PT_DEBUG("MediaType option not found!");
747                 optionCube[0][PT_QUALITY_ANY][PT_PAPER_NORMAL][PT_GRAYSCALE_ANY][PT_DUPLEX_ANY] = (ppd_choice_t *)1;
748                 aPaper = PT_PAPER_NORMAL;
749         }
750         if (aDuplex == PT_DUPLEX_ANY) {
751                 PT_DEBUG("Duplex option not found!");
752                 optionCube[0][PT_QUALITY_ANY][PT_PAPER_ANY][PT_GRAYSCALE_ANY][PT_DUPLEX_OFF] = (ppd_choice_t *)1;
753                 aDuplex = PT_DUPLEX_OFF;
754         }
755 }
756
757 static int mark_choice(ppd_file_t *ppd, ppd_choice_t* ch) {
758         if (ch && ch != (ppd_choice_t*) 1) {
759                 ch->marked = 1;
760                 return ppdConflicts(ppd);
761         }
762         return -1;
763 }
764
765 static void unmark_choice(ppd_choice_t* ch) {
766     if (ch && ch != (ppd_choice_t*) 1) {
767         ch->marked = 0;
768     }
769 }
770
771 static void check_constraints(ppd_file_t *ppd, int papersize)
772 {
773         int sPaperSize, sQuality, sPaper, sColor, sDuplex;
774         ppd_choice_t* ch;
775         ppd_choice_t* qualityCh;
776         ppd_choice_t* paperCh;
777         ppd_choice_t* colorCh;
778
779         // saving default values
780         sPaperSize = aPaperSize;
781         sQuality = aQuality;
782         sPaper = aPaper;
783         sColor = aColor;
784         sDuplex = aDuplex;
785         aPaperSize = papersize;
786         ppdMarkDefaults(ppd);
787         ppdMarkOption(ppd, "PageSize", paper_sizes->choices[papersize].choice);
788         for (aQuality=0; aQuality<PT_QUALITY_ANY; aQuality++) {
789                 qualityCh = pt_selected_choice(PT_OPTION_ID_QUALITY, PT_ORIENTATION_PORTRAIT);
790                 mark_choice(ppd, qualityCh);
791                 for (aPaper=0; aPaper<PT_PAPER_ANY; aPaper++) {
792                         paperCh = pt_selected_choice(PT_OPTION_ID_PAPER, PT_ORIENTATION_PORTRAIT);
793                         mark_choice(ppd, paperCh);
794                         for (aColor=0; aColor<PT_GRAYSCALE_ANY; aColor++) {
795                                 colorCh = pt_selected_choice(PT_OPTION_ID_GRAYSCALE, PT_ORIENTATION_PORTRAIT);
796                                 mark_choice(ppd, colorCh);
797                                 for(aDuplex=0; aDuplex<PT_DUPLEX_ANY; aDuplex++) {
798                                         ch = duplex_exists(aDuplex);
799                                         if(ch && ch != (ppd_choice_t*)1) {
800                                                 if (ppdMarkOption(ppd, ch->option->keyword, ch->choice) > 0) {
801                                                         optionCube[papersize][aQuality][aPaper][aColor][aDuplex] = (ppd_choice_t *) -1;
802                                                 }
803                                                 ch->marked = 0;
804                                         } else if(ppdConflicts(ppd) > 0) {
805                                                 optionCube[papersize][aQuality][aPaper][aColor][aDuplex] = (ppd_choice_t *) -1;
806                                         }
807                                 }
808                                 unmark_choice(colorCh);
809                         }
810                         unmark_choice(paperCh);
811                 }
812                 unmark_choice(qualityCh);
813         }
814         // restoring default values
815         aQuality = sQuality;
816         aPaper = sPaper;
817         aColor = sColor;
818         aDuplex = sDuplex;
819         aPaperSize = sPaperSize;
820 }
821
822 #ifdef PT_OPTIONCUBE_TEST_PRINT
823
824 static void testprint(int paper)
825 {
826         int i, j, k;
827         char dbgPrint[256];
828         char *dbgPrintPtr;
829         ppd_choice_t *choi;
830
831         PT_DEBUG("           Gray         Color         Any         for PaperSize: %s", paper_sizes->choices[paper].choice);
832         for (i=0; i<=PT_QUALITY_ANY; i++) {
833                 PT_DEBUG("----------------- %s ------------------", qualitynames[i]);
834                 for (j=0; j<=PT_PAPER_ANY; j++) {
835                         dbgPrintPtr = dbgPrint;
836                         dbgPrintPtr += sprintf(dbgPrintPtr, "%s", papernames[j]);
837                         for (k=0; k<=PT_GRAYSCALE_ANY; k++) {
838                                 choi = optionCube[paper][i][j][k][PT_DUPLEX_ANY];
839                                 if (choi == (ppd_choice_t *)(-1)) {
840                                         dbgPrintPtr += sprintf(dbgPrintPtr, "  disabled   ");
841                                 } else if (choi == (ppd_choice_t *)1) {
842                                         dbgPrintPtr += sprintf(dbgPrintPtr, "   enabled   ");
843                                 } else if (choi) {
844                                         dbgPrintPtr += sprintf(dbgPrintPtr, "    %s  ", choi->choice);
845                                 } else {
846                                         dbgPrintPtr += sprintf(dbgPrintPtr, "    <n/a>    ");
847                                 }
848                         }
849                         PT_DEBUG("%s", dbgPrint);
850                 }
851         }
852 }
853 #endif
854
855 static bool pt_validate_settings(int s, int q, int p, int c, int d)
856 {
857         if (s < 0 || s >= paper_sizes->num_choices) {
858                 return false;
859         }
860         if (q < PT_QUALITY_DRAFT || q > PT_QUALITY_HIGH) {
861                 return false;
862         }
863         if (p < PT_PAPER_NORMAL || p > PT_PAPER_PHOTO) {
864                 return false;
865         }
866         if (c < PT_GRAYSCALE_GRAYSCALE || c > PT_GRAYSCALE_COLOUR) {
867                 return false;
868         }
869         if (d < PT_DUPLEX_OFF || d > PT_DUPLEX_TUMBLE) {
870                 return false;
871         }
872         return true;
873 }
874
875 static void pt_try_settings(int s, int q, int p, int c, int d)
876 {
877         int sPaperSize = aPaperSize;
878         int sQuality = aQuality;
879         int sPaper = aPaper;
880         int sColor = aColor;
881         int sDuplex = aDuplex;
882
883         if(pt_validate_settings(s, q, p, c, d)) {
884                 if (!pt_is_enabled(PT_OPTION_ID_QUALITY, q) || !pt_is_enabled(PT_OPTION_ID_PAPER, p) ||
885                         !pt_is_enabled(PT_OPTION_ID_GRAYSCALE, c) || !pt_is_enabled(PT_OPTION_ID_DUPLEX, d)) {
886                         aPaperSize = sPaperSize;
887                         aQuality = sQuality;
888                         aPaper = sPaper;
889                         aColor = sColor;
890                         aDuplex = sDuplex;
891                 } else {
892                         aPaperSize = s;
893                         aQuality = q;
894                         aPaper = p;
895                         aColor = c;
896                         aDuplex = d;
897                 }
898         }
899 }
900
901 void pt_load_user_choice(void) {
902         FILE *stream;
903         char buf[255] = {0,};
904         char *args;
905         int s;
906         int q;
907         int p;
908         int c;
909         int d;
910         char *null_check = NULL;
911
912         stream = fopen(PT_USER_OPTION_CONFIG_FILE,"r");
913         if(stream == NULL) {
914                 PT_DEBUG("Can't open settings file");
915                 return;
916         }
917         while(fgets(buf, sizeof(buf), stream) != NULL) {
918                 null_check = strchr(buf, '\n');
919                 if (null_check) {
920                         *null_check = '\0';
921                 }
922
923                 gchar **tokens = g_strsplit((gchar *)buf, ",", 0);
924                 if (g_strv_length(tokens) != 6) {
925                         g_strfreev(tokens);
926                         continue;
927                 }
928
929                 if (!strcasecmp(tokens[0], aModelName)) {
930                         s = atoi(tokens[1]);
931                         q = atoi(tokens[2]);
932                         p = atoi(tokens[3]);
933                         c = atoi(tokens[4]);
934                         d = atoi(tokens[5]);
935                         pt_try_settings(s, q, p, c, d);
936                         g_strfreev(tokens);
937                         break;
938                 }
939                 g_strfreev(tokens);
940         }
941         fclose(stream);
942 }
943
944 int pt_set_choice(int op, int ch)
945 {
946         int ret = -1;
947         switch (op) {
948         case PT_OPTION_ID_QUALITY:
949                 if (quality_exists(ch)) {
950                         aQuality = ch;
951                 }
952                 ret = aQuality;
953                 break;
954         case PT_OPTION_ID_PAPER:
955                 if (paper_exists(ch)) {
956                         aPaper = ch;
957                 }
958                 ret = aPaper;
959                 break;
960         case PT_OPTION_ID_GRAYSCALE:
961                 if (color_exists(ch)) {
962                         aColor = ch;
963                 }
964                 ret = aColor;
965                 break;
966         case PT_OPTION_ID_PAPERSIZE:
967                 if (pt_is_enabled(op, ch)) {
968                         aPaperSize = ch;
969                 }
970                 ret = aPaperSize;
971                 break;
972         case PT_OPTION_ID_DUPLEX:
973                 if (duplex_exists(ch)) {
974                         aDuplex = ch;
975                 }
976                 ret = aDuplex;
977         default:
978                 break;
979         }
980         return ret;
981 }
982
983 int pt_get_selected(int op)
984 {
985         int choi = -1;
986         switch (op) {
987         case PT_OPTION_ID_QUALITY:
988                 choi = aQuality;
989                 break;
990         case PT_OPTION_ID_PAPER:
991                 choi = aPaper;
992                 break;
993         case PT_OPTION_ID_GRAYSCALE:
994                 choi = aColor;
995                 break;
996         case PT_OPTION_ID_PAPERSIZE:
997                 choi = aPaperSize;
998                 break;
999         case PT_OPTION_ID_DUPLEX:
1000                 choi = aDuplex;
1001                 break;
1002         default:
1003                 break;
1004         }
1005         return choi;
1006 }
1007
1008 int pt_is_enabled(int op, int ch)
1009 {
1010         int enabled = true;
1011         switch (op) {
1012         case PT_OPTION_ID_QUALITY:
1013                 if (!quality_exists(ch)) {
1014                         enabled = false;
1015                 }
1016                 break;
1017         case PT_OPTION_ID_PAPER:
1018                 if (!paper_exists(ch)) {
1019                         enabled = false;
1020                 }
1021                 break;
1022         case PT_OPTION_ID_GRAYSCALE:
1023                 if (!color_exists(ch)) {
1024                         enabled = false;
1025                 }
1026                 break;
1027         case PT_OPTION_ID_PAPERSIZE:
1028                 if (optionCube[ch][aQuality][aPaper][aColor][aDuplex] == (ppd_choice_t *)(-1)) {
1029                         enabled = false;
1030                 }
1031                 break;
1032         case PT_OPTION_ID_DUPLEX:
1033                 if (!duplex_exists(ch)) {
1034                         enabled = false;
1035                 }
1036                 break;
1037         default:
1038                 break;
1039         }
1040         return enabled;
1041 }
1042
1043 int pt_get_selected_paper_size_pts(pt_pagesize_t *s)
1044 {
1045         int ret = 0;
1046         ppd_size_t *size = pt_utils_paper_size_pts(paper_sizes->choices[aPaperSize].choice);
1047         if (size) {
1048                 s->x = size->width;
1049                 s->y = size->length;
1050                 strcpy(s->name, size->name);
1051                 PT_DEBUG("%s pagesize selected (%f x %f)", s->name, s->x, s->y);
1052         } else {
1053                 PT_DEBUG("No pagesize selected!");
1054                 ret = 1;
1055         }
1056         return ret;
1057 }
1058
1059 char *pt_get_print_option_papersize(int papersize_num)
1060 {
1061         PT_RETV_IF(paper_sizes == NULL, NULL, "paper_sizes is NULL");
1062         return paper_sizes->choices[papersize_num].text;
1063 }
1064
1065 char *pt_get_print_option_papersize_cmd(int papersize_num)
1066 {
1067         PT_RETV_IF(paper_sizes == NULL, NULL, "paper_sizes is NULL");
1068         return paper_sizes->choices[papersize_num].choice;
1069 }
1070
1071 int pt_get_print_option_papersize_num(void)
1072 {
1073         PT_RETV_IF(paper_sizes == NULL, 0, "paper_sizes is NULL");
1074         return paper_sizes->num_choices;
1075 }
1076
1077 int pt_get_print_option_default_papersize(void)
1078 {
1079         PT_RETV_IF(paper_sizes == NULL, 0, "paper_sizes is NULL");
1080         int i;
1081         for (i=0; i< paper_sizes->num_choices; i++)
1082                 if (!strcasecmp(paper_sizes->choices[i].choice, paper_sizes->defchoice)) {
1083                         return i;
1084                 }
1085         return 0;
1086 }
1087
1088 /* parse_options: search ppd options and call certain function */
1089 void pt_parse_options(ppd_file_t *ppd)
1090 {
1091         int i;
1092         ppd_option_t *opt = NULL;
1093         ppd_attr_t *at = NULL;
1094         KeyActions *ka = NULL;
1095
1096         opt = ppdFindOption(ppd, "PageSize");
1097         if (opt != NULL) {
1098                 parse_pagesize(opt);
1099         }
1100
1101         at = ppdFindAttr(ppd, "ModelName", NULL);
1102         if (at != NULL) {
1103                 aModelName = at->value;
1104                 PT_DEBUG("ModelName found, value: %s; spec: %s; text: %s", at->value, at->spec, at->text);
1105         } else {
1106                 PT_DEBUG("ModelName not found");
1107         }
1108
1109         reset_option_cube(paper_sizes->num_choices);
1110
1111         //find all options and call necessary function
1112         for (i = 0, ka = &KA[i]; ka[i].key != NULL; i++) {
1113                 opt = ppdFindOption(ppd, ka[i].key);
1114                 if (opt != NULL) {
1115                         ka[i].fn(opt);
1116                 }
1117         }
1118         // Check, if all options were set otherwise set them "by force"
1119         check_defaults(ppd);
1120         // copy found options and check UI constraints for all paper sizes
1121         for (i=1; i<paper_sizes->num_choices; i++) {
1122                 PT_DEBUG("Copying option cubes %d", i);
1123                 memcpy(optionCube[i], optionCube[0], sizeof(OPTIONCUBE));
1124                 PT_DEBUG("Checking UI constraints");
1125                 check_constraints(ppd, i);
1126 #ifdef PT_OPTIONCUBE_TEST_PRINT
1127                 testprint(i);
1128 #endif
1129         }
1130
1131         // check UI Constraints for paper size No 0 too.
1132         check_constraints(ppd, 0);
1133         pt_load_user_choice();
1134         return;
1135 }
1136
1137 ppd_choice_t *pt_selected_choice(int op, pt_orientation_e p)
1138 {
1139         ppd_choice_t *choi = NULL;
1140         switch (op) {
1141         case PT_OPTION_ID_QUALITY:
1142                 choi = quality_exists(aQuality);
1143                 break;
1144         case PT_OPTION_ID_PAPER:
1145                 choi = paper_exists(aPaper);
1146                 break;
1147         case PT_OPTION_ID_GRAYSCALE:
1148                 choi = color_exists(aColor);
1149                 break;
1150         case PT_OPTION_ID_PAPERSIZE:
1151                 choi = &paper_sizes->choices[aPaperSize];
1152                 break;
1153         case PT_OPTION_ID_DUPLEX:
1154                 choi = duplex_exists(aDuplex);
1155                 if(aDuplex != PT_DUPLEX_OFF) {
1156                         choi = (p == PT_ORIENTATION_PORTRAIT) ? duplex_exists(PT_DUPLEX_NO_TUMBLE) : duplex_exists(PT_DUPLEX_TUMBLE);
1157                 }
1158                 break;
1159         default:
1160                 break;
1161         }
1162         if(choi == (ppd_choice_t*)1) {
1163                 // Special case. Set by force, no ppd option. Use printer default.
1164                 // No need to send smth. to printer.
1165                 choi = NULL;
1166         }
1167         return choi;
1168 }
1169
1170 void pt_save_user_choice(void) {
1171         FILE* stream;
1172         fpos_t position;
1173         char buf[255];
1174         char *args;
1175         int ret = -1;
1176
1177         stream = fopen(PT_USER_OPTION_CONFIG_FILE,"r+");
1178         if(stream == NULL) {
1179                 //may be file doesn't exist, try to create it...
1180                 stream = fopen(PT_USER_OPTION_CONFIG_FILE,"w");
1181                 if(stream == NULL) {
1182                         PT_DEBUG("Can't create settings file");
1183                         return;
1184                 }
1185         }
1186         fgetpos(stream, &position);
1187         while(fgets(buf, sizeof(buf)-1, stream) != NULL) {
1188                 args = strchr(buf, ',');
1189                 if(args == NULL) {
1190                         continue;
1191                 }
1192                 *args++ = '\0';
1193                 if(!strcasecmp(buf, aModelName)) {
1194                         ret = fsetpos(stream, &position);
1195                         if (ret == -1) {
1196                                 fclose(stream);
1197                                 return;
1198                         }
1199                         fprintf(stream, "%s,%03d,%03d,%03d,%03d,%03d\n", aModelName, aPaperSize, aQuality, aPaper, aColor, aDuplex);
1200                         fclose(stream);
1201                         return;
1202                 }
1203                 fgetpos(stream, &position);
1204         }
1205         ret = fsetpos(stream, &position);
1206         if (ret == -1) {
1207                 fclose(stream);
1208                 return;
1209         }
1210         fprintf(stream, "%s,%03d,%03d,%03d,%03d,%03d\n", aModelName, aPaperSize, aQuality, aPaper, aColor, aDuplex);
1211         fclose(stream);
1212 }