Операционная система Microsoft Windows 3.1 для программиста. Дополнительные главы© Александр Фролов, Григорий ФроловТом 17, М.: Диалог-МИФИ, 1994, 287 стр. 5.1. Стандартные драйверыВ этом разделе мы очень кратко расскажем о стандартных драйверах Windows, обслуживающих такие устройства компьютера, как видеоконтроллер, принтер и плоттер, клавиатуру, мышь и асинхронный последовательный адаптер. Драйвер видеоконтроллераДрайвер видеоконтроллера оказывает решающее влияние на производительность Windows как операционной системы с графическим интерфейсом пользователя. Поэтому он составляется, как правило, на языке ассемблера. В состав дистрибутива Windows входят драйверы лишь для ограниченного набора видеоконтроллеров. В частности, имеется драйвер для видеоконтроллера VGA, с которым совместимы практически все современные видеоконтроллеры. Для реализации режимов SVGA производители видеоконтроллеров создают собственные драйверы и поставляют их в комплекте со своими изделиями. Как мы уже говорили в 14 томе "Библиотеки системного программиста", приложения Windows работают с видеоконтроллером и принтером через интерфейс графических устройств GDI, реализованный как DLL-библиотека gdi.exe. Этот интерфейс обеспечивает независимость приложений от особенностей физической аппаратуры. Модули интерфейса GDI не работают с регистрами видеоадаптера или принтера, а обращаются к соответствующим драйверам. Заметим, что драйвер видеоадаптера вызывается для выполнения операций достаточно высокого уровня, например, рисования линии или закрашивания области. Если драйвер не поддерживает нужную операцию, GDI выполняет ее самостоятельно. Однако только драйвер может выполнять операции наиболее быстрым образом, так как GDI "не знает" особенностей аппаратуры. Если Windows работает в расширенном режиме, в дело включается виртуальный драйвер видеоконтроллера, который выполняет операции ввода/вывода над регистрами видеоконтроллера и осуществляет запись данных в видеопамять. В составе DDK есть исходные тексты виртуальных драйверов для некоторых типов видеоконтроллеров, таких как CGA, EGA и VGA. Основная задача виртуального драйвера видеоконтроллера заключается в координации коллективного доступа к аппаратуре видеоконтроллера со стороны виртуальных машин MS-DOS и системной виртуальной машины, в которой работают приложения Windows. В последнее время в качестве видеоконтроллера обычно используется так называемый ускоритель Windows (Windows Accelerator), способный выполнять многие графические операции на аппаратном уровне без загрузки центрального процессора компьютера. При этом значительно увеличивается скорость вывода изображения в среде Windows. Разумеется, для того чтобы задействовать новые возможности акселераторов Windows, необходимо подключить соответствующие драйверы, которые всегда поставляются вместе с видеоконтроллером. Драйверы экспортируют многие функции, которые по выполняемым действиям можно отнести к интерфейсу GDI, например, BitBlt, ExtTextOut, SetPalette, StretchDIBits и многие другие. При этом достигается максимальная производительность, так как только разработчик видеоконтроллера знает все его аппаратные особенности. Так как драйвер видеоконтроллера выполняет многие критические функции, возможные ошибки, допущенные при создании драйвера, могут сказаться на работе любых приложений Windows. Авторам известна ошибка в одной из версий драйвера Cirrus Logic, влияющая на режим предварительного просмотра документа текстового процессора Word for Windows. Поэтому если вы обнаружили, что ваше приложение работает неправильно (рисует не то, что нужно или даже завершается с сообщением о нарушении защиты памяти), проверьте его работу с другим драйвером или при другом разрешении. Помимо экспортирования функций, связанных с рисованием на экране, драйвер "экспортирует" многие ресурсы, такие как шрифты, битовые изображения, пиктограммы и другие. При изображении таких стандартных органов управления, как системные меню, движки полос просмотра, заголовки окон и курсоры, Windows пользуется ресурсами, определенными в драйвере видеоконтроллера. При установке видеоконтроллера в системный каталог Windows копируются файлы шрифтов, соответствующие текущему разрешению. Последнее обстоятельство приводит в замешательство некоторых пользователей, работающих с символами кириллицы. Установив Windows и драйвер видеоконтроллера VGA для разрешения 640х480 пикселов, такие пользователи выполняют русификацию Windows при помощи таких продуктов типа CyrWin, ParaWin и т. п. В ходе этой процедуры многие шрифты из системного каталога Windows заменяются на другие, сходные по начертанию, но имеющие в своем составе символы кириллицы. Если теперь установить другой драйвер видеоконтроллера, например, для разрешения 800х600 пикселов, опять произойдет замена шрифтов. На этот раз в системный каталог Windows будут скопированы шрифты, которые поставляются вместе с драйвером видеоконтроллера. Как правило, эти шрифты не содержат символов кириллицы, поэтому русские буквы исчезнут с экрана. Следовательно, всякий раз, когда вы меняете драйвер видеоконтроллера, необходимо заново устанавливать приложение, отвечающее за использование символов кириллицы. Еще одна важная задача, выполняемая драйвером видеоконтроллера (вернее, отдельным модулем, который устанавливается вместе с драйвером) заключается в сохранении и восстановлении содержимого экрана при переключении от виртуальной машины MS-DOS к системной виртуальной машине, в рамках которой работают все приложения Windows. Сохранение и восстановление содержимого экрана виртуальной машины MS-DOS выполняется модулем, который называется Display Grabber. Мы будем называть его модулем сохранения экрана. В реальном и стандартном режиме работы Windows модуль сохранения экрана представляет собой односегментную программу реального режима, составленную на языке ассемблера. По своей структуре она больше всего напоминает com-программу для MS-DOS. В расширенном режиме работы Windows виртуальные машины MS-DOS могут работать как в полноэкранном, так и в оконном режиме. При этом используется другой модуль сохранения экрана, выполненный в виде обычной DLL-библиотеки. Его основная задача заключается в преобразовании формата изображения к виду, пригодному для отображения в окне. Само же отображение выполняется драйвером видеоконтроллера. Другая важная задача, выполняемая модулем сохранения экрана расширенного режима - копирование содержимого окна виртуальной машины MS-DOS в универсальный буфер обмена Clipboard. Можно также скопировать произвольный фрагмент окна, выделенный пользователем. Функции выделения фрагмента окна в расширенном режиме работы Windows также выполняются модулем сохранения экрана. Драйверам видеоконтроллера можно было бы посвятить отдельную книгу, так как решаемые этим драйвером задачи очень сложны. Однако, как мы уже говорили, вы едва ли будете составлять такие драйверы самостоятельно. Всю необходимую информацию при необходимости вы сможете найти в документации, которая поставляется в составе DDK. Драйвер принтераВ 14 томе "Библиотеки системного программиста" мы рассказали вам о том, как приложения Windows работают с принтером. Мы сказали тогда, что для печати используются те же функции графического интерфейса GDI, что и для рисования на экране, плюс некоторые дополнительные. Можно было бы ожидать, что в процессе печати функции GDI выводят данные на принтер, обращаясь к аппаратуре соответствующего параллельного или последовательного порта, однако это не так. Прежде всего, данные, которые выводятся на печать, попадают на вход драйвера принтера. После обработки драйвером данные направляются снова в интерфейс GDI, который далее может направить их либо в систему спулинга печати, либо сразу передать драйверу параллельного или последовательного порта, к которому подключен принтер. Система спулинга печати, которая управляется через приложение Print Manager, способна накапливать данные и передавать их драйверу параллельного или последовательного порта в фоновом режиме, почти не влияя на работу других приложений. Драйвер принтера может не делать практически ничего, просто возвращая полученные от GDI данные в нужном формате без какой-либо сложной обработки. Однако в некоторых случаях драйвер принтера может ускорять процесс печати, например, выполняя самостоятельно операции по преобразованию битовых изображений. Так же, как и драйвер видеоконтроллера, драйвер принтера экспортирует функции BitBlt, ExtTextOut, SetPalette, StretchDIBits и другие. Для облегчения задачи создания собственного драйвера принтера DLL-библиотека gdi.exe экспортирует "грубые" функции (Brute Functions), которые выполняют основные операции с монохромными битовыми изображениями. Имена этих функций начинаются с префикса dm, например, dmBitBlt. Другая возможность, которая есть в распоряжении разработчика драйвера принтера - функции для работы с приоритетными очередями, также экспортируемые GDI. С помощью этих функций можно создавать и уничтожать приоритетные очереди печати, добавлять в очередь или удалять из нее задания на печать, устанавливать размер очереди и определять параметры самого приоритетного задания. Драйвер клавиатурыВ стандартном режиме работы Windows используется драйвер клавиатуры в виде обычной DLL-библиотеки. Основное назначение драйвера клавиатуры, как нетрудно догадаться, заключается в определении скан-кода нажатой или отпущенной клавиши, преобразования его в код ANSI и передаче этих кодов Windows для создания соответствующего сообщения WM_KEYDOWN или WM_KEYUP. Клавиатурное сообщение будет затем записано в очередь приложения, имеющего фокус ввода. Процедура передачи кодов заключается в вызове процедуры, адрес которой Windows передает драйверу при инициализации драйвера. Эта процедура называется процедурой события (Event Procedure). Менее очевидно второе назначение драйвера клавиатуры, которое состоит в преобразовании кодировки символов из стандарта OEM в стандарт ANSI и обратно. Почему задача преобразования кодов возложена именно на драйвер клавиатуры? Ответ заключается в том, что при разработке этого драйвера приходится решать проблемы использования символов национального языка: внешний вид или, как говорят, раскладка клавиатуры зависит от национальных особенностей и состава алфавита. Поэтому в комплекте с драйвером клавиатуры поставляются библиотеки перекодировки и таблицы перекодировки, по одной для каждого национального языка. Таблица перекодировки предназначена для преобразования кодировки символов из стандарта OEM в стандарт ANSI и обратно. Библиотеки перекодировки - это обычные DLL-библиотеки, которые содержат табличную информацию о раскладке клавиатуры. После всего сказанного выше для вас не будет удивительно, что драйвер клавиатуры экспортирует среди прочих такие функции, как VkKeyScan, AnsiToOem и OemToAnsi. В расширенном режиме работы Windows в дело включается виртуальный драйвер клавиатуры, задачей которого является виртуализация клавиатуры для ее совместного использования одновременно работающими виртуальными машинами MS-DOS и системной виртуальной машиной Windows. Дополнительно виртуальный драйвер клавиатуры обеспечивает симулирование клавиатурного ввода при выполнении операции вставки содержимого Clipboard в окно виртуальной машины MS-DOS (эта возможность есть только в расширенном режиме работы Windows). При этом виртуальный драйвер клавиатуры определяет метод, используемый программой MS-DOS для ввода с клавиатуры - вызов прерывания INT 16h или непосредственное сканирование клавиатурного буфера в области данных BIOS. Еще одно назначение виртуального драйвера клавиатуры - обработка клавиш активизации или ускоренного запуска (Hot Key). Если пользователь нажмет такую клавишу, будет запущено соответствующее приложение или выполнены другие действия. Виртуальный драйвер клавиатуры может также обеспечить доступ к клавиатуре другим виртуальным драйверам, войдя в так называемый режим сообщений (Message Mode). Драйвер клавиатуры подключается в секции [boot] файла system.ini: keyboard.drv=keyboard.drv Кроме этого, используется секция [keyboard]: [keyboard] subtype= type=4 keyboard.dll= oemansi.bin=xlat866.bin С помощью строки type задается тип клавиатуры. Значение 1 соответствует клавиатуре XT, значение 4 - клавиатуре AT. Строка subtype нужна только для драйвера клавиатуры Olivetti и описывает разновидность клавиатуры внутри одного типа. При помощи строки keyboard.dll задается библиотека перекодировки, определяющая раскладку клавиатуры. По умолчанию используется американский вариант расположения клавиш. Строка oemansi.bin определяет таблицу перекодировки символов из стандарта OEM в стандарт ANSI и обратно. Для корректной перекодировки текстов, содержащих символы кириллицы, необходимо использовать специальную таблицу, которая поставляется в составе таких средств русификации Windows, как CyrWin или ParaWin. Еще одно небольшое замечание относительно использования символов кириллицы. Есть два подхода в решении этой проблемы. Первый заключается в использовании русифицированных версий MS-DOS, Windows и других продуктов. Русификация выполнена А.О. Microsoft, поэтому можно считать, что она сделана профессионально. При втором подходе вы отдельно приобретаете оригинальные версии MS-DOS, Windows и т. п., и отдельно средства русификации, такие, как CyrWin, ParaWin, WinOrfo, Hameleon и т. п. Первый подход обычно удобен для начинающих пользователей, не привыкших к англоязычным версиям программ. Вы просто устанавливаете им русские версии программных продуктов, и они сразу начинают работать. Второй подход обеспечивает возможность работы с символами кириллицы без перевода на русский язык меню и сообщений. Он используется профессиональными программистами и теми, для кого языковый барьер не является проблемой. Такие пользователи тяжело воспринимают переход к русским версиям, так как все строки меню и термины изменились до неузнаваемости и им трудной найти то, что нужно. Кроме того, работая с русскими версиями, пользователи будут вынуждены ждать появления русифицированного варианта новой версии, в то время как оригинальный вариант уже доступен. Поэтому в настоящий момент, несмотря на то что А.О. Microsoft своевременно выпускает русские версии программных продуктов, по-прежнему существует необходимость в средствах русификации оригинальных операционных систем и прикладных программ. Для того чтобы средства русификации Windows работали правильно, желательна правильная русификация MS-DOS. В частности, необходимо обеспечить в MS-DOS кодовую страницу с номером 866. Самый простой способ корректной русификации оригинальной версии MS-DOS заключается в замене файлов ega.cpi и country.sys на аналогичные файлы из русифицированной MS-DOS с внесением соответствующих изменений в файлы config.sys и autoexec.bat. В файле config.sys следует указать код страны 7 и подключить драйвер дисплея display.sys, указав кодовую страницу 866: COUNTRY=7,,C:\CYR\COUNTRY.SYS DEVICE=C:\DOS\DISPLAY.SYS CON=(EGA,866,1) В файле autoexec.bat нужно подготовить и загрузить шрифт, соответствующий 866-й кодовой странице: C:\DOS\MODE CON CP PREP=((866) C:\CYR\EGA.CPI) C:\DOS\MODE CON CP SEL=866 Кроме этого, можно подключить любую резидентную программу русификации клавиатуры, не загружающую экранные шрифты или допускающую отключение такой загрузки, например, keyrus: C:\KEYR\KEYRUS /KEYS=C:\KEYR\KBDMAIN /ROM /GRAPH=16 Далее следует русифицировать Windows, запустив CyrWin или аналогичное изделие. При выполнении русификации описанным выше способом обеспечивается согласованное использование кодовой страницы 866 как в MS-DOS, так и в Windows. Большинство обычных русификаторов MS-DOS ограничиваются лишь загрузкой экранных шрифтов и переключением раскладки клавиатуры, нисколько не беспокоясь об изменении номера кодовой страницы в MS-DOS. До сих пор нам не встречалось ни одно комплексное средство русификации MS-DOS и Windows, которое бы с одной стороны, было бы удобно в работе, а с другой - выполняло бы корректную русификацию MS-DOS и Windows с заменой всех необходимых шрифтов (в частности, часто используемого шрифта MS Sans Serif). Возможно, что вы сможете решить эту проблему. Исходные тексты драйвера клавиатуры, библиотек перекодировки и таблиц перекодировки есть в DDK, так что можно попробовать! Драйвер мышиЕдва ли вам потребуется создавать собственный драйвер мыши, разве что вам придет в голову идея подключить к Windows одновременно две мыши для работы вдвоем. Тем не менее, мы скажем пару слов о драйвере этого устройства. Назначение драйвера мыши очевидно - подготовка данных для генерации сообщений мыши. Так же, как и драйвер клавиатуры, драйвер мыши вызывает для этого процедуру, адрес которой передается драйверу при инициализации. Процедура вызывается тогда, когда пользователь перемещает мышь, либо нажимает на одну из ее клавиш. Самое интересное в драйвере мыши заключается в том, что он работает напрямую с аппаратурой, не пользуясь услугами драйвера последовательного адаптера. Драйвер последовательного адаптераДрайвер последовательного адаптера обслуживает не только последовательный, но и параллельный адаптер. Это странно и неудобно, так как если вы разрабатываете драйвер для нестандартного последовательного адаптера, то вам необходимо реализовать в нем все функции параллельного адаптера и наоборот, разработчик нестандартного параллельного адаптера вынужден иметь дело с последовательным адаптером. Частично такой подход оправдывается тем, что использованный протокол взаимодействия с этими типами устройства одинаков и ориентирован на посимвольную передачу данных. В расширенном режиме работы Windows дополнительно используется виртуальный коммуникационный драйвер VCD и виртуальный коммуникационный буфер COMMBUFF (который есть ни что иное, как еще один виртуальный драйвер). Первый из них отвечает за виртуализацию аппаратуры, второй - за буферизацию данных. Виртуальный коммуникационный драйвер может зарезервировать порт отдельной виртуальной машине. Если другая виртуальная машина попытается получить доступ (обратиться) к зарезервированному порту, пользователь получит предупреждающее сообщение о такой попытке. |