Как создать свою графическую оболочку для linux

Создание графических приложений

Цилюрик О.И.

Настоящая статья является дополнением к книге «Инструменты Linux для Windows-программистов». Это не описание как делать GUI приложения в Linux, это описание того, как ПРИСТУПИТЬ к созданию графических приложений в Linux, и, хотелось бы надеяться что это прозвучит — чем принципиально программирование графики в Linux отличается от того же занятия в Windows. Главным требованием здесь была простота. Сделав простейший шаблон GUI прложения, дальше двигаться уже гораздо проще. Кроме того, все эти простейшие приёмы программирования показаны сравнительно: на основе основных графических технологий (библиотек), используемых в UNIX.

Все примеры к тексту вы можете скачать в виде общего архива.

Создание приложений, взаимодействующих с пользователем посредством графического интерфейса (GUI приложений), является частным классом задач, отдельной областью программирования. Из числа других подобных областей приложения можно было бы привести, как примеры:

  • реализация алгоритмов цифровой обработки сигналов (DSP): быстрые спектральные преобразования (FFT и другие), вэйвлеты, авторегрессионные разложения. ;
  • обработка аудио-потоков (пакеты: sox, ogg, speex и другие);
  • задачи IP-телефонии, SIP протокола, реализация разнообразных программных SoftSwitch;

Это сравнительный ряд автономных областей развития приведен как пример таких частных классов, одним из которых является и разработка GUI приложений. И как частный класс, со своей спецификой инструментов и средств, он не заслуживал бы отдельного упоминания, если бы не одно обстоятельство — принципиально отличающееся, диаметрально противоположное отношение к GUI в операционных системах семейства Windows и в UNIX (и в Linux, как его частный вид):

  • В Windows каждое приложение является принципиально GUI, неотъемлемым атрибутом любого приложения в Win32 API (низкого уровня) является главное окно приложения, уже само приложение «вяжется» вокруг его главного окна. Операционная система регистрирует классы окон и уже далее к ним соотносит конкретные приложения. Не может существовать приложения (взаимодействующего с пользователем, не системные службы) без окна, с этим были связаны и первоначальные сложности Windows в реализации консольных (терминальных) приложений.
  • в UNIX картина принципиально обратная: первичным является приложение, которое, по умолчанию, является консольным, текстовым, вся графическая система не является составной частью операционной системы, а является надстройкой пользовательского уровня. Чаще всего такой графической надстройкой является X11 (в реализации Xorg или X11R5), но и это не обязательно: практиковались и другие графические системы, хороший пример тому графические системы Qwindow, а затем Photon в операционной системе QNX, сосуществующие там одновременно с X11.
  • Показательно в этом смысле то, что вся оригинальная часть реализации X11 работает в пространстве пользователя, не в привилегированном режиме ядра (супервизора): работа с аппаратурой видеоадаптеров, устройствами ввода и другое. Отдельные реализации (видеосистемы NVIDIA или ATI Radeon) могут быть реализованы в режиме ядра (модули), но это а) сторонние относительно X11 разработки, и б) решение вопросов только производительности.

Из-за обозначенной специфики, разработка GUI приложений в UNIX (Linux) принципиально отличается:

  • вся работа GUI приложений ведётся через промежуточные слои (библиотеки) пользовательского уровня;
  • из-за того, что это ординарный пользовательский уровень, для разработчика предлагается широкий спектр альтернативных инструментов (библиотек), практически равнозначных, и конкурирующих друг с другом: Xlib, GTK+, Qt, wxWorks и многие другие.
  • базовый API работы с X11 предоставляет Xlib, все другие используют уже её функционал, как это показано на рисунке.

  • разработчик имеет возможность широкого выбора тех уровня и инструментов, которые он предполагает использовать, начиная от Xlib и выше (хотя уровень Xlib и слишком низок и работа с ним громоздкая).

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

Читайте также:  Windows 10 нет пункта удаленный рабочий стол

Средства Xlib (архив Xlib.tgz ):

