BeOS - статьи

         

BeOS FAQ


Оригинал (возможно, более поздняя версия) находится по адресу , там же можно оставить комментарии - вопросы и ответы, которые будут добавлены в FAQ.



Q: А есть ли FIDO пакеты под BeOS и где их взять?


A:

1 Исходники: или на CVS, инструкция тут:

2. husky пакет под BeOS - BeFTN - живет на (Собирают: под BeOS5.1 Paul Galashin 2:5053/777.12, под BeOS5.0.3 Siarzhuk Zharski 2:465/204.43)



Q: BeOS не распознает устройства в моем компьютере


A: (BeNews.ru)

Многие проблемы при установке и определении некоторых устройств возникают из-за так называемой спецификации Microsoft на Plug'n'Play. Если BeOS не может определить ваш сетевой адаптер или звуковую карту, отключите в них поддержку PnP. Это можно сделать при помощи программного обеспечения, поставляемого с этими устройствами. Также можно попробовать отключить поддержку PnP в BIOS.



Q: БеОС загрузился в черно-белом режиме. Что делать?


A: (BeNews.ru)

Черно-белый экран означает, что БеОС не смог найти драйвер для вашей видеокарты. Если порыскав по вышеприведенным ссылкам вы тоже не нашли драйвера, то для вас есть два решения - конючить драйвер на форумах, вдруг кто такой написал (хотя такое - редкость), либо установить VesaAccepted (http://www.bebits.ru/cgi-bin/item.pl?Vesa%20Accepted) Она переведет BeOS в VEGA режим - все будет цветным, правда система будет поттормаживать на слабых машинах, и в некоторые игрушки поиграть не удастся...



Q: BeOS зависает при загрузке между 4-й и 5-й иконками.


A: (BeNews.ru)

Суть проблемы: Неправильно опознается режим (U)DMA.

Причины: несовместимый IDE-чипсет на motherboard (или отдельном контроллере IDE) или неправильная инициализация железа.

Лечение -

1) если BeOS установлен в виде файла под Windows - попробуйте загрузится с дискетки. Если это поможет, но вы не хотите дальше работать с дискетки - установите BeOS на отдельный раздел

2) Если BeOS не загружается с дискетки или отдельного раздела - запретите в BIOS (в Integrated Peripherals обычно) DMA.

Если после этого загрузится, зайдите в BeOS в папку

home/config/settings/kernel/drivers.

Там будет папка sample. Перетащите из нее в

home/config/settings/kernel/drivers файлы ata и atapi и отредактируйте их, разэкранировав нужные строки и выбрав вариант nodma и подставив ваши параметры (на каком канале диск, master или slave, идентификационная строка диска). Файлы внутри откомментированы вполне достаточно.

Иногда наоброт, помогает выбор forcedma именно для того диска и канала, которые на это способны.

Вообще, файлы из sample, перетащенные в drivers в точности дублируют все опции SAFE MODE при необходимости (см совет 335 на )



Q: Будьте осторожны при копировании уже существующих папок!


A: (BeNews.ru)

Windows и BeOS во многом похожи, но есть и некоторые отличия. Например, когда вы копируете папку в место, где уже существует папка с аналогичным названием, обе системы спросят вас "Replace?" и если вы ответите положительно:

Windows – скопирует только те файлы, которых нет в "папке назначения", BeOS – перезапишет папку, полностью удалив старую!

Т.е. если вы скопируете в вашу папку /home (там папка config существует по-умолчанию) папку с названием "config" и ответите положительно в диалоге "Replace?", то вы удалите все содержимое старой папки! Папка config является системной (в ней хранятся ваши файлы конфигурации) и ее повреждение может отрицательно сказаться на работоспособности BeOS.

В BeOS R5 диалог "Replace?" будет дополнен некоторыми опциями которые позволят указывать что же вы хотите сделать: заместить или дополнить.



Q: Дописывание с помощью клавиши "TAB".


A: (BeNews.ru)

A: В большинстве UNIX-систем, а также в BeOS, Вы можете сделать так, чтобы операционная система сама дописывала длинное имя файла или папки. Для этого надо всего лишь нажать на кнопку "TAB" после того, как Вы написали часть имени файла или папки. Например, предположим, что Вам нужно распаковать файл с именем "BeBox_Updater_ROM_September23_1997.tar.gz" и Вы находитесь в папке, содержащий этот файл. Попробуйте напечатать "gunzip BeB" и затем нажать на кнопку "TAB". Вы увидете, что командная строка сама допишет имя файла, и все, что Вам останется сделать - нажать на "Return" ("Enter").

Но что, если существует другой файл, начинающийся на "BeB"? Нет проблем -- командная строка довольно умна, она допишет только ту часть имени файла, до того, пока части имен этих файлов совпадают. Далее Вы должны напечатать следующую букву или буквы имени файла, уникальные только для интересующео файла и снова нажать на "TAB".

Прислали: greenrul, wBlaze, Beo.



Q: Focus Follows Mouse


A: (BeNews.ru)

Если вы откроете панель Mouse preferences, то увидите опцию под названием «Focus Follows Mouse». Если вы ее выберете, щелкать мышью внутри окна чтобы ввести его в фокус внимания операционной системы больше не придется. В отличие от Windows, которая выводит активное окно поверх остальных, в BeOS вы можете работать в окне, частично заслоненном другими окнами. Это свойство вызывает большие споры: люди и любят его, и ненавидят. По большей части, те, кому оно нравится, провели много лет в мире Unix. В любом случае, FFM можно отключить.



Q: Где мне найти драйвер для моего устройства?


A: (BeNews.ru)

Рекомендую прежде всего поискать драйвер на этих страницах:



Q: Хранение файлов BeOS в другой файловой системе.


A: (BeNews.ru)

Как вы знаете, атрибуты файлов очень важны для многих приложений и функций BeOS. Без атрибутов ваши почтовые сообщения не будут иметь заголовка или отправителя, ваши Интернет-закладки не будут хранить никакой информации, и т.д. Если вам необходимо перенести ваши файлы с диска BeOS на диск с другой файловой системой (FAT, HFS, EXT2FS...), заархивируйте их архиватором, поддерживающим атрибуты BeOS. В настоящий момент, это поддерживает zip. Полные инструкции по использованию zip для создания архивов находятся здесь -



Q: Изменение иконок BeOS.


A: (BeNews.ru)

Иконки BeOS не хранятся в отдельных файлах, как это сделано в Windows.

Вместо этого они хранятся как атрибуты отдельных файлов или типов файлов. Для того, чтобы сменить иконку, запустите панель filetypes (как для отдельных файлов, так и для типов файлов, используя панель FileTypes preferences). Теперь вам остается лишь поместить в поле Icon новую иконку, или щелкнув два раза мышкой, перейти к редактированию существующей. Если необходимо, сохраните результаты, и иконка изменена.

Внимание: если вы меняете иконку для типа файлов, возможны проблемы с возвращением стандартной иконки. Если вы оказались в этой ситуации, посмотрите вопрос "Восстановление потерянных иконок".



Q: Изменение порядка использования Alt и Ctrl.


A: (BeNews.ru)

Если перешли на BeOS после долгого использования Windows и не можете привыкнуть к тому, что Alt используется как первичная клавиша чаще чем Ctrl, используйте панель Menu preferences чтобы поменять порядок использования этих двух клавиш. Изменения произойдут сразу, перезагрузки не потребуется. Имейте в виду, что теперь для того, чтобы остановить выполняемую в терминале работу, вам придется использовать Alt+C. Также вы должны быть готовы к тому, что придется привыкать к мысленному переводу значений клавиш Alt и Ctrl при чтении документации, связанной с BeOS.

Однако особой нужды менять значение этих клавиш не существует. Некоторое время старые стереотипы их использования будут сказываться на уровне мышечной памяти, но скоро они заменятся новыми, специфичными для BeOS.



Q: Я дизайнер. В чем мне под Бе рисовать?


А: В данный момент разрабатываются два серъезных пакета - Refraction () и Pixel32, оба вроде коммерческие, но демоверсию пикселя можно уже попробовать -

Другие редакторы можно найти на или



Q: Как изменить положение Deskbar?


A: (BeNews.ru)

Для того, чтобы передвинуть Deskbar (это такая серая полосочка с менюшкой "Be", часиками и списком выполняющихся приложений), нужно мышкой "схватить" его за область, помеченную точками, слева от часиков и "тащить" в нужном направлении. В зависимости от местоположения, Deskbar будет изменять свою форму, но всегда будет "прилипать" к одной из сторон экрана.



Q: Как мне совместить БеОС и Windows на одной машине?


A: Если вы установили БеОС в отдельный раздел, Бе поинтересовалась - можно ли установить свой ос селектор (bootmanager), и в случае, если вы отказались, или он вас не устраивает, вы можете установить другой загрузчик операционных систем:

Cоветую использовать программу Acronic OS Selector Deluxe,

Если же вы пользователь Windows 2000, NT, XP и полюбили встроенный ос селектор этих систем, тогда вот как можно добавить БеОС в их список загрузки:

Будучи в windows, найдите на своем BeOS компакте папку, которая называется NT (сама она находится в папке Experimental) там должен находиться файл addbeos.exe (если что, поищите в BeShare)

Запустите этот файл. Программа автоматически добавит несколько строчек в файл boot.ini и скопирует в корневой каталог вашего диска файл BeOS.bs.

При следующей перезагрузке, вы сможете загрузить BeOS, просто выбрав ее в загрузочном меню WindowsNT/2000/ХР.



Q: Как настроить ТВ-тюнер на чипсете bt848 под BeOS


А: Настраиваем каналы: создаем файл tvfavorites в каталоге /boot/home/config/settings/Media/bt848/ и вбиваем туда номера, названия каналов и частоты(в _герцах_).

Через табуляцию. Пример:

1-ORT 49750000 (до пожара).

Перезапускаем МедиаСервер.

Программы



Q: Как научить BeOS работать с AMD Athlon XP/MP/4 (Palomino)


A: (Михаил Панасюк)

Способ 1.

Для тех, у кого установлена BeOS R5.1d0 "Exp/Dano".

Грузимся в BeOS (возможно, на другом компьютере) и заменяем все вхождения строки "memcpy_pIII" на строку "memcpy_default" в файлах

/boot/beos/system/intel_kernel.patch

/boot/beos/system/lib/libroot.so.patch

PS. Способ был подсмотрен на форуме BeGroovy.com пару месяцев назад.

PPS. Не тестировал, но, возможно, это будет работать в BeOS R5.0.x + BONE.

Способ 2.

Для тех, у кого стандартная BeOS R5.0.x Personal Edition или Pro

Скачиваем патч для ядра с BeBits.ru (). Грузимся в BeOS (возможно, на другом компьютере) и далее все делаем по инструкции, прилагаемой к патчу.



Q: Как разделить пункты меню в BeOS?


A: (BeNews.ru)

Вы можете разделить меню Be на секции. Откройте папку /boot/home/config/be создайте пустой файл с пробелом в начале имени файла (например "-------------------") и пустой иконкой. Это и будет разделительной линией в меню.



Q: Как руссифицировать браузер Opera?


A: Ответ делится на две части:

1) Просмотр русских страниц - те же рецепты что и для Opera for Windows. Единственная специфика для BeOS, но ОЧЧЕНЬ ВАЖНАЯ - не все шрифты с русскими буквами подходят в нашем случае, а только специально препарированные, такие, где верхние WESTERN символы заменены на русские. На эту тему смотри:

и

При установке шрифтов обратите внимание, чтоб у вас в системе не было бы уже шрифтов с такими точно же внутренними именами, а то система их не поставит,а вы даже не будете об этом знать, или поставит но будут глюки - половина букв отображается, половина квадратики.

Есть еще грабли, которые нужно учитывать, прежде чем начинать плакать что ничего не получается. Дело в том, что многие страницы указывают насильно, какие шрифты нужно применять для отображения. При этом может оказаться, что среди "переделанных шрифтов" таких нет, тогда опять вместо русских букв будет непонятно что. Тут есть два выхода - или оставить в системе только "переделанные" шрифты, или поработать в настройках Оперы в разделе Document Appearance, убрав галочку с "Document fonts and colors"

2) Ввод русского текста.

В данной версии 3.62 RC1 необходимо применение специальной русской клавиатурной раскладки, не той, которая стандартно подходит для BeOS. На эту тему также смотри статью здесь

3)Для отображения и Win1251 и KOI8R во-первых, нужны еще и переделанные таким же образом шрифты (Upper WesternKOI8R), а во-вторых, придется сделать копию файла Opera.ini, переименовать её как-нибудь, например в OperaKOI.ini, и отредактировать последний, заменив там все названия шрифтов на шрифты, поддерживающие KOI. Запускать тогда нужно из терминала c указанием OperaKOI.ini в качестве параметра - или создать соответствующий shell-скрипт.

4) Если КОИ ставить лень( а многие сайты/сервера определяют что у вас ОС наподобие юникс и подсовывают КОИ-8. И некоторые горе-дизайнеры не удосужились кнопочки сделать чтобы выбирать кодировки.От некоторых серваков непонятно на каком порту искать эту самую Вин1251 - 8080 не работает, 810x тоже.) - то может помочь следующее:

В общем, чтоб не мучаться - пропишите в Opera.ini в секции [ADV USER PREFS]

следующее:

http-accept-charset="windows-1251"

Тогда те сервера что могут - будут выдвать вам c с большей вероятностью сразу в Вин1251.



Q: Какие есть офисные пакеты под Бе? Вроде MS Office и т.д.


A: Самый мощный и популярный - GoBe Productive. Скачать его можно

либо

Есть еще AbiSuite, но его считают нестабильным:



Q: Какие ТВ-тюнеры поддерживает BeOS?


А: Большинство тюнеров на чипсетах bt848/bt878 прекрасно работают под BeOS. Например модели от AverMedia: TV-Phone, TV-Capture, TV-Phone98, TV-Phone98 w/VCR, JoyTV, FunTV.



Q: Переключение между рабочими областями


A: (BeNews.ru)

Благодаря рабочим областям BeOS у вас больше места для работы, чем вы можете себе представить. Нажмите Alt и любую функциональную клавишу, например, Alt+F2, Alt+F6, и т.д. В результате вы получите чистую рабочую область с независимым разрешением и возможностью запускать в нем различные приложения.

Можно запускать рабочие области графически, из Workspaces preferences applet. В аплет также встроена возможность перетаскивать приложения из одной рабочей области в другую.



Q: Почему БеОС не выключает компьютер при выключении (Shtudown) системы?


A: (BeNews.ru)

Advanced Power Management (APM, расширенное управление питанием) поддерживается BeOS начиная с версии 4.5, и некоторые компьютеры могут выключать питание, когда Вы выбираете пункт "Shutdown" (Выключить) из меню Ве. Однако эта штука работает не на всех машинах и может вызвать некоторые проблемы (на пример: компьютер сам включится через несколько минут или часов после выключения). По умолчанию в Ве эта опция отключена, SMP машины могут иметь проблемы с этой возможностью.

Если Вы хотите включить эту опцию, то загляните в совет 355 (), и затем отредактируйте файл:

~/config/settings/kernel/drivers/kernel

Уберите комментарии (символ "#") со строки

enable_shutdown true # enable power-off on system shutdown

При следующей загрузке Вы можете попробовать завершить работу и посмотреть на результат. Но, это не безопасно убирать комментарии со строчки вверху...



Q: При необходимости удалите оборудование, которое не поддерживается.


A: (BeNews.ru)

В подавляющем большинстве случаев BeOS на платформе Intel игнорирует оборудование, которое не поддерживается, например, карты SCSI. Однако иногда бывает, что неподдерживаемые карты I/O вызывают зависание BeOS при загрузке. Их удаление позволяет нормально загрузить систему.



Q: Расположение полосы заголовка.


A: (BeNews.ru)

Полосы заголовков во всех окнах BeOS по умолчанию располагаются слева вверху. Если вам нужно быстро сдвинуть полосу заголовка в сторону, переместите ее при помощи мышки влево или вправо, удерживая клавишу Shift. Для чего это нужно? В BeOS вы можете использовать полосы заголовков для того, чтобы выстраивать по своему вкусу последовательность окон и более легко в них ориентироваться.



Q: У меня не отображается русский текст, и я не могу поменять раскладку. Что делать?


A: Установить Switcher() - переключатель раскладок, и в папку /boot/beos/etc/fonts/ttfonts или /boot/home/config/fonts/ttfonts положите либо взятые из Windows ttf шрифты, либо BeOS-русифицированные (). Потом зайти в настройки Fonts и поменять сами шрифты по умолчанию на нужные.



Q: Замена типов файлов


A: (BeNews.ru)

Панель установок FileTypes здорово обновилась по сравнению с R4, хотя ее функциональность осталась во многом неизменной. Одна клевая вещь, которую вы можете сделать - это изменять тип десятков, сотен или тысяч файлов за раз. Выделите группу файлов в Tracker-е и перетащите всю группу на панель FileTypes. Появится специальный диалог, из которого вы сможете выбрать новый тип. После выборки нажмите File | Save. Ответьте “Yes” подтверждающему диалогу и все эти типы будут изменены в раз.



Классы и объекты, отступление первое


Хаотичное программирование a-la GOTO/BASIC и даже классическое структурное-процедурное программирование сильно напоминают один анекдот, про технологическую карту на советском авиазаводе, где пораженному новичку в сборочном цехе неожиданно предстало нечто, гораздо более напоминающее паравоз, а не истребитель.

В ответ ветеран производства ткнул его носом в последнюю инструкцию на карте: "До окончательного вида изделие довести рашпилем".

Объектное же программирование больше напоминает ситуацию в западном автомобильно производстве, когда многочисленные модели Seat, Skoda, VW - всего лишь вариации на тему относительно небольшой линейки шасси и прочих компонент.

Что же такое класс? Это упакованная в одно целое коллекция процедур, функций и (структур) данных. Все эти функции по большей части предназначены для работы с данными, упрятанными внутри этого самого класса. В некотором смысле класс - это развитие понятия структур из языка C. Но просто собрать это все вместе каким-то образом - невеликое достижение, и толку для программера от этого было бы чуть. Примерно, как от способности копипэйстить свой и чужой код из старых программ:)

Главное качество классов-объектов для программиста-"лентяя" - возможность делать из существующих объектов, НЕ ТРОГАЯ (и часто вообще не имея доступа к) код этого объекта, свой собственный прекрасных объект всего лишь парой легких мазков.

Ну а для больших и сложных проектов со многими разработчиками, это даже не прихоть, а, зачастую - жизненная необходимость.

Такая возможность обеспечивается нескольими магическими терминами, которые я упомянул в предыдущей статье, теперь же я поясню их.

К примеру, в заголовочном файле KrutojeOkno.h у нас будет строчка c таким куском:

class KrutojeOkno : public BWindow

Таким элементарным способом мы создаем (объявляем) совершенно новый класс (как это происходит - забота компилятора, а не наша:), но который, при этом, независимо от того, как мы его обвесим причиндалами в дальнейшем, будет обладать автоматически всеми свойствами нормального BeOS-окошка (класс BWindow).


То есть, будет иметь желтую полоску со всеми причитающимися кнопками, будет растягиваться и сжиматься, при передвижении мышкой правого нижнего уголка, а все кнопки будут работать, как им и должно - менять размер к оптимальному, закрывать окно.

По научному этот трюк называется наследование, а по забугорному - inheritance.

Естественно, что наследуются и всякие полезные фунции-методы класса-родителя (для этого в языке С++ требуется, чтобы в объявлении было слово public перед названием родительского класса).

В нашем случае, это, например, Zoom(), Minimize(), SetTitle().

То есть, чтобы в программе в дальнейшем изменить заголовок окна, вам придется написать нечто вроде:

KrutojeOkno->SetTitle("Eto mojo pervoje okno!");

Те, кто пытался на ассемблере или даже в BASIC для DOS написать программульку, рисующую рамку, в которой точка бегала бы за курсором, должны представлять себе, что это самое окно, которое BWindow - не фунт изюма. Кода всяческого там внутри тьма - но нам-то какое до этого дело?

Например до того, где и как хранится название/титул окна - в char title[], или в AnsiString WindowName. Все знать - это не знать ничего, поскольку невозможно.

Для наших целей достоточно уметь установить название (KrutojeOkno->SetTitle()) или его узнать (nazvanije = KrutojeOkno->Title()). То же самое с механизмом изменения размера окна - что там внутри и как происходит, как называются переменные, хранящие эти размеры, какие при этом сообщения бегают между окном и сервером приложений - не наше дело. Наше дело - уметь установить нужный нам размер окна - KrutojeOkno->ResizeTo(ширина, высота), или узнать нынешние размеры -

ramka = KrutojeOkno->Frame();

Такое вот отсекание лишних для прикладного программиста сущностей методом упрятывания с глаз долой и называется инкапсуляцией (encapsualtion).

Идея термина понятна - все, что не должно путаться под ногами-руками, как бы засовывается в непрозрачную капсулу:)

Вещь исключительно полезная и в программировании и в жизни - не будете же вы отправлять подругу (да и самим лучше не связываться в цивилизованном мире) регулировать сцепление или карбюратор в качестве обучения вождению автомобиля - гораздо полезнее объяснить, что лучше на газ и тормоз одновременно не давить:)



Многие моджахеды от ООП вообще считают, например, что никакие переменные класса не могут быть доступны извне "напрямую". Например, если у нас есть класс точки Point (состоящий из X и Y), то за такое его воплощение, где можно написать Point.X = 0, моджахеды эти предлагают отрезать половину седалища и убивать на месте методом скармливания тонны овсянки без соли. По их мнению, право на жизнь имеет только такая конструкция Rect.SetX(0). Впрочем, OOП-языки - это такая мощная штука, которая позволяет удовлетворить и правых и левых, например, когда вы пишете Point.X = 0 - на самом то деле может вызываться целая куча методов, которые, например, проверяют, допустимый ли это X и когда вы последний раз чистили зубы.

