Выкладываю обещанные подробности
В архиве содержится собранная копия ББ, в которой при запуске выполняется код, приводящий к появлению GTK+ окна с одной кнопкой, на которой написано "Hello world"
В составе комплекта идет подсистема Gnome, представляющая собой сгенерированные файлы для библиотек GTK, GDK, Pango, Atk, GdkPixbuf.
В автоматически сгенерированном коде содержатся определения для процедур (методов), которые принадлежат каким-то объектам. Определения процедур не-методов опущены, поскольку предполагается, что в этом нет необходимости (это рассуждение для проекта Gtk#, где есть возможность использовать C код напрямую).
Поэтому для успешного запуска программы потребовалась ручная доводка.
В модуль GTK добавлены определения процедур gtk_main, gtk_main_quit. Кроме того, в код модуля GObject добавлены определения процедур g_signal_connect_data. Добавлен модуль GObjectStuff, в котором записаны процедуры g_signal_connect, g_signal_connect_swapped. Эти процедуры в коде
оригинальной системы GLib представляют собой #define определения. В ББ пришлось сделать для них отдельный модуль, поскольку у меня не получилось соединить определения библиотечных процедур (без реализации) и процедур модуля (с реализацией). Если знаете как это сделать - подскажите.
В итоге имеем приложение, запускаемое при старте ББ. Оно вызывает окно, которое правильно ведет себя в GTK-системе и реагирует на команды пользователя.
Уже немало.
Основные проблемы, с которыми пришлось столкнуться.
1) Не производится инициализация структуры Kernel.bootInfo или я неправильно понимаю, откуда брать argc и argv. Обращение к Kernel.bootInfo.arg(c|v) гарантированно ведет к трапу.
Поэтому вызов gtk_init производится в виде gtk_init(0, 0);
Что не есть правильно.
Поделитесь, кто может, информацией о старте приложения в Linux, откуда берется командная строка? Что-то про регистр BX в исходниках ББ сказано, но, это все вилами по воде писано.
2) Я не придумал как избежать обращения к SYSTEM при присваивании процедур.
В процедуру g_signal_connect одним из параметров передается указатель на процедуру. Причем сигнатура процедуры на момент вызова g_signal_connect значения не имеет, объект разбирается с сигнатурой самостоятельно в процессе работы.
Как передать в процедуру указатель на процедуру для процедур разной сигнатуры? Я не придумал.
Есть решение сделать объект с одним полем, представляющим собой указатель на процедуру и делать расширение некоего общего предка:
Код:
GCallback = EXTENSIBLE RECORD
END;
...
GMyCallback = RECORD(GCallback)
callback: PROCEDURE ...
END;
Но тогда появляются проблемы другого рода - где-то нужна сама процедура, а где-то указател на нее. Кроме того, при работе с модулем появляется дополнительная (промежуточная) сущность. В общем это у меня не получилось, использую SYSTEM.ADR. Можно было бы спрятать использование SYSTEM в отдельный модуль, но это не решает проблему процедур разной сигнатуры. Их же как-то надо подать на вход оберточной процедуры...
3) Явно не хватает автогенерации модулей GLib и GObject.
Для того, чтобы получить перевод этих модулей с C на КП, можно использовать утилиту gapi_pp.pl (из Gtk#), которая вытаскивает из C-шных исходников определения процедур, структур, перечислений и прочего.
Затем необходимо произвести перевод из этого экстракта в удобоваримую форму или сразу на КП.
У меня руки не скоро дойдут до этого.
Впрочем, мне пока хватает того, что у меня есть (из ручной сборки). Более того, что это работает :Р
Продублировано в
блоге.
Вложение:
BB-GTK-hello.tar.gz [2.79 МБ]
Скачиваний: 653