typedef struct {
int type; /* of event */
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window window; /* "event" window it is reported relative to */
Window root; /* root window that the event occured on */
Window subwindow; /* child window */
Time time; /* milliseconds */
int x, y; /* pointer x, y coordinates in event window */
int x_root, y_root; /* coordinates relative to root */
unsigned int state; /* key or button mask */
unsigned int button; /* detail */
Bool same_screen; /* same screen flag */
} XButtonEvent;
typedef XButtonEvent XButtonPressedEvent;
typedef XButtonEvent XButtonReleasedEvent;
Button1Mask Left mouse button
Button2Mask Middle mouse button
Button3Mask Right mouse button
ShiftMask Shift key
LockMask Shift lock key
ControlMask Control key
typedef struct {
int type; /* of event */
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window window; /* "event" window reported relative to */
Window root; /* root window that the event occured on */
Window subwindow; /* child window */
Time time; /* milliseconds */
int x, y; /* pointer x, y coordinates in event window */
int x_root, y_root; /* coordinates relative to root */
unsigned int state; /* key or button mask */
char is_hint; /* detail */
Bool same_screen; /* same screen flag */
} XMotionEvent;
typedef XMotionEvent XPointerMovedEvent
typedef struct {
int type;
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window event;
Window window;
int x, y;
int width, height;
int border_width;
Window above;
Bool override_redirect;
} XConfigureEvent;
typedef void (*func)();
struct line_struct {
int type;
func draw;
char *next;
double x1, y1;
double x2, y2;
};
typedef struct line_struct *Line;
struct rect_struct {
int type;
func draw;
char *next;
double x1, y1;
double x2, y2;
};
typedef struct rect_struct *Rectangle;
void display_line(w,gc,line)
Widget w;
GC gc;
Line line; {
int x1, y1, x2, y2;
x1 = width * line->x1;
y1 = height * (1.0 - line->y1);
x2 = width * line->x2;
y2 = height * (1.0 - line->y2);
XDrawLine(XtDisplay(w), XtWindow(w), gc, x1, y1,
x2, y2);
}
redisplay(w)
Widget w; {
char *list;
Line node;
func p;
int n;
Arg wargs[5];
GC gc;
XClearWindow(XtDisplay(w), XtWindow(w));
n=0;
XtSetArg(wargs[n], XtNheight, &height); n++;
XtSetArg(wargs[n], XtNwidth, &width); n++;
XtGetValues(w, wargs, n);
gc = XCreateGC(XtDisplay(w), XtWindow(w),
NULL, NULL);
XSetForeground(XtDisplay(w), gc, 1);
XSetBackground(XtDisplay(w), gc, 0);
list = display_list;
while(list != NULL) {
node = (Line) list;
p = node->draw;
(*p)(w, gc, node);
list = node->next;
}
}
Line make_line(x1, y1, x2, y2)
int x1, y1, x2, y2; {
Line result;
result = (Line) malloc(sizeof *result);
result->type = LINE;
result->draw = display_line;
result->x1 = ((double) x1) / width;
result->y1 = 1.0 - ((double) y1) / height;
result->x2 = ((double) x2) / width;
result->y2 = 1.0 - ((double) y2) / height;
result->next = display_list;
display_list = (char *) result;
return(result);
}
XtAddEventHandler(drawing, ExposureMask |
StructureNotifyMask, FALSE, redisplay_event, NULL);
void redisplay_event(w, client, ev)
Widget w;
XtPointer client;
XExposeEvent *ev; {
if(ev->type == ConfigureNotify)
redisplay(w);
if(ev->type == Expose && ev->count == 0)
redisplay(w);
}
Button1Press Create a new line, mouse position
is the first end point
ButtonMotion Erase old line, update line's end
point, draw new line
Button1Release Fix the second end point
void update_line(w,line,x,y)
Widget w;
Line line;
int x, y; {
double x2, y2;
x2 = x;
y2 = y;
line->x2 = x2/width;
line->y2 = 1.0 - y2/height;
}
struct drag_struct {
GC gc;
GC xor_gc;
char *object;
} drag_client;
void press_event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XButtonEvent *ev; {
if(ev->button == Button1) {
drag->object = (char *) make_line(ev->x, ev->y,
ev->x, ev->y);
}
if(ev->button == Button2) {
drag->object = (char *) make_rectangle(ev->x,
ev->y, ev->x, ev->y);
}
}
oid motion_event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XMotionEvent *ev; {
func draw;
Line obj;
obj = (Line) drag->object;
draw = obj->draw;
draw(w, drag->xor_gc, obj);
(*obj->update)(w, obj, ev->x, ev->y);
draw(w, drag->xor_gc, obj);
}
void release-event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XButtonEvent *ev; {
Line obj;
obj = (Line) drag->object;
(*obj->draw)(w, drag->gc, obj);
}
/**************************************************
*
* list.h
*
* Include file for simple drawing program example
*
****************************************************/
typedef void (*func)();
struct line_struct {
int type;
func draw;
func update;
char *next;
double x1, y1;
double x2, y2;
};
typedef struct line_struct *Line;
struct rect_struct {
int type;
func draw;
func update;
char *next;
double x1, y1;
double x2, y2;
};
typedef struct rect_struct *Rectangle;
#define LINE 1
#define RECTANGLE 2
Line make_line();
Rectangle make_rectangle();
/*****************************************************
*
* object.c
*
* Graphics routines for the simple editing program
*
*****************************************************/
#include < X11/StringDefs.h >
#include < X11/Intrinsic.h >
#include "list.h"
static short width;
static short height;
static char *display_list = NULL;
redisplay(w)
Widget w; {
char *list;
Line node;
func p;
int n;
Arg wargs[5];
GC gc;
XClearWindow(XtDisplay(w), XtWindow(w));
n=0;
XtSetArg(wargs[n], XtNheight, &height); n++;
XtSetArg(wargs[n], XtNwidth, &width); n++;
XtGetValues(w, wargs, n);
gc = XCreateGC(XtDisplay(w), XtWindow(w), NULL, NULL);
XSetForeground(XtDisplay(w), gc, 1);
XSetBackground(XtDisplay(w), gc, 0);
list = display_list;
while(list != NULL) {
node = (Line) list;
p = node->draw;
(*p)(w, gc, node);
list = node->next;
}
}
void display_line(w,gc,line)
Widget w;
GC gc;
Line line; {
int x1, y1, x2, y2;
x1 = width * line->x1;
y1 = height * (1.0 - line->y1);
x2 = width * line->x2;
y2 = height * (1.0 - line->y2);
XDrawLine(XtDisplay(w), XtWindow(w), gc, x1, y1, x2, y2);
}
void update_line(w,line,x,y)
Widget w;
Line line;
int x, y; {
double x2, y2;
x2 = x;
y2 = y;
line->x2 = x2/width;
line->y2 = 1.0 - y2/height;
}
Line make_line(x1, y1, x2, y2)
int x1, y1, x2, y2; {
Line result;
result = (Line) malloc(sizeof *result);
result->type = LINE;
result->draw = display_line;
result->update = update_line;
result->x1 = ((double) x1) / width;
result->y1 = 1.0 - ((double) y1) / height;
result->x2 = ((double) x2) / width;
result->y2 = 1.0 - ((double) y2) / height;
result->next = display_list;
display_list = (char *) result;
return(result);
}
void display_rectangle(w,gc,rect)
Widget w;
GC gc;
Rectangle rect; {
int x1, y1, x2, y2;
int Width, Height;
x1 = width * rect->x1;
y1 = height * (1.0 - rect->y1);
x2 = width * rect->x2;
y2 = height * (1.0 - rect->y2);
Width = x2 - x1;
Height = y2 - y1;
if(Width < 0) {
Width = -Width;
x1 = x2;
}
if(Height < 0) {
Height = -Height;
y1 = y2;
}
XDrawRectangle(XtDisplay(w), XtWindow(w), gc, x1, y1,
Width, Height);
}
void update_rectangle(w, rect, x, y)
Widget w;
Rectangle rect;
int x, y; {
double x2, y2;
x2 = x;
y2 = y;
rect->x2 = x2/width;
rect->y2 = 1.0 - y2/height;
}
Rectangle make_rectangle(x1, y1, x2, y2)
int x1, y1, x2, y2; {
Rectangle result;
result = (Rectangle) malloc(sizeof *result);
result->type = RECTANGLE;
result->draw = display_rectangle;
result->update = update_rectangle;
result->x1 = ((double) x1) / width;
result->y1 = 1.0 - ((double) y1) / height;
result->x2 = ((double) x2) / width;
result->y2 = 1.0 - ((double) y2) / height;
result->next = display_list;
display_list = (char *) result;
return(result);
}
/********************************************************
*
* editor.c
*
* Simple editing program that shows how events are
* used in X.
*
*******************************************************/
#include < X11/StringDefs.h >
#include < X11/Intrinsic.h >
#include < X11/Core.h >
#include < X11/Xaw/Form.h >
#include "list.h"
#include "../lib/lib.h"
void redisplay_event(w, client, ev)
Widget w;
XtPointer client;
XExposeEvent *ev; {
if(ev->type == ConfigureNotify)
redisplay(w);
if(ev->type == Expose && ev->count == 0)
redisplay(w);
}
struct drag_struct {
GC gc;
GC xor_gc;
char *object;
} drag_client;
void press_event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XButtonEvent *ev; {
if(ev->button == Button1) {
drag->object = (char *) make_line(ev->x, ev->y,
ev->x, ev->y);
}
if(ev->button == Button2) {
drag->object = (char *) make_rectangle(ev->x, ev->y,
ev->x, ev->y);
}
}
void release_event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XButtonEvent *ev; {
Line obj;
obj = (Line) drag->object;
(*obj->draw)(w, drag->gc, obj);
}
void motion_event(w, drag, ev)
Widget w;
struct drag_struct *drag;
XMotionEvent *ev; {
func draw;
Line obj;
obj = (Line) drag->object;
draw = obj->draw;
draw(w, drag->xor_gc, obj);
(*obj->update)(w, obj, ev->x, ev->y);
draw(w, drag->xor_gc, obj);
}
main(argc,argv)
int argc;
char **argv; {
Widget toplevel;
Widget form;
Widget drawing;
Widget quit;
int n;
Arg wargs[10];
toplevel = XtInitialize(argv[0], "editor", NULL, 0,
&argc, argv);
form = XtCreateManagedWidget("form", formWidgetClass,
toplevel, NULL, 0);
quit = quit_button(form);
drawing = XtCreateManagedWidget("drawing", coreWidgetClass,
form, NULL, 0);
n = 0;
XtSetArg(wargs[n], XtNheight, 300); n++;
XtSetArg(wargs[n], XtNwidth, 300); n++;
XtSetArg(wargs[n], XtNfromVert, quit); n++;
XtSetValues(drawing, wargs, n);
XtAddEventHandler(drawing, ExposureMask | StructureNotifyMask,
FALSE, redisplay_event, NULL);
XtAddEventHandler(drawing, ButtonPressMask, FALSE,
press event, &drag_client);
XtAddEventHandler(drawing, ButtonReleaseMask, FALSE,
release_event, &drag_client);
XtAddEventHandler(drawing, ButtonMotionMask, FALSE,
motion_event, &drag_client);
XtRealizeWidget(toplevel);
/*
* we can't create the graphics contexts until
* after the widgets have been realized
*/
drag_client.gc = XCreateGC(XtDisplay(drawing),
XtWindow(drawing),NULL,NULL);
XSetForeground(XtDisplay(drawing), drag_client.gc, 1);
XSetBackground(XtDisplay(drawing), drag_client.gc, 0);
drag_client.xor_gc = XCreateGC(XtDisplay(drawing),
XtWindow(drawing),NULL,NULL);
XSetForeground(XtDisplay(drawing), drag_client.xor_gc, 1);
XSetBackground(XtDisplay(drawing), drag_client.xor_gc, 0);
XSetFunction(XtDisplay(drawing), drag_client.xor_gc, GXxor);
XtMainLoop();
}