Summary: | Переделать систему печати | ||
---|---|---|---|
Product: | WINE@Etersoft | Reporter: | Виталий Перов <vitperov> |
Component: | Печать ; Диалог печати | Assignee: | Виталий Перов <vitperov> |
Status: | CLOSED FIXED | QA Contact: | Денис Баранов <baraka> |
Severity: | minor | ||
Priority: | P4 | ||
Version: | 1.0.10 | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: | |||
Заявки RT: | Связано с: | ||
Дата напоминания: | |||
Bug Depends on: | |||
Bug Blocks: | 42, 443, 4063, 5618, 6009 |
Description
Виталий Перов
2009-07-13 19:27:53 MSD
система печати в wine pure изменилась. Теперь Она основана на функции ScheduleJob, которая берёт требуемые настройки из реестра. Интересно то, что печать идёт в любом случае в файл, а уже затем этот файл перенаправляется в нужное место (читается из HKCU/Software/Wine/Printing/Spooler) В качестве хака можно добавить туда что-нибудь вроде ETERPRINT, и добавить в ScheduleJob отдельный кейс для этого. Однако пока не понятно откуда брать необходимые параметры (количество копий, дуплекс, разбивка по копиям). Можно также протестировать различные поддерживаемые режимы: LPR: CUPS: возможно в каких-то из них заработает передача параметров дуплекса и collate внутри PostScript. Откатил патч реализующий нашу систему печати: commit dad71e013ee670dc2d7518c4fde55e587d3c291c Author: Vitaly Perov <vitperov@etersoft.ru> Date: Fri Feb 5 15:02:13 2010 +0300 wineps.drv: fix collate & duplex (fix eterbug #4721, #2843, #3688) Попробую разобраться с новой системой из pure. Дополнительно откатил в eterhack патч: commit 716f8a679c5dfff618874c866092f9820d4685ed Author: Vitaly Lipatov <lav@etersoft.ru> Date: Mon Jul 20 20:35:52 2009 +0400 wineps.drv: fix warning Разобрался. функция ScheduleJob ищет в реестре по ключу HKCU/Software/Wine/Printing/Spooler значение portnamе. В нашем случае оно равно L"LPR:HpTest". Если такого значениея нет, то она проверяет не содержится ли в строке port LPR: или CUPS:. LPR:HpTest берётся из каких-то настроек по умолчанию (без HpTest). LPR:HpTest - берётся из настроек принтера из реестра. Попробовал изменить на CUPS:HpTest Теперь печать идёт через cups, но collate не работает. Пробовал добавить Collate внутрь PostScript-файла - не помогло. для печати через cups используется функция: ret = pcupsPrintFile(queue, unixname, unix_doc_title, 0, NULL); третий и четвёртый параметры - количество опций и сами опции. Возможно при добавлении туда collate=true разбивка по копиям заработает > Возможно при добавлении туда collate=true
> разбивка по копиям заработает
>
Для этого есть специальная функция cupsAddOption.
Добавил collate=true - ничего не изменилось.
Итоги: * Разбивка по копиям внутри PostScript файла предусмотрена, но не работает. * Функции печати CUPS не предусматривают параметра collate. Остаётся только один выход: использовать предыдущий работающий способ (через lpr). функция ScheduleJob - как-раз и отправляет документ на печать. Если формирование необходимой строки команды сделать именно здесь, то возможно решится бага 4063. Т.к к моменту вызова ScheduleJob количество копий должно быть уже известным. Только проблема в том, как передать необходимые параметры (количество копий, разбивка, дуплекс) в ScheduleJob. Функция ScheduleJob принимает только хендл принтера и JobID, притом информацию о том куда и как ей печать она берёт из ветки реестра, соответствующей этому принтеру. Функция получает информацию о принтере с помощью структуры PRINTER_INFO_5W. Вместо этого можно запрашивать структуру PRINTER_INFO_2W, в которой кроме этого содержится LPDEVMODEW pDevMode; А там уже есть поля, содержащие требуемые параметры. Сделал пробную версию патча - не работает. В упомянутой структуре всегда стоит 1 копия и отключена разбивка. Вполне логично. Структура pDevMode, полученная с помощью GetPrinterW не связана с каким-то конкретным заданием для печати. С помощью функции GetJobW можно получить структуру JOB_INFO_2A. Там тоже есть pDevMode. Возможно в этом случае там будут необходимые нам данные. Написал патч. Проверил. Не работает. В структуре JOB_INFO_2W заполнены только поля JobId и pDocument. Остальные все пустые. Структуру JOB_INFO_2W заполняет функция get_job_info. Для неё видим только hPrinter, из которого она извлекает нужную структуру, соответствующую указанному заданию на печать. А оттуда - необходимые параметры. Структура называется job_t. По всей видимости она чисто вайновская (т.е её можно было бы дополнить). В ней добавить указатель на DevMode. Для установки параметров есть специальная функция SetJobW, но в wine она также заполняет только некоторые поля. Можно попытаться её доработать (дописать сохранение devMode в новое поле job_t) Дописал поддержку нового параметра в функции SetJobW и GetJobW Функцию SetJobW нужно вызывать из PSDRV_EndPage (в этот момент уже точно известно количество копий) Дописал добавление devMode из функции PSDRV_EndPage. Ура! В ScheduleJob параметре Collate и Copies передаются. Остаётся только дописать патч, проверить, и привести его к нормальному виду. Часть патча, касающаяся SetJobW и GetJobW может быть отправлена в wineqh, но вряд ли им понравится изменение структуры job_t Также функция GetJobW не заполняет поле pPrinterName fixme:winspool:ScheduleJob Destination string = 'L"|lpr -P'(null)' -T'no name' -# 20563 -o Collate=False -o sides=one-sided"' Возникает следующая проблема: Структуру заполняет функция: get_job_info, которой в качестве параметре передаётся hPrinter. далее она определяет уровень, и вызывает get_job_info_2 для заполнения структуры JOB_INFO_2W. Проблема в том, что в get_job_info_2 передаётся именно job, и название принтера из hPrinter ей не доступно. - добавлять параметр hPrinter в get_job_info_2 - выглядит не хорошо - патч вряд ли примут - добавлять новые параметры во внутреннюю структуру job_t - дублирование информации Реализовал первый вариант (добавил аргумент в функцию). Оказалось, что в структуре opened_printer_t поля name и printername заполнены каким-то хламом: ixme:winspool:ScheduleJob Destination string = 'L"|lpr -P'鎠ø⽥潢瑴敬⽳畢獧ⸯ楷敮㐭ㄱ⼱潤摳癥捩獥振⼺楷摮睯⽳祳瑳浥㈳猯潰汯倯䥒呎剅⽓〰〰⸲偓L' -T'01.txt' -# 20563 -o Collate=True -o sides=one-sided"' Переделал. Сделал через дополнительное поле во внутренней структуре. Заполняю поле при вызове SetJobW. Опять работает не так, как надо. fixme:winspool:ScheduleJob Destination string = 'L"|lpr -P'߈èst' -T'01.txt' -# 5 -o Collate=True -o sides=one-sided"' Видимо память "затирается". Вместо ссылки надо копировать. нашёл проблему: При вызове SetJobA все поля полученной структуры перекодируются в юникод. После этого вызывается SetJobW, а после её вызова все поля затираются. Т.е хранить саму строку - задача SetJobW Думаю алгоритм должен быть следующим: При обновлении информации затирать старую стоку и выделять память под новую. При этом не забывать очищать память при удалении задания. Функция SetJobА не обрабатывает параметр pPrinterName. В комментариях сказано, что pPrinterName игнорируется функцией (имеется ввиду виндовой). Скорее всего он заполняется при вызове AddJobA и больше не меняется. Реализовал. Проверил. Работает. Сделал патч. Приложил в eterwine и eterhack Багу закрываю |