Средства GTK+ (архив GTK+.tgz ):

$ gcc gtk.c -o gtk `pkg-config —cflags —libs gtk+-2.0`

Средства Qt (архив Qt.tgz ):

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

Теперь проделываем последовательно:

Исходя из «подручных» файлов исходных кодов, у нас сгенерировался файл проекта и, далее, сценарий сборки ( Makefile ). Далее проделываем традиционную сборку, а заодно и посмотрим опции компиляции и сборки, которые нам сгенерировал проект:

g++ -c -pipe -Wall -W -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector —param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables

g++ -o Qt index.o -L/usr/lib/qt-3.3/lib -lqt-mt -lXext -lX11 -lm

index.cc index.o Makefile Qt Qt.pro

Средства wxWidgets (архив wxWidgets.tgz):

$ g++ simple.cc `wx-config —cxxflags` `wx-config —libs` -o simple

Средства GLUT (архив glut.tgz):

OpenGL Utility Toolkit, как и следует из названия, это средства использования технологии OpenGL в приложениях, которая требует определённой поддержки со стороны видео оборудования.

$ gcc glut.c -o glut -lX11 -lglut

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

В данной статье были показаны образцы кода GUI приложений. Естественно, визуальные образы таких приложений строятся не путём непосредственного кодирования, а при использовании некоторых визуальных построителей, в составе тех или иных интегрированных средств разработки (IDE).

Источник

Графическая среда, как сделать?

Доброго времени! Интересует вопрос создания графической среды для linux. Интересно есть ли какие-нибудь мануалы или книги? Не спрашивайте зачем. Это просто для себя. Я бы хотел, чтобы те кто знает отписались по теме. Заранее спасибо!

Что есть графическая среда? Ты имеешь ввиду ДЕ? Или ВМ? Или ты вообще собрался новые иксы писать?

убиват. одних(не считая недо-поделок) достаточно

Книг нет. Начните с изучения lxde и razor-qt.

1. Учимся выводить точки на фреймбуфер.
2. Учимся выводить текст на фреймбуфер.
3. Пишем абстракцию системы рисования от фреймбуфера.
4. Учимся обрабатывать мышку.
5. Пишем вывод курсора с обработкой мышки.
6. Пишем простые классы для окон.
7. Пишем перетаскивание окон мышкой.
8. Пишем простой графический интерфейс.
9. Выкидываем все и переписываем заново, но лучше и более гибко.

вопрос создания графической среды для linux.

Я слышал, что они уже есть.

Мне почему-то кажется, что он имел в виду IDE.

Если под «графической средой» подразумевается создание иксовых программулин, то на выбор есть всякие GTK, Tk, Qt, motif и т.п. Все мануалы есть в интернете. Книг почти нет, да и не нужны они по большому счету, т.к. устаревают еще во время печати.

«Каникулы?» Ну конечно) Я просто не мог не задать вопрос. На каникулах все школьники на ЛОР заглядывают, не так ли?)) Правда почему-то мой друг Денис не заходит(((

Имеется ввиду не ИДЕ, а что-то типа Кеда или Гнома. note173, спасибо,єто и вправду ценная информация. Можно будет нагуглить по ‘этому поводу. AITap, и вам спасибо огромное, тоже буду гуглить.

«Я слышал, что они уже есть.» Да ну? Правда что-ли? А вообще просто хочу чего-то очень нестандартного для себя. Я в основном программирую в вебе, делфях, бейсик, учу с++ и джаву. Поэтому и спрашиваю в каком направлении двигаться.

Всем спасибо за ответы!

Я в основном программирую в вебе

Тогда есть смысл сконцентрироваться на веб-приложениях.

dwm у него вообще только 1 файл, и он не превышает 2000 строк.

Если нужны кресты, то смотри на fluxbox.

В dwm хоть строк мало, но для изучения он не очень хорош. Там не очень мнемонический код, хотя если есть желание
PS: Запилите мне в dwm titlebar в плавающем режиме

Читайте также:  Exiting pxe rom как исправить windows 10

Интересует вопрос создания графической среды для linux.

вместе с иксами идут Over9000 мелких, и никому ненужных приложений (типа xclock), уверен, их сделали специально для вас.

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

Предлагаю другое: есть бэкэнд broadway для gtk3, который отправляет картинку окна в клиент на html5(canvas) по протоколу VNC. Ничего серьезного пока с этим не сделали, хотя уже работает. Можно попробовать реализовать веб-менеджер с возможностью запуска программы на удаленной машине и удаленного управления приложениями. Получится что-то вроде jolicloud, только с полноценным настольным софтом.

мой тебе совет — http://razor-qt.org — скачай исходники этой среды и развивай ее, она написана на Qt, если ты хочешь нестандартную DE и накрутить что-то свое, то razor-qt подходит больше всех ИМХО

1. Учимся выводить точки на фреймбуфер.
2. Учимся выводить текст на фреймбуфер.
3. Пишем абстракцию системы рисования от фреймбуфера.
4. Учимся обрабатывать мышку.
5. Пишем вывод курсора с обработкой мышки.
6. Пишем простые классы для окон.
7. Пишем перетаскивание окон мышкой.
8. Пишем простой графический интерфейс.
9. Выкидываем все и переписываем заново, но лучше и более гибко.

9. Выкидываем все и пользуемся уже написаным готовым ДЕ, ибо оно «лучше и более гибко.»
//починено во имя справедливости.

По сабжу: рекомендуют читать исходники ЛХДЕ и xfce4.

Источник

Давайте напишем командную оболочку Linux

Приветствие

Всем привет! Хочу поделиться своим опытом написания собственной командной оболочки Linux используя Posix API, усаживайтесь поудобнее.

Итоговый результат

Что должна уметь наша командная оболочка

Запуск процессов в foreground и background режиме

Завершение background процессов

Поддержка перемещения по директориям

Как устроена работа командной оболочки

Считывание строки из стандартного потока ввода

Разбиение строки на токены

Создание дочернего процесса с помощью системного вызова fork

Замена дочернего процесса на необходимый с помощью системного вызова exec

Ожидание завершения дочернего процесса (в случае foreground процесса)

Немного про системный вызов fork()

Простыми словами системный вызов fork создает полный клон текущего процесса, отличаются они лишь своим идентификатором, т. е. pid .

Что выведет данная программа:

I’m parent process!
I’m child process!

Что же произошло? Системный вызов fork создал клон процесса, т. е. теперь мы имеем родительский и дочерний процесс.

Чтобы отличить дочерний процесс от родительского в коде достаточно сделать проверку. Если результат функции fork равен 0 — мы имеем дело с дочерним процессом, если нет — с родительским. Это не означает, что в операционной системе id дочернего процесса равен 0 .

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

Подробнее про exec()

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

Системный вызов exec заменяет текущий процесс сторонним. Естественно, сторонний процесс задается через параметры функции.

Что выведет данная программа

total 16
-rwxr-xr-x 1 runner runner 8456 Jan 13 07:33 main
-rw-r—r— 1 runner runner 267 Jan 13 07:33 main.c

Родительский процесс как обычно ожидает завершения дочернего процесса. В это время после системного вызова exec происходит замена дочернего процесса на консольную утилиту ls , она была взята для примера.

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

Перейдем к полноценной реализации

Часть 1. Чтение строки с консоли

Изначально нам надо уметь считывать строку из командной строки. Думаю, с этим не возникнет сложностей.

В данной функции происходит чтение строки с применением функции getline . После чего, если в конце строки имеется символ переноса строки, удаляем его.

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

Часть 2. Разбиение строки на токены

В данной части будет представлена реализация разбиения строки на массив токенов.

Читайте также:  Linux from usb pendrive

Определения начальной длины массива и разделителей строки.

Код выглядит довольно громоздким, однако в нем нет ничего сложного.

Очередной токен получается с использованием функции strtok . После чего данный токен копируется в массив токенов. Если в массиве токенов не достаточно места, массив увеличивается в 2 раза.

Завершается всё добавлением завершающего токена равного NULL , т. к. функция exec() ожидает наличие данного завершающего токена.

Часть 3. Выполнение процессов

Структура хранения списка запущенных процессов

Напишем определения структур для foreground и background процессов, fg_task и bg_task . А также определение структуры для хранения всех процессов tasks .

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

Вспомогательные функции добавления процессов

Установка foreground процесса выглядит банально и не нуждается в комментировании.

Добавление background процесса выглядит посложнее.

На деле же все проще. Смотрим есть ли место в массиве для хранения информации о процессе. Если его недостаточно — увеличиваем длину массива в 2 раза. После чего происходит добавление структуры bg_task в массив и последующее заполнение полей структуры информацией о процессе.

Данная функция возвращает -1 в случае неудачи.

Вспомогательные функции для завершения процессов

Добавим функцию экстренного завершения foreground процесса. Данная функция с помощью системного вызова kill с параметром SIGTERM завершает процесс по id процесса.

Также добавим функцию для завершения background процесса.

Данная функция принимает в себя массив токенов вида <"term", " ", NULL>. После чего преобразует токен индекса background задачи в число. Убивает background задачу посредством системного вызова kill .

Непосредственно запуск процессов

Для удобства введем функцию is_background , определяющую является ли задача фоновым процессом. Данная функция просто проверяет наличие & в конце.

Введем функцию launch которая будет запускать background процесс если в конце присутствует токен & , иначе будет запускаться foreground процесс.

То, что происходит в этой функции уже должно быть все понятно.

Создается дубликат процесса с помощью системного вызова fork

Заменяем дочерний процесс на требуемый с помощью системного вызова exec

Определяем является ли процесс фоновым

Если процесс фоновый — просто добавляем его в список bacground задач

Если процесс не фоновый — дожидаемся окончания выполнения процесса

В функции присутствует неизвестная функция quit . Ее мы разберем в следующем блоке.

Вспомогательные функции для командной оболочки.

Введем функцию execute , которая в зависимости от первого токена выбирает нужное действие.

Данная функция пропускает действие, если первый токен NULL . Смена директории, если первый токен cd . Вывод справки об использовании, если первый токен help . Завершение работы командной оболочки, если первый токен quit . Вывод списка background задач, если первый токен bg . Завершение процесса по индексу, если первый токен term .

Во всех других случаях запускается процесс.

Реализация вспомогательных функций

Значение CONTINUE означает дальнейшее исполнение главного цикла командной оболочки. Значение EXIT прерывает выполнение главного цикла программы.

Функция quit отключает все callback функции по событию SIGCHLD — т. е. функции, выполняющиеся когда дочерний элемент был завершен. После этого завершает все активные процессы.

Основные цвета командной оболочки.

Часть 4. Главный цикл командной оболочки

Здесь и происходит вся магия. Взгляните на следующие строки. С помощью функции signal задаются callback функции на заданные события.

Событие SIGINT — срабатывает при нажатии комбинации ctrl-C , которое в дефолтном поведении завершает работу программы. В нашем же случае мы переназначаем его на завершение foreground процесса.

Событие SIGCHLD — срабатывает при завершении дочернего процесса созданyого с помощью системного вызова fork . В нашем случае мы переопределяем его на пометку фоновой задачи как выполненной с помощью функции mark_ended_task .

Все что описано в главном цикле командной оболочки можно описать словами:

Вывод информации о пользователе и текущей директории с помощью функции display

Чтение строки из стандартного потока ввода

Разбиение строки на токены

Выполнение ранее описанной функции execute , которая в зависимости от массива токенов выполняет нужное нам действие.

Нам осталось реализовать одну оставшуюся функцию display . Которая получает информацию о текущей директории с помощью функции getcwd и имя пользователя с помощью функции getpwuid .

Часть 5. Итоговый результат

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

С исходным кодом проекта вы можете ознакомиться по данной ссылке.

Источник

Оцените статью