Tizen 2.1 base
[platform/upstream/epson-inkjet-printer-escpr.git] / lib / epson-escpr-services.c
1 /*____________________________   epson-escpr-services.c   ______________________________*/\r
2 \r
3 /*       1         2         3         4         5         6         7         8        */\r
4 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/\r
5 /*******************************************|********************************************/\r
6 /*\r
7  *   Copyright (c) 2009  Seiko Epson Corporation                 All rights reserved.\r
8  *\r
9  *   Copyright protection claimed includes all forms and matters of\r
10  *   copyrightable material and information now allowed by statutory or judicial\r
11  *   law or hereinafter granted, including without limitation, material generated\r
12  *   from the software programs which are displayed on the screen such as icons,\r
13  *   screen display looks, etc.\r
14  *\r
15  */\r
16 /*******************************************|********************************************/\r
17 /*                                                                                      */\r
18 /*                      Epson ESC/P-R Lib Internal Service Routines                     */\r
19 /*                                                                                      */\r
20 /*                                Public Function Calls                                 */\r
21 /*                              --------------------------                              */\r
22 /*              EPS_ERR_CODE serAnalyzeStatus       (Status, StatusInfo         );      */\r
23 /*              void         serDelayThread         (Milliseconds               );      */\r
24 /*              EPS_ERR_CODE serSleep               (Milliseconds               );      */\r
25 /*              EPS_INT32    serGetInkError         (pStatInfo,  pNotify        );      */\r
26 /*              EPS_INT32    _SP_ChangeSpec_UpdatePMReply(printer,  orgPmString );      */\r
27 /*              EPS_ERR_CODE _SP_ChangeSpec_DraftOnly(printer,  jobAtter        );      */\r
28 /*                                                                                      */\r
29 /*******************************************|********************************************/\r
30 \r
31 /*------------------------------------  Includes   -------------------------------------*/\r
32 /*******************************************|********************************************/\r
33 #include "epson-escpr-err.h"\r
34 #include "epson-escpr-mem.h"\r
35 #include "epson-escpr-media.h"\r
36 #include "epson-escpr-services.h"\r
37 #ifdef GCOMSW_CMD_ESCPAGE_S\r
38 #include "epson-escpage-s.h"\r
39 #endif\r
40 /*------------------------------------  Definition   -----------------------------------*/\r
41 /*******************************************|********************************************/\r
42     /*** Index of printing quality                                                      */\r
43     /*** -------------------------------------------------------------------------------*/\r
44 #define Q_DRAFT                         0\r
45 #define Q_NORMAL                        1\r
46 #define Q_HIGH                          2\r
47 \r
48 #ifdef EPS_LOG_MODULE_SER\r
49 #define EPS_LOG_MODULE  EPS_LOG_MODULE_SER\r
50 extern EPS_CMN_FUNC    epsCmnFnc;\r
51 #else\r
52 #define EPS_LOG_MODULE  0\r
53 #endif\r
54 \r
55 \r
56 /*----------------------------  ESC/P-R Lib Global Variables  --------------------------*/\r
57 /*******************************************|********************************************/\r
58 \r
59 /*------------------------------  Local Global Variables  ------------------------------*/\r
60 /*******************************************|********************************************/\r
61 typedef struct _tagSP_OBSERVER\r
62 {\r
63         const EPS_PRINTER_INN    *printer;               /* current printer                     */\r
64     EPS_UINT8                colorPlane;         /* Image color plane                   */\r
65 }SP_OBSERVER;\r
66 \r
67 static SP_OBSERVER      g_observer = {0};\r
68 \r
69 /*---------------------------  Special PM String table   -------------------------------*/\r
70 /*******************************************|********************************************/\r
71 typedef struct _tagSP_PM_STRINGS\r
72 {\r
73         EPS_UINT32               id;    /* ID */\r
74         const EPS_UINT8* res;   /* PM String */\r
75         EPS_UINT32               len;   /* length */\r
76 }SP_PM_STRINGS;\r
77 \r
78 const EPS_UINT8 spm_E300[] = {0x40, 0x42, 0x44, 0x43, 0x20, 0x50, 0x4D, 0x0D, 0x0A, 0x53, 0x0F, 0x54, 0x26, 0x82, 0x2F, 0x54,\r
79                                                         0x0B, 0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x0A, 0x54, 0x26, 0x82, 0x2F, 0x54, 0x0B,\r
80                                                         0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x10, 0x54, 0x0B, 0x82, 0x2F, 0x54, 0x08, 0x02, \r
81                                                         0x2F, 0x2F, 0x53, 0x23, 0x54, 0x0B, 0x82, 0x2F, 0x2F, 0x0D, 0x0A};\r
82 const EPS_UINT8 spm_E500[] = {0x40, 0x42, 0x44, 0x43, 0x20, 0x50, 0x4D, 0x0D, 0x0A, 0x53, 0x0F, 0x54, 0x26, 0x82, 0x2F, 0x54,\r
83                                                         0x0B, 0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x0A, 0x54, 0x26, 0x82, 0x2F, 0x54, 0x0B,\r
84                                                         0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x2B, 0x54, 0x0B, 0x82, 0x2F, 0x2F, 0x53, 0x10,\r
85                                                         0x54, 0x0B, 0x82, 0x2F, 0x54, 0x08, 0x02, 0x2F, 0x2F, 0x53, 0x23, 0x54, 0x0B, 0x82, 0x2F, 0x2F,\r
86                                                         0x0D, 0x0A};\r
87 const EPS_UINT8 spm_PM200[] = {0x40, 0x42, 0x44, 0x43, 0x20, 0x50, 0x4D, 0x0D, 0x0A, 0x53, 0x0A, 0x54, 0x26, 0x82, 0x2F, 0x54,\r
88                             0x0B, 0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x10, 0x54, 0x08, 0x02, 0x2F, 0x2F, 0x0D, \r
89                                                         0x0A};\r
90 const EPS_UINT8 spm_PM240[] = {0x40, 0x42, 0x44, 0x43, 0x20, 0x50, 0x4D, 0x0D, 0x0A, 0x53, 0x0A, 0x54, 0x26, 0x82, 0x2F, 0x54, \r
91                             0x0B, 0x82, 0x2F, 0x54, 0x2B, 0x82, 0x2F, 0x2F, 0x53, 0x2B, 0x54, 0x0B, 0x82, 0x2F, 0x2F, 0x53, \r
92                                                         0x10, 0x54, 0x08, 0x42, 0x2F, 0x2F, 0x0D, 0x0A};\r
93 \r
94 const SP_PM_STRINGS     spPMStrTbl[] = \r
95 {\r
96         { EPS_PMS_E300,  spm_E300,  sizeof(spm_E300)    },\r
97         { EPS_PMS_E500,  spm_E500,  sizeof(spm_E500)    },\r
98         { EPS_PMS_PM200, spm_PM200, sizeof(spm_PM200)   },\r
99         { EPS_PMS_PM240, spm_PM240, sizeof(spm_PM240)   }\r
100 };\r
101 \r
102 const EPS_UINT32 EPS_SPM_STRINGS = sizeof(spPMStrTbl) / sizeof(SP_PM_STRINGS);\r
103 \r
104 /*--------------------------------  Local Functions   ----------------------------------*/\r
105 /*******************************************|********************************************/\r
106 static EPS_INT32    _SP_LoadPMString                (EPS_UINT32, EPS_UINT8*, EPS_UINT32 );\r
107 static EPS_INT32    _pmFindSfield                   (EPS_UINT8, EPS_UINT8*, EPS_UINT8**, EPS_UINT8**);\r
108 static EPS_UINT8*   _pmScanTfield                   (EPS_UINT8, EPS_UINT8*              );\r
109 static EPS_INT16    _pmAppendTfield                 (EPS_UINT8*, EPS_UINT8*             );\r
110 static void         _pmValidateRemoveDelimiter      (EPS_UINT8*, EPS_UINT8*, EPS_INT32  );\r
111 static EPS_INT16    _pmValidateRemoveUnknownSfield  (EPS_UINT8*, EPS_UINT8*             );\r
112 static void         _pmCorrectUnknownTfield         (EPS_UINT8*, EPS_UINT8*             );\r
113 static void         _pmCorrectDupulicatedFields     (EPS_UINT8*, EPS_UINT8*             );\r
114 static void         _pmAdjustQuality                (EPS_UINT8*                         );\r
115 \r
116 /*-----------------------------------  Debug Dump  -------------------------------------*/\r
117 /*******************************************|********************************************/\r
118 #define _DEBUG_BIN_STATUS_          0       /* 0: OFF    1: ON                          */\r
119 \r
120 #if _DEBUG_BIN_STATUS_ || _VALIDATE_SUPPORTED_MEDIA_DATA_\r
121 #define SerDebugPrintf(a)  EPS_DBGPRINT( a )\r
122 #else\r
123 #define SerDebugPrintf(a)\r
124 #endif\r
125 \r
126 /*------------------------------------  Debug Dump   -----------------------------------*/\r
127 /*******************************************|********************************************/\r
128     /*** ALL Debug Dump Switch for <epson-escpr-service.c>                              */\r
129     /*** -------------------------------------------------------------------------------*/\r
130 #define _ESCPR_DEBUG_SP             0       /* 0: OFF    1: ON                          */\r
131 #define _ESCPR_DEBUG_SP_VERBOSE     0       /* 0: OFF    1: ON                          */\r
132 \r
133     /*** _ESCPR_DEBUG_SP --- Definition of << DUMP_PMREPLY() >>                         */\r
134     /*** -------------------------------------------------------------------------------*/\r
135 #if _ESCPR_DEBUG_SP | _VALIDATE_SUPPORTED_MEDIA_DATA_\r
136 \r
137 typedef enum _DUMP_TYPE {\r
138     DUMP_HEX = 0,\r
139     DUMP_ASCII,\r
140     DUMP_S_TAG_ONLY,\r
141 } DUMP_TYPE;\r
142 \r
143 char* str[] ={\r
144                  "DUMP_HEX",\r
145                  "DUMP_ASCII",\r
146                  "DUMP_S_TAG_ONLY",\r
147              };\r
148 \r
149 static void print_PMREPLY(EPS_UINT8* pm, DUMP_TYPE type, EPS_INT8* msg)\r
150 {\r
151     EPS_UINT8* p = pm;\r
152     EPS_INT16 col = 0;\r
153 \r
154     if(*p != 'S') {\r
155         if(type != DUMP_HEX) {\r
156             return; /* do not anything */\r
157         }\r
158 \r
159         /* Anyway if type is DUMP_HEX then dump it */\r
160     }\r
161 \r
162     printf("%s\r\n", msg);\r
163     printf("PM REPLY DUMP [TYPE:%s]\r\n", str[type]);\r
164 \r
165     if(type == DUMP_HEX) {\r
166         while(!((*p == 0x0D) && (*(p+1) == 0x0A))) {\r
167             printf("0x%02X ",   *p++);\r
168 \r
169             if((++col % 10) == 0) {\r
170                 printf("\r\n");\r
171             }\r
172         }\r
173 \r
174     } else {\r
175         while(*p == 'S') {\r
176             printf("%c ",   *p++);\r
177             printf("%02d\r\n", *p++);\r
178             while(*p == 'T') {\r
179                 printf("  %c",     *p++);\r
180                 printf("  %02d",   *p++);\r
181                 printf("  [0x%02X]", *p++);\r
182                 printf("  %c\r\n",     *p++);\r
183             }\r
184             printf("%c\r\n",     *p++);\r
185 \r
186             if(type == DUMP_S_TAG_ONLY) {\r
187                 break;\r
188             }\r
189 \r
190             if ((*p == 0x0D) && (*(p+1) == 0x0A)) {\r
191                 break;\r
192             }\r
193         }\r
194 \r
195     }\r
196 \r
197     if(type != DUMP_S_TAG_ONLY) {\r
198         printf("0x%02X ",   *p++);\r
199         printf("0x%02X ",   *p);\r
200     }\r
201 \r
202     printf("\r\nEND\r\n");\r
203 \r
204 }\r
205 #endif\r
206 \r
207 #if _ESCPR_DEBUG_SP\r
208 #define DUMP_PMREPLY(a) print_PMREPLY a\r
209 #else\r
210 #define DUMP_PMREPLY(a)\r
211 #endif\r
212 \r
213     /*** _ESCPR_DEBUG_SP_VERBOSE                                                        */\r
214     /***    --- Definition of << VERBOSE_DUMP_PMREPLY() >>  and << verbose_dbprint() >> */\r
215     /*** -------------------------------------------------------------------------------*/\r
216 #if _ESCPR_DEBUG_SP_VERBOSE\r
217 #define VERBOSE_DUMP_PMREPLY(a) print_PMREPLY a\r
218 #define verbose_dbprint(a)      EPS_DBGPRINT(a)\r
219 #else\r
220 #define VERBOSE_DUMP_PMREPLY(a)\r
221 #define verbose_dbprint(a)  \r
222 #endif\r
223 \r
224 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
225 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
226 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
227 /*--------------------              Public Functions               ---------------------*/\r
228 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
229 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
230 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
231 \r
232 /*******************************************|********************************************/\r
233 /*                                                                                      */\r
234 /* Function name:   serParseDeviceID()                                                  */\r
235 /*                                                                                      */\r
236 /* Arguments                                                                            */\r
237 /* ---------                                                                            */\r
238 /* Name:            Type:           Description:                                        */\r
239 /* deviceIDString       EPS_INT8*       I: DeviceID string                                  */\r
240 /* manufacturer         EPS_INT8*       I: Manufacturer Name                                */\r
241 /* modelName            EPS_INT8*       I: Model Name                                       */\r
242 /*                                                                                      */\r
243 /* Return value:                                                                        */\r
244 /*      TRUE                    - Success                                               */\r
245 /*      FALSE                   - Bad format or Not ESC/P-R device                      */\r
246 /*                                                                                      */\r
247 /* Description:                                                                         */\r
248 /*      Get the manufacturer name and modelName from DeviceID string.                   */\r
249 /*                                                                                      */\r
250 /*******************************************|********************************************/\r
251 EPS_BOOL     serParseDeviceID (\r
252 \r
253                 EPS_INT8*                       deviceIDString,\r
254         EPS_INT8*                       manufacturer,\r
255         EPS_INT8*                       modelName,\r
256         EPS_INT32*                      cmdLevel,\r
257                 EPS_UINT32*                     lang\r
258 \r
259 ){\r
260     EPS_INT8*       i;\r
261     EPS_INT8*       j;\r
262     EPS_INT8*       k;\r
263     EPS_INT8*       p;\r
264         EPS_BOOL                found = FALSE;\r
265 \r
266         EPS_LOG_FUNCIN;\r
267 \r
268 /*** Delete the data of the device ID length from string                                */\r
269         if(strlen(deviceIDString) < 2){\r
270                 EPS_RETURN( FALSE );\r
271         }\r
272     if(deviceIDString[0] == 0x00 || deviceIDString[1] == 0x00)\r
273         deviceIDString += 2;\r
274 \r
275 /*** ================================================================================== */\r
276 /*** Step 1: Check for ESC/PR Support                                                   */\r
277 /*** ================================================================================== */\r
278     if((i = strstr(deviceIDString, "CMD:")) == NULL) {\r
279                 EPS_RETURN( FALSE );\r
280         }\r
281         i += 4;\r
282 \r
283     if((j = strstr(i, ";")) == NULL) {\r
284                 EPS_RETURN( FALSE );\r
285         }\r
286         *j = '\0';\r
287 \r
288         while( NULL != i ){\r
289                 if((k = strstr(i, ",")) != NULL) {\r
290                         *k = '\0';\r
291                 }\r
292 \r
293                 if((p = strstr(i, "ESCPR")) != NULL) {\r
294                         found = TRUE;\r
295                         if(NULL != lang){\r
296                                 *lang = EPS_LANG_ESCPR;\r
297                         }\r
298                         if(NULL != cmdLevel){\r
299                                 sscanf(p+5, "%d", cmdLevel);\r
300                         }\r
301                         break;\r
302 \r
303 #ifdef GCOMSW_CMD_ESCPAGE\r
304                 } else if(strstr(i, "ESCPAGECOLOR") != NULL) {\r
305                         found = TRUE;\r
306                         if(NULL != lang){\r
307                                 *lang = EPS_LANG_ESCPAGE_COLOR;\r
308                         }\r
309                         if(NULL != cmdLevel){\r
310                                 *cmdLevel = 1;\r
311                         }\r
312                         break;\r
313 \r
314                 } else if(strstr(i, "ESCPAGE") != NULL) {\r
315                         if(strstr(i, "ESCPAGES") == NULL) {\r
316                                 found = TRUE;\r
317                                 if(NULL != lang){\r
318                                         *lang = EPS_LANG_ESCPAGE;\r
319                                 }\r
320                                 if(NULL != cmdLevel){\r
321                                         *cmdLevel = 1;\r
322                                 }\r
323 #ifdef GCOMSW_CMD_ESCPAGE_S\r
324                         } else{\r
325                                 found = pageS_ParseLang(i, cmdLevel, lang);\r
326 #endif\r
327                         }\r
328 #endif\r
329                 }\r
330 \r
331                 if(k){\r
332                         *k = ',';\r
333                         i = k+1;\r
334                         if(i >= j){\r
335                                 break;\r
336                         }\r
337                 } else{\r
338                         break;\r
339                 }\r
340         }\r
341         if(k)*k = ',';\r
342 \r
343         *j = ';';\r
344 \r
345         if(FALSE == found){\r
346                 EPS_RETURN( FALSE );\r
347         }\r
348 \r
349     \r
350 /*** ================================================================================== */\r
351 /*** Step 2: Get Manufacturer Name                                                      */\r
352 /*** ================================================================================== */\r
353     if((i = strstr(deviceIDString, "MFG:")) == NULL) {\r
354         /* Invalid device ID. */\r
355                 EPS_RETURN( FALSE );\r
356         }\r
357     \r
358     i += 4;\r
359     j  = i;\r
360     \r
361     while(*j != ';')\r
362     {\r
363         j++;\r
364         \r
365         /* Emergency exit condition to prevent an infinite loop scenario; if we hit a   */\r
366         /* carriage return, we've run too far                                           */\r
367         if(*j == 0x0D) {\r
368             EPS_RETURN( FALSE );\r
369         }\r
370     }\r
371     /* Null-terminate the MFG substring. */\r
372     *j = 0;\r
373     \r
374     /* Make sure the manufacturer name is not longer than 64 bytes. */\r
375     if(strlen(i) < 64) {\r
376         strcpy(manufacturer, i);    /* If the name is OK, copy the whole string as-is */\r
377     }\r
378     else {\r
379         memcpy(manufacturer, i, 63);    /* If the name is longer than 64 bytes, only copy */\r
380     }                                   /* 63 bytes and leave the 64th as null terminator */\r
381     \r
382     /* Return the string to its original format. */\r
383     *j = ';';\r
384     \r
385 /*** ================================================================================== */\r
386 /*** Step 3: Get Model Name                                                             */\r
387 /*** ================================================================================== */\r
388     if((i = strstr(deviceIDString, "MDL:")) == NULL) {\r
389         /* Invalid device ID. */\r
390                 EPS_RETURN( FALSE );\r
391         }\r
392     \r
393     i += 4;\r
394     j  = i;\r
395     \r
396     while (*j != ';')\r
397     {\r
398         j++;\r
399         \r
400         /* Emergency exit condition to prevent an infinite loop scenario; if we hit a   */\r
401         /* carriage return, we've run too far                                           */\r
402         if(*j == 0x0D){\r
403             /* Invalid device ID. */\r
404             EPS_RETURN( FALSE );\r
405         }\r
406     }\r
407     \r
408     /* Null-terminate the MDL substring. */\r
409     *j = 0;\r
410     \r
411     /* Make sure the model name is not longer than 64 bytes. */\r
412     if(strlen(i) < 64) {\r
413         strcpy(modelName, i);   /* If the name is OK, copy the whole string as-is */\r
414     }\r
415     else {\r
416         memcpy(modelName, i, 63);   /* If the name is longer than 64 bytes, only copy */\r
417                                     /* 63 bytes, leaving the 64th as null terminator  */\r
418     }\r
419     \r
420     EPS_RETURN( TRUE );\r
421 }\r
422 \r
423 \r
424 /*******************************************|********************************************/\r
425 /*                                                                                      */\r
426 /* Function name:   serAnalyzeStatus()                                                  */\r
427 /*                                                                                      */\r
428 /* Arguments                                                                            */\r
429 /* ---------                                                                            */\r
430 /* Name:        Type:               Description:                                        */\r
431 /* Status       EPS_INT8*           I: Printer Status string                            */\r
432 /* pstInfo      EPS_STATUS_INFO*    O: Printer Status information                       */\r
433 /*                                                                                      */\r
434 /* Return value:                                                                        */\r
435 /*      EPS_ERR_NONE                    - Success                                       */\r
436 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */\r
437 /*                                                                                      */\r
438 /* Description:                                                                         */\r
439 /*      Get the printer status and analyze the status string.                           */\r
440 /*                                                                                      */\r
441 /*******************************************|********************************************/\r
442 EPS_ERR_CODE    serAnalyzeStatus (\r
443 \r
444         EPS_INT8*           Status,\r
445         EPS_STATUS_INFO*    pstInfo\r
446 \r
447 ){\r
448     EPS_UINT8*  Field;\r
449     EPS_UINT8*  EndField;\r
450     EPS_INT32   i;\r
451     EPS_INT32   Min;\r
452     \r
453     EPS_UINT8   Header;\r
454     EPS_UINT8   ParameterByte;\r
455     EPS_INT8*   Ink;\r
456     EPS_INT8    Parameter[128];\r
457     EPS_UINT8   InkCartridgeType = 0;\r
458 \r
459         EPS_LOG_FUNCIN;\r
460 \r
461         if((Field = (EPS_UINT8*)strstr(Status,"ST2")) == NULL ){\r
462         SerDebugPrintf(("EPS SER: Get Stat -> ST not found [%s]\r\n",Status));\r
463         EPS_RETURN( EPS_ERR_COMM_ERROR );\r
464     }\r
465     \r
466     pstInfo->nState = EPS_ST_IDLE;\r
467     pstInfo->nError = EPS_PRNERR_NOERROR;\r
468     pstInfo->nWarn  = EPS_PRNWARN_NONE;\r
469 #if _DEBUG_BIN_STATUS_\r
470         EPS_DUMP(Status, 256);    \r
471 #endif\r
472     Field    = Field + 5;\r
473     EndField = Field + (2+(*Field)+ ((*(Field+1))*256) );\r
474     Field    = Field + 2;\r
475     \r
476     while ( Field < EndField ) {\r
477     \r
478         Header        = (EPS_UINT8) Field[0];\r
479         ParameterByte = (EPS_UINT8) Field[1];\r
480         memcpy(Parameter, Field+2, (EPS_INT8)ParameterByte );\r
481         \r
482         Field = Field + 2 + ParameterByte;\r
483         \r
484         switch( Header ) {\r
485             case 0x01: /* ST */\r
486                 switch( Parameter[0] ) {\r
487                     case 0x00: pstInfo->nState = EPS_ST_ERROR;               break;\r
488                     case 0x01: pstInfo->nState = EPS_ST_SELF_PRINTING;       break;\r
489                     case 0x02: pstInfo->nState = EPS_ST_BUSY;                break;\r
490                     case 0x03: pstInfo->nState = EPS_ST_WAITING;             break;\r
491                     case 0x04: pstInfo->nState = EPS_ST_IDLE;                break;\r
492                 /*  case 0x05: pstInfo->nState = EPS_ST_PAUSE;               break;*/    /* Not supported by 2006 Model */\r
493                 /*  case 0x06: pstInfo->nState = EPS_ST_INKDRYING            break;*/    /* Not supported by 2006 Model */\r
494                     case 0x07: pstInfo->nState = EPS_ST_CLEANING;            break;\r
495                     case 0x08: pstInfo->nState = EPS_ST_FACTORY_SHIPMENT;    break;\r
496                 /*  case 0x09: pstInfo->nState = EPS_ST_MOTOR_DRIVE_OFF;     break;*/    /* Not supported by 2006 Model */\r
497                     case 0x0A: pstInfo->nState = EPS_ST_SHUTDOWN;            break;\r
498                 /*  case 0x0B: pstInfo->nState = EPS_ST_WAITPAPERINIT;       break;*/    /* Not supported by 2006 Model */\r
499                 /*  case 0x0C: pstInfo->nState = EPS_ST_INIT_PAPER;          break;*/    /* Not supported by 2006 Model */\r
500                     default:   \r
501                                                 pstInfo->nState = EPS_ST_ERROR;               \r
502                                                 if(pstInfo->nError == EPS_PRNERR_NOERROR){\r
503                                                         pstInfo->nError = EPS_PRNERR_GENERAL;\r
504                                                 }\r
505                                                 break;\r
506                 }\r
507                 break;\r
508             case 0x02: /* ER */\r
509                                 EPS_DBGPRINT(("* ERR 0x%02X *\n", Parameter[0]))\r
510                 switch(Parameter[0]) {\r
511                     case 0x00: pstInfo->nError = EPS_PRNERR_FATAL;                  break;\r
512                     case 0x01: pstInfo->nError = EPS_PRNERR_INTERFACE;              break;\r
513                     case 0x02: \r
514                                                 if ( obsIsA3Model(EPS_MDC_STATUS) == TRUE ) {\r
515                                                         pstInfo->nError = EPS_PRNERR_CDRGUIDEOPEN;\r
516                                                 } else{\r
517                                                         pstInfo->nError = EPS_PRNERR_COVEROPEN;\r
518                                                 }\r
519                                                 break;\r
520                 /*  case 0x03: pstInfo->nError = EPS_PRNERR_LEVERPOSITION;          break;*/    /* Not supported by 2006 Model */\r
521                     case 0x04: pstInfo->nError = EPS_PRNERR_PAPERJAM;               break;\r
522                     case 0x05: pstInfo->nError = EPS_PRNERR_INKOUT;                 break;\r
523                     case 0x06: pstInfo->nError = EPS_PRNERR_PAPEROUT;               break;\r
524                 /*  case 0x07: pstInfo->nError = EPS_PRNERR_INITIALIZESETTING;      break;*/    /* Not supported by 2006 Model */\r
525                 /*  case 0x08: pstInfo->nError = EPS_PRNERR_UNKNOWN;                break;*/    /* Not supported by 2006 Model */\r
526                 /*  case 0x09: pstInfo->nError = EPS_PRNERR_PAPERCHANGE_UNCOMP;     break;*/    /* Not supported by 2006 Model */\r
527                     case 0x0A: pstInfo->nError = EPS_PRNERR_SIZE_TYPE_PATH/*EPS_PRNERR_PAPERSIZE*/;break;/* supported by 2008 Model */\r
528                 /*  case 0x0B: pstInfo->nError = EPS_PRNERR_RIBBONJAM;              break;*/    /* Not supported by 2006 Model */\r
529                     case 0x0C: pstInfo->nError = EPS_PRNERR_SIZE_TYPE_PATH;         break;\r
530                 /*  case 0x0D: pstInfo->nError = EPS_PRNERR_PAPERTHICKLEVER;        break;*/    /* Not supported by 2006 Model */\r
531                 /*  case 0x0E: pstInfo->nError = EPS_PRNERR_PAPERFEED;              break;*/    /* Not supported by 2006 Model */\r
532                 /*  case 0x0F: pstInfo->nError = EPS_PRNERR_SIMMCOPY;               break;*/    /* Not supported by 2006 Model */\r
533                     case 0x10: pstInfo->nError = EPS_PRNERR_SERVICEREQ;             break;\r
534                 /*  case 0x11: pstInfo->nError = EPS_PRNERR_WAITTEAROFFRETURN;      break;*/    /* Not supported by 2006 Model */\r
535                     case 0x12: pstInfo->nError = EPS_PRNERR_DOUBLEFEED;             break;\r
536                 /*  case 0x13: pstInfo->nError = EPS_PRNERR_HEADHOT;                break;*/    /* Not supported by 2006 Model */\r
537                 /*  case 0x14: pstInfo->nError = EPS_PRNERR_PAPERCUTMIS;            break;*/    /* Not supported by 2006 Model */\r
538                 /*  case 0x15: pstInfo->nError = EPS_PRNERR_HOLDLEVERRELEASE;       break;*/    /* Not supported by 2006 Model */\r
539                 /*  case 0x16: pstInfo->nError = EPS_PRNERR_NOT_CLEANING;           break;*/    /* Not supported by 2006 Model */\r
540                 /*  case 0x17: pstInfo->nError = EPS_PRNERR_PAPERCONFIG;            break;*/    /* Not supported by 2006 Model */\r
541                 /*  case 0x18: pstInfo->nError = EPS_PRNERR_PAPERSLANT;             break;*/    /* Not supported by 2006 Model */\r
542                 /*  case 0x19: pstInfo->nError = EPS_PRNERR_CLEANINGNUMOVER;        break;*/    /* Not supported by 2006 Model */\r
543                     case 0x1A: pstInfo->nError = EPS_PRNERR_INKCOVEROPEN;           break;\r
544                 /*  case 0x1B: pstInfo->nError = EPS_PRNERR_LFP_INKCARTRIDGE;       break;*/    /* Not supported by 2006 Model */\r
545                 /*  case 0x1C: pstInfo->nError = EPS_PRNERR_CUTTER;                 break;*/    /* Not supported by 2006 Model */\r
546                 /*  case 0x1D: pstInfo->nError = EPS_PRNERR_CUTTERJAM;              break;*/    /* Not supported by 2006 Model */\r
547                 /*  case 0x1E: pstInfo->nError = EPS_PRNERR_INKCOLOR;               break;*/    /* Not supported by 2006 Model */\r
548                 /*  case 0x1F: pstInfo->nError = EPS_PRNERR_CUTTERCOVEROPEN;        break;*/    /* Not supported by 2006 Model */\r
549                 /*  case 0x20: pstInfo->nError = EPS_PRNERR_LFP_INKLEVERRELEASE;    break;*/    /* Not supported by 2006 Model */\r
550                 /*  case 0x22: pstInfo->nError = EPS_PRNERR_LFP_NOMAINTENANCETANK1; break;*/    /* Not supported by 2006 Model */\r
551                 /*  case 0x23: pstInfo->nError = EPS_PRNERR_CARTRIDGECOMBINATION;   break;*/    /* Not supported by 2006 Model */\r
552                 /*  case 0x24: pstInfo->nError = EPS_PRNERR_LFP_COMMAND;            break;*/    /* Not supported by 2006 Model */\r
553                 /*  case 0x25: pstInfo->nError = EPS_PRNERR_LEARCOVEROPEN;          break;*/    /* Not supported by 2006 Model */\r
554                     case 0x25: pstInfo->nError = EPS_PRNERR_COVEROPEN;              break;\r
555                 /*  case 0x26: pstInfo->nError = EPS_PRNERR_MULTICENSORGAIN;        break;*/    /* Not supported by 2006 Model */\r
556                 /*  case 0x27: pstInfo->nError = EPS_PRNERR_NOT_AUTOADJUST;         break;*/    /* Not supported by 2006 Model */\r
557                 /*  case 0x28: pstInfo->nError = EPS_PRNERR_FAILCLEANING;           break;*/    /* Not supported by 2006 Model */\r
558                     case 0x29: pstInfo->nError = EPS_PRNERR_NOTRAY;                 break;\r
559                     case 0x2A: pstInfo->nError = EPS_PRNERR_CARDLOADING;            break;\r
560                     case 0x2B: \r
561                                                 if ( obsIsA3Model(EPS_MDC_STATUS) == TRUE ) {\r
562                                                         pstInfo->nError = EPS_PRNERR_CDRGUIDEOPEN;\r
563                                                 } else {\r
564                                                         pstInfo->nError = EPS_PRNERR_CDDVDCONFIG;                                                       /* supported by 2008 Model */\r
565                                                 }\r
566                                                 break;\r
567                     case 0x2C: pstInfo->nError = EPS_PRNERR_CARTRIDGEOVERFLOW;      break;\r
568                 /*  case 0x2D: pstInfo->nError = EPS_PRNERR_LFP_NOMAINTENANCETANK2; break;*/    /* Not supported by 2006 Model */\r
569                 /*  case 0x2E: pstInfo->nError = EPS_PRNERR_INKOVERFLOW2;           break;*/    /* Not supported by 2006 Model */\r
570                     case 0x2F: pstInfo->nError = EPS_PRNERR_BATTERYVOLTAGE;         break;\r
571                     case 0x30: pstInfo->nError = EPS_PRNERR_BATTERYTEMPERATURE;     break;\r
572                     case 0x31: pstInfo->nError = EPS_PRNERR_BATTERYEMPTY;           break;\r
573                     case 0x32: pstInfo->nError = EPS_PRNERR_SHUTOFF;                break;      /* Not supported by 2006 Model */\r
574                     case 0x33: pstInfo->nError = EPS_PRNERR_NOT_INITIALFILL;        break;      /* Not supported by 2006 Model */\r
575                     case 0x34: pstInfo->nError = EPS_PRNERR_PRINTPACKEND;           break;      /* Not supported by 2006 Model */\r
576                 /*  case 0x35: pstInfo->nError = EPS_PRNERR_ABNORMALHEAT;           break;*/    /* Not supported by 2006 Model */\r
577                     case 0x37:\r
578                                                 if ( obsIsA3Model(EPS_MDC_STATUS) == TRUE ) {\r
579                                                         pstInfo->nError = EPS_PRNERR_COVEROPEN;\r
580                                                 } else {\r
581                                                         pstInfo->nError = EPS_PRNERR_SCANNEROPEN;\r
582                                                 }\r
583                                                 break;\r
584                     case 0x38:\r
585                                                 if ( obsIsA3Model(EPS_MDC_STATUS) == TRUE ) {\r
586                                                         pstInfo->nError = EPS_PRNERR_CDDVDCONFIG;\r
587                                                 } else {\r
588                                                         pstInfo->nError = EPS_PRNERR_CDRGUIDEOPEN;\r
589                                                 }\r
590                                                 break;\r
591                     case 0x44: pstInfo->nError = EPS_PRNERR_CDRGUIDEOPEN;                       break;\r
592                                         case 0x45: pstInfo->nError = EPS_PRNERR_CDREXIST_MAINTE;                break;\r
593                                         case 0x46: pstInfo->nError = EPS_PRNERR_TRAYCLOSE;                              break;\r
594                                         case 0x47: pstInfo->nError = EPS_PRNERR_INKOUT;                                 break;          /* BlackPrint Error */\r
595 \r
596                                         default:   \r
597                                                 pstInfo->nError = EPS_PRNERR_GENERAL;                \r
598                                                 break;\r
599                 }\r
600                 break;\r
601             case 0x04: /* WR */\r
602                 /* ESC/P-R Lib does not notified the warning to application, */\r
603                 /* so warning analysis dose not need to be done completely.  */\r
604                                 pstInfo->nWarn = EPS_PRNWARN_NONE;\r
605                                 for(i = 0; i < ParameterByte; i++){\r
606                                         if( Parameter[i] >= 0x10 && Parameter[i] <= 0x1A ){\r
607                                                 /* Ink Low Warning */\r
608                                                 pstInfo->nWarn |= EPS_PRNWARN_INKLOW;\r
609                                         } else if( Parameter[i] >= 0x51 && Parameter[i] <= 0x5A ){\r
610                                                 pstInfo->nWarn |= EPS_PRNWARN_DISABLE_CLEAN;\r
611                                         /*} else if( Parameter[i] == 0x44 ){    not use\r
612                                                 pstInfo->nWarn |= EPS_PRNWARN_COLOR_INKOUT;*/\r
613                                         }\r
614                                 }\r
615                 break;\r
616 \r
617             case 0x0F: /* INK */\r
618                 Ink = Parameter;\r
619                 \r
620                 pstInfo->nInkError = EPS_INKERR_NONE;\r
621 \r
622                 if (Ink[1] >= 0x40) {\r
623                     InkCartridgeType = MI_CARTRIDGE_ONE;\r
624                 } else {\r
625                     InkCartridgeType = MI_CARTRIDGE_INDEP;\r
626                 }\r
627                 \r
628                 for( pstInfo->nInkNo=0, i=0; i<EPS_INK_NUM; i++ ) {\r
629                     pstInfo->nColorType[i] = EPS_COLOR_UNKNOWN;\r
630                     pstInfo->nColor[i]     = EPS_INK_NOTAVAIL;\r
631                     \r
632                     if( Ink > Parameter+ParameterByte-Parameter[0] )\r
633                         continue;\r
634                     \r
635                     pstInfo->nInkNo++;\r
636 \r
637                     switch( Ink[2] ) {\r
638                         \r
639                         case 0x00:    pstInfo->nColorType[i] = EPS_COLOR_BLACK;        break;\r
640                         case 0x01:    pstInfo->nColorType[i] = EPS_COLOR_CYAN;         break;\r
641                         case 0x02:    pstInfo->nColorType[i] = EPS_COLOR_MAGENTA;      break;\r
642                         case 0x03:    pstInfo->nColorType[i] = EPS_COLOR_YELLOW;       break;\r
643                         case 0x04:    pstInfo->nColorType[i] = EPS_COLOR_LIGHTCYAN;    break;\r
644                         case 0x05:    pstInfo->nColorType[i] = EPS_COLOR_LIGHTMAGENTA; break;\r
645                         case 0x06:    pstInfo->nColorType[i] = EPS_COLOR_LIGHTYELLOW;  break;\r
646                         case 0x07:    pstInfo->nColorType[i] = EPS_COLOR_DARKYELLOW;   break;\r
647                         case 0x08:    pstInfo->nColorType[i] = EPS_COLOR_LIGHTBLACK;   break;\r
648                         case 0x09:    pstInfo->nColorType[i] = EPS_COLOR_RED;          break;\r
649                         case 0x0A:    pstInfo->nColorType[i] = EPS_COLOR_VIOLET;       break;\r
650                         case 0x0B:    pstInfo->nColorType[i] = EPS_COLOR_CLEAR;        break;\r
651                         case 0x0C:    pstInfo->nColorType[i] = EPS_COLOR_LIGHTLIGHTBLACK;    break;\r
652                         case 0x0D:    pstInfo->nColorType[i] = EPS_COLOR_ORANGE;                break;\r
653                         case 0x0E:    pstInfo->nColorType[i] = EPS_COLOR_GREEN;                 break;\r
654                         default:     \r
655                                                         pstInfo->nColorType[i] = EPS_COLOR_UNKNOWN;      \r
656                                                         break;\r
657                     }\r
658 \r
659                     switch( Ink[3] ) {\r
660                         case 'w' :\r
661                         case 'r' :\r
662                             pstInfo->nColor[i] = EPS_INK_FAIL;\r
663                             ( pstInfo->nColorType[i]==EPS_COLOR_BLACK ) ? \r
664                                 (pstInfo->nInkError=EPS_INKERR_CFAILB) : (pstInfo->nInkError=EPS_INKERR_CFAILC);\r
665                             break;\r
666                         case 'n' :\r
667                             pstInfo->nColor[i] = EPS_INK_NOTPRESENT;\r
668                             ( pstInfo->nColorType[i]==EPS_COLOR_BLACK ) ?\r
669                                 (pstInfo->nInkError = EPS_INKERR_CEMPTYB) : (pstInfo->nInkError = EPS_INKERR_CEMPTYC);\r
670                             break;\r
671                         case 'i' :\r
672                             pstInfo->nColor[i] = EPS_INK_NOREAD;\r
673                             break;\r
674                         default:\r
675                             if((Ink[3] >= 0) && (Ink[3] <= 100)) {\r
676                                 \r
677                                 pstInfo->nColor[i] = serInkLevelNromalize( Ink[3] );\r
678                                 \r
679                                 if( pstInfo->nColor[i] == 0) {\r
680                                     if( pstInfo->nColorType[i]==EPS_COLOR_BLACK )\r
681                                         (pstInfo->nInkError = EPS_INKERR_INKENDB);\r
682                                     else\r
683                                         (pstInfo->nInkError = EPS_INKERR_INKENDC);\r
684                                 }\r
685                             } else {\r
686                                 pstInfo->nColor[i] = EPS_INK_FAIL;\r
687                                 if( pstInfo->nColorType[i]==EPS_COLOR_BLACK )\r
688                                     (pstInfo->nInkError=EPS_INKERR_CFAILB);\r
689                                 else\r
690                                     (pstInfo->nInkError=EPS_INKERR_CFAILC);\r
691                             }\r
692                             break;\r
693                     }\r
694 \r
695                     Ink = Ink + Parameter[0];\r
696                 }\r
697                 \r
698                 if((InkCartridgeType == MI_CARTRIDGE_ONE)){\r
699                     switch(pstInfo->nInkError) {\r
700                         case EPS_INKERR_INKENDB:\r
701                         case EPS_INKERR_INKENDC:\r
702                             pstInfo->nInkError = EPS_INKERR_INKENDALL;\r
703                             break;\r
704                         case EPS_INKERR_CFAILB:\r
705                         case EPS_INKERR_CFAILC:\r
706                             pstInfo->nInkError = EPS_INKERR_CFAILALL;\r
707                             break;\r
708                         case EPS_INKERR_CEMPTYB:\r
709                         case EPS_INKERR_CEMPTYC:\r
710                             pstInfo->nInkError = EPS_INKERR_CEMPTYALL;\r
711                             break;\r
712                     }\r
713                 }\r
714                 break;\r
715             case 0x13: /* CANCEL REQUEST by Printer cancel botton */\r
716                 switch((EPS_UINT8)Parameter[0]) {\r
717                     case 0x81:\r
718                         pstInfo->nCancel = EPS_CAREQ_CANCEL;\r
719                         break;\r
720                     default:\r
721                         pstInfo->nCancel = EPS_CAREQ_NOCANCEL;\r
722                         break;\r
723                 }\r
724                 break;\r
725             case 0x18: /* Stacker(tray) open status */\r
726                 switch((EPS_UINT8)Parameter[0]) {\r
727                     case 0x02:  /* Closed*/\r
728                         pstInfo->nPrepare = EPS_PREPARE_TRAYCLOSED;\r
729                         break;\r
730                     case 0x03: /* Open*/\r
731                         pstInfo->nPrepare = EPS_PREPARE_TRAYOPENED;\r
732                         break;\r
733                 }\r
734                 break;\r
735             case 0x1C: /* Temperature information */\r
736                 switch((EPS_UINT8)Parameter[0]) {\r
737                     case 0x01: /* The printer temperature is higher than 40C*/\r
738                         pstInfo->nPrepare = EPS_PREPARE_OVERHEAT;\r
739                         break;\r
740                     case 0x00: /* The printer temperature is lower than 40C*/\r
741                         pstInfo->nPrepare = EPS_PREPARE_NORMALHEAT;\r
742                         break;\r
743                 }\r
744                 break;\r
745 \r
746             default:\r
747                 break;\r
748         }\r
749     }\r
750 \r
751         if( EPS_CAREQ_CANCEL == pstInfo->nCancel ){\r
752                 EPS_DBGPRINT(("*** Cancel Request (ignore error) ***\n"))\r
753                 pstInfo->nState = EPS_ST_WAITING;\r
754                 pstInfo->nError = EPS_PRNERR_NOERROR;\r
755         }\r
756 \r
757 #if _DEBUG_BIN_STATUS_\r
758     SerDebugPrintf(("***** ST = %d\r\n", pstInfo->nState));\r
759     SerDebugPrintf(("***** ER = %d\r\n", pstInfo->nError));\r
760     SerDebugPrintf(("***** WR = %d\r\n", pstInfo->nWarn));\r
761     SerDebugPrintf(("***** CA = %d\r\n", pstInfo->nCancel));\r
762     SerDebugPrintf(("***** INK NUM = %d\r\n", pstInfo->nInkNo));\r
763     for(i = 0; i < pstInfo->nInkNo; i++){\r
764     SerDebugPrintf(("***** INK = %d\t%d\r\n", pstInfo->nColorType[i], pstInfo->nColor[i]));\r
765     }\r
766 #endif\r
767         \r
768         if(InkCartridgeType == MI_CARTRIDGE_ONE) {\r
769         Min = pstInfo->nColor[0];\r
770         for(i = 1; i < pstInfo->nInkNo; i++){\r
771             Min = ( (Min <= pstInfo->nColor[i]) ? Min : pstInfo->nColor[i] );\r
772         }\r
773         for(i = 0; i < pstInfo->nInkNo; i++){\r
774             pstInfo->nColor[i] = Min;\r
775         }\r
776     }\r
777 \r
778     EPS_RETURN( EPS_ERR_NONE );\r
779 \r
780 }\r
781 \r
782 EPS_INT32    serInkLevelNromalize (\r
783 \r
784                 EPS_INT32 level\r
785 \r
786 ){\r
787     if (       (level >= 75) && (level <= 100)) {\r
788         return 100;\r
789     } else if ((level >= 50) && (level <=  74)) {\r
790         return  75;\r
791     } else if ((level >= 25) && (level <=  49)) {\r
792         return  50;\r
793     } else if ((level >=  4) && (level <=  24)) {\r
794         return  25;\r
795     } else if ((level >=  1) && (level <=   3)) {\r
796         return   1;\r
797     } else if ( level ==  0) {\r
798         return   0;\r
799     }\r
800 \r
801         return level;\r
802 }\r
803  \r
804 \r
805 /*******************************************|********************************************/\r
806 /*                                                                                      */\r
807 /* Function name:   serDelayThread()                                                    */\r
808 /*                                                                                      */\r
809 /* Arguments                                                                            */\r
810 /* ---------                                                                            */\r
811 /* Name:        Type:               Description:                                        */\r
812 /* milliseconds EPS_UINT32          I: Sleep Period in microseconds                     */\r
813 /*                                                                                      */\r
814 /* Return value:                                                                        */\r
815 /*      None                                                                            */\r
816 /*                                                                                      */\r
817 /* Description:                                                                         */\r
818 /*      Wait <milliseconds>.                                                            */\r
819 /*      If OS sleep function is used, change the unit of sleep time from milliseconds   */\r
820 /*      to microseconds.                                                                */\r
821 /*                                                                                      */\r
822 /*******************************************|********************************************/\r
823 void    serDelayThread (\r
824 \r
825         EPS_UINT32              milliseconds,\r
826                 EPS_CMN_FUNC*   epsCmnFnc\r
827 \r
828 ){\r
829 \r
830 #ifdef GCOMSW_EPSON_SLEEP\r
831     if (epsCmnFnc->sleep == serSleep) {\r
832         epsCmnFnc->sleep((EPS_UINT32)milliseconds); /* Ignore return value of sleep func */\r
833     } else{\r
834         epsCmnFnc->sleep(milliseconds * 1000);      /* Ignore return value of sleep func */\r
835     }\r
836 #else\r
837     epsCmnFnc->sleep(milliseconds * 1000);          /* Ignore return value of sleep func */\r
838 #endif /* GCOMSW_EPSON_SLEEP */\r
839 \r
840 }\r
841 \r
842 /*******************************************|********************************************/\r
843 /*                                                                                      */\r
844 /* Function name:   serSleep()                                                          */\r
845 /*                                                                                      */\r
846 /* Arguments                                                                            */\r
847 /* ---------                                                                            */\r
848 /* Name:        Type:               Description:                                        */\r
849 /* sleepPeriod  EPS_UINT32          I: Sleep Period in milliseconds                     */\r
850 /*                                                                                      */\r
851 /* Return value:                                                                        */\r
852 /*      EPS_ERR_NONE                    - Success                                       */\r
853 /*                                                                                      */\r
854 /* Description:                                                                         */\r
855 /*      ESC/P-R Lib original sleep function.                                            */\r
856 /*      This function is used when "epsCmnFnc.sleep = NULL".                            */\r
857 /*                                                                                      */\r
858 /*******************************************|********************************************/\r
859 #ifdef GCOMSW_EPSON_SLEEP\r
860 EPS_ERR_CODE    serSleep (\r
861 \r
862         EPS_UINT32  sleepPeriod             /* Sleep Period in milliseconds             */\r
863 \r
864 ){\r
865 \r
866 /*** Declare Variable Local to Routine                                                  */\r
867     EPS_INT32    idx;                       /* General loop/index varaible              */\r
868     EPS_INT32    endx;\r
869     struct timeb sleepM;\r
870 \r
871 /*** Initialize Local Variables                                                         */\r
872     endx = sleepPeriod*printJob.sleepSteps;\r
873     if (printJob.sleepSteps <= 0) endx = sleepPeriod/(-printJob.sleepSteps);\r
874 \r
875 /*** Sleep for about the requested sleepPeriod                                          */\r
876     for (idx = 1; idx < endx; idx++) {ftime(&sleepM); } \r
877 \r
878 /*** Return to Caller                                                                   */\r
879     return((EPS_ERR_CODE)EPS_ERR_NONE);\r
880 \r
881 }\r
882 #endif /* GCOMSW_EPSON_SLEEP */\r
883 \r
884 \r
885 /*******************************************|********************************************/\r
886 /*                                                                                      */\r
887 /* Function name:   serGetInkError()                                                    */\r
888 /*                                                                                      */\r
889 /* Arguments                                                                            */\r
890 /* ---------                                                                            */\r
891 /* Name:        Type:               Description:                                        */\r
892 /* pStatInfo    EPS_STATUS_INFO*    I: Printer Status Information                       */\r
893 /* pNotify      EPS_INT32*          O: Notification Code                                */\r
894 /*                                                                                      */\r
895 /* Return value:                                                                        */\r
896 /*      EPS_ERR_NONE                    - Success                                       */\r
897 /*      EPS_ERR_OPR_FAIL                - Failed to operate                             */\r
898 /*                                                                                      */\r
899 /* Description:                                                                         */\r
900 /*      Set notification code about ink error                                           */\r
901 /*                                                                                      */\r
902 /*******************************************|********************************************/\r
903 EPS_INT32    serGetInkError (\r
904 \r
905         EPS_STATUS_INFO*    pStatInfo,\r
906         EPS_INT32*          pNotify\r
907 \r
908 ){\r
909     SerDebugPrintf(("EPS SER : In Get Ink Error\r\n"));\r
910 \r
911     SerDebugPrintf(("EPS SER : In SP CTG %d,%d,%d,%d,%d,%d,%d,%d\r\n",\r
912                                 pStatInfo->nColor[0],\r
913                                 pStatInfo->nColor[1],\r
914                                 pStatInfo->nColor[2],\r
915                                 pStatInfo->nColor[3],\r
916                                 pStatInfo->nColor[4],\r
917                                 pStatInfo->nColor[5],\r
918                                 pStatInfo->nColor[6],\r
919                                 pStatInfo->nColor[7]));\r
920 \r
921     switch(pStatInfo->nInkError){\r
922 /*** Ink End                                                                            */\r
923         case EPS_INKERR_INKENDALL:\r
924         case EPS_INKERR_INKENDB:\r
925         case EPS_INKERR_INKENDC:\r
926             *pNotify  = EPS_PRNERR_INKOUT;\r
927             break;\r
928 \r
929 /*** Ink Fail                                                                           */\r
930         case EPS_INKERR_CFAILALL:\r
931         case EPS_INKERR_CFAILB:\r
932         case EPS_INKERR_CFAILC:\r
933             *pNotify = EPS_PRNERR_CFAIL;\r
934             break;\r
935 \r
936 /*** Ink Empty                                                                          */\r
937         case EPS_INKERR_CEMPTYALL:\r
938         case EPS_INKERR_CEMPTYB:\r
939         case EPS_INKERR_CEMPTYC:\r
940             *pNotify = EPS_PRNERR_CEMPTY;\r
941             break;\r
942 \r
943         case EPS_INKERR_NONE:\r
944             break;\r
945 \r
946         default:\r
947             return EPS_ERR_OPR_FAIL;\r
948     }\r
949     \r
950     return EPS_ERR_NONE;\r
951 }\r
952 \r
953 \r
954 /*******************************************|********************************************/\r
955 /*                                                                                      */\r
956 /* Function name:   _SP_ChangeSpec_UpdatePMReply()                                      */\r
957 /*                                                                                      */\r
958 /* Arguments                                                                            */\r
959 /* ---------                                                                            */\r
960 /* Name:        Type:               Description:                                        */\r
961 /* printer      EPS_PRINTER_INN*    I/O: Pointer to a printer infomation                */\r
962 /* orgPmString  EPS_UINT8*          I: String of the pm command reply                   */\r
963 /*                                                                                      */\r
964 /* Return value:                                                                        */\r
965 /*      EPS_ERR_NONE                    - Success                                       */\r
966 /*      EPS_ERR_SP_INVALID_POINTER      - Input pointer error                           */\r
967 /*      EPS_ERR_SP_INVALID_HEADER       - pm string header error                        */\r
968 /*      EPS_ERR_SP_INVALID_TERMINATOR   - pm string terminator error                    */\r
969 /*      EPS_ERR_SP_NO_VALID_FIELD       - pm string field error                         */\r
970 /*                                                                                      */\r
971 /* Description:                                                                         */\r
972 /*      - Invalid formats       : Delete                                                */\r
973 /*      - Unknown 'S' field     : Delete                                                */\r
974 /*      - Unknown 'T' field     : Replace to PGPP-Premium Glossy Photo Paper(id:0x0b)   */\r
975 /*                                field If PGPP aleady exist its 'S' field then just    */\r
976 /*                                combine the mode property                             */\r
977 /*      - Duplicated 'S' fields : Merge together                                        */\r
978 /*      - Duplicated 'T' fields : Merge together and combine each mode properties       */\r
979 /*      - Only DRAFT mode exist : Add NORMAL mode to its print quality property         */\r
980 /*                                                                                      */\r
981 /* NOTE:                                                                                */\r
982 /*      Be sure that the pData is a pointers that a starting address of 512 bytes       */\r
983 /*      buffer should be assigned or memory acces violation should be occured.          */\r
984 /*                                                                                      */\r
985 /*******************************************|********************************************/\r
986 EPS_ERR_CODE     _SP_ChangeSpec_UpdatePMReply (\r
987 \r
988                 EPS_PRINTER_INN*    printer,\r
989         EPS_UINT8*                  orgPmString,\r
990         EPS_INT32                   bufSize\r
991 \r
992 ){\r
993 \r
994 /*** Declare Variable Local to Routine                                                  */\r
995     EPS_UINT8* pBefore = NULL;\r
996     EPS_UINT8* pAfter  = NULL;\r
997     EPS_UINT8* pSrc    = NULL;\r
998     EPS_UINT8* pDes    = NULL;\r
999     EPS_UINT8  tempPmString[EPS_PM_MAXSIZE];    /* Retrieved PM data from printer       */\r
1000     EPS_UINT8  paperSize;\r
1001     EPS_UINT8  paperType;\r
1002 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1003         EPS_UINT8  PmStringForCompare[EPS_PM_MAXSIZE];    /* Retrieved PM data from printer       */\r
1004 #endif    \r
1005     static const EPS_UINT8 PM_REPLY_HEADER[EPS_PM_HEADER_LEN] = {\r
1006       /*  @     B     D     C   <SP>    P     M   <CR>  <LF> */\r
1007         0x40, 0x42, 0x44, 0x43, 0x20, 0x50, 0x4D, 0x0D, 0x0A\r
1008     };\r
1009         \r
1010     EPS_INT16 idx;\r
1011 \r
1012         EPS_LOG_FUNCIN;\r
1013 \r
1014 /*** Validate input parameters                                                          */\r
1015     if(orgPmString == NULL) {\r
1016         SerDebugPrintf(("_SP_ChangeSpec_UpdatePMReply > EPS_ERR_SP_INVALID_POINTER\r\n"));\r
1017         EPS_RETURN( EPS_ERR_SP_INVALID_POINTER );\r
1018     }\r
1019 \r
1020     if(memcmp(orgPmString, PM_REPLY_HEADER, EPS_PM_HEADER_LEN) != 0) {\r
1021         SerDebugPrintf(("_SP_ChangeSpec_UpdatePMReply > EPS_ERR_SP_INVALID_HEADER\r\n"));\r
1022         EPS_RETURN( EPS_ERR_SP_INVALID_HEADER );\r
1023     }\r
1024 \r
1025     for(idx = EPS_PM_HEADER_LEN; idx <= (EPS_PM_MAXSIZE-EPS_PM_TERMINATOR_LEN); idx++) {\r
1026         if(orgPmString[idx]== 0x0D && orgPmString[idx+1] == 0x0A) {\r
1027             break;\r
1028         }\r
1029     }\r
1030 \r
1031     if(idx > (EPS_PM_MAXSIZE-EPS_PM_TERMINATOR_LEN)) {\r
1032         SerDebugPrintf(("_SP_ChangeSpec_UpdatePMReply > EPS_ERR_SP_INVALID_TERMINATOR\r\n"));\r
1033         EPS_RETURN( EPS_ERR_SP_INVALID_TERMINATOR );\r
1034     }\r
1035 \r
1036 /*** Initialize Local Variables                                                         */\r
1037     memset(tempPmString, 0x00, EPS_PM_MAXSIZE);\r
1038 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1039     memset(PmStringForCompare, 0x00, EPS_PM_MAXSIZE);\r
1040 #endif\r
1041 \r
1042     /* Initialize pm data state */\r
1043     memset(printer->pmData.pmString, 0x00, EPS_PM_MAXSIZE);\r
1044     printer->pmData.state = EPS_PM_STATE_NOT_FILTERED;\r
1045 \r
1046 /*** Correct PM REPLY following 7 steps                                                 */\r
1047 /*** ---------------------------------------------------------------------------------- */\r
1048 /*** STEP 1 : Replace Built-in resource. Because PM REPLY of the following printers     */\r
1049 /***          is insufficient,                                                          */\r
1050 /*** ---------------------------------------------------------------------------------- */\r
1051         if(        (strcmp(printer->modelName, "E-300" ) == 0) ){\r
1052                 bufSize = _SP_LoadPMString(EPS_PMS_E300, orgPmString, EPS_PM_MAXSIZE);\r
1053 \r
1054         } else if( (strcmp(printer->modelName, "E-500" ) == 0) ||\r
1055                        (strcmp(printer->modelName, "E-700" ) == 0) ) {\r
1056         bufSize = _SP_LoadPMString(EPS_PMS_E500, orgPmString, EPS_PM_MAXSIZE);\r
1057 \r
1058         } else if( (strcmp(printer->modelName, "PictureMate PM 200" ) == 0) ||\r
1059                        (strcmp(printer->modelName, "PictureMate PM 210" ) == 0) ){\r
1060         bufSize = _SP_LoadPMString(EPS_PMS_PM200, orgPmString, EPS_PM_MAXSIZE);\r
1061 \r
1062         } else if( (strcmp(printer->modelName, "PictureMate PM 240" ) == 0) ||\r
1063                        (strcmp(printer->modelName, "PictureMate PM 250" ) == 0) ||\r
1064                            (strcmp(printer->modelName, "PictureMate PM 280" ) == 0) ){\r
1065         bufSize = _SP_LoadPMString(EPS_PMS_PM240, orgPmString, EPS_PM_MAXSIZE);\r
1066         }\r
1067         if(bufSize <= 0){\r
1068                 return bufSize;\r
1069         }\r
1070 \r
1071         \r
1072         /* Use work pointers to call each filter functions */\r
1073     pBefore = orgPmString + EPS_PM_HEADER_LEN;             /* position of first tab 'S' */\r
1074     pAfter  = tempPmString;\r
1075         bufSize -= EPS_PM_HEADER_LEN;\r
1076 \r
1077 /*** ---------------------------------------------------------------------------------- */\r
1078 /*** STEP 2 : Remove <CR><LF> on the way                                                */\r
1079 /*** ---------------------------------------------------------------------------------- */\r
1080     pSrc = pBefore;\r
1081     pDes = pAfter;\r
1082 \r
1083     DUMP_PMREPLY((pSrc, DUMP_HEX, "< ORIGINAL >"));\r
1084 \r
1085     _pmValidateRemoveDelimiter(pDes, pSrc, bufSize);\r
1086 \r
1087 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1088         if(memcmp(pBefore, pAfter, EPS_PM_DATA_LEN) != 0){\r
1089                 printf("!!!!!!!!! PM reply data modified on STEP 2. !!!!!!!!!\nRemove <CR><LF> on the way\n\n");\r
1090         }\r
1091 #endif\r
1092     /* Update orgPmString                                                               */\r
1093         memcpy(pBefore, pAfter, EPS_PM_DATA_LEN);\r
1094 \r
1095     VERBOSE_DUMP_PMREPLY((pDes, DUMP_ASCII, "< STEP 1 PASSED >"));\r
1096         \r
1097 /*** ---------------------------------------------------------------------------------- */\r
1098 /*** STEP 3 : Copy only valid fields to reply buffer and remove unknown 'S' from reply  */\r
1099 /*** ---------------------------------------------------------------------------------- */\r
1100     pSrc = pBefore;\r
1101     pDes = pAfter;\r
1102 \r
1103     DUMP_PMREPLY((pSrc, DUMP_HEX, "< ORIGINAL >"));\r
1104 \r
1105         if(_pmValidateRemoveUnknownSfield(pDes, pSrc) == 0) {\r
1106         SerDebugPrintf(("_SP_ChangeSpec_UpdatePMReply > EPS_ERR_SP_NO_VALID_FIELD\r\n"));\r
1107         EPS_RETURN( EPS_ERR_SP_NO_VALID_FIELD );\r
1108     }\r
1109 \r
1110 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1111         if(memcmp(pBefore, pAfter, EPS_PM_DATA_LEN) != 0){\r
1112                 printf("!!!!!!!!! PM reply data modified on STEP 3. !!!!!!!!!\n\n\n");\r
1113             print_PMREPLY(pAfter, DUMP_HEX, "< Filterd >");\r
1114         }\r
1115 #endif\r
1116     /* Update orgPmString                                                               */\r
1117         memcpy(pBefore, pAfter, EPS_PM_DATA_LEN);\r
1118 \r
1119     VERBOSE_DUMP_PMREPLY((pDes, DUMP_ASCII, "< STEP 1 PASSED >"));\r
1120 \r
1121 /*** ---------------------------------------------------------------------------------- */\r
1122 /*** STEP 4 : Correct unknown 'T' fields                                                */\r
1123 /*** ---------------------------------------------------------------------------------- */\r
1124     pSrc = pBefore;\r
1125     pDes = pAfter;\r
1126 \r
1127     _pmCorrectUnknownTfield(pDes, pSrc);\r
1128 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1129         if(memcmp(pBefore, pAfter, EPS_PM_DATA_LEN) != 0){\r
1130                 printf("!!!!!!!!! PM reply data modified on STEP 4. !!!!!!!!!\n\n\n");\r
1131             print_PMREPLY(pAfter, DUMP_HEX, "< Filterd >");\r
1132         }\r
1133 #endif\r
1134 \r
1135     /* Update orgPmString                                                               */\r
1136         memcpy(pBefore, pAfter, EPS_PM_DATA_LEN);\r
1137 \r
1138         VERBOSE_DUMP_PMREPLY((pDes, DUMP_ASCII, "< STEP 2 PASSED >"));\r
1139 \r
1140 /*** ---------------------------------------------------------------------------------- */\r
1141 /*** STEP 5 : Merge duplicated fields                                                   */\r
1142 /*** ---------------------------------------------------------------------------------- */\r
1143     pSrc = pBefore;\r
1144     pDes = pAfter;\r
1145 \r
1146     _pmCorrectDupulicatedFields(pDes, pSrc);\r
1147 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1148         if(memcmp(pBefore, pAfter, EPS_PM_DATA_LEN) != 0){\r
1149                 printf("!!!!!!!!! PM reply data modified on STEP 5. !!!!!!!!!\n\n\n");\r
1150             print_PMREPLY(pAfter, DUMP_HEX, "< Filterd >");\r
1151         }\r
1152 #endif\r
1153 \r
1154     /* Update orgPmString                                                               */\r
1155         memcpy(pBefore, pAfter, EPS_PM_DATA_LEN);\r
1156 \r
1157         VERBOSE_DUMP_PMREPLY((pDes, DUMP_ASCII, "< STEP 3 PASSED >"));\r
1158 \r
1159     /* Now, Service Pack retains filtered data its original quality properties */\r
1160     /* within the inner buffer g_PMinfo.data */\r
1161     /* This data would be referenced whenever it is required to compare its originality */\r
1162     DUMP_PMREPLY((orgPmString, DUMP_ASCII, \\r
1163                   "< FILTERED (Retained within SP-same printer's caps) >"));\r
1164 \r
1165 \r
1166 /*** ---------------------------------------------------------------------------------- */\r
1167 /*** STEP 6 : Delete the paper type "CD/DVD label" from the pm string when "Stylus      */\r
1168 /***          Photo R380" or "Stylus Photo RX580" is used.                              */\r
1169 /*** ---------------------------------------------------------------------------------- */\r
1170         if ((strcmp(printer->modelName, "Stylus Photo R380" ) == 0) ||\r
1171         (strcmp(printer->modelName, "Stylus Photo RX580") == 0)    ) {\r
1172 \r
1173             pSrc = pBefore;\r
1174         pDes = pAfter;\r
1175         paperSize = 0xFF;\r
1176         paperType = 0xFF;\r
1177 \r
1178         while (*pSrc == 'S') {\r
1179             paperSize = *(pSrc + 1);        /* Save the media size                      */\r
1180 \r
1181             *pDes++ = *pSrc++;            /* set 'S'                                  */\r
1182             *pDes++ = *pSrc++;            /* set the meida size                       */\r
1183 \r
1184             while (*pSrc == 'T') {\r
1185                 paperType = *(pSrc + 1);    /* Save the media type                      */\r
1186                 \r
1187                 if ((paperSize == EPS_MSID_LETTER) && (paperType == EPS_MTID_CDDVD)) {\r
1188                     pSrc += 4;              /* Move to next 'T'                         */\r
1189                 } else{\r
1190                     *pDes++ = *pSrc++;    /* set 'T'                                  */\r
1191                     *pDes++ = *pSrc++;    /* set the media type                       */\r
1192                     *pDes++ = *pSrc++;    /* set the printing mode info               */\r
1193                     *pDes++ = *pSrc++;    /* set '/'                                  */\r
1194                 }\r
1195             }\r
1196             if (*pSrc == '/') {\r
1197                 *pDes++ = *pSrc++;        /* set '/'                                  */\r
1198             }\r
1199 \r
1200             /* check for string termination                                                 */\r
1201             if ((*pSrc == 0xD) && (*(pSrc+1) == 0xA)) {\r
1202                 *pDes++ = *pSrc++;\r
1203                 *pDes++ = *pSrc++;\r
1204                 break;\r
1205             }\r
1206         }\r
1207 \r
1208         /* Update orgPmString                                                               */\r
1209         memcpy(pBefore, pAfter, EPS_PM_DATA_LEN);\r
1210     }\r
1211 \r
1212 /*** ---------------------------------------------------------------------------------- */\r
1213 /*** STEP 7 : Adjust quality properties to the formal in order to return to the driver. */\r
1214 /***          it dose not change the filtered data through previous steps retained      */\r
1215 /***          within Service Pack. but just change the buffer asigned as parameter.     */\r
1216 /***          (in this case orgPmString)                                                */\r
1217 /***          after duplicating the filtered data to it.                                */\r
1218 /*** ---------------------------------------------------------------------------------- */\r
1219     /* set filterd value "printer->pmData.pmString" */\r
1220     memset(printer->pmData.pmString, 0x00, EPS_PM_MAXSIZE);\r
1221     memcpy(printer->pmData.pmString, orgPmString, EPS_PM_MAXSIZE);\r
1222 \r
1223         printer->pmData.state = EPS_PM_STATE_FILTERED;\r
1224 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1225         memcpy(PmStringForCompare, orgPmString, EPS_PM_DATA_LEN);\r
1226 #endif\r
1227 \r
1228     /* If Draft Quality is only supported, add Normal Quality */\r
1229     _pmAdjustQuality(orgPmString);\r
1230 #if _VALIDATE_SUPPORTED_MEDIA_DATA_\r
1231         if(memcmp(PmStringForCompare, orgPmString, EPS_PM_DATA_LEN) != 0){\r
1232                 printf("!!!!!!!!! PM reply data modified on STEP 7. !!!!!!!!!\n\n\n");\r
1233             print_PMREPLY(PmStringForCompare + EPS_PM_HEADER_LEN, DUMP_HEX, "< Origin >");\r
1234             print_PMREPLY(orgPmString + EPS_PM_HEADER_LEN, DUMP_HEX, "< Filterd >");\r
1235         }\r
1236 #endif\r
1237         \r
1238         DUMP_PMREPLY((orgPmString+EPS_PM_HEADER_LEN, DUMP_ASCII, \\r
1239                   "< FILTERED (Returned data to the driver-adjusted quality properties) >"));\r
1240 \r
1241 /*** Return to caller                                                                   */\r
1242     EPS_RETURN( EPS_ERR_NONE );\r
1243 }\r
1244 \r
1245 \r
1246 /*******************************************|********************************************/\r
1247 /*                                                                                      */\r
1248 /* Function name:   _SP_ChangeSpec_DraftOnly()                                          */\r
1249 /*                                                                                      */\r
1250 /* Arguments                                                                            */\r
1251 /* ---------                                                                            */\r
1252 /* Name:        Type:               Description:                                        */\r
1253 /* printer      EPS_PRINTER_INN*    I/O: Pointer to a printer infomation                */\r
1254 /* jobAtter     EPS_JOB_ATTRIB*     I: Data structure containing page attribut settings */\r
1255 /*                                                                                      */\r
1256 /* Return value:                                                                        */\r
1257 /*      EPS_ERR_NONE                    - Success                                       */\r
1258 /*                                                                                      */\r
1259 /* Description:                                                                         */\r
1260 /*      If the quality mode which is not supported by printer is assigned, replace it   */\r
1261 /*      to printer's support mode.                                                      */\r
1262 /*                                                                                      */\r
1263 /*******************************************|********************************************/\r
1264 EPS_ERR_CODE     _SP_ChangeSpec_DraftOnly (\r
1265 \r
1266                 EPS_PRINTER_INN*    printer,\r
1267         EPS_JOB_ATTRIB*     jobAtter          /* Print Attributes for this Job         */\r
1268 \r
1269 ){\r
1270 /*** Declare Variable Local to Routine                                                  */\r
1271     EPS_UINT8  mediaSizeID;\r
1272     EPS_UINT8  mediaTypeID;\r
1273     EPS_UINT8* pPMinfo;\r
1274     EPS_UINT8* pS_begin;\r
1275     EPS_UINT8* pS_end;\r
1276     EPS_UINT8* pTfield;\r
1277     EPS_UINT8  quality[3];      /* Q_DRAFT / Q_NORMAL / Q_HIGH                          */\r
1278 \r
1279         EPS_LOG_FUNCIN;\r
1280 \r
1281 /*** Validate input parameters                                                          */\r
1282     if(printer->pmData.state != EPS_PM_STATE_FILTERED) {\r
1283         SerDebugPrintf(("ChangeSpec_DraftOnly : PM info not initialized\r\n"));\r
1284         /* it is not able to hadle this situation so do nothing */\r
1285         EPS_RETURN( EPS_ERR_NONE ); \r
1286     }\r
1287 \r
1288 /*** Initialize Global/Local Variables                                                  */\r
1289     mediaSizeID = (EPS_UINT8)jobAtter->mediaSizeIdx;\r
1290     mediaTypeID = (EPS_UINT8)jobAtter->mediaTypeIdx;\r
1291     pPMinfo     = NULL;\r
1292     pS_begin    = NULL;\r
1293     pS_end      = NULL;\r
1294     pTfield     = NULL;\r
1295         memset(quality, 0, sizeof(quality));\r
1296 \r
1297 /*** Change quality                                                                     */\r
1298     /* Refer the data retained within Service Pack. */\r
1299     /* "printer->pmData.pmString" has the header.   */\r
1300     pPMinfo = (EPS_UINT8*)(printer->pmData.pmString + EPS_PM_HEADER_LEN);\r
1301 \r
1302     /* S field start postion */\r
1303     if(_pmFindSfield(mediaSizeID, pPMinfo, &pS_begin, &pS_end) < 0) {\r
1304         SerDebugPrintf(("ChangeSpec_DraftOnly : cannot find mediaSizeID(%d)\r\n", mediaSizeID));\r
1305         /* it is not able to hadle this situation so do nothing */\r
1306         EPS_RETURN( EPS_ERR_NONE ); \r
1307     };\r
1308 \r
1309     VERBOSE_DUMP_PMREPLY((pS_begin, DUMP_S_TAG_ONLY, \r
1310             "< ChangeSpec_DraftOnly : retained S field info >"));\r
1311 \r
1312     /* Fetch the T field */\r
1313     if((pTfield = _pmScanTfield(mediaTypeID, pS_begin)) == NULL) {\r
1314         SerDebugPrintf(("ChangeSpec_DraftOnly : cannot find mediaTypeID(%d)\r\n", mediaTypeID));\r
1315         /* it is not able to hadle this situation so do nothing */\r
1316         EPS_RETURN( EPS_ERR_NONE ); \r
1317     }\r
1318 \r
1319     /* Quality should be assigned to the only supported mode */\r
1320     verbose_dbprint((" >> adjusted PrintQuality : %d -> ", jobAtter->printQuality));\r
1321 \r
1322         if(!((*(pTfield+2) & 0x07) &   /* Printer's support mode actually */\r
1323         (jobAtter->printQuality))) { /* Upper layer(driver) assigned mode */\r
1324 \r
1325         /* The quality mode which is not supported by printer is assigned */\r
1326         /* Replace it to printer's support mode */ \r
1327         switch(*(pTfield+2) & 0x07) {\r
1328             case 0x01: /* 0 0 1 : Draft  only       */\r
1329                 quality[Q_DRAFT]  = EPS_MQID_DRAFT;\r
1330                 quality[Q_NORMAL] = EPS_MQID_DRAFT;\r
1331                 quality[Q_HIGH]   = EPS_MQID_DRAFT;\r
1332                 break;\r
1333             case 0x02: /* 0 1 0 : Normal only       */\r
1334                 quality[Q_DRAFT]  = EPS_MQID_NORMAL;\r
1335                 quality[Q_NORMAL] = EPS_MQID_NORMAL;\r
1336                 quality[Q_HIGH]   = EPS_MQID_NORMAL;\r
1337                 break;\r
1338             case 0x04: /* 1 0 0 : High   only       */\r
1339                 quality[Q_DRAFT]  = EPS_MQID_HIGH;\r
1340                 quality[Q_NORMAL] = EPS_MQID_HIGH;\r
1341                 quality[Q_HIGH]   = EPS_MQID_HIGH;\r
1342                 break;\r
1343             case 0x03: /* 0 1 1 : Normal and Draft  */\r
1344                 quality[Q_DRAFT]  = EPS_MQID_DRAFT;\r
1345                 quality[Q_NORMAL] = EPS_MQID_NORMAL;\r
1346                 quality[Q_HIGH]   = EPS_MQID_NORMAL;\r
1347                 break;\r
1348             case 0x05: /* 1 0 1 : High   and Draft  */\r
1349                 quality[Q_DRAFT]  = EPS_MQID_DRAFT;\r
1350                 quality[Q_NORMAL] = EPS_MQID_HIGH;\r
1351                 quality[Q_HIGH]   = EPS_MQID_HIGH;\r
1352                 break;\r
1353             case 0x06: /* 1 1 0 : High   and Normal */\r
1354                 quality[Q_DRAFT]  = EPS_MQID_NORMAL;\r
1355                 quality[Q_NORMAL] = EPS_MQID_NORMAL;\r
1356                 quality[Q_HIGH]   = EPS_MQID_HIGH;\r
1357                 break;\r
1358             case 0x07: /* 1 1 1 : Anything possible */\r
1359                 break;\r
1360             default: \r
1361                 break;\r
1362         }\r
1363 \r
1364         /* Now, the value of quality array of index which is same as PrintQuality is valid */\r
1365                 switch(jobAtter->printQuality) {\r
1366                         case EPS_MQID_DRAFT:\r
1367                                 jobAtter->printQuality= quality[Q_DRAFT];\r
1368                                 break;\r
1369                         case EPS_MQID_NORMAL:\r
1370                                 jobAtter->printQuality= quality[Q_NORMAL];\r
1371                                 break;\r
1372                         case EPS_MQID_HIGH:\r
1373                                 jobAtter->printQuality= quality[Q_HIGH];\r
1374                                 break;\r
1375                 }\r
1376     }\r
1377 \r
1378     verbose_dbprint(("%d\r\n", jobAtter->printQuality));\r
1379 \r
1380     EPS_RETURN( EPS_ERR_NONE );\r
1381 }\r
1382 \r
1383 \r
1384 /*******************************************|********************************************/\r
1385 /*                                                                                      */\r
1386 /* Function name:   serAppendMedia()                                                    */\r
1387 /*                                                                                      */\r
1388 /* Arguments                                                                            */\r
1389 /* ---------                                                                            */\r
1390 /* Name:        Type:                Description:                                       */\r
1391 /* pMedia       EPS_SUPPORTED_MEDIA* I/O: supported media structuer                     */\r
1392 /*                                                                                      */\r
1393 /* Return value:                                                                        */\r
1394 /*      none                                                                            */\r
1395 /*                                                                                      */\r
1396 /* Description:                                                                         */\r
1397 /*      Append Media attribute from PM reply info.                                      */\r
1398 /*                                                                                      */\r
1399 /*******************************************|********************************************/\r
1400 void     serAppendMedia (\r
1401 \r
1402         EPS_SUPPORTED_MEDIA*  pMedia\r
1403 \r
1404 ){\r
1405     EPS_INT32       idxSize, idxType;\r
1406     EPS_BOOL        foundCD = FALSE;\r
1407 \r
1408         EPS_LOG_FUNCIN;\r
1409 \r
1410         for(idxSize = 0; idxSize < pMedia->numSizes; idxSize++){\r
1411                 /*** Append "CD/DVD Label" rayout to plain, CDDVD ***/\r
1412                 for(idxType = 0; idxType < pMedia->sizeList[idxSize].numTypes; idxType++){\r
1413 \r
1414                         if( EPS_IS_CDDVD( pMedia->sizeList[idxSize].typeList[idxType].mediaTypeID ) ){\r
1415                                 /* Set "CD/DVD Label" rayout to CDDVD */\r
1416                                 pMedia->sizeList[idxSize].typeList[idxType].layout = EPS_MLID_CDLABEL;\r
1417 \r
1418                                 /* paperSource is only CD tray */\r
1419                                 pMedia->sizeList[idxSize].typeList[idxType].paperSource = EPS_MPID_CDTRAY;\r
1420                                 \r
1421                                 foundCD = TRUE;\r
1422                         } else if(EPS_MTID_MINIPHOTO == pMedia->sizeList[idxSize].typeList[idxType].mediaTypeID){\r
1423                                 /* Append "16 Division" rayout to Photo Stickers */\r
1424                                 pMedia->sizeList[idxSize].typeList[idxType].layout |= EPS_MLID_DIVIDE16;\r
1425                         }\r
1426                 }\r
1427 \r
1428                 if(foundCD){\r
1429                         for(idxType = 0; idxType < pMedia->sizeList[idxSize].numTypes; idxType++){\r
1430                                 if(EPS_MTID_PLAIN == pMedia->sizeList[idxSize].typeList[idxType].mediaTypeID ){\r
1431                                         /* Append "CD/DVD Label" rayout to plain */\r
1432                                         pMedia->sizeList[idxSize].typeList[idxType].layout |= EPS_MLID_CDLABEL;\r
1433                                         break;\r
1434                                 }\r
1435                         }\r
1436                         foundCD = FALSE;\r
1437                 }\r
1438         }\r
1439 \r
1440         EPS_RETURN_VOID\r
1441 }\r
1442 \r
1443 \r
1444 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
1445 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
1446 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
1447 /*--------------------               Local Functions               ---------------------*/\r
1448 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/\r
1449 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
1450 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
1451 \r
1452 /*******************************************|********************************************/\r
1453 /*                                                                                      */\r
1454 /* Function name:   _SP_LoadPMString()                                                  */\r
1455 /*                                                                                      */\r
1456 /* Arguments                                                                            */\r
1457 /* ---------                                                                            */\r
1458 /* Name:        Type:               Description:                                        */\r
1459 /* resouceID    EPS_UINT32          I: PM resouce ID                                    */\r
1460 /* pString      EPS_INT8*           O: PM string                                        */\r
1461 /* bufSize      EPS_INT32           I: pString size                                     */\r
1462 /*                                                                                      */\r
1463 /* Return value:                                                                        */\r
1464 /* EPS_INT32    buffer size or error                                                    */\r
1465 /*                                                                                      */\r
1466 /* Description:                                                                         */\r
1467 /*      Load special PM string. Because a part of model is insufficient PM reply info.  */\r
1468 /*                                                                                      */\r
1469 /*******************************************|********************************************/\r
1470 EPS_INT32  _SP_LoadPMString (\r
1471 \r
1472         EPS_UINT32  resouceID,\r
1473         EPS_UINT8*  pString,\r
1474                 EPS_UINT32  bufSize\r
1475 \r
1476 ){\r
1477     EPS_UINT32 i = 0;\r
1478 \r
1479         for (i = 0; i < EPS_SPM_STRINGS; i++){\r
1480                 if (spPMStrTbl[i].id == resouceID){\r
1481                         if(bufSize < spPMStrTbl[i].len){\r
1482                                 return EPS_ERR_OPR_FAIL;\r
1483                         }\r
1484                         memcpy(pString, spPMStrTbl[i].res, spPMStrTbl[i].len);\r
1485                         return spPMStrTbl[i].len;\r
1486                 }\r
1487         }\r
1488 \r
1489         return EPS_ERR_OPR_FAIL;\r
1490 }\r
1491 \r
1492 \r
1493 /*******************************************|********************************************/\r
1494 /*                                                                                      */\r
1495 /* Function name:   _pmFindSfield()                                                     */\r
1496 /*                                                                                      */\r
1497 /* Arguments                                                                            */\r
1498 /* ---------                                                                            */\r
1499 /* Name:        Type:               Description:                                        */\r
1500 /* id           EPS_UINT8           I: Media Size ID                                    */\r
1501 /* pSrc         EPS_UINT8*          I: pm String                                        */\r
1502 /* pStart       EPS_UINT8**         O: Start Pointer of 'S' fields                      */\r
1503 /* pEnd         EPS_UINT8**         O: End Pointer of 'S' fields                        */\r
1504 /*                                                                                      */\r
1505 /* Return value:                                                                        */\r
1506 /*      Length of founded 'S' fields    - Success                                       */\r
1507 /*      -1                              - There is NOT the Media Size ID in pm string   */\r
1508 /*                                                                                      */\r
1509 /* Description:                                                                         */\r
1510 /*      Find a 'S' field that includes the <id> in <pSrc> and save its starting('S')    */\r
1511 /*      and ending pointer('/') to <pStart> and <pEnd>.                                 */\r
1512 /*      <pSrc> should be a complete PM REPLY format that start with 'S' and terminate   */\r
1513 /*      at "0x0D 0x0A".                                                                 */\r
1514 /*                                                                                      */\r
1515 /*******************************************|********************************************/\r
1516 static EPS_INT32    _pmFindSfield (\r
1517 \r
1518         EPS_UINT8   id,\r
1519         EPS_UINT8*  pSrc,\r
1520         EPS_UINT8** pStart,\r
1521         EPS_UINT8** pEnd\r
1522 \r
1523 ){\r
1524         EPS_LOG_FUNCIN;\r
1525 \r
1526     while (*pSrc != 0xD || *(pSrc+1) != 0xA) {\r
1527 \r
1528         *pStart = NULL;\r
1529         *pEnd   = NULL;\r
1530 \r
1531         /* find 'S' */\r
1532         while(*pSrc == 'S') {\r
1533             if(id == *(pSrc+1)) {\r
1534                 *pStart = pSrc;\r
1535             }\r
1536 \r
1537             pSrc += 2;\r
1538 \r
1539             while(*pSrc == 'T') {\r
1540                 pSrc += 4;\r
1541             }\r
1542 \r
1543             /* Found id */\r
1544             if(*pStart != NULL) {\r
1545                 *pEnd = pSrc;\r
1546                 EPS_RETURN( (EPS_INT32)(*pEnd - *pStart)+1 );\r
1547             }\r
1548 \r
1549             /* next 'S' */\r
1550             pSrc++;\r
1551         }\r
1552 \r
1553                 if(*pSrc == 'M' || *pSrc == 'R'){\r
1554                         pSrc += 6;\r
1555                 }\r
1556     }\r
1557 \r
1558     EPS_RETURN( (-1) );\r
1559 }\r
1560 \r
1561 \r
1562 /*******************************************|********************************************/\r
1563 /*                                                                                      */\r
1564 /* Function name:   _pmScanTfield()                                                     */\r
1565 /*                                                                                      */\r
1566 /* Arguments                                                                            */\r
1567 /* ---------                                                                            */\r
1568 /* Name:        Type:               Description:                                        */\r
1569 /* id           EPS_UINT8           Media Type ID                                       */\r
1570 /* pSfield      EPS_UINT8*          Pointer to 'S' field                                */\r
1571 /*                                                                                      */\r
1572 /* Return value:                                                                        */\r
1573 /*      Pointer to 'T' on the pSfield   - Success                                       */\r
1574 /*      NULL                            - There is NOT 'T' in the pSfield               */\r
1575 /*                                                                                      */\r
1576 /* Description:                                                                         */\r
1577 /*      Find 'T' field that includs the <id>.                                           */\r
1578 /*                                                                                      */\r
1579 /*******************************************|********************************************/\r
1580 static EPS_UINT8*   _pmScanTfield (\r
1581 \r
1582         EPS_UINT8   id,\r
1583         EPS_UINT8*  pSfield\r
1584 \r
1585 ){\r
1586     EPS_UINT8* pScan = pSfield;\r
1587     EPS_UINT8* pT    = NULL;\r
1588 \r
1589         if(*pScan == 'S') {\r
1590         pScan += 2;\r
1591 \r
1592         while(*pScan == 'T') {\r
1593             if(id == *(pScan+1)) {\r
1594                 pT = pScan;\r
1595                 break;\r
1596             }\r
1597 \r
1598             pScan += 4;\r
1599         }\r
1600     }\r
1601 \r
1602     return pT;\r
1603 \r
1604 }\r
1605 \r
1606 /*******************************************|********************************************/\r
1607 /*                                                                                      */\r
1608 /* Function name:   _pmAppendTfield()                                                   */\r
1609 /*                                                                                      */\r
1610 /* Arguments                                                                            */\r
1611 /* ---------                                                                            */\r
1612 /* Name:        Type:               Description:                                        */\r
1613 /* pT           EPS_UINT8*          I: Pointer to 'T' field                             */\r
1614 /* pDes         EPS_UINT8*          O: Pointer to 'S' field                             */\r
1615 /*                                                                                      */\r
1616 /* Return value:                                                                        */\r
1617 /*      4                               - Success (Return increased bytes)              */\r
1618 /*      -1                              - Failure                                       */\r
1619 /*                                                                                      */\r
1620 /* Description:                                                                         */\r
1621 /*      Append 'T' field to <pDes> if same field dose not exsit, but same one aleady    */\r
1622 /*      exsits just combine mode properdy.                                              */\r
1623 /*      <pDes> should have a complete 'S' field consist of 'S' and '/' and pT should    */\r
1624 /*      have a 'T' field of 4 bytes starts with 'T'.                                    */\r
1625 /*      This function returns the increased bytes so that caller change the last        */\r
1626 /*      position or (-1) to indicate nothing changed.                                   */\r
1627 /*                                                                                      */\r
1628 /*******************************************|********************************************/\r
1629 static EPS_INT16    _pmAppendTfield (\r
1630 \r
1631         EPS_UINT8*  pT,\r
1632         EPS_UINT8*  pDes\r
1633 \r
1634 ){\r
1635     EPS_UINT8 t_id    = *(pT+1);\r
1636     EPS_INT16 t_exist = 0;\r
1637 \r
1638         if(*pDes == 'S') {\r
1639 \r
1640         pDes += 2; /* move to first 'T' */\r
1641 \r
1642         while(*pDes == 'T') {\r
1643 \r
1644             /* same id exist */\r
1645             if(t_id == *(pDes+1)) {\r
1646                 /* Just combine mode property */\r
1647                 *(pDes+2) |= *(pT+2);\r
1648 \r
1649                 t_exist = 1;\r
1650                 break;\r
1651             }\r
1652 \r
1653             /* next 'T' */\r
1654             pDes += 4;\r
1655         }\r
1656 \r
1657         /* samd id field dose not exist */\r
1658         /* Append new 'T' fields */\r
1659         if(t_exist == 0) {\r
1660             memcpy(pDes, pT, 4);\r
1661             pDes += 4;\r
1662             *pDes = '/';\r
1663 \r
1664             return 4; /* size of 'T' field */\r
1665         }\r
1666 \r
1667         /* type id aleady exist then do not anything */\r
1668     }\r
1669 \r
1670     return (-1);\r
1671 \r
1672 }\r
1673 \r
1674 /*******************************************|********************************************/\r
1675 /*                                                                                      */\r
1676 /* Function name:   _pmValidateRemoveDelimiter()                                         */\r
1677 /*                                                                                      */\r
1678 /* Arguments                                                                            */\r
1679 /* ---------                                                                            */\r
1680 /* Name:        Type:               Description:                                        */\r
1681 /* pDes         EPS_UINT8*          O: Pointer to validated pm string                   */\r
1682 /* pSrc         EPS_UINT8*          I: Pointer to original pm string                    */\r
1683 /*                                                                                      */\r
1684 /* Return value:                                                                        */\r
1685 /*      The number of valid fields                                                      */\r
1686 /*                                                                                      */\r
1687 /* Description:                                                                         */\r
1688 /*      Copy valid fields to reply buffer only.                                         */\r
1689 /*      Remove <CR><LF> on the way.                                                     */\r
1690 /*                                                                                      */\r
1691 /*******************************************|********************************************/\r
1692 static void    _pmValidateRemoveDelimiter (\r
1693 \r
1694         EPS_UINT8*  pDes,\r
1695         EPS_UINT8*  pSrc, \r
1696                 EPS_INT32   bufSize\r
1697 \r
1698 ){\r
1699 \r
1700     EPS_UINT8* pEOF  = pSrc + bufSize;\r
1701 \r
1702         EPS_LOG_FUNCIN;\r
1703 \r
1704     while (pSrc < pEOF) {\r
1705 \r
1706         if(*pSrc == 'S') {\r
1707                         memcpy(pDes, pSrc, 2);\r
1708             pSrc += 2;\r
1709                         pDes += 2;\r
1710 \r
1711             while(*pSrc == 'T') {\r
1712                                 memcpy(pDes, pSrc, 3);\r
1713                 pSrc += 3;\r
1714                                 pDes += 3;\r
1715 \r
1716                 if(*pSrc == '/') {\r
1717                     *pDes++ = *pSrc++;\r
1718                 }\r
1719             }\r
1720 \r
1721             if(*pSrc == '/') {\r
1722                 *pDes++ = *pSrc++;\r
1723             }\r
1724 \r
1725                 } else if(*pSrc == 'M' || *pSrc == 'R'){\r
1726                         /* Jpeg size limit */ \r
1727                         if( *(pSrc + 5) == '/' ){\r
1728                                 memcpy(pDes, pSrc, 6 );\r
1729                                 pSrc += 6;\r
1730                                 pDes += 6;\r
1731                         }\r
1732                 } else if(*pSrc == 0xD || *(pSrc+1) == 0xA){\r
1733                         /* Terminater skip */\r
1734                         pSrc += 2;\r
1735                 } else{\r
1736                         /* unknown field */\r
1737                 pSrc++;\r
1738                 }\r
1739     }\r
1740 \r
1741         /* set truth terminater */\r
1742     *pDes++ = 0x0d;   /* 0xD */\r
1743     *pDes   = 0x0a;   /* 0xA */\r
1744 \r
1745     EPS_RETURN_VOID;\r
1746 }\r
1747 \r
1748 \r
1749 /*******************************************|********************************************/\r
1750 /*                                                                                      */\r
1751 /* Function name:   _pmValidateRemoveUnknownSfield()                                    */\r
1752 /*                                                                                      */\r
1753 /* Arguments                                                                            */\r
1754 /* ---------                                                                            */\r
1755 /* Name:        Type:               Description:                                        */\r
1756 /* pDes         EPS_UINT8*          O: Pointer to validated pm string                   */\r
1757 /* pSrc         EPS_UINT8*          I: Pointer to original pm string                    */\r
1758 /*                                                                                      */\r
1759 /* Return value:                                                                        */\r
1760 /*      The number of valid fields                                                      */\r
1761 /*                                                                                      */\r
1762 /* Description:                                                                         */\r
1763 /*      Copy valid fields to reply buffer only.                                         */\r
1764 /*      Remove unknown 'S' field.                                                       */\r
1765 /*      Minimum conditons for valid PM REPLY are                                        */\r
1766 /*       - it must have a complete 'S' field more than one ( 'S' ~ '/').                */\r
1767 /*       - it must end with 0xD and 0xA.                                                */\r
1768 /*                                                                                      */\r
1769 /*******************************************|********************************************/\r
1770 static EPS_INT16    _pmValidateRemoveUnknownSfield (\r
1771 \r
1772         EPS_UINT8*  pDes,\r
1773         EPS_UINT8*  pSrc\r
1774 \r
1775 ){\r
1776 \r
1777     EPS_UINT8* pPrev = NULL;    /* save previous pointer                                */\r
1778     EPS_UINT8* pS    = NULL;    /* valid field's starting position                      */\r
1779     EPS_UINT8* pE    = NULL;    /* valid field's ending postion                         */\r
1780 \r
1781     EPS_INT16  valid = 0;       /* flag for indicating 'S' field's validation           */\r
1782     EPS_INT16  t_cnt = 0;       /* count valid 'T' fields                               */\r
1783     EPS_UINT16 s_idx = 0;       /* index of epsMediaSize                                */\r
1784 \r
1785     EPS_INT16  num_valid_fields = 0;    /* value for returning                          */\r
1786 \r
1787         EPS_LOG_FUNCIN;\r
1788 \r
1789 #ifdef _TEST_PM_STEP_1 /* Change first 'S' field's id to unknown id such as 0xFF */\r
1790     *(pSrc+1) = 0xFF;\r
1791 #endif\r
1792 \r
1793     while (*pSrc != 0xD || *(pSrc+1) != 0xA) {\r
1794         pPrev = pSrc;\r
1795 \r
1796         pS    = NULL;\r
1797         pE    = NULL;\r
1798         valid = 0;\r
1799         t_cnt = 0;\r
1800         s_idx = 0;\r
1801 \r
1802         if(*pSrc == 'S') {\r
1803             pS    = pSrc;\r
1804             pSrc += 2;\r
1805 \r
1806             while(*pSrc == 'T') {\r
1807                 pSrc += 3;\r
1808 \r
1809                 if(*pSrc == '/') {\r
1810                     pSrc++;\r
1811                     t_cnt++;\r
1812                 }\r
1813             }\r
1814 \r
1815             if(t_cnt && *pSrc == '/') {\r
1816                 pE = pSrc;\r
1817             }\r
1818 \r
1819                 } else if(*pSrc == 'M' || *pSrc == 'R'){\r
1820                         /* Jpeg size limit */ \r
1821                         if( *(pSrc + 5) == '/' ){\r
1822                                 memcpy(pDes, pSrc, 6 );\r
1823                                 pDes += 6;\r
1824                                 pSrc += 6;\r
1825                                 continue;\r
1826                         }\r
1827                 }\r
1828 \r
1829         /* Copy valid and support 'S' fields only */\r
1830         /* Valid means size id should be find in its table */\r
1831         /* and 'T' field exist at least more than one */\r
1832         /* Unknown 'S' field should be removed */\r
1833         if(pS && pE) {\r
1834             for(s_idx = 0; s_idx < EPS_NUM_MEDIA_SIZES; s_idx++) {\r
1835                 if(epsMediaSize[s_idx].id == *(pS+1)) {\r
1836                     memcpy(pDes, pS, (EPS_UINT32)((pE-pS)+1) );\r
1837                     pDes += (pE-pS)+1;\r
1838                     valid = 1;\r
1839 \r
1840                     /* now increase num of valid fields */\r
1841                     num_valid_fields++;\r
1842 \r
1843                     break;\r
1844                 }\r
1845             }\r
1846         }\r
1847 \r
1848         /* Restore work buffer pos to the previous */\r
1849         /* cause fail to get a valid fields */\r
1850         if(valid == 0) {\r
1851             pSrc = pPrev;\r
1852         }\r
1853 \r
1854         pSrc++;\r
1855     }\r
1856 \r
1857     *pDes++ = *pSrc++;   /* 0xD */\r
1858     *pDes++ = *pSrc;     /* 0xA */\r
1859 \r
1860     EPS_RETURN( num_valid_fields );\r
1861 \r
1862 }\r
1863 \r
1864 \r
1865 /*******************************************|********************************************/\r
1866 /*                                                                                      */\r
1867 /* Function name:   _pmCorrectUnknownTfield()                                           */\r
1868 /*                                                                                      */\r
1869 /* Arguments                                                                            */\r
1870 /* ---------                                                                            */\r
1871 /* Name:        Type:               Description:                                        */\r
1872 /* pDes         EPS_UINT8*          O: Pointer to validated pm string                   */\r
1873 /* pSrc         EPS_UINT8*          I: Pointer to original pm string                    */\r
1874 /*                                                                                      */\r
1875 /* Return value:                                                                        */\r
1876 /*      None                                                                            */\r
1877 /*                                                                                      */\r
1878 /* Description:                                                                         */\r
1879 /*      Change an unknown 'T' field to PGPP's in case that PGPP dose not exist in       */\r
1880 /*      'S' field. If aleady PGPP exist delete it.                                      */\r
1881 /*                                                                                      */\r
1882 /*******************************************|********************************************/\r
1883 static void     _pmCorrectUnknownTfield (\r
1884 \r
1885         EPS_UINT8*  pDes,\r
1886         EPS_UINT8*  pSrc\r
1887 \r
1888 ){\r
1889 \r
1890     static const EPS_UINT8 PGPP_FIELD [ ] = { 0x54, 0x0B, 0x87, 0x2F };\r
1891 \r
1892     EPS_INT16 PGPP    = 0;      /* Premium Glossy Photo Paper (type id : 0x0b)          */\r
1893     EPS_UINT16 t_idx  = 0;      /* Index of table defined Support 'T' id table          */\r
1894     EPS_UINT8 * pScan = NULL;   /* word pointer for scanning id                         */\r
1895 \r
1896         EPS_LOG_FUNCIN;\r
1897 \r
1898 #ifdef _TEST_PM_STEP_2 /* Change 'T' field's id to unknown id such as 0xFF */\r
1899     *(pSrc+3) = 0xFF;\r
1900 #endif\r
1901 \r
1902     while (*pSrc != 0xD || *(pSrc+1) != 0xA) {\r
1903         /* reset PGPP flag each new 'S' field */\r
1904         PGPP = 0;\r
1905 \r
1906         if(*pSrc == 'S') {\r
1907             /* Scan PGPP in current 'S' field */\r
1908             pScan = pSrc;\r
1909 \r
1910             if(_pmScanTfield(EPS_MTID_PGPHOTO, pScan) != NULL) {\r
1911                 PGPP = 1;\r
1912             }\r
1913 \r
1914             *pDes++ = *pSrc++;\r
1915             *pDes++ = *pSrc++;\r
1916 \r
1917             while(*pSrc == 'T') {\r
1918                 /* Copy support 'T' field */\r
1919                 for(t_idx = 0; t_idx < EPS_NUM_MEDIA_TYPES; t_idx++) {\r
1920                     if(epsMediaTypeIndex[t_idx] == *(pSrc+1)) {\r
1921                         memcpy(pDes, pSrc, 4);\r
1922                         pDes += 4;\r
1923                         break;\r
1924                     }\r
1925                 }\r
1926 \r
1927                 /* Unknown type id encountered */\r
1928                 /* if PGPP did not exist in 'S' field */\r
1929                 /* then append PGPP fields to pDes */\r
1930                 if(t_idx == EPS_NUM_MEDIA_TYPES && PGPP == 0) {\r
1931                     memcpy(pDes, PGPP_FIELD, 4);\r
1932                     pDes += 4;\r
1933                     PGPP  = 1;\r
1934                 }\r
1935 \r
1936                 /* move to next 'T' */\r
1937                 pSrc += 4;\r
1938             }\r
1939 \r
1940             /* copy '/' and move next 'S' */\r
1941             *pDes++ = *pSrc++;\r
1942 \r
1943                 }else if(*pSrc == 'M' || *pSrc == 'R') {\r
1944                         memcpy(pDes, pSrc, 6);\r
1945                         pDes += 6;\r
1946                         pSrc += 6;\r
1947                 }\r
1948     }\r
1949 \r
1950     *pDes++ = *pSrc++;   /* 0xD */\r
1951     *pDes   = *pSrc;     /* 0xA */\r
1952 \r
1953     EPS_RETURN_VOID;\r
1954 }\r
1955 \r
1956 /*******************************************|********************************************/\r
1957 /*                                                                                      */\r
1958 /* Function name:   _pmCorrectDupulicatedFields()                                       */\r
1959 /*                                                                                      */\r
1960 /* Arguments                                                                            */\r
1961 /* ---------                                                                            */\r
1962 /* Name:        Type:               Description:                                        */\r
1963 /* pDes         EPS_UINT8*          O: Pointer to validated pm string                   */\r
1964 /* pSrc         EPS_UINT8*          I: Pointer to original pm string                    */\r
1965 /*                                                                                      */\r
1966 /* Return value:                                                                        */\r
1967 /*      None                                                                            */\r
1968 /*                                                                                      */\r
1969 /* Description:                                                                         */\r
1970 /*      Merge duplicated fields.                                                        */\r
1971 /*                                                                                      */\r
1972 /*******************************************|********************************************/\r
1973 static void     _pmCorrectDupulicatedFields (\r
1974 \r
1975         EPS_UINT8*  pDes,\r
1976         EPS_UINT8*  pSrc\r
1977 \r
1978 ){\r
1979     EPS_UINT8 merged_buf[EPS_PM_MAXSIZE];\r
1980 \r
1981     EPS_UINT8* pFieldS = NULL;      /* current 'S' in merged buffer                     */\r
1982     EPS_UINT8* pFieldT = NULL;      /* work pontter to merge a 'T'                      */\r
1983     EPS_UINT8* pS      = NULL;      /* duplicated field's starting position             */\r
1984     EPS_UINT8* pE      = NULL;      /* duplicated field's ending postion                */\r
1985     EPS_UINT8* pM      = NULL;      /* pos of merged buffer                             */\r
1986     EPS_UINT8* pScan   = NULL;      /* work pointer to find a field                     */\r
1987     EPS_UINT8  s_id    = 0xFF;      /* current 'S' id                                   */\r
1988     EPS_INT16  bytes;\r
1989 \r
1990         EPS_LOG_FUNCIN;\r
1991 \r
1992 #ifdef _TEST_PM_STEP_3\r
1993     *(pSrc+8) = 0x0F; /* make duplicate 'S' */\r
1994 #endif\r
1995         memset(merged_buf, 0, EPS_PM_MAXSIZE);\r
1996     pM = &merged_buf[0];\r
1997 \r
1998     /* Aleady merged fields no need to copy again */\r
1999     while (*pSrc != 0xD || *(pSrc+1) != 0xA) {\r
2000         pFieldS = NULL;\r
2001 \r
2002         if(*pSrc == 'S') {\r
2003             VERBOSE_DUMP_PMREPLY((pSrc, DUMP_S_TAG_ONLY, "< STEP 3 : SOURCE 'S' ... >"));\r
2004 \r
2005             /* save current 'S' id */\r
2006             s_id = *(pSrc+1);\r
2007 \r
2008             if(s_id != MERGED_FIELD) {\r
2009                 /* Current 'S' field's starting pos */\r
2010                 /* it is used to merge fields later */\r
2011                 pFieldS = pM;\r
2012 \r
2013                 COPY_BYTES(pM, pSrc, 2);\r
2014             }\r
2015 \r
2016             pSrc += 2; /* move to first 'T' */\r
2017 \r
2018             /* Merge 'T' fields */\r
2019             while(*pSrc == 'T') {\r
2020 \r
2021                 if(pFieldS && s_id != MERGED_FIELD) {\r
2022                     /* if 'T' aleady exist just combine its property by BIT OR operation */\r
2023                     if((pFieldT = _pmScanTfield(*(pSrc+1), pFieldS)) != NULL) {\r
2024                         *(pFieldT+2) |= *(pSrc+2);\r
2025                     }\r
2026 \r
2027                     /* Copy only new 'T' field */\r
2028                     if(pFieldT == NULL) {\r
2029                         COPY_BYTES(pM, pSrc, 4);\r
2030                     }\r
2031                 }\r
2032 \r
2033                 pSrc += 4; /* next 'T' */\r
2034             }\r
2035                 }else if(*pSrc == 'M' || *pSrc == 'R') {\r
2036                         memcpy(pM, pSrc, 6);\r
2037                         pM += 6;\r
2038                         pSrc += 6;\r
2039                         continue;\r
2040                 }\r
2041 \r
2042         if(s_id != MERGED_FIELD) {\r
2043             COPY_BYTES(pM, pSrc, 1);\r
2044         }\r
2045         pSrc++;\r
2046 \r
2047         /* aleady merged field just go on next */\r
2048         if(s_id == MERGED_FIELD)  {\r
2049             continue;\r
2050         }\r
2051 \r
2052         /*----------------------------------------------------*/\r
2053         /* Find dupulicated 'S' being followed and merge them */\r
2054 \r
2055         pScan = pSrc; /* do not change pSrc in following loop */\r
2056 \r
2057         while(_pmFindSfield(s_id, pScan, &pS, &pE) > 0) {\r
2058 \r
2059             /* Change source's 'S' id to MERGED_FIELD */\r
2060             *(pS+1) = MERGED_FIELD;\r
2061             pS     += 2;\r
2062 \r
2063             /* merge dupulicated 'T' */\r
2064             while(*pS == 'T') {\r
2065 \r
2066                 /* Append NEW 'T' field to the current 'S' field */\r
2067                 /* aleady same 'T' exist only its mode property will be combined */\r
2068                 /* after called function */\r
2069                 if(pFieldS) {\r
2070                     if((bytes = _pmAppendTfield(pS, pFieldS)) > 0) {\r
2071 \r
2072                     /* update merged_buf's the last pos that pM point it */\r
2073                     pM += bytes; /* MUST 4 BYTES(size of 'T' field) ! */\r
2074                     }\r
2075                 }\r
2076 \r
2077                 pS += 4; /* next 'T' */\r
2078             }\r
2079 \r
2080             /* find next 'S' */\r
2081             pScan = (pE+1);\r
2082 \r
2083             VERBOSE_DUMP_PMREPLY((pFieldS, DUMP_S_TAG_ONLY, "< STEP 3 : MERGE PROCESSING ... >"));\r
2084         }\r
2085     }\r
2086 \r
2087     /* 0x0D & 0x0A */\r
2088     COPY_BYTES(pM, pSrc, 2);\r
2089 \r
2090     /*----------------------------------*/\r
2091     /* Copy the merged PM REPLY to pDes */\r
2092 \r
2093     pM = &merged_buf[0];\r
2094 \r
2095     while (*pM != 0xD || *(pM+1) != 0xA) {\r
2096         *pDes++ = *pM++;\r
2097     }\r
2098 \r
2099     *pDes++ = *pM++; /* 0xD */\r
2100     *pDes   = *pM;   /* 0xA */\r
2101 \r
2102     EPS_RETURN_VOID;\r
2103 }\r
2104 \r
2105 /*******************************************|********************************************/\r
2106 /*                                                                                      */\r
2107 /* Function name:   _pmAdjustQuality()                                                  */\r
2108 /*                                                                                      */\r
2109 /* Arguments                                                                            */\r
2110 /* ---------                                                                            */\r
2111 /* Name:        Type:               Description:                                        */\r
2112 /* pData        EPS_UINT8*          I/O: Pointer to pm string                           */\r
2113 /*                                                                                      */\r
2114 /* Return value:                                                                        */\r
2115 /*      None                                                                            */\r
2116 /*                                                                                      */\r
2117 /* Description:                                                                         */\r
2118 /*      Adjust quality properties to the formal.                                        */\r
2119 /*      example : quality has only draft mode -> turn on normal mode.                   */\r
2120 /*                                                                                      */\r
2121 /*******************************************|********************************************/\r
2122 static void     _pmAdjustQuality (\r
2123 \r
2124         EPS_UINT8*  pData\r
2125 \r
2126 ){\r
2127     EPS_UINT8* p = pData;\r
2128 \r
2129         EPS_LOG_FUNCIN;\r
2130 \r
2131         /* skip pm heder */\r
2132     p += EPS_PM_HEADER_LEN;\r
2133 \r
2134     verbose_dbprint(("< STEP 4 :  Adjust quality >\r\n"));\r
2135 \r
2136     /* adjuct each quality properties */\r
2137     while(!(*p == 0x0D && *(p+1) == 0x0A)) {\r
2138 \r
2139         while(*p == 'S') {\r
2140 \r
2141             verbose_dbprint(("%c %02d\r\n", *p, *(p+1)));\r
2142 \r
2143             p += 2; /* move to the first T field */\r
2144 \r
2145             while(*p == 'T') {\r
2146 \r
2147                 verbose_dbprint(("\t%c %02d 0x%02x %c -> ", *p, *(p+1), *(p+2), *(p+3)));\r
2148 \r
2149                 p += 2; /* move to quality pos */\r
2150 \r
2151                 /* Quality property */\r
2152                 switch(*p & 0x07) {\r
2153                     /* Should be handled following case 1 bit of Draft turned on only */\r
2154                     case 0x01: /* 0 0 1 -> 0 1 1 */\r
2155                         *p |= (1<<1); /* turn normal on */\r
2156                         break;\r
2157                     default:\r
2158                         break;\r
2159                 }\r
2160 \r
2161                 verbose_dbprint(("%c %02d 0x%02x %c\r\n", *(p-2), *(p-1), *(p), *(p+1)));\r
2162 \r
2163                 p += 2; /* move to the next T field */\r
2164             }\r
2165 \r
2166             p += 1; /* move to the next S field */\r
2167         }\r
2168 \r
2169                 if(*p == 'M' || *p == 'R') {\r
2170                         p += 6;\r
2171                 }\r
2172     }\r
2173 \r
2174     EPS_RETURN_VOID;\r
2175 }\r
2176 \r
2177 \r
2178 /*******************************************|********************************************/\r
2179 /*                                                                                      */\r
2180 /* Function name:   obsSetPrinter()                                                     */\r
2181 /*                                                                                      */\r
2182 /* Arguments                                                                            */\r
2183 /* ---------                                                                            */\r
2184 /* Name:        Type:               Description:                                        */\r
2185 /* printer      EPS_PRINTER_INN8*   I: Pointer to printer info                          */\r
2186 /*                                                                                      */\r
2187 /* Return value:                                                                        */\r
2188 /*      None                                                                            */\r
2189 /*                                                                                      */\r
2190 /* Description:                                                                         */\r
2191 /*      set the observation target printer.                                             */\r
2192 /*                                                                                      */\r
2193 /*******************************************|********************************************/\r
2194 void     obsSetPrinter (\r
2195 \r
2196         const EPS_PRINTER_INN* printer\r
2197 \r
2198 ){\r
2199         g_observer.printer = printer;\r
2200 }\r
2201 \r
2202 \r
2203 /*******************************************|********************************************/\r
2204 /*                                                                                      */\r
2205 /* Function name:   obsSetColorPlane()                                                  */\r
2206 /*                                                                                      */\r
2207 /* Arguments                                                                            */\r
2208 /* ---------                                                                            */\r
2209 /* Name:        Type:               Description:                                        */\r
2210 /* colorPlane   EPS_UINT8           I: color plane                                      */\r
2211 /*                                                                                      */\r
2212 /* Return value:                                                                        */\r
2213 /*      None                                                                            */\r
2214 /*                                                                                      */\r
2215 /* Description:                                                                         */\r
2216 /*      set color plane of current job.                                                 */\r
2217 /*                                                                                      */\r
2218 /*******************************************|********************************************/\r
2219 void     obsSetColorPlane (\r
2220 \r
2221         EPS_UINT8 colorPlane\r
2222 \r
2223 ){\r
2224         g_observer.colorPlane = colorPlane;\r
2225 }\r
2226 \r
2227 \r
2228 /*******************************************|********************************************/\r
2229 /*                                                                                      */\r
2230 /* Function name:   obsClear()                                                          */\r
2231 /*                                                                                      */\r
2232 /* Arguments                                                                            */\r
2233 /* ---------                                                                            */\r
2234 /* Name:        Type:               Description:                                        */\r
2235 /* N/A                                                                                  */\r
2236 /*                                                                                      */\r
2237 /* Return value:                                                                        */\r
2238 /*      None                                                                            */\r
2239 /*                                                                                      */\r
2240 /* Description:                                                                         */\r
2241 /*      clear all property.                                                             */\r
2242 /*                                                                                      */\r
2243 /*******************************************|********************************************/\r
2244 void     obsClear (\r
2245 \r
2246         void\r
2247 \r
2248 ){\r
2249         g_observer.printer = NULL;\r
2250         g_observer.colorPlane = EPS_CP_FULLCOLOR;\r
2251 }\r
2252 \r
2253 \r
2254 /*******************************************|********************************************/\r
2255 /*                                                                                      */\r
2256 /* Function name:   obsGetPageMode()                                                    */\r
2257 /*                                                                                      */\r
2258 /* Arguments                                                                            */\r
2259 /* ---------                                                                            */\r
2260 /* Name:        Type:               Description:                                        */\r
2261 /* N/A                                                                                  */\r
2262 /*                                                                                      */\r
2263 /* Return value:                                                                        */\r
2264 /*      Means to page process.                                                          */\r
2265 /*                                                                                      */\r
2266 /* Description:                                                                         */\r
2267 /*      The means to page process is decided.                                           */\r
2268 /*                                                                                      */\r
2269 /*******************************************|********************************************/\r
2270 EPS_INT32     obsGetPageMode (\r
2271 \r
2272         void\r
2273 \r
2274 ){\r
2275         const EPS_INT8 *modelName = NULL;\r
2276 \r
2277         if( NULL == g_observer.printer ){\r
2278                 return EPS_PM_PAGE;\r
2279         }\r
2280 \r
2281         if(EPS_CP_JPEG == g_observer.colorPlane )\r
2282         {\r
2283                 modelName = g_observer.printer->modelName;\r
2284                 if( (strcmp(modelName, "EP-801A"             ) == 0) ||\r
2285                     (strcmp(modelName, "Artisan 700"         ) == 0) ||\r
2286                     (strcmp(modelName, "Stylus Photo TX700W" ) == 0) ||\r
2287                     (strcmp(modelName, "Stylus Photo PX700W" ) == 0) ||\r
2288                     (strcmp(modelName, "EP-901F"             ) == 0) ||\r
2289                     (strcmp(modelName, "EP-901A"             ) == 0) ||\r
2290                     (strcmp(modelName, "Artisan 800"         ) == 0) ||\r
2291                     (strcmp(modelName, "Stylus Photo PX800FW") == 0) ||\r
2292                     (strcmp(modelName, "Stylus Photo TX800FW") == 0) )\r
2293                 {\r
2294                         return EPS_PM_JOB;\r
2295                 }\r
2296         }\r
2297 \r
2298         return EPS_PM_PAGE;\r
2299 }\r
2300 \r
2301 \r
2302 EPS_BOOL    obsIsA3Model (\r
2303                                                           \r
2304                 EPS_INT32 ch\r
2305                                                           \r
2306 ){\r
2307         const EPS_INT8 *modelName = NULL;\r
2308         \r
2309         modelName = g_observer.printer->modelName;\r
2310         if(EPS_MDC_STATUS == ch){                       /* status code */\r
2311                 if( (strcmp(modelName, "PX-5V"                                          ) == 0) ||\r
2312                            (strcmp(modelName, "Epson Stylus Photo R3000") == 0) ||\r
2313                            (strcmp(modelName, "PX-7V"                                   ) == 0) ||\r
2314                            (strcmp(modelName, "Epson Stylus Photo R2000") == 0) ||\r
2315                            (strcmp(modelName, "EP-4004"                                 ) == 0) ||\r
2316                            (strcmp(modelName, "Artisan 1430"            ) == 0) ||\r
2317                            (strcmp(modelName, "Epson Stylus Photo 1430") == 0)  ||\r
2318                            (strcmp(modelName, "Epson Stylus Photo 1500") == 0) )\r
2319                 {\r
2320                         return TRUE;\r
2321                 }\r
2322         } else if(EPS_MDC_NOZZLE == ch){        /* nozzle patern */\r
2323                 if( (strcmp(modelName, "PX-5V"                                          ) == 0) ||\r
2324                            (strcmp(modelName, "Epson Stylus Photo R3000") == 0) ||\r
2325                            (strcmp(modelName, "PX-7V"                                   ) == 0) ||\r
2326                            (strcmp(modelName, "Epson Stylus Photo R2000") == 0) )\r
2327                 {\r
2328                         return TRUE;\r
2329                 }\r
2330         }\r
2331 \r
2332         return FALSE;\r
2333 }\r
2334 \r
2335 \r
2336 static EPS_INT8 modelFY11Bussiness[][16] = {\r
2337                                         "PX-1600F", "WF-7510 Series", "WF-7511 Series", "WF-7515 Series",\r
2338                                         "PX-1700F", "WF-7520 Series", "WF-7521 Series", "WF-7525 Series",\r
2339                                         "PX-1200", "WF-7010 Series", "WF-7011 Series", "WF-7012 Series", "WF-7015 Series",\r
2340                                         "PX-B750F", "WP-4511 Series", "WP-4515 Series", "WP-4521 Series", "WP-4525 Series", \r
2341                                         "WP-4530 Series", "WP-4531 Series", "WP-4535 Series", \r
2342                                         "WP-4540 Series", "WP-4545 Series", \r
2343                                         "PX-B700", "WP-4015 Series", "WP-4011 Series", "WP-4020 Series", "WP-4025 Series"\r
2344 };\r
2345 \r
2346 EPS_BOOL    obsEnableDuplex (\r
2347                                                           \r
2348                 EPS_INT32       sizeID\r
2349                                                           \r
2350 ){\r
2351         const EPS_INT8 *modelName = NULL;\r
2352         EPS_INT32 i = 0;\r
2353         \r
2354         if( !(sizeID == EPS_MSID_A4             || \r
2355                 sizeID == EPS_MSID_LETTER       || \r
2356                 sizeID == EPS_MSID_B5           ))\r
2357         {\r
2358                 modelName = g_observer.printer->modelName;\r
2359                 for(i = 0; i < 28; i++){\r
2360                         EPS_DBGPRINT(("%s\n", modelFY11Bussiness[i]));\r
2361                         if( strcmp(modelName, modelFY11Bussiness[i]) == 0){\r
2362                                 return FALSE;\r
2363                         }\r
2364                 }\r
2365         }\r
2366 \r
2367         return TRUE;\r
2368 }\r
2369 /*____________________________   epson-escpr-services.c   ______________________________*/\r
2370 \r
2371 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/\r
2372 /*       1         2         3         4         5         6         7         8        */\r
2373 /*******************************************|********************************************/\r
2374 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
2375 /***** End of File *** End of File *** End of File *** End of File *** End of File ******/\r
2376 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r