I'm trying to use a bit of X stuff... the following code is an
experience of window resizing. My problem is the following: if I
enlarge the window, the drawing is cliped to the size of the original
window! (when shrinking to a smaller window everything is allright,
nevertheless).
An easy solution would be to declare first a huge window (eg
5000x5000) and then resize it... everything would run. But maybe
there's a more elegant classical solution?
Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <X11/Xlib.h>
int main()
{
Display * display;
Window win, root;
XGCValues gc_values;
GC win_gc;
/* des variables utilisées dans la boucle d'événements */
XEvent boum;
KeySym keysymbol;
char * string = NULL;
int redraw = 0, recalc = 0, loop = 1;
unsigned int win_x=0, win_y=0;
unsigned int width=500, height=500;
unsigned int border_width=2;
/*
* Ouvre display
*/
int depth;
int screen_num;
unsigned int display_width, display_height;
char * display_name = getenv("DISPLAY");
display = XOpenDisplay(display_name);
if (!display)
{
fprintf(stderr,"je ne peux pas me connecter au serveur X\n");
return 1;
}
screen_num = DefaultScreen(display);
root = RootWindow(display, screen_num);
depth = DefaultDepth(display, screen_num);
display_width = DisplayWidth(display,screen_num);
display_height = DisplayHeight(display, screen_num);
/*
* On crée une fenêtre
*/
win = XCreateSimpleWindow(display, root,
win_x, win_y, width, height,
border_width,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
/* un contexte graphique tout con pour cette fenetre */
win_gc = XCreateGC(display, win, 0, &gc_values);
XMapWindow(display, win);
/* ploum ploum */
XSetBackground(display,win_gc,WhitePixel(display,screen_num));
XSetForeground(display,win_gc,BlackPixel(display,screen_num));
/*
* Boucle d'événements
*/
XSelectInput(display, win, ExposureMask | KeyPressMask
| ResizeRedirectMask );
while(loop)
{
XNextEvent(display, &boum);
puts("hop");
switch(boum.type)
{
case ResizeRequest:
puts("resize");
while(XCheckWindowEvent(display,win,ResizeRedirectMask,&boum))
{}
height = boum.xresizerequest.height;
width = boum.xresizerequest.width;
win_gc = XCreateGC(display, win, 0, &gc_values);
recalc = redraw = 1;
break;
case Expose: redraw = 1; break;
case KeyPress:
keysymbol = XKeycodeToKeysym(display,
boum.xkey.keycode, 0);
string = XKeysymToString(keysymbol);
if (strcmp("q",string) == 0) /* quit */
{
loop = 0;
}
break;
default:
break;
}
if(recalc)
{
puts("recalc");
recalc = 0;
}
if(redraw)
{
puts("redraw");
XSetForeground(display,win_gc,WhitePixel(display,screen_num));
XFillRectangle(display,win,win_gc,0,0,width,height);
XSetForeground(display,win_gc,BlackPixel(display,screen_num));
XDrawArc(display, win, win_gc, 0, 0, width, height, 0, 360*64);
XDrawPoint(display,win,win_gc,width/2,height/2);
redraw = 0;
}
}
/*************/
XCloseDisplay(display);
return 0;
}
> I'm trying to use a bit of X stuff... the following code is an
> experience of window resizing. My problem is the following: if I
> enlarge the window, the drawing is cliped to the size of the original
> window! (when shrinking to a smaller window everything is allright,
> nevertheless).
[...]
> XSelectInput(display, win, ExposureMask | KeyPressMask
> | ResizeRedirectMask );
>
>
> while(loop)
> {
> XNextEvent(display, &boum);
> puts("hop");
> switch(boum.type)
> {
>
> case ResizeRequest:
> puts("resize");
> while(XCheckWindowEvent(display,win,ResizeRedirectMask,&boum))
> {}
>
> height = boum.xresizerequest.height;
> width = boum.xresizerequest.width;
> win_gc = XCreateGC(display, win, 0, &gc_values);
Why always creating a new GC?
>
> recalc = redraw = 1;
>
> break;
You intercept the resize request (by the window manager) when you select
for ResizeRedirectMask. Use StructureNotifyMask and evaluate
ConfigureNotify events.
[...]
> XSetForeground(display,win_gc,WhitePixel(display,screen_num));
> XFillRectangle(display,win,win_gc,0,0,width,height);
> XSetForeground(display,win_gc,BlackPixel(display,screen_num));
> XDrawArc(display, win, win_gc, 0, 0, width, height, 0, 360*64);
> XDrawPoint(display,win,win_gc,width/2,height/2);
Instead of changing properties each time, better use two different GCs.
Regards,
Daniel
Thanks for your answer.
> Why always creating a new GC?
For nothing ! just something I should have erased (remains of a
previous test).
> >
> > recalc = redraw = 1;
> >
> > break;
>
>
> You intercept the resize request (by the window manager) when you select
> for ResizeRedirectMask. Use StructureNotifyMask and evaluate
> ConfigureNotify events.
Thanks a lot, I'll try that.
> [...]
> > XSetForeground(display,win_gc,WhitePixel(display,screen_num));
> > XFillRectangle(display,win,win_gc,0,0,width,height);
> > XSetForeground(display,win_gc,BlackPixel(display,screen_num));
> > XDrawArc(display, win, win_gc, 0, 0, width, height, 0, 360*64);
> > XDrawPoint(display,win,win_gc,width/2,height/2);
>
> Instead of changing properties each time, better use two different GCs.
Yes, ok.
If I use 256 colours should I create an array of 256 gc ?
It depends... I think server side resources like Windows and GCs are not
expensive. But, if I would write a painting program, where only the pen
color can be changed, I would not use one GC per color.
Regards,
Daniel