Ключевые слова:example, gcc, x, window, (найти похожие документы)
Date: Tue, 7 May 2002 08:19:11 +0000 (UTC)
From: alexey.vyskubov@nokia.com
Newsgroups: fido7.ru.linux
Subject: Пример программы на Си, которая выводит окошко и рисует в нем линию
> Если не трудно, киньте в нетмэйл текст простейшей проги на C, создающей
> окошко.
Я подумал, что это может быть интересно и в конференции. В принципе,
ничего Linux-специфичного тут нет, но спрашивают уже не первый раз.
Далее следует пример простейшей программы, которая выводит окошко и
рисует в нем линию. Программа максимально низкоуровневая, то есть даже
Xt не использует -- только Xlib. Пример с ошибками, которые дальше
разбираются. Если я чего забыл -- поправляйте.
#include <X11/Xlib.h>
/* Без этого никуда */
int main() {
Display *dpy;
int black, white;
window win;
GC gc;
dpy = XOpenDisplay(NULL);
/*
* Аргументом XOpenDisplay является имя дисплея, при
* использовании NULL в качестве аргумента значение берется из
* $DISPLAY
*/
black = BlackPixel(dpy, DefaultScreen(dpy));
white = WhitePixel(dpy, DefaultScreen(dpy));
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
640, 480, 0, black, white);
/* man XCreateSimpleWindow */
XMapWindow(dpy, win);
/* Окошко нужно не только создать, но и вывести на экран */
gc = XCreateGC(dpy, win, 0, NULL);
/* Создадим графический контекст. man XCreateGC */
XSetForeground(dpy, gc, black);
/* Ошибка 1. Попробуйте понять, что пропущено? */
XDrawLine(dpy, win, gc, 1, 1, 199, 199);
/* Ошибка 2. Попробуйте понять, что пропущено? */
while (1) {
;
}
return 0; /* unreachable */
}
Теперь к ошибкам.
Ошибка 1. Если вдруг сообщение о рисовании линии придет до того, как
окошко будет отмаплено, то X-сервер с радостью его (сообщение) выбросит,
ничего не сделав. Поэтому нужно было:
1. XSelectInput(dpy, win, StructureNotifyMask); -- мы хотим
получить сообщение StructureNotify для окна.
2. На месте /* ошибка 1 */ написать что-то вроде:
while(1) {
XEvent event;
XNextEvent(dpy, &event);
if (MapNotify == event.type) {
break;
}
}
Это позволит нам дождаться появления окошка на экране и только
потом рисовать.
Ошибка 2. Сюда бы нужно написать XFlush(dpy); . man XFlush.
Кроме того, эта программа *не обновляет* окно. То есть если его свернуть
и развернуть (или проехаться по нему другим окном) -- линия исчезнет :)
Чтобы этого не было, нужно указать соответствующую маску в XSelectInput
и в конце в цикле while (1) звать XNextEvent, ловя сообщение Expose, по
которому перерисовывать окошко. В этом случае, как я понимаю, MapNotify
можно не ловить, так как после того, как окошко отмаплено, для него
X-сервер сгенерит Expose (соответственно, линию вне цикла рисовать тоже
не нужно).
Резюме: нужно или хорошо понимать, как работает X внутри, или писать на
высокоуровневом тулките (к сожалению, есть ощущение, что авторы gtk не
очень понимали сами, как работает X... Про Qt я ничего не знаю.)
DISCLAIMER: мои знания в X-программировании очень ограничены.
Приведенная выше программа может стереть все данные с вашего диска и
отправить все ваши пароли злобным хакерам. Если она делает что-то еще --
то только по ошибке.
--
Алексей
В моем <X11/Xlib.h>
тип данных 'Window' называется именно так, а не 'window' (с заглавной буквы).
Честно говоря я даже не знаю, ваша ли это ошибка или данный тип данных стал так называтся с недавних пор...