PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänerfragen mit purer XLib-programmierung



axeljaeger
05-04-2003, 13:47
Ich hab gestern angefange, mal ein paar Anleitungen zu lesen, die sich mit Programmierung der XLib beschäftigen. Jetzt habe ich zwei Fragen, die noch nicht geklärt sind:

Wie fange ich ein Repaint-Event ab?
Wie fange ich ein WindowClose Event ab?

Leider scheint es zu XLib so gut wie keine deutsche Dokumentation zu geben. Und nein, ich möchte nicht lieber Qt oder Gtk nehmen. Für einen speziellen Zweck brauch ich mal die XLib direkt.

anda_skoa
05-04-2003, 17:18
Ich kenn mich da nicht as, aber vielleicht hilft es dir, im Source von Qt oder GTK nachzusehen.
Dort muss das ja gelöst sein.

Ciao,
_

axeljaeger
05-04-2003, 17:30
hm, das Problem ist, das Qt ja im Source knappe 10 Millionen Zeilen Quelltext hat. Ich hoffe, es findet sich doch noch jemand, der sich da auskennt. Ein Beispielprogramm, wo zufällig sowas gemacht wird, würde schon helfen. Aber ich werde selber nochmal forschen

pik7
05-04-2003, 17:32
hallo,

Repaint- und WindowClose Events gibts in xlib nicht.
Es gibt aber Expose und WindowDestroyNotify Events.
Mal ein kleines Beispiel:



#include <X11/Xlib.h>
#include <stdio.h>
#include <unistd.h>

Window win;
Display *disp;
XEvent events;

int main(int argc, char **argv)
{

Window win;
Display *disp;
XEvent events;
int exposure_count=0;
disp = XOpenDisplay(NULL);
win =XCreateSimpleWindow(disp,DefaultRootWindow(disp), 200,200,100,100,0,0,0);

XMapWindow(disp,win);
XFlush(disp);

XSelectInput(disp,win,ExposureMask);
XSelectInput(disp,DefaultRootWindow(disp),Substruc tureNotifyMask|DestroyNotify);

for (;;) {

XNextEvent(disp,&events);
switch (events.type)
{
case Expose:{

printf("Expose Nr.%d\n" , exposure_count);
exposure_count++;

}break;

case DestroyNotify:{

printf("Window putt\n");

}break;

default:break;
}
}
return 1;
}


das kleine programm macht mal ein kleines Fenster auf
und verarbeitet alle seine eigenen Expose events.
Alle WindowDestroy Events die auf dem RootWindow passieren
werden auch regestriert.
Also wenn du jetzt zb ein Xterm startest und dann beendest
wird das regestriert durch und du bekommst die meldung "Window putt".
Sollte mit jedem X-programm funktionieren.
Bei einem Eterm bekommst du mehrere Destroy events weil der hat je noch
seine subwindows die auch alle geschlossen werden.

Das ganze ist jetzt mal was einfach gehalten und deshalb wirst du nicht
vermeiden können dir das "Xlib Programming Manual" reinzuziehen.(gibts im Netz)
Das gibts zwar nur auf englisch aber muss man halt öfter lesen
bis man die Sache in der Hohlen Birne hat.
Wenn man das dan mal begriffen hat ist das mal gar nicht so schwer,

axeljaeger
05-04-2003, 17:36
ah, man dankt!

axeljaeger
05-04-2003, 19:17
Ich hab in einem Beispielprogramm eine ganz komische Syntax gefunden:

erst:




Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);


und dann in der Mainloop:



case ClientMessage:
if (*XGetAtomName(dpy, event.xclient.message_type) ==
*"WM_PROTOCOLS")
{
printf("Exiting sanely...\n");
running = false;
}
break;


Es wäre ja schön, wenn man in deinem Beispiel einfach sagen könnte:




SelectInput(disp,win,DestroyNotify);



Aber da krieg ich immer nur ein "X connection to :0.0 broken (explicit kill or server shutdown)."

pik7
05-04-2003, 19:35
hallo,

währe mal nicht schlecht wenn du mal genauer
erläutern könntest was du überhaupt machen möchtest.
XAtoms sind Eigenschaften die entweder gesetzt sind oder vom
Programm gesetzt werden können.

z.b die rootwindow Background Pixmap für pseudo transparente Windows



if((prop=XInternAtom(disp,"_XROOTPMAP_ID",True))!=None) {

ret=XGetWindowProperty(disp,DefaultRootWindow(disp ),
prop,0L,1L,False,AnyPropertyType,&type,
&format,&length,&after,&data);

if((ret==Success)&&(type==XA_PIXMAP)&&((p=*((Pixmap *)data))!=None)) {

imlib_context_set_drawable(*((Pixmap *)data));

back_buffer=imlib_create_image_from_drawable(0,0,0 ,win_w,win_h,1);

} else {

printf("Keine Backgroundpixmap vorhanden\n");

}



die Atoms kann man natürlich jetzt nicht alle kennen.
Also schreib mal präziser was du eigentlich machen möchtest.

axeljaeger
05-04-2003, 20:42
Das Beispiel, was ich jetzt genannt hatte, war zuständig, das CloseEvent des Fensters abzufangen. Es stammt aus einem Beispiel von nehe.gamedev.net. Ich möchte, das wenn man auf das X in der Titelleiste mein Programm ein Signal kriegt, sich aber möglcihst erst beendet, wenn ich das expliziet anordne. Das war es dann auch schon fast, was ich überhaupt mit X11 machen wollte. Ich nämlich ein anderes Programm, was sich in mein Fenster einbetten soll. Und das Fenster, in das eingebettet werden soll, ist wahlweise ein Qt-Widget, oder halt dieses X11-Fenster, was ich dann in den FullScreenMode schalten möchte.

pik7
05-04-2003, 23:28
hallo,

habe das jetzt mal nachgeschaut und WM_DELETE_WINDOW ist kein
"predefined Atom".

Vieleicht ist das jetzt die Lösung:



#include <X11/Xlib.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/Xatom.h>

int main(int argc, char **argv)
{
Window win;
Display *disp;
int ein;
Atom atom;
XEvent events;

disp = XOpenDisplay(NULL);
win =XCreateSimpleWindow(disp,DefaultRootWindow(disp), 200,200,100,100,0,0,0);

XMapWindow(disp,win);
XFlush(disp);

atom=XInternAtom(disp,"WM_DELETE_WINDOW",True);
XSetWMProtocols(disp,win,&atom,1);
XSelectInput(disp,win,ClientMessage);

for (;;) {

XNextEvent(disp,&events);

switch (events.type) {

case ClientMessage:{

if(*XGetAtomName(disp, events.xclient.message_type) == *"WM_PROTOCOLS")
{

printf("Window zerstören? j \n");

ein=getc(stdin);

if(ein=='j') {

XDestroyWindow(disp,win);

return 1;

}
ein=getc(stdin);
}

}break;

}
}
return 1;
}


Hoffe das hilft