Created
August 19, 2012 07:55
-
-
Save FloooD/3393459 to your computer and use it in GitHub Desktop.
drag/drop something that follows the X cursor perfectly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <GL/glx.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
struct asdf { | |
Display *dpy; | |
Window win, root; | |
GLXFBConfig *fbc; | |
XVisualInfo *vi; | |
XSetWindowAttributes swa; | |
XWindowAttributes gwa; | |
GLXContext gc; | |
int w, h; | |
int bw, bh, bx, by, px, py; | |
int drag; | |
}; | |
void resize(struct asdf *a, int w, int h) | |
{ | |
glViewport(0, 0, w, h); | |
glClear(GL_COLOR_BUFFER_BIT); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glOrtho(0.0, w, 0.0, h, -1.0, 1.0); | |
a->by += h - a->h; | |
a->py += h - a->h; | |
a->w = w; | |
a->h = h; | |
} | |
void init(struct asdf *a, int w, int h) | |
{ | |
a->dpy = XOpenDisplay(NULL); | |
if (a->dpy == NULL) { | |
printf("Could not open display"); | |
exit(1); | |
} | |
int att[] = { | |
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, | |
GLX_RENDER_TYPE, GLX_RGBA_BIT, | |
None | |
}; | |
int n; | |
a->fbc = glXChooseFBConfig(a->dpy, DefaultScreen(a->dpy), att, &n); | |
a->vi = glXGetVisualFromFBConfig(a->dpy, a->fbc[0]); | |
a->root = DefaultRootWindow(a->dpy); | |
a->swa.colormap = | |
XCreateColormap(a->dpy, a->root, a->vi->visual, AllocNone); | |
a->swa.event_mask = ExposureMask | ButtonPressMask | Button1MotionMask; | |
a->win = | |
XCreateWindow(a->dpy, a->root, 0, 0, w, h, 0, a->vi->depth, | |
InputOutput, a->vi->visual, CWColormap | CWEventMask, | |
&(a->swa)); | |
XMapWindow(a->dpy, a->win); | |
a->gc = glXCreateContext(a->dpy, a->vi, NULL, GL_TRUE); | |
glXMakeCurrent(a->dpy, a->win, a->gc); | |
glClearColor(0.0, 0.0, 0.0, 0.0); | |
resize(a, w, h); | |
a->bw = 40, a->bh = 40; | |
a->bx = 400, a->by = 300; | |
a->px = a->bx, a->py = a->by; | |
a->drag = 0; | |
} | |
void quit(struct asdf *a) | |
{ | |
glXMakeCurrent(a->dpy, None, NULL); | |
glXDestroyContext(a->dpy, a->gc); | |
XDestroyWindow(a->dpy, a->win); | |
XCloseDisplay(a->dpy); | |
exit(0); | |
} | |
void ev_handle(struct asdf *a) | |
{ | |
XEvent e; | |
while (XPending(a->dpy)) { | |
XNextEvent(a->dpy, &e); | |
switch (e.type) { | |
case Expose: | |
XGetWindowAttributes(a->dpy, a->win, &(a->gwa)); | |
if (a->w != a->gwa.width || a->h != a->gwa.height) | |
resize(a, a->gwa.width, a->gwa.height); | |
break; | |
case MotionNotify: | |
if (!a->drag) | |
break; | |
if (e.xmotion.x < 0) | |
e.xmotion.x = 0; | |
else if (e.xmotion.x > a->w - 1) | |
e.xmotion.x = a->w - 1; | |
if (e.xmotion.y < 0) | |
e.xmotion.y = 0; | |
else if (e.xmotion.y > a->h - 1) | |
e.xmotion.y = a->h - 1; | |
a->bx += e.xmotion.x - a->px; | |
a->by -= e.xmotion.y - a->py; | |
a->px = e.xmotion.x; | |
a->py = e.xmotion.y; | |
break; | |
case ButtonPress: | |
if (e.xbutton.button != 1) | |
quit(a); | |
if (e.xbutton.x - a->bx <= a->bw | |
&& e.xbutton.x - a->bx >= 0 | |
&& a->h - e.xbutton.y - a->by <= a->bh | |
&& a->h - e.xbutton.y - a->by >= 0) { | |
a->px = e.xbutton.x; | |
a->py = e.xbutton.y; | |
a->drag = 1; | |
} else { | |
a->drag = 0; | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
void draw(struct asdf *a) | |
{ | |
glColor3f(0.0, 1.0, 0.0); | |
glBegin(GL_LINE_LOOP); | |
glVertex3f(a->bx + 0.5, a->by - 0.5, 0.0); | |
glVertex3f(a->bx + a->bw + 0.5, a->by - 0.5, 0.0); | |
glVertex3f(a->bx + a->bw + 0.5, a->by + a->bh - 0.5, 0.0); | |
glVertex3f(a->bx + 0.5, a->by + a->bh - 0.5, 0.0); | |
glEnd(); | |
glFlush(); | |
glClear(GL_COLOR_BUFFER_BIT); | |
} | |
int main(void) | |
{ | |
struct asdf a; | |
init(&a, 800, 600); | |
#define get_t PFNGLXGETVIDEOSYNCSGIPROC | |
#define wait_t PFNGLXWAITVIDEOSYNCSGIPROC | |
get_t get_vsync = (get_t) glXGetProcAddress((const GLubyte *)"glXGetVideoSyncSGI"); | |
wait_t wait_vsync = (wait_t) glXGetProcAddress((const GLubyte *)"glXWaitVideoSyncSGI"); | |
unsigned vsc; | |
while (1) { | |
ev_handle(&a); | |
draw(&a); | |
get_vsync(&vsc); | |
wait_vsync(2, (vsc + 1) % 2, &vsc); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -O3 asdf.c -o asdf -lGL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment