Skip to content
Ivan Denisov edited this page Apr 4, 2019 · 4 revisions

BlackBox для GNU/Linux, OpenBSD, FreeBSD и Windows

Составители: А.В. Ширяев, И.А. Денисов

Аннотация

В документе представлено описание текущего состояния портирования BlackBox на на UNIX-подобные операционные системы, а именно GNU/Linux и BSD. Графический интерфейс основан на ОС-независимой библиотеке Gtk2. Портирование не завершено окончательно, однако большая часть работает на современных версиях Ubuntu, Fedora Core и OpenBSD. Корректно функционируют все инструменты разработки и примеры (кроме ObxTabView). Детали каркаса, требующие доработки, обозначены в перечне нерешенных проблем ниже.

Все ОС-независимые модули Блэкбокса взяты от версии 1.7.1. ОС-зависимая подсистема Host, а также модули Kernel, Init, Config, которые подлежали изменению, также были синхронизированы с этой версией.

Используемые библиотеки

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

  • Библиотеки, не зависящие от графического пользовательского интерфейса:
    • GNU/Linux: libc (LinLibc, LinIconv, LinIoctl, LinTermios, LinNet), libdl (LinDl), librt (LinRt);
    • OpenBSD: libc (LinLibc, LinIoctl, LinTermios, LinNet), libiconv (LinIconv), ld.so (LinDl);
    • FreeBSD: libc (LinLibc, LinDl, LinIoctl, LinTermios, LinNet), libiconv (LinIconv).
  • Библиотеки для графического пользовательского интерфейса на основе Gtk2:
    • GLib, GObject, Pango, Gdk, Gtk.

Модуль LinDl предназначен для динамической загрузки библиотек (используется в Kernel). Модуль LinRt предназначен для вызова функции clock_gettime (в Linux). Модуль LinIconv предназначен для преобразования кодировок. Модули LinIoctl, LinTermios и LinNet нужны для подсистемы Comm. Преобразование кодировок можно реализовать на компонентном паскале, но такую реализацию затруднительно использовать в HostFiles. Поэтому принято решение для преобразования кодировок использовать iconv (LinIconv). Исключение — кодировка UTF-8, функции для которой реализованы в модуле Kernel.

Кодировки строк

Внутренняя кодировка BlackBox — UCS-2.

Кодировка имен файлов, консоли, переменных окружения задаются переменной окружения LANG (системная кодировка) вида "язык_СТРАНА.КОДИРОВКА" (язык — по ISO 639). Если эта переменная не определена, то считается, что кодировка ASCII. Работа с этой переменной, а также для реализация Dialog.LanguageHook, находится в модуле HostLang. Имя кодировки хранится в переменной HostLang.enc

Внутренняя кодировка Gtk2 — UTF-8. Исключение — кодировка для имен файлов.

В документации Gtk2 написано, что кодировка имен файлов задается переменной окружения G_FILENAME_ENCODING, а если эта переменная не определена, то считается, что UTF-8. Смысл G_FILENAME_ENCODING не понятен, т.к. кодировка имен файлов уже задается в переменной окружения LANG (см. выше), и при правильной настройке переменная G_FILENAME_ENCODING должна совпадать с кодировкой, указанной в LANG. Поэтому G_FILENAME_ENCODING не пользуемся, и считаем, что кодировка имен файлов задается переменной окружения LANG. Кодировка имен файлов для Gtk2 нужна, например, для диалоговых окон (см. модуль HostDialog).

Для работы с кодировкой UTF-8 предназначены процедуры Kernel.StringToUtf8 и Kernel.Utf8ToString. Для преобразования строк с другими кодировками используется модуль LinIconv, представляющий собой интерфейс к iconv. Имя системной кодировки (определяемой из переменной LANG) хранится в Hostlang.enc.

Командная строка и переменные окружения

Т.к. в UNIX-подобных операционных системах нет функции, позволяющей получить командную строку (т. е. нет аналога WinAPI GetCommandLine), одно из решений — отказаться от командной строки и использовать переменные окружения вместо неё.

Но для работы со сторонними библиотеками параметры командрой строки без обработки кодировки размещаются в переменные Kernel.argc и Kernel.argv.

BlackBox для Windows использует параметры командной строки в HostFiles (/USE), в HostMenus (/NOAPPWIN и т. д.). Ниже перечислен полный список соответствия параметров командной строки, используемых в BlackBox для Windows, и переменных окружения этой реализации:

windows unix-like Комментарий
нет BB_PRIMARY_DIR первичный каталог BlackBox
/USE BB_SECONDARY_DIR вторичный каталог BlackBox
нет BB_PACKED_NAME имя файла, в котором хранятся запакованные файлы, для HostPackedFiles
нет LANG язык и системная кодировка
/LOAD не реализовано загрузка модуля (Kernel.LoadMod)
/P не реализовано печать
/PT не реализовано печать
/EMBEDDING не реализовано
/NOAPPWIN не реализовано
/NOSCROLL не реализовано
/FULLSIZE не реализовано
/LTRB не реализовано
/LANG не требуется см. LANG язык
/O не реализовано открыть файл
/PAR не требуется ?

Перечень нерешенных проблем

  • Недоработки в HostCFrames (убрать все зависимости от Gtk2)
    • поля ввода с правым выравниванием, многострочные поля ввода
    • списки (ComboBox, ListBox, SelectionBox)
    • TreeFrame, UpDownField
  • HostTabFrames: ObxTabView зависает
  • HostMenus.ReadCommandLine
  • HostPrinters, диалог настройки печати в HostDialog
  • HostBitmaps, HostPictures? (сделать поддержку PNG, SVG? )
  • DevProfiler
  • обработка трапов не всегда корректна
  • Kernel: обработка stack overflow
    • OpenBSD: ждать, пока заработает /usr/src/regress/sys/kern/stackjmp
    • Linux: как защитить нижнюю границу стека от перезаписи при переполнении?
  • StdTables <- HostPorts: интерфейс HostPorts должен совпадать c Windows версией
  • StdTabViews <-
  • StdMenuTool <- HostMenus
  • нужно доработать линкер Dev2, чтобы он собирал PE-приложения не хуже DevLinker и с таким же интерфейсом для Windows, что позволит заменить DevLinker на новую кросс-платформенную версию.
  • компилятор для платформы x64
  • окно Gtk2 изменяет размер не сразу, а только после второго щелчка
  • меню на некоторых темах полностью всё в квадратиках для галочек, было бы хорошо что-то придумать, чтобы этого не было
  • прокрутку в окнах надо отвязать от Gtk2, рисовать средствами Ports