#include <stdio.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
struct _menudata {
int x, y, width, height;
char *name;
Window win;
} menu[] = {
{ 0, 0, 80, 30, "Line"},
{ 0, 30, 80, 30, "Rectange"},
{ 0, 60, 80, 30, "Circle"}
};
int figure=0;
#define min(x,y) (((x)<(y)) ? (x) : (y))
#define max(x,y) (((x)>(y)) ? (x) : (y))
#define N_MENU (sizeof(menu)/sizeof(struct _menudata))
void DrawFig(Display *dpy,Window win,GC gc,int x0,int y0,int x1,int y1) {
int x, y, w, h;
x = min(x0,x1);
y = min(y0,y1);
w = max(x0,x1) - min(x0,x1) +1;
h = max(y0,y1) - min(y0,y1) +1;
switch (figure) {
case 0:
XDrawLine(dpy,win,gc,x0,y0,x1,y1);
break;
case 1:
XDrawRectangle(dpy,win,gc,x,y,w,h);
break;
case 2:
XDrawArc(dpy,win,gc,x,y,w,h,0,360*64);
break;
default:
fprintf(stderr,"unknown figure %d\n",figure);
}
}
int main() {
Display *dpy;
int scr,i;
Window win,menuwin;
GC gc, gc2;
XGCValues gcv;
XSetWindowAttributes xswa;
char *xservname=NULL;
if ((dpy = XOpenDisplay(xservname)) == NULL) {
fprintf(stderr, "cant open display %s\n",XDisplayName(xservname));
exit(1);
}
scr = DefaultScreen(dpy);
xswa.background_pixel = WhitePixel(dpy,scr);
xswa.border_pixel = BlackPixel(dpy,scr);
xswa.event_mask =
ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
win=XCreateWindow(dpy,RootWindow(dpy,scr),0,0,320,240,1,
CopyFromParent,CopyFromParent,CopyFromParent,
CWBackPixel|CWBorderPixel|CWEventMask,&xswa);
menuwin=XCreateWindow(dpy,RootWindow(dpy,scr),0,0,menu[0].width,
menu[N_MENU-1].y+menu[N_MENU-1].height,1,
CopyFromParent,CopyFromParent,CopyFromParent,
CWBackPixel|CWBorderPixel|CWEventMask,&xswa);
for (i=0; i<N_MENU; ++i) {
menu[i].win=XCreateWindow(dpy,menuwin,menu[i].x,menu[i].y,
menu[i].width, menu[i].height, 1,
CopyFromParent,CopyFromParent,CopyFromParent,
(CWBackPixel|CWBorderPixel|CWEventMask),&xswa);
}
gcv.background = WhitePixel(dpy,scr);
gcv.foreground = BlackPixel(dpy,scr);
gcv.function = GXcopy;
gc = XCreateGC(dpy,win,(GCForeground|GCBackground|GCFunction),&gcv);
gcv.function = GXinvert;
gc2 = XCreateGC(dpy,win,(GCForeground|GCBackground|GCFunction),&gcv);
XMapWindow(dpy,win);
XMapWindow(dpy,menuwin);
XMapSubwindows(dpy,menuwin);
for (;;) {
XEvent ev;
int x0,y0,x1,y1;
XNextEvent(dpy, &ev);
switch (ev.type) {
case Expose:
while (XCheckTypedWindowEvent(dpy,ev.xany.window,Expose,&ev));
XClearWindow(dpy,ev.xany.window);
for (i=0; i<N_MENU; ++i) {
if (menu[i].win == ev.xany.window) {
XDrawString(dpy,ev.xany.window,gc,5,20,menu[i].name,
strlen(menu[i].name));
break;
}
}
break;
case ButtonPress:
printf("button press\n");
if (ev.xany.window == win) {
if (ev.xbutton.button == 3) exit(0);
x0=ev.xbutton.x;
y0=ev.xbutton.y;
x1=x0; y1=y0;
DrawFig(dpy,win,gc2,x0,y0,x1,y1);
} else {
for (i=0; i<N_MENU; ++i) {
if (menu[i].win == ev.xany.window) {
figure = i;
break;
}
}
}
break;
case ButtonRelease:
printf("button release\n");
if (ev.xany.window == win) {
DrawFig(dpy,win,gc2,x0,y0,x1,y1);
x1=ev.xbutton.x;
y1=ev.xbutton.y;
DrawFig(dpy,win,gc,x0,y0,x1,y1);
}
break;
case MotionNotify:
printf("pointer motion\n");
if (ev.xany.window == win) {
DrawFig(dpy,win,gc2,x0,y0,x1,y1);
x1=ev.xbutton.x;
y1=ev.xbutton.y;
DrawFig(dpy,win,gc2,x0,y0,x1,y1);
}
break;
default:
break;
}
}
}
|