«

»

Июн 20 2014

В SkyLA добавлена поддержка Linux

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

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

  • Создание окна и его перемещение, сворачивание на панель задач
  • Вывод в окно содержимого RGBX8 фреймбуфера (как в масштабе 1:1, так и в масштабе 2:1 для режима совместимости с мониторами высокой чёткости)
  • Получение событий ввода от мыши и клавиатуры

Первой трудностью в реализации работы под Linuxстало то, что X11 упорно не хотел принимать изображение в формате RGBX8. Максимум на что он был согласен это BGRX8. Пришлось добавлять перестановку цветовых каналов после завершения отрисовки. Возможность такой проблемы я предполагал изначально. А вот то, что в X11 нет встроенного масштабирования изображения при выводе (пусть и простейшим методом) я не ожидал – пришлось сделать масштабирование своим кодом через дополнительный буфер кадра.

А вот уж чего-чего, но того, что система ресурсов в исполнимом файле это сугубо Windows-фитча я совсем не ожидал. Пришлось отказаться от использования механизма ресурсов и включать все необходимые ресурсы в исполнимый файл с констант (ресурс хранится как отдельный включаемый файл, содержащий константу-массив с данными). Мало того, пришлось сделать дополнительную утилиту для преобразования бинарного файла данных в константу. Но у отсутствия поддержки ресурсов было и другое, куда более неприятное, последствие. Во-первых, иконку для отображения на панели задач пришлось делать тоже через константу (ещё одна лишняя утилита), да к тому же она устанавливается совершенно нетривиальным способом. Во-вторых, у исполняемого файла в Linuxнет иконки. Всякие ярлыки в меню пуск или на панели задач требуют задавать иконку из отдельного png-файла. И это реально была проблема. Идея запускающего приложения предусматривала, что оно само является строго одним файлом. На эту проблему мне пока пришлось закрыть глаза.

Реализация цикла обработки событий оказалась на удивление беспроблемной. Хотя именно тут я ожидал наибольшей подставы, т.к. в Windowsв цикле обработки сообщений одновременно находятся сообщения окна, сети, да ещё и асинхронный файловый ввод-вывод через MsgWaitForMultipleObjectsEx.

Следующей трудность, которая также не была предсказана заранее, стало то, что в Linuxкоды клавиш не только отличаются от Windows, но ещё и могу разниться в зависимости от драйвера ввода. Windowsпри нажатии таких клавиш как Shift, Ctrl и Alt передаёт с WM_KEYDOWN просто код Shift, Ctrl или Alt, но без указания нажата ли правая кнопка или левая, Linuxже чётко их различает. Кроме того Windows умудряется ещё и для кнопок цифровой клавиатуры передавать разные значения в зависимости от состояния NumLock, хотя Linuxопять же, видит их нормально. А ещё в Linuxаналог события WM_KEYUP приходит после каждого нажатия клавиши.

Ну и на десерт особенности ввода текста. Проблемы в них ожидались изначально и они мало того что были, они даже не решены до конца. В Windowsещё удалось добиться более-менее нормального варианта принудительно загружая необходимые раскладки и не допуская переключения ни на что другое. А вот в Linuxдело вообще тёмное. Хотя у меня вроде всё работает, но сказать уверенно, что будет работать везде, я не могу.

Как итог скажу лишь, что не зря я так плохо отношусь к кроссплатформенной разработке как к таковой. Заставить приложение работать одинаково на даже на 2-х ОС попросту нельзя, всегда будут нюансы.

Добавить комментарий