Попутно отмечу, что во многих случаях набора методов родительского класса не хватает для полного счастья. То же самое KrutojeOkno - ну что с ним делать, если оно имеет только то, что получило от родителей - ну порастягивать, посжимать. Закрыть и забыть. Проблема решается двумя способами - добавлением совершенно своих методов и переменных, и замещением (заменой, перекрытием) уже имеющихся в родительском классе. О втором - чуть позже, а пока - о добавлении собственного:

class KrutojeOkno : public BWindow { * GlavnajaKrasnajaKnopka; }

Таким вот простым способом мы утерли нос ребятам из Be Inc - в нашем окошке кроме глупых рамки и желтой полоски будет существовать еще и отличная Главная Кнопка.

Ясно конечно, что все не совсем так просто - эту кнопку надо как-то инициализировать и пришпандорить к окну, а может даже заставить что-то делать - но это уже другая история. Не очень страшная, впрочем.

Да, тут подошло время традиционного объяснения различия между словами класс и объект (класса). За дальнейшее объяснение экстремисты и пуристы могут меня и замочить, но я смелый, когда надо, чтоб народу было понятнее. Класс - это заготовка, шаблон, мертвая последовательность байт в библиотеке. Объектом класс становится, когда наполняется жизнью - то есть когда запускается программа, выделяется место в памяти и происходит инициализация этого ранее мертвого кода и лежачих данных.


Опять же по традиции, во всяческих пособиях для уменьшения словофлудия заместо обоих слов обычно говорят просто - класс! А там уж из текста обычно понятно, о чем речь.

Еще один столп, на котором прочно устроилось ООП - это полиморфизм (polymorphism).

(Попутно будет к месту упомянуть и т.н. перегрузку (overloading)

Чуть выше, в разговоре про экстремистов, мы отметили, что невинный значок присваивания может оказаться совсем непростой вещью. Что понятно.

Например, если мы пишем Ekran1 = Ekran2, где оба члена выражения происходят от класса BBitmap (по сути - трехмерный массив байтов) - оператор "=" делает за сценой совсем не то же, когда мы присваиваем одно целое другому (int x, y; x = y;)

ООП-языки позволяют вам создавать свои определения давно закомых значков операторов, всяких "+", "-", "=", подобный трюк и называется overloading, но рассказ об этом явно лежит за рамками "Курса начинающего пчеловода".)

Так вот, полиморфизм - это когда за одним и тем же именем функции (как и за операторами в предыдущем примере) могут скрываться совершенно разные вещи. Ну вот грубоватый пример - рисование линии - под одним и тем же названием Linija мы скроем две разные по действию функции:

int Linija(int x1, int y1); - чертит линию
от текущего положения (пера) до точки x1,y1.

int Linija(int x0, int y0, int x1, int y1);
- чертит линию от x0,y0 до x1,y1.

и где-то в теле программы у вас есть код для двух функций.

int Linija(int x1, int y1) { DrawLine(x1, y1); } и int Linija(int x0, int y0, int x1, int y1) { MovePenTo(x0, y0); DrawLine(x1, y1); }

В программе вы можете вызвать Linija() с думя или четырьмя параметрами, а уж забота компилятора - как раз по числу параметров решить, какая версия будет вызываться.

Другой способ использовать одно и то же имя для разных целей - это виртуальные (virtual) методы. КРАЙНЕ ВАЖНЫЙ для BeOS-программирования, и, несмотря на грозное и загадочное звучание - весьма простой способ. Важный - потому что практически вся обработка событий и сообщений в BeOS, включая рисование, производится с использованием виртуальных методов, а просто - потому что это просто надо привыкнуть:)



Суть дела тут вот в чем, применительно к проблемам BeOS-программирования. Если перед объявлением любой функции класса стоит слово virtual,

например:

class KrutojeOkno : public BWindow { .... virtual int KnopkaNazhata(); ... }

и как-то в этом классе эта функция реализована, что-то делает (или не делает), то, в другом классе, сделанном на основе старого (да-да, теперь мы и наш первый класс может использовать как кубик для построения новых ), можно объявить функцию с точно таким же названием, как в родительском классе:

class PrjamojeOkno : public KrutojeOkno { ....

virtual int KnopkaNazhata(); ... }

при этом с совершенно другим кодом.

Если бы мы так не сделали, то вызов PrjamojeOkno->KnopkaNazhata(); на самом деле бы запускал старую функцию, из класса KrutojeOkno, по праву наследования.

Хм, что, уважаемому читателю пока не очень понятно, зачем эта муть? Не проще ли было просто создать функцию с другим именем, безо всякой виртуальной мистики и дело с концом? Ну что ж, возьмем более жизненный пример.

В стандартном "системном" классе есть виртуальная функция MouseDown(int x, int y).

Причем в этом самом классе - она пустая, по сути - заготовка.

virtual void MouseDown(int x, int y) { }

то есть не делает ничего, НО! - эта функция автоматически вызывается, когда пользователь щелкнул мышкой в окне. Причем вызывается с "правильными" параметрами - местом, где щелкнули.

Грех не использовать такую простую, но ценную штуку в собственном классе - а как же еще мы может поймать мышиный щелчок в нашей программе? Но при этом мы можем снабдить ее осмысленным кодом:

(отрывок заголовочного файла - здесь мы объявляем, что у нас будет своя версия этой функции)

class VidVOkne : public BView { ... virtual void MouseDown(int x, int y, int buttons); ... } ---------------------- (файл с кодом - здесь мы расписываем,
что наша версия делает) virtual void VidVOkne :: MouseDown(int x, int y) { DrawLine(x, y); }

Ну вот, просто, но уже действенно - при нажатии на кнопку мыши в нашем окне будет рисоваться линия к месту щелчка.


Для новичков в С++ на этом примере поясню, что когда вы объявляете класс, например внутри заголовочного *.h-файла (то есть описываете схематически, что у него внутри) - переменные и методы пишутся безо всяких "добавок", но когда уже идет код, то есть как методы этого класса "сделаны", например в *.cpp файле - перед собственным именем метода добавляется спереди название класса, к которому этом метод принадлежит - VidVOkne :: MouseDown.

Ну а для тех, кто еще до сих пор в танке - фраза

class VidVOkne : public BView

означает, что наш класс VidVOkne будет наследником (со всеми потрохами) класса BView.

Естественно, и код здесь слегка неполный, с точки зрения BeOS API, да и функции могут чуть не совпадать с описанными в BeBook - но идея должна быть понятна - вот тебе и виртуальные, но вполне себе действенные методы.

Теперь возвращаемся непосредственно к BeOS - API. На данный момент, чтобы создать и запустить что-либо видимое, нам не хватает пояснений по классу .

В тексте мы его уже упоминали, в связи с нашим классом KrutojeOkno, но безо всяких пояснений. Теперь вроде с пояснениями будет полегче, когда я скажу, что BWindow является, как и BApplication, наследником классов (и , соответственно), но боюсь, что еще не все новички-пчеловоды переварили порцию про классы и наследование. Поэтом на сей раз отмечу только факт, важный и для новичков и для гуру -

В самом BWindow НЕВОЗМОЖНО РИСОВАТЬ!!!.

Объекты этого класса не предназначены ни для рисования, ни для "окончательной" реакции на нажатие мыши или клавиатуры.

Предназначение BWindow, кроме создания пустой рамки на экране:

1)Служить вместилищем-контейнером-родителем (parent) для других объектов-детей (child, children), которые и будут рисовать-петь-плясать и приносить нам кофе с утра в постель.

NB!!! BWindow не может быть добавлен к другому BWindow в качестве ребенка - окна в окне в BeOS не бывает !!!

2)Служить посредником-связником между этими объектами-детьми и системой. То есть ApplicationServer, InputServer и другими системными компонентами.



Вторая функция включает в себя прием и диспетчеризацию (переотправку) сообщений, как от системы ( частично уже прошедших через BApplication) к частям программы, так и от частей программы.

Для того, чтобы обеспечить как рисование, так и работу с сообщениями, в Application Server (см. часть 1 "Введения") создается "близнец" КАЖДОГО окна. Автоматически и невидимо для программиста. Впрочем, можно сказать, когда это происходит - в тот момент, когда в первый раз вызывается метод Show() класса BWindow.

Вот с ним-то, с этим близнецом на самом деле BWindow и общается, незаметно ни для пользователя, ни для программиста.

Впрочем, наблюдать этот факт крайне просто - сгрузите с Bebits программу (если вы такой чудак, что еще не поставили ее), запустите. Поместите ее в Deskbar или на рабочий стол, щелкните на иконке и пойдите в раздел "Kill, Debug or Change Priority", там найдите app_server, плавно наведите на него курсор и, в раскрывшемся меню, вы увидите некоторое количество строк с "w::" в начале. Внимательно посмотрев, можно осознать, что все эти строчки с "w::" имеют соответствия на ваших рабочих столах, в виде открытых окон разных программ. Причем, если вы, в меню предыдущего уровня, наведете курсор не на app_server, а на какую-либо программу, то увидите, что там у каждой программы тоже прописаны свои соответствия этим окнам.

И хотя я об этом уже вроде говорил, повторить не мешает - BeOS - система сугубо, глубоко и автоматически многопоточная. В частности, эксперимент с ProcessController подтверждает тот факт, что каждое существующее окно - это даже не один, а два потока. Первый - в самой программе, второй - в сервере приложений.

За более подробный разбор BWindow и код простейшей программы придется взяться в следующий раз. Мозги-то у читателя не из хром-кобальта, могут и поизноситься от перегрузки, а нам, для полного счастья, еще не хватает пояснения-отступления про конструкторы-деструкторы, а также стеки и кучи.


Особенности программирования BeOS API для пришельцев - введение. Часть 2-я.


,

В мы остановились на обещании рассказать про main() и be_app.

И хотя данный цикл заметок не предполагает рассказать про все-все-все сразу, но у некоторых читателей может возникнуть желание тут же начать переводить всю эту премудрость в код. Поэтому надо указать на необходимые инструменты.


,

В конце мы дали ссылку на статью с примером кода, однако из комментариев читателей выяснился прискорбный факт - короткого упоминания об инструментах разработки и сопутствующих вещах оказалось недостаточно даже для тех, у кого вроде должен быть некоторый опыт на других платформах.




,

Невозможно рассказать об особенностях программирования в BeOS, не упомянув одну особенность архитектуры этой ОС - модульность. BeOS целиком построен на основе сервисов, или серверов (servers) - программных демонов (в юникс-терминологии). Таких как Сервер Приложений (Application Server), выполняющий отрисовку всего видимого слоя в BeOS и обеспечивающего общение программ с системой и между собой. Или Медиа-Сервер (MediaServer) - превращающий медиа-потоки в звук и видео. Все вызовы функций/методов BeOS API из пользовательской программы в подавляющем числе случаев выполняются одним из этих серверов. В иерархии слоев ОС эти сервера находятся на уровне обычной пользовательской программы. То есть имеют те же права и методы доступа к системным ресурсом (памяти, процессору, периферии), как и гипотетическая "любая обычная" программа. А это значит, что ошибка в пользовательской программе вызовет в худшем случае падение только этого сервера (во многих случаях его можно перезапустить, "не отходя от кассы", то есть не перегружая всю систему - как многие из вас делали с NetServer или MediaServer).

Кроме того, каждый из серверов запускает множество практически независимых потоков (threads, дословно - нить) для обслуживания обращений от других программ, поэтому, во многих случаях, умирает лишь "поврежденный" поток. Такие умирающие не своей смертью потоки вылавливаются постоянно действующей "ловушкой для клопов и соломкой для падений" - Debug Server. Для последующей экспертизы. Причем, это не совсем паталогоанатомия трупа - до закрытия окна Debug Server поток находится в состоянии всего лишь клинической смерти, ему могут быть сделаны анализы, а иногда он может быть даже реанимирован

.

Наиболее важный из них для нашего дальнейшего разговора - это, естественно, Application Server, обеспечивающий наибольшую часть функциональности программ. Не то, что бы мы его намеревались упоминать направо и налево, но во всем дальнейшем разговоре он будет играть роль "серого кардинала".




,

Невозможно рассказать об особенностях программирования в BeOS, не упомянув одну особенность архитектуры этой ОС - модульность. BeOS целиком построен на основе сервисов, или серверов (servers) - программных демонов (в юникс-терминологии). Таких как Сервер Приложений (Application Server), выполняющий отрисовку всего видимого слоя в BeOS и обеспечивающего общение программ с системой и между собой. Или Медиа-Сервер (MediaServer) - превращающий медиа-потоки в звук и видео. Все вызовы функций/методов BeOS API из пользовательской программы в подавляющем числе случаев выполняются одним из этих серверов. В иерархии слоев ОС эти сервера находятся на уровне обычной пользовательской программы. То есть имеют те же права и методы доступа к системным ресурсом (памяти, процессору, периферии), как и гипотетическая "любая обычная" программа. А это значит, что ошибка в пользовательской программе вызовет в худшем случае падение только этого сервера (во многих случаях его можно перезапустить, "не отходя от кассы", то есть не перегружая всю систему - как многие из вас делали с NetServer или MediaServer).

Кроме того, каждый из серверов запускает множество практически независимых потоков (threads, дословно - нить) для обслуживания обращений от других программ, поэтому, во многих случаях, умирает лишь "поврежденный" поток. Такие умирающие не своей смертью потоки вылавливаются постоянно действующей "ловушкой для клопов и соломкой для падений" - Debug Server. Для последующей экспертизы. Причем, это не совсем паталогоанатомия трупа - до закрытия окна Debug Server поток находится в состоянии всего лишь клинической смерти, ему могут быть сделаны анализы, а иногда он может быть даже реанимирован

.

Наиболее важный из них для нашего дальнейшего разговора - это, естественно, Application Server, обеспечивающий наибольшую часть функциональности программ. Не то, что бы мы его намеревались упоминать направо и налево, но во всем дальнейшем разговоре он будет играть роль "серого кардинала".




В принципе, AppServer - хорошая иллюстрация быстрой и эффективной клиент- серверной архитектуры для графического интерфейса пользователя (GUI).

То, о чем десктопный юникс-народ с их X11 может пока только мечтать (о сетевой функциональности X11 здесь речь не идет, тем более, что в версии BeOS 5.1 по имеющимся сведениям, вся эта клиент-серверность с тем же успехом работала и через сеть).

Впрочем, есть и другой пример эффективной реализации этой идеи - Photon в операционной системе QNX.

Значительная заслуга во впечатляющей работе AppServer принадлежит многопоточности.

Наверное надо чуть пояснить про потоки. Начинающие программисты, даже программируя в многозадачной среде, редко в явном виде сталкиваются с этим зверем. В BeOS же без него ни шагу не ступить. Или, скорее невозможно на эти грабли не наступить. Образно говоря, это такой минимальный целостный кусок исполняемого кода, у которого может создаться впечатление, что он настолько самый главный, что все ресурсы машины принадлежат ему одному.

Концепция потоков является развитием концепции многозадачности. На всякий пожарный, поясню и это.

Вас никогда не удивляло, что процессор, как правило - один, видеокарта, скажем, тоже одна - а тем не менее вроде все программы выполняются одновременно и другу другу не мешают (хехе, вот тут и отличие грамотно сделанной ОС от...)? Делается это за счет очень быстрого переключения процессора с одного куска кода на другой. Для временно осиротевшего кода запоминается его состояние и частично состояние ОС в момент остановки, то есть всяческие данные, необходимые для последующей реанимации.

Вот такой исполняющийся код, вместе с этими самыми постоянно обновляемыми "реанимационными данными", и есть процесс, или задача. В былые времена весь код, относящейся к одной программе, обычно и представлял из себя единый и единственный процесс. Теперь же и единая программа может из себя представлять целый набор параллельно выполняющихся кусков, тем самых потоков-нитей (threads). В целом же потоки-нити одной программы образуют связку - team.


При этом каждый из потоков программы может получить некоторый доступ к общим для team данным.

При последовательной и аккуратной реализации многопоточности можно заметно повысить эффективность и отдельных программ, и всей ОС. Кроме того, это сильно облегчает реализацию Симметричной Многопроцессорности (SMP).

Поскольку тут не придется специально заботиться, как загрузить крутую многопроцессорную тачку - каждый поток может быть отдан любому из процессоров, на котором сейчас потоков меньше - без долгих раздумий и разбора обстоятельств. Счастливчики с BeOS на многопроцессорной тачке могут воочию наблюдать этот радующий сердце факт при помощи программы ProcessController.

Теперь можно спуститься и поближе к земле, то есть к BeOS API. Единственно, что меня слегка гложет - это степень необходимости пояснения понятия Объектно Ориентированного Программирования (OOP) по ходу текста.

Хотя нынешняя молодежь должны была бы всосать это дело с первым глотком кока-колы, мой опыт показывает, что это не так. Хотя даже VisualBasic дает (тем кто интересуется) достаточный опыт, оказывается, что и активные пользователи таких объектных сред как Delphi и BorlandBuilder зачастую имеют о предмете весьма смутное представление. Так что заранее прошу OOP-гуру извинить меня за последующее занудство и некоторый примитивизм:)

Для удобства программиста (который тоже человек:), весь набор фунций/методов для BeOS разбит на инструментальные комплекты - Kits. Например Networking Kit, Media Kit, Storage Kit. Сейчас нас будут интересовать два из них Инструментарий Приложений - Application Kit и Инструментарий Интерфейса - Interface Kit.

На все это дело можно взглянуть в библии BeOS-програмирования, BeBook.

В интернете -

или, если вы уже поставили комплект разработчика BeOS - BeOS Development Tools - на вашем диске:

file:///boot/beos/documentation/Be%20Book/index.html

Начнем с головы, точнее с двух - main() и be_app. И если первое слово знакомо каждому С-шнику, то второе - уже чистый BeOS.



В принципе, AppServer - хорошая иллюстрация быстрой и эффективной клиент- серверной архитектуры для графического интерфейса пользователя (GUI).

То, о чем десктопный юникс-народ с их X11 может пока только мечтать (о сетевой функциональности X11 здесь речь не идет, тем более, что в версии BeOS 5.1 по имеющимся сведениям, вся эта клиент-серверность с тем же успехом работала и через сеть).

Впрочем, есть и другой пример эффективной реализации этой идеи - Photon в операционной системе QNX.

Значительная заслуга во впечатляющей работе AppServer принадлежит многопоточности.

Наверное надо чуть пояснить про потоки. Начинающие программисты, даже программируя в многозадачной среде, редко в явном виде сталкиваются с этим зверем. В BeOS же без него ни шагу не ступить. Или, скорее невозможно на эти грабли не наступить. Образно говоря, это такой минимальный целостный кусок исполняемого кода, у которого может создаться впечатление, что он настолько самый главный, что все ресурсы машины принадлежат ему одному.

Концепция потоков является развитием концепции многозадачности. На всякий пожарный, поясню и это.

Вас никогда не удивляло, что процессор, как правило - один, видеокарта, скажем, тоже одна - а тем не менее вроде все программы выполняются одновременно и другу другу не мешают (хехе, вот тут и отличие грамотно сделанной ОС от...)? Делается это за счет очень быстрого переключения процессора с одного куска кода на другой. Для временно осиротевшего кода запоминается его состояние и частично состояние ОС в момент остановки, то есть всяческие данные, необходимые для последующей реанимации.

Вот такой исполняющийся код, вместе с этими самыми постоянно обновляемыми "реанимационными данными", и есть процесс, или задача. В былые времена весь код, относящейся к одной программе, обычно и представлял из себя единый и единственный процесс. Теперь же и единая программа может из себя представлять целый набор параллельно выполняющихся кусков, тем самых потоков-нитей (threads). В целом же потоки-нити одной программы образуют связку - team.


При этом каждый из потоков программы может получить некоторый доступ к общим для team данным.

При последовательной и аккуратной реализации многопоточности можно заметно повысить эффективность и отдельных программ, и всей ОС. Кроме того, это сильно облегчает реализацию Симметричной Многопроцессорности (SMP).

Поскольку тут не придется специально заботиться, как загрузить крутую многопроцессорную тачку - каждый поток может быть отдан любому из процессоров, на котором сейчас потоков меньше - без долгих раздумий и разбора обстоятельств. Счастливчики с BeOS на многопроцессорной тачке могут воочию наблюдать этот радующий сердце факт при помощи программы ProcessController.

Теперь можно спуститься и поближе к земле, то есть к BeOS API. Единственно, что меня слегка гложет - это степень необходимости пояснения понятия Объектно Ориентированного Программирования (OOP) по ходу текста.

Хотя нынешняя молодежь должны была бы всосать это дело с первым глотком кока-колы, мой опыт показывает, что это не так. Хотя даже VisualBasic дает (тем кто интересуется) достаточный опыт, оказывается, что и активные пользователи таких объектных сред как Delphi и BorlandBuilder зачастую имеют о предмете весьма смутное представление. Так что заранее прошу OOP-гуру извинить меня за последующее занудство и некоторый примитивизм:)

Для удобства программиста (который тоже человек:), весь набор фунций/методов для BeOS разбит на инструментальные комплекты - Kits. Например Networking Kit, Media Kit, Storage Kit. Сейчас нас будут интересовать два из них Инструментарий Приложений - Application Kit и Инструментарий Интерфейса - Interface Kit.

На все это дело можно взглянуть в библии BeOS-програмирования, BeBook.

В интернете -

или, если вы уже поставили комплект разработчика BeOS - BeOS Development Tools - на вашем диске:

file:///boot/beos/documentation/Be%20Book/index.html

Начнем с головы, точнее с двух - main() и be_app. И если первое слово знакомо каждому С-шнику, то второе - уже чистый BeOS.


Отступление 1 - Инструменты.


Для аскетичных пришельцев-радикалов из мира юникс, достаточно будет следующих сведений:

Имеется vim. И ряд других редакторов консольного режима.

Шаблон makefile для BeOS находится в /boot/develop/etc/.

Имеются версии gcc - 2.9 и 2.95*. 3-й gcc можно собрать, но применять не получится из-за ABI.

Функции уровня POSIX находятся в libroot.so (glibc+libm+еще что-то, хотя не полностью).

Библиотека стандартных классов С++ - libstdc++.r4.so.

Значительная часть BeOS API, прежде всего интерфейсная - в libbe.so.

Для менее радикальных отмечу, что можно использовать GUI-редакторы Pe (http://bebits.com/app/3356), Eddie (http://bebits.com/app/95) и BeIDE - /boot/develop/BeIDE/BeIDE.

Последнее - это стандартная для BeOS интегрированная среда разработки (от Metrowerks), проект-ориентированная, но позволяет, для пуристов, генерировать и make-файлы из проекта.

Она же рекомендуется и тем новичкам в BeOS, кто привык разрабатывать программы в более современных средах.

Инструменты Быстрой Разработки Приложений (RAD) - BeXL, MeTOS, VisualBe, BeBuilder - на этом этапе категорически не рекомендуются.

Может быть рекомендована добавка к BeIDE - Don'tWorry(http://bebits.com/app/2374) - помогает в изучении иерархии классов.

Тем, кто привык к IDE, освоить BeIDE будет легко, впрочем, несколько замечаний необходимы:

1)Файлы BeOS-проектов имеют расширение *.proj. Для создания своего проекта, создайте сначала новую папочку и скопируйте туда файл(ы) из /boot/develop/BeIDE/stationery/x86/BeApp/ - это шаблон стандартного BeOS-проекта. Их можно переименовать под ваш проект. Запустите BeIDE двойным щелчком на proj-файле.

Впрочем, можно и просто запустить BeIDE, cоздать "новый проект" и выбрать тип шаблона прямо изнутри BeIDE.

2)А теперь не стоит сразу переходить на "русский народный" по поводу "диких" клавиатурных сочетаний (шорткатов) - они все настраиваются под ваш вкус в окне проекта - Edit->Preferences->General->KeyBindings. Цвета настраиваются в Edit->Preferences->Editor->SyntaxStyling.


Для тех же, кто не боится "Читать Эти Грёбаные Руководства" (RTFM) - есть мануал BeIDE от Metrowerks

Теперь, когда мы знаем, чем писать программы, можно открыть Главный Секрет "как писать" - каждая программа должна иметь начало. Менее главный секрет - программа в BeOS, как и любая другая С и С++ программа, начинается с выполнения функции main().

Никаких особых подвохов тут нет, единственно, что можно заметить на будущее, если программу запускать из командной строки с аргументами, то эти аргументы могут быть считаны не только традиционным способом в качестве параметров main() - argc и argv, но также и получены BeOS-приложением более натуральным для BeOS способом - через сообщение главному циклу сообщений (Message Loop) BeOS-программы. Такое сообщение отправляется AppServer-ом автоматически, при наличии этих самых аргументов.

Еще стоит отметить, что в GUI-шных BeOS-программах код в самой main обычно крайне минималистичен, и предназначен, главным образом, для запуска BeOS Application (наследник класса BApplication )- по сути того самого главного Message Loop. К сожалению, рассказать, что такое классы и что такое сообщения одновременно - довольно затруднительно, поэтому начну с сообщений.


Отступление 2. Сообщения - отправители, диспетчеры, обработчики, прерывания.


В первой части введения мы уже задавались вопросом - как это все программы умудряются работать одновременно? - и частично на него ответили. Необъясненным осталось то, как же всё-таки все эти куски, которые считают, что каждый из них - чуть ли не единственный на белом свете, взаимодействуют с друг другом в многозадачной операционной системе.

Ответ простой - они обмениваются телеграммами/письмами/SMS-ками/бандеролями/и даже грузовыми контейнерами:) - т.е. сообщениями (в unix-мире больше распространена концепция сигналов - signals, в BeOS signals реализованы в слое эмуляции POSIX).

Щелкнул мышкой - драйвер сработал, послал сообщение InputServer-у, тот - ApplicationServer-у, AppServer - в свою очередь - программе.

Хочет программа что либо нарисовать - сообщение AppServer-у, а уж доля того - общаться с драйверами видеокарты.

Соответственно, у всех жильцов в общежитии операционной системы должны быть способности к

1)отправке сообщений - отправитель в BeOS "называется" BMessenger,

2)приему-перехвату сообщений и решению, что с ними дальше делать (диспетчеризация) - этим занимается цикл приема и распределения сообщений - message loop, BLooper в BeOS,

3)обработке сообщений (обработчик по английски - handler) - BHandler в BeOS.

(Как вы могли догадаться, названия компонент-классов BeAPI начинаются с 'B'.)

Теперь немножко о самих BeOS-сообщениях, для тех знатоков, кто сталкивался с сообщениями в других ОС/платформах. Их отличительное качество - практически "свободный" формат. Единственный обязательный член BMessage - признак "ЧТО" (what). Например, если в сообщении, полученном BeOS-приложением этот what==B_ARGV_RECEIVED (константа, определенная в системе) - это означает, что программа была запущена из командной строки и там имеются аргументы - см. параграф про main().

А дальше (я не зря упомянул не только телеграммы, но и бандероли, и грузовые контейнеры) - в теле сообщения может содержаться практически все что угодно, любого размера. В теории - хоть DVD-диск упакуй туда.
Но не рекомендую:)

Раз уж мы вдарились в объяснения, как работает многозадачная/ многопоточная OS, можно спуститься поближе к земле, то есть к кремнию и железу, и пояснить, на чем все это основано. То есть, рассказать о прерываниях. Знатоки, а также ленивые и нелюбопытные могут смело пропустить нижеследующее безо всякого ущерба.

Есть два способа реагировать на изменения в обстановке - программный опрос (polling) и прерывания (interrupts).

Первый - это когда программа состоит из ужасных запутанных циклов, проверяющих по кругу состояния всего и вся - портов устройств, программ, системного таймера (чтобы время от времени переключаться между программами). На вид просто, с этого народ обычно начинает писать программы, на деле, написать ОС, работающую таким способом - надо быть крутым садомазохистом.

Это как если бы телефонная связь работала по тому принципу, что вам надо было бы раз в секунду подбегать к трубке и слушать, не пытается ли кто с вами пообщаться.

Второй - прерывания. Когда какому-нибудь устройству или программе невтерпеж пообщаться (например, буфер последовательного порта уже почти забит данными из модема) - они "звонят" процессору - выставляют запрос на прерывание, тот самый печально известный IRQ (interrupt request). Дальше начинается некоторая машинерия - кого обслужить первым и т.д., но, в конечном счете, запоминается текущее состояние системы, выполнение предыдущих программ прекращается (откладывается), и система переходит на выполнение кода, указанного в запросе на прерывание.

После удовлетворения потребности в тусовке, система возвращается к выполнению отложенных задач.

Так вот, и разделение времени между программами из первого объяснения про многозадачность, и создание/перехват/обработка сообщений из второго, происходят при помощи прерываний.

Для первого используются прерывания от системного таймера, для второго - используются так называемые программные прерывания. Аналогию с телефоном/пэйджером/SMS можете додумать сами :)

Теперь читатель знает почти достаточно, чтобы показать ему, как выглядит запуск BeOS-программы.


А выглядит он, в сокращенном виде, так:

-------------------------------- main() { KrutajaProgramma.Run() ------------------------------- или так: main() { SuperPuperProgramma->Run() --------------------------------

Этот Run() - метод класса BApplication, запускающий главный цикл - приемник/диспетчер/обработчик сообщений для BeOS-программы в целом.

Охх, опять эти грабли, это "знает почти достаточно" - классы, методы, энкапсуляция, наследование, полиморфизм и прочие ругательства...боюсь что начало этого цикла статей так и будет состоять из сплошных отступлений. Может, отложим до завтра?:) Да и караул уже устал.

Разве что сейчас можно упомнять для знатоков, что be_app из предыдущей главки - это глобальный (доступный всем компонентам программы) указатель на объект этой программы. Переменная с таким именем создается автоматически, при создании объекта-наследника BApplication.

(В данном случае be_app == SuperPuperProgramma или be_app == &KrutajaProgramma). А в связи с отступлением про сообщения, надо упомянуть также то, что BApplication является наследником BLooper и BHandler.

А для тех, кто не устал и полон энтузиазма запустить свою первую BeOS-программу - может от Эрика Шеперда и Макса "Базы" Базарова.

       


Замечание мимоходом - снова об инструментах разработки


Во-первых, если у кого вдруг на системе еще нет ни BeIDE, ни BeBook ни компилятора С++ - все это можно сгрузить с ", пакет называется (17.9 MB). Если сей линк не сработал, посмотрите внимательней, там довольно большой список зеркал. Архив надо распаковать в /boot/

Теперь про BeIDE. Это не компилятор, а интергрированная среда разработки, способная работать практически с любым компилятором (например с Java и Pascal). По умолчанию она заточена на компилятор gcc (всякие другие имена компиляторов, типа cc или g++, тоже работают, но представляют собой или линки или скрипты, исользующие gcc). Упоминавшийся в одном из комментариев компилятор от Metrowerk (mwcc) ныне присутствует только в версии для PowerPC, но не для x86.

Библиотеки располагаются в двух местах:

/boot/beos/system/lib/ (основные системные)

и

/boot/home/config/lib/ (дополнительные)

а в /boot/develop/lib/x86/

располагаются в основном линки на библиотеки из указанных выше мест.

Заголовочные файлы располагаются в

/boot/develop/headers/

и

/boot/home/config/include/

Впрочем, эти факты можно было бы узнать, набрав в терминале незамысловатую команду:

set или set | more которая, среди прочего, выдаст вам значения
таких переменных, как: BEINCLUDES BELIBRARIES BE_CPLUS_COMPILER BE_C_COMPILER CPLUS_INCLUDE_PATH C_INCLUDE_PATH LIBRARY_PATH

впрочем, на начальном этапе, возможно, не все из них будут присутствовать в вашем списке. BeBook после правильной распаковки пакета разработчика будет располагаться по адресу "/boot/beos/documentation/Be Book/index.html".

Считаем, что эту вашу проблему мы решили, теперь упомяну о моей - нынешний движок qube.ru не слишком приспособлен для ввода-вывода хорошо форматированного кода в статьях, так что с красивыми отступами у нас могут быть проблемы, так же, как может быть, и с прямым копирование кода из браузера в BeIDE.

Итак, в предыдущей части введения мы, наконец, успели сказать, что настоящая BeOS-программа должна содержать объект класса , а запускаться все это должно вызовом метода Run() класса BApplication.


Ну что ж, самое время для небольшого обещанного базара о классах и всем таком прочем. Знатоки ООП эту часть смело могут пропустить, хотя бы для того чтобы уберечь челюсть от повреждений в результате ухмылок. Единственно, что стоит для них упомянуть, так же как и для новичков - никакой другой возможности (эффективно) программировать в BeOS, кроме C++ OOП API на данный момент нету. Поскольку просто не существует другого API, кроме полноценного объектного под C++. Есть правда компилятор Basic, который транслирует Basic-код в C++, а последний потом компилируется нормальным образом, но такому способу недостает ни полноты, ни гибкости. Так же не хватает полноты и гибкости и для существующей версии Pascal (с до сих пор не законченной библиотекой оберток вокруг нативных вызовов Be C++ API).
Даже на С нельзя писать почти ничего, что выходило бы за рамки консольных приложений и драйверов.
Так что рекомендация писать на C++ в BeOS - это не дурная шутка, вроде MFC, и не удачный прикол, вроде OWL и VCL - а это то, из чего BeOS сама сделана, снизу доверху, за исключением (частей)ядра и (частей) драйверов.
Впрочем, те, кто не специалист в ООП, тоже могут пропустить это сжатое и слегка сумбурное изложение, а вместо этого в спокойной обстановке просмотреть .

Как написать драйвер принтера в BeOS


Автор публикации - , 6.04.2004

Оригинал статьи: http://open-beos.sourceforge.net/nsl.php?mode=display&id=51#181

Перевод опубликован на сайте



Драйвер принтера в BeOS R5 — это модуль (add-on), который экспортирует специфический API. Этот модуль используется сервером печати (print_server) для того, чтобы добавить новый принтер, настроить страницу, управлять заданием печати (Print Job) и наконец напечатать задание на принтере. Эта статья поможет понять, как сервер печати взаимодействует с драйвером принтера.

Сервер печати отвечает за управление настройками (например размер бумаги). Обмен настройками между сервером печати и драйвером происходит при помощи BMessage. Если драйвер принтера возвращает объект BMessage и хочет указать на удачное завершение работы, то значением поля what будет 'okok'. При ошибке этот метод должен вернуть NULL. В большинстве случаев сервер печати интепретирует значение what, отличающееся от 'okok', как неудачную операцию. В любом случае драйвер принтера не должен полагаться на это и при ошибке всегда возвращать NULL.

Задание печати — файл, созданный печатающим приложением. Для создания задания, приложение использует класс BPrintJob из Interface Kit (рис 1). Этот файл содержит архивированные объекты BPicture, одно на каждый вызов BPrintJob::DrawView(). Для примера растровый драйвер принтера может использовать BPicture для каждой страницы и рисовать его в BBitmap. После этого конвертировать BBitmap в формат, понятный принтеру. Драйвер также может изменять BPicture, включая преобразование в полутона и цветокоррекцию. Учтите, что в BeOS не существует общего подхода для реализации таких особенностей печати.

Для передачи задания на принтер драйвер использует транспортный модуль (transport add-on). Этот модуль «знает» как передать данные на устройство (через LPT, USB, TCP/IP итп). Разделяя транспорт и драйвер принтера, мы получаем возможность использовать один драйвер для принтера, подключенного разными способами, например, через LPT или USB.
Это позволяет упростить код. Драйвер не должен знать, каким способом будут доставляться данные на принтер, он—просто выводит поток данных.



Местонахождение драйвера

Системные драйвера, которые установлены с ОС, находятся в B_BEOS_ADDONS_DIRECTORY в подкаталоге Print (т.е. /boot/beos/system/add-ons/Print). Драйвера, установленные пользователем, находятся в B_USER_ADDONS_DIRECTORY в подкаталоге Print (т.е. /boot/home/config/add-ons/Print).

Транспортные модули находятся в пользовательском или системном каталоге драйверов в подкаталоге transport.

Жизнь драйвера принтера

Установка драйвера

Для установки драйвера достаточно скопировать нужный файл в каталог драйверов. Драйвер не должен быть слинкован с какими-либо динамическими библиотеками кроме системных. Старайтесь использовать статическую линковку. Это позволит избежать проблем с конфликтом версий.

Добавление нового принтера

Если пользователь добавит новый принтер через диалог Printers, он выберет имя принтера, модель принтера и транспортный модуль. Приложение Printers создаст каталог спулера (spooler), названный именем принтера в B_USER_PRINTERS_DIRECTORY

(например: /boot/home/config/settings/printers). Имя транспортного модуля сохранится в атрибуте transport каталога спулера. Тип этого атрибута - B_STRING_TYPE.

Когда сервер печати получит сообщение, что был добавлен новый принтер, то он вызовет драйвер, чтобы его настроить. Прототип функции в драйвере принтера выглядит так:

char* add_printer(char* printer_name);

Это даст шанс драйверу открыть диалог конфигурирования. Все настройки могут сохранены в атрибутах каталога спулера. При удачном завершении операции драйвер должен вернуть указатель на строку printer_name, а в случае неудачи, как было оговорено выше — NULL.

Настройка страницы

Когда приложение пользователя вызовет BPrintJob::ConfigPage(), сервер печати вызовет следующую функцию в драйвере:

BMessage* config_page (BNode* spool_folder, BMessage* settings);

В этом вызове драйверу будет передан указатель на спулер печати, и в результате этого драйвер сможет прочитать настройки из атрибутов спулера.


В settings будут переданы настройки печати предыдущей страницы. Как минимум, ореинтация и размер бумаги.

Обычно драйвер принтера открывает диалог настройки страницы для того, чтобы пользователь мог выбрать размер бумаги, орентацию и возможно, другие настройки (например ручной лоток или лоток автоподачи). Все другие настройки специфичны для каждой модели принтера, а упомянутые выше обязательные поля приведены в таблице:

Поле

Тип

Примечание

printable_rect B_RECT_TYPE размер печатаемой области в разрешении 72 пикселя на дюйм.
paper_rect B_RECT_TYPE размер бумаги в разрешении 72 пикселя на дюйм
orientation B_INT32_TYPE 0-портрет, 1-пейзаж
xres B_INT32_TYPE горизонтальное разрешение
yres B_INT32_TYPE вертикальное разрешение
Если конфигурирование было удачным, то драйвер принтера должен вернуть указатель на BMessage с новыми настройками, в противном случае NULL (например пользователь нажал на кнопку «Отменить» в диалоге настройки станицы).

Транспортный модуль

Для непосредственной передачи задания печати, драйвер принтера должен загрузить ассоциируемый с ним транспортный модуль. Имя транспортного модуля, как было оговорено выше, драйвер может получить из атрибута transport каталога спулера. Сначала драйвер должен поискать модуль в пользовательском каталоге (B_USER_ADDONS_DIRECTORY каталог Print/transport) и только в случае неудачи — в системном (B_SYSTEM_ADDONS_DIRECTORY каталог Print/transport).

Транспортный модуль экспортирует две функции:

BDataIO* init_transport(BMessage *settings);
void exit_transport(void);

Единственный параметр init_transport() — это BMessage с записью printer_file (B_STRING_TYPE) внутри. Эта запись должна указывать на каталог спулера. При нормальном завершении, функция вернет указатель на BDataIO объект, а в случае неудачи NULL. Полученый объект будет использоваться для записи данных в принтер.

Драйвер не должен удалять BDataIO объект. Удаление объекта происходит при вызове exit_transport() и выгрузке транспортного модуля.

Пример кода можно посмотреть в методе Open() класса PrinterTransport в каталоге



current/src/add-ons/print/shared/ CVS-репозитория OBOS. Заголовочный файл
PrintTransport.h находится в каталоге current/headers/private/print.

Печатаем задание печати

Теперь мы добрались до самого ядра драйвера. Этот прототип функции вызывается сервером печати, когда все готово:

BMessage* take_job(BFile* print_job, BNode* spool_folder, BMessage* settings);

Задание печати передается в print_job. Формат задания будет описан далее. Атрибуты спулера печати могут быть доступны через spool_folder, а в settings передаются параметры страницы, например ее размер.

Для передачи задания на принтер, драйвер должен загрузить к этому времени транспортный модуль и получить указатель на объект BDataIO.

Для чтения задания печати может быть использован класс PrintJobReader. Его можно найти в репозитории OBOS. Небольшой фрагмент кода демонстрирует как этот класс может быть использован:

PrintJobReader reader(print_job); if (reader.InitCheck() == B_OK) { // the settings stored in the print job BMessage* settings = reader.JobSettings();

// получим номер первой страницы int32 firstPage = reader.FirstPage();

// получим номер последней станицы int32 lastPage = reader.LastPage();

// размер бумаги и размер печатаемой области BRect paperRect = reader.PaperRect(); BRect printableRect = reader.PrintableRect();

// разрешение int32 xdpi, ydpi; reader.GetResolution(pi, &ydpi);

int32 pages = reader.NumberOfPages(); // для каждой страницы for (int page = 0; page < pages; page ++) {

PrintJobPage pjp;

if (reader.GetPage(page, pjp) == B_OK) { BPicture picture; BPoint point; BRect rect;

// для каждого изображения на странице while (pjp.NextPicture(picture, point, rect) == B_OK) { // проделываем "черную работу" с каждым изображением } } } }


Описание предпечатной обработки данных драйвером не попадает в рамки этой статьи, но вы можете посмотреть примеры драйверов в репозитории OBOS. Примеры растровых драйверов Canon LIPS, PCL5 или PCL6 драйвера. Примером «векторного» драйвера будет OBOS PDF драйвер.



Заголовок задания печати

struct print_file_header { int32 version; int32 page_count; off_t first_page; int32 _reserved_3_; int32 _reserved_4_; int32 _reserved_5_; };
Эта структура декларирована в PrintJob.h. В файле задания печати после заголовка следует
плоский BMessage, содержащий в себе настройки переданные take_job().Задание печати содержит
в себе page_count страниц. Первая станица находится по смещению first_page.
Заголовок Страницы

struct page_header { int32 picture_count; off_t next_page; int32 _reserved[10]; };
Этот заголовок находится перед picture_count изображений. Следующая станица начинается со
смещения next_page.
Заголовок Изображения

struct _picture_header_ { BPoint point; BRect rect; };
Содержит плоский BPicture объект.

Удаление принтера

Принтер может быть удален через аплет Printers. Удаление каталога спулера происходит только когда в спулере не находится ни одного задания печати.

Деинсталяция драйвера

Драйвер может быть деинсталирован через аплет Printers только когда все принтеры, зависящие от этого драйвера, были удалены. Для удаления драйвера надо просто удалить модуль из соответсвующего каталога. Следует заметить, что удаление драйвера не принесет большой пользы т.к. от этого не уменьшится ни время загрузки системы, как и не увеличитсяпроизводительность.

Обновление драйвера

Обычно при установки новой версии драйвера не требуется удалять и добавлять заново уже установленные принтеры. В большинстве случаев достаточно заменить соответствующий модуль.

Возможные проблемы при написании драйвера

Драйвер принтера — модуль, который загружается и выгружается по требованию. Это означает, что состояния не могут быть сохранены в глобальных переменных. Как говорилось выше, драйвер может сохранять свои состояния в атрибутах каталога спулера.

Также существует ситуация, когда могут быть загружены несколько копий драйвера (Например, когда печатается задание и в этот же момент пользователь конфигурирует принтер в диалоге настройки).

Многопоточность в драйвере тоже может стать проблемой.


Вы должны завершать все потоки, запущенные внутри драйвера, пока он еще не вышел из функции. Т.е. когда драйвер открывает окно для конфигурирования страницы в config_page(), паралельно запускается поток окна. А config_page() ожидает, пока окно будет закрыто и все объекты, принадлежащие окну, будут уничтожены. Если не делать этого, то может произойти ситуация когда драйвер будет выгружен, но поток окна будет исполняться. Это вызовет ошибку доступа (access violation) т.к. поток окна попытается работать с памятью драйвера, который уже выгружен.

Ссылки на источники кода

Файл

Местонахождение

PrintJobReader.cpp current/src/add-ons/print/shared
PrintJobReader.h current/headers/private/print
Printer Drivers current/src/add-ons/print
Transport Protocols current/src/add-ons/print/transports

document.write('');

Новости мира IT:

02.08 - 02.08 - 02.08 - 02.08 - 02.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 01.08 - 31.07 - 31.07 - 31.07 - 31.07 - 31.07 -

Архив новостей

Последние комментарии:

 (66)

2 Август, 17:53

 (19)

2 Август, 17:51

 (34)

2 Август, 15:40

 (42)

2 Август, 15:35

 (1)

2 Август, 14:54

 (3)

2 Август, 14:34

 (3)

2 Август, 14:15

 (2)

2 Август, 13:34

 (7)

2 Август, 13:04

 (3)

2 Август, 12:28



BrainBoard.ru

Море работы для программистов, сисадминов, вебмастеров.

Иди и выбирай!


Loading

google.load('search', '1', {language : 'ru'}); google.setOnLoadCallback(function() { var customSearchControl = new google.search.CustomSearchControl('018117224161927867877:xbac02ystjy'); customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET); customSearchControl.draw('cse'); }, true);

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
PR-акции, размещение рекламы — ,
тел. +7 495 6608306, ICQ 232284597

Пресс-релизы —

<


This Web server launched on February 24, 1997

Copyright © 1997-2000 CIT, © 2001-2009
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
Началась продажа путевок в для туристов.


Настройка:


Далее я расскажу, как настроить драйвера и приведу настройки аудио-микшера для оптимального качества звука (искажения и шумы по-минимуму, нормальный баланс каналов) на примере Creative SB Live! 5.1 Digital [SB0220]. Изначально звук настроен так, что он хрипит и слишком завышены басы.

Запустите панель настроек Media (меню Be|Preferences|Media). В разделе Audio Settings выберите Emuxki (Emuxki SB Live 5.1 в моём случае) в качестве основной звуковой карты.

Рис. 1. Audio Settings

Перейдите во вкладку Setup настроек Audio Mixer'а и установите все опции, как показано на скриншоте. Опцию 'Use non linear gain sliders (like BeOS R5)' лучше отключить, тогда значение всех полозков будет изменяться линейно (поверьте мне, работать с такими полозками гораздо удобнее).

С помощью опций 'Allow output channel remapping' и 'Allow input channel remapping' можно получить доступ к очень тонкой настройке выходных и входных каналов (такого в явном виде нет даже в драйверах под Windows). Советую ничего не менять, если вы не уверены в том, что делаете.

Рис. 2. Audio Mixer Setup

Перейдите во вкладку Gain Controls настроек Audio Mixer'а и установите уровень громкости выходного сигнала примерно так же, как на скриншоте, можно чуть ниже.

Рис. 3. Audio Mixer Gain Controls

Переходим непосредственно к настройке драйвера (Emuxki SB Live 5.1). Зайдите во вкладку Setup и выберите необходимый audio mode. Для DVD это, очевидно, 5.1. А вот у проигрывания стерео-композиций есть свои особенности. В Windows, даже если в системе выставлен режим аудио 5.1, все стерео-композиции проигрываются как квадра (4.0, Front + Rear). В BeOS же они микшируются на все 6 каналов и звучат, соответственно, по-другому (как правило - хуже). Так что при прослушивании стерео приходится явно выставлять формат звука 4.0. Опцию 'Enable Digital' следует выбирать только в том случае, если ваша акустическая система подключена к карте через цифровой выход.

Рис. 5. Emuxki Setup

Во вкладке AC97 Mixer рекомендую выставить Center/Lfe на Mute, сильно сказывается на качестве звука в DVD (в лучшую сторону). На режимы 2.0 и 4.0 этот полозок не оказывает никакого влияния.

Рис. 6. Emuxki AC97 Mixer

Перейдите во вкладку Playback и убедитесь в том, что все полозки стоят в верхнем положении.

Рис. 4. Emuxki Playback

Теперь можно выставить приемлемый для себя уровень громкости, регулируя соответствующие органы управления акустической системы и/или полозок Master Output в настройках Audio Mixer'а (советую сильно не повышать его уровень - появляются искажения). Если во время изменения каких-либо настроек появился посторонний треск - перезагрузите media-подсистему.



Проблема:


В BeOS R5 и старше есть стандартный драйвер для аудио-карт на базе чипов серии emu10k (Creative SB Live!, Audigy, Audigy2), но его главный недостаток в том, что он работает только в режиме стерео (2.0). Кроме того, он поддерживает не все звуковые карты серий Audigy и Audigy2.



В частности, это драйвер emuxki


Проблему можно решить, установив в BeOS драйвера и некоторые части media-подсистемы (Media Kit) OpenBeOS. В частности, это драйвер emuxki для аудиокарт на базе emu10k1, emu10k2 и набор из двух media_addon'ов: mixer.media_addon и multi_audio.media_addon. Кое-что из этого можно найти на BeBits.com, но это довольно старые версии и там нет mixer.media_addon'а. В качестве альтернативы скачиванию и компиляции исходников с CVS OpenBeOS.org я предлагаю свой билд от 1 января 2004 года (работает как в R5, так и в R5.1d0 Exp/Dano):
Из комментариев пользователей и разработчиков на BeBits.com:
1. Audigy LS работать в BeOS не будет, так как часть её функциональности эмулируется программно.
2. У первых Audigy был аппаратный дефект (шумы), который был исправлен программным путём - Creative выпустила патч для драйверов Windows. Под BeOS эта проблема всё ещё остаётся.

Установка:


1. Скопируйте emuxki в /boot/home/config/add-ons/kernel/drivers/bin и сделайте ссылку на него в /boot/home/config/add-ons/kernel/drivers/dev/audio/multi

2. Скопируйте все media_addon'ы в /boot/home/config/add-ons/media

3. Запустите панель настроек Media из меню Be|Preferences|Media и в Audio (или Video) Settings нажмите кнопку 'Restart Media Services'.

Удалять аналогичные системные media_addon'ы и драйвера не обязательно.

Вот где проявляются некоторые отличительные черты BeOS - после установки новых драйверов моя звуковая карта была тут же определена, без перезагрузки компьютера. После установки media_addon'ов я перезапустил media-подсистему и услышал звук в колонках (поганого качества, правда, но это уже вина установок драйвера по-умолчанию).



Проблема решена, но всё же


Проблема решена, но всё же остаётся едва заметная разница в качестве звука под Windows и BeOS (причём не в пользу последней). Думаю, это можно списать на alpha-версию драйвера и media_addon'ов.

Помещение репликанта на Shelf Deskbar'а


, avix.pp.ru

Статья опубликована на сайте

Статья рассматривает процесс создания репликанта Deskbar'а - приложения для BeOS, помещающегося на Shelf'е Deskbar'а.

Определим некоторые термины, используемые в изложении.

Deskbar - системная программа, содержащая меню доступа к приложениям и настройкам системы (меню BeOS), а также список запущенных задач.

Shelf Deskbar'а - прямоугольная область темно-серого цвета в окне Deskbar'а, на которой расположены часы. В этой области размещают свои иконки приложения. Как правило, это системные утилиты, стартующие при запуске системы и выполняющие какие-либо управляющие функции все время работы системы.

Репликант Deskbar'а - собственно то приложение, которое помещает (встраивает) свою иконку на Shelf Deskbar'а. В более общем случае репликант - приложение, встраиваемое в другое приложение. Примерами репликантов Deskbar'а могут служить утилиты Pulse, Switcher.

Создаваемый нами репликант будет выполнять следующие действия. При нажатии левой клавиши мыши на иконке репликанта выдается окно с информацией о программе (окно About). При нажатии на иконке правой клавиши мыши появляется контекстное меню, содержащее пункты About и Quit. Выбор пункта About вызывает окно About, выбор пункта Quit убирает репликант из Shelf'а.

Приступим к разработке программы. Запустим исполняемый файл среды разработки BeIDE (/boot/develop/BeIDE/BeIDE). Выберем в меню File/New Project. В появившемся окне выбираем тип приложения BeApp, и нажимаем кнопку Create. Во вновь появившемся окне указываем желаемое размещение проекта и имя (в нашем случае пишем имя DeskbarReplicantDemo.proj). Мы создали файл проекта для нашего репликанта. В проект уже включены библиотеки libbe.so и libroot.so, необходимые для работы программы.

Выбираем в меню File/New Text. Создается файл, в котором будем записывать непосредственно текст программы. Сохраняем этот файл (меню File/Save As) под именем DeskbarReplicantDemo.cpp в каталоге с файлом проекта. В окне сохранения ставим галочку возле надписи Add to Project - в этом случае файл будет добавлен в окно проекта.


Зададим имя исполняемому файлу. Для этого в окне проекта выбираем меню Edit/Project Settings. В появившемся окне указываем элемент списка x86 ELF Project, а в правой части окна в графе FileName пишем DeskbarReplicantDemo. Нажимаем кнопку Save и даем утвердительный ответ на вопрос о необходимости повторной линковки проекта.

Текст программы начинаем писать с функции main - главной функции любой C/C++-программы:

int main(void) { DRDAppClass DRDApp; return 1; }

DRDAppClass является классом приложения
- наследником класса BApplication:

class DRDAppClass:public BApplication { public: DRDAppClass(); };

Для возможности использования этого класса следует включить в текст программы заголовочный файл

#include < Application.h>

Класс DRDAppClass содержит единственную функцию - конструктор класса, поскольку его задачей является всего лишь инициализация объекта класса-наследника BView, помещаемого на Shelf Deskbar'а. После чего приложение завершает свою работу (функция main не содержит вызова функции Run() объекта класса DRDAppClass).

DRDAppClass::DRDAppClass():BApplication(APP_NAME) { BDeskbar d; if(d.HasItem(VIEW_NAME)) return;

DRDAppViewClass *DRDAppView; DRDAppView=new DRDAppViewClass(); status_t err=d.AddItem(DRDAppView); if(err!=B_OK) { char temp[255]; sprintf(temp, "Error starting: %s", strerror(err)); BAlert *alert = new BAlert("", temp, "OK"); alert->Go(); } }

Сигнатуру приложения APP_NAME и имя VIEW_NAME объекта, помещаемого на Shelf, задаем следующим образом:

#define APP_NAME "application/x-vnd.DeskbarReplicantDemo" #define VIEW_NAME "DRDAppView"

В первых двух строках конструктора класса DRDAppClass выполняется проверка наличия на Shelf'е объекта с именем VIEW_NAME и выход из конструктора, если такой объект уже существует. Таким образом предотвращается помещение на Shelf нескольких экземпляров одного и того же объекта.

Для того, чтобы иметь доступ к классу BDeskbar, включаем заголовочный файл

#include < Deskbar.h>



Далее в конструкторе происходит создание объекта класса DRDAppViewClass, наследованного от класса BView, и попытка помещения его на Shelf. В случае неудачи выводится окно с сообщением об ошибке. Для возможности вывода сообщения и работы с классом BView включаем заголовочные файлы

#include < Alert.h>

#include < String.h>

#include < stdio.h>

#include < View.h>

Класс DRDAppViewClass объявляется следующим образом:

class DRDAppViewClass:public BView { public: DRDAppViewClass(); DRDAppViewClass(BMessage *msg); virtual status_t Archive(BMessage
*data, bool deep=true) const; virtual void AttachedToWindow(); virtual void Draw(BRect p); static DRDAppViewClass *
Instantiate(BMessage *data); virtual void MouseDown(BPoint p); virtual bool QuitRequested(void); private: BPopUpMenu *m; BBitmap *bg; };

Опишем последовательно функции и структуры данных, которые содержатся в классе DRDAppViewClass.

Конструктор класса без параметров создает первоначальный объект - область размером 16x16 пикселов с именем VIEW_NAME, определенным ранее.

DRDAppViewClass::DRDAppViewClass()
:BView(BRect(0,0,15,15), VIEW_NAME, B_FOLLOW_LEFT, B_WILL_DRAW) { return; }

Класс DRDAppViewClass, объект которого помещается на Shelf Deskbar'a, должен быть архивируемым (archivable). Размещение выполняется посредством архивации и последующей разархивации созданного объекта класса. Поэтому в описание класса включены функции Archive, Instantiate и конструктор DRDAppViewClass с параметром BMessage *msg. Функция Archive осуществляет упаковку объекта, созданного конструктором без параметров, в переменную-объект класса BMessage*:

status_t DRDAppViewClass::Archive
(BMessage *data, bool deep=true) const { BView::Archive(data, deep); data->AddString("add_on",APP_NAME); data->AddString("class", VIEW_NAME); return B_OK; }

В архив - объект класса BMessage* - добавляются имя объекта класса DRDAppViewClass для контроля при последующей распаковке и сигнатура приложения.


Параметр deep отвечает за включение в архив всех объектов, принадлежащих архивируемому (true - включать, false - нет). Для нашего случая значение deep не играет роли.

Функция Instantiate распаковывает объект класса BMessage*, восстанавливая ранее созданный объект класса DRDAppViewClass. В случае, если переданный параметр (объект класса BMessage*) не является архивом объекта класса с именем VIEW_NAME, возвращается NULL.

DRDAppViewClass *DRDAppViewClass::
Instantiate(BMessage *data) { if(!validate_instantiation
(data, VIEW_NAME)) return NULL; return new DRDAppViewClass(data); };

Функции Archive и Instantiate явно в программе не вызываются. По-видимому, их вызов происходит в функции AddItem класса BDeskbar.

Вызов конструктора класса DRDAppViewClass(BMessage* msg) в функции Instantiate создает непосредственно тот объект, который будет помещен на Shelf Deskbar'а. Именно в этом конструкторе мы создадим и инициализируем все необходимые для работы объекты и переменные:

DRDAppViewClass::DRDAppViewClass
(BMessage *msg):BView(msg) { m=new BPopUpMenu("PopUpMenu",false,false); m->AddItem(new BMenuItem("About",
new BMessage(B_ABOUT_REQUESTED))); m->AddSeparatorItem(); m->AddItem(new BMenuItem("Quit",
new BMessage(B_QUIT_REQUESTED))); m->SetTargetForItems(this); bg=new BBitmap(BRect(0,0,15,15),B_CMAP8); bg->SetBits(bmpdata,256,0,B_CMAP8); return; };

Необходимыми объектами являются выпадающее меню и иконка, отображаемая на Shelf'е. Меню создается конструктором BPopUpMenu и содержит два пункта. Выбор пункта About приводит к появлению информации о программе, выбор пункта Quit приводит к удалению репликанта из Shelf'а. Для обеспечения возможности работы с меню включаем в текст программы соответствующие заголовочные файлы:

#include < MenuItem.h>

#include < PopUpMenu.h>

Иконка, отображаемая на Shelf'е, занимает квадрат размером 16x16 пикселов и представляет собой объект класса BBitmap. Рисунок иконки является 256-цветным.


Данные для его инициализации берутся из массива bmpdata размером 256 байт:

unsigned char bmpdata[256]={......};

// в фигурных скобках находятся 256 чисел, каждое в интервале от 0 до 255.

Установить соответствия между цветами и их числовыми значениями для режима B_CMAP8 можно с помощью программы 256. Также можно преобразовать уже готовый рисунок в заголовочный файл с помощью программы ImageToHeader.

Вывод рисунка иконки осуществляется функцией Draw(), которая устанавливает иконку в качестве фона для объекта класса DRDAppViewClass:

void DRDAppViewClass::Draw(BRect p) { SetViewBitmap(bg); Invalidate(BRect(0,0,15,15)); }

Функция Draw() вызывается системой каждый раз при необходимости перерисовать изображение, а программой - при присоединении объекта класса DRDAppViewClass к Shelf'у в функции AttachedToWindow:

void DRDAppViewClass::AttachedToWindow() { Draw(BRect(0,0,15,15)); }

Осталось рассмотреть две функции класса DRDAppViewClass. Функция MouseDown() вызывается системой при нажатии на иконке клавиши мыши. В ней производится обработка нажатий:

void DRDAppViewClass::MouseDown(BPoint p) { uint32 b; BPoint p1; GetMouse(&p1, &b); if(b==B_SECONDARY_MOUSE_BUTTON) { p1.Set(0,0); ConvertToScreen(&p1); BRect r=BRect(p1.x,p1.y,p1.x+15,p1.y+15); ConvertToScreen(&p); BMenuItem *mi=m->Go(p, false, true, r); if(mi) switch (mi->Message()->what) { case B_ABOUT_REQUESTED: (new BAlert("","Deskbar Replicant Demo
\nby Al.V. Sarikov.\nKherson, Ukraine, 2004. \nE-mail: avix@ukrpost.net.\nHome page:
http://avix.pp.ru.","OK"))->Go(); break; case B_QUIT_REQUESTED: QuitRequested(); break; } } else if(b==B_PRIMARY_MOUSE_BUTTON) (new BAlert("","Deskbar Replicant Demo
\nby Al.V. Sarikov.\nKherson, Ukraine, 2004. \nE-mail: avix@ukrpost.net.\nHome page:
http://avix.pp.ru.","OK"))->Go(); }

При нажатии левой клавиши мыши (Primary Mouse Button) выводится информация о программе и авторе. При нажатии правой клавиши мыши (Secondary Mouse Button) вызывается выпадающее меню функцией Go().


Параметры функции задают вызов меню в точке, в которой находится курсор мыши (первый параметр). Меню остается на экране после отпускания клавиши мыши (третий и четвертый параметры) и при выборе пункта меню не передает сообщения (второй параметр). Координаты прямоугольника, в который заключена иконка репликанта, и координаты курсора мыши пересчитываются относительно экрана функцией ConvertToScreen().

Функция Go() возвращает выбранный пункт меню. В данной программе пункты меню различаются по назначенным им сообщениям. Если выбран пункт About (сообщение B_ABOUT_REQUESTED), то выводится информация о программе. Если выбран пункт Quit (сообщение B_QUIT_REQUESTED), то вызывается функция QuitRequested(), которая удаляет выпадающее меню и репликант из Shelf'а. При невозможности удалить репликант выводится сообщение об ошибке:

bool DRDAppViewClass::QuitRequested(void) { BDeskbar d; status_t err=d.RemoveItem(VIEW_NAME); if (err!=B_OK) { char temp[255]; sprintf(temp, "Error removing:
%s", strerror(err)); BAlert *alert=new BAlert("", temp, "OK"); alert->Go(); } delete m; return true; }

Замечание: такой способ выхода из программы-репликанта Deskbar'а не приводит к полной потере Deskbar'ом информации о репликанте. Это можно проверить следующим образом: поместим репликант на Shelf и выгрузим его. Затем изменим что-либо в тексте программы, перекомпилируем и поместим на Shelf опять. Мы увидим, что на Shelf был помещен старый вариант репликанта, несмотря на то, что исполняемый файл, запущенный нами, уже изменен. Для того, чтобы на Shelf поместить измененный репликант, нужно перегрузить Deskbar (нажать Ctrl-Alt-Del, удалить Deskbar посредством Kill, затем опять нажать Ctrl-Alt-Del, а затем - появившуюся кнопку Restart the Desktop и Cancel для выхода из окна со списком задач).

Теперь программа полностью написана. Но, откомпилировав и запустив ее, мы увидим сообщение об ошибке: "Error starting: application could not be found". Дело в том, что mime-тип приложения APP_NAME не зарегистрирован в системе.


Наиболее простой способ зарегистрировать mime-тип в любой системе, где запускается программа - включить его описание в виде ресурса в саму программу. Для этого откомпилированный файл DeskbarReplicantDemo открываем с помощью приложения FileTypes. В появившемся окне в графе Signature пишем: application/x-vnd.DeskbarReplicantDemo (т.е. аналогично APP_NAME). В меню выбираем File/Save. Теперь при запуске mime-тип будет зарегистрирован и приложение запустится нормально.

Но еще лучше сохранить описание mime-типа в файле ресурсов и подключить этот файл в проект, чтобы описание mime-типа автоматически добавлялось в исполняемый файл при перекомпиляции проекта. Для этого сделаем все, как описано в предыдущем абзаце, но вместо File/Save выберем File/Save into Resource File. Введем имя файла DeskbarReplicantDemo.rsrc и сохраним его в каталог с проектом. Чтобы подключить файл ресурсов к проекту, просто перетащим его на окно проекта. Далее следует пересобрать (Link) проект.

Теперь, имея файл ресурсов, можно, например, создать для приложения свою иконку. Как это сделать - описано в .

Файлы проекта, описанного в статье, можно загрузить (вместе с текстом этой статьи).


О BeOS


BeOS - сравнительно новая операционная система, появившаяся в 1995 году. Это удобная, надежная, быстрая и красивая система для домашнего и офисного использования.

BeOS была создана корпорацией Be Incorporated. В начале 2000 года Be Inc. "изменила приоритеты" и перестала заниматься развитием этой "настольной" мультимедийной ОС. До этого "изменения приоритетов" BeOS была коммерческой ОС. После него она была выложена (и остается доступной) для свободного скачивания под названием "BeOS R5 personal edition."

В конце 2001 года Be Inc. закрылась и продала свою интеллектуальную собственность Palm. Сразу же были предприняты попытки избежать исчезновения этой ОС и выпустить совместимые версии с открытым исходным кодом (см., например, http://www.openbeos.org/).



Основные особенности BeOS и ее последователей:


Объектно-ориентированный дизайн

Интерфейс программирования приложений (API) в BeOS объектно-ориентирован в большей степени, чем в других распространенных операционных системах. Это значительно облегчает создание новых приложений и улучшение существующих.

Оптимизация работы с мультимедийными данными

Традиционные операционные системы способны обрабатывать цифровую информацию, но это не является их основной задачей. Однако сегодня это направление является приоритетным независимо от области применения, будь то экономика или физика, творчество или развлечения. Архитектура BeOS специально оптимизирована для эффективной обработки видео- и аудиоинформации и выполнения широкого круга задач, связанных с коммуникационными возможностями.

Простота

При создании BeOS особое внимание обращалось на то, чтобы решение задач, возлагаемых на операционную систему и ее приложения, было как можно более простым и элегантным.

Поддержка существующих стандартов

В BeOS поддерживаются многие средства разработки, протоколы, сетевые службы и утилиты ОС семейства UNIX

Узнать, где скачать BeOS, можно здесь.