static int handle_event(Display *dpy, XEvent *ev) { static int win_mapped; KeySym keysym; switch(ev->type) { case MapNotify: win_mapped = 1; break; case UnmapNotify: win_mapped = 0; break; case Expose: if(win_mapped) { if(display_rect_func) { display_rect_func(ev->xexpose.x, ev->xexpose.y, ev->xexpose.width, ev->xexpose.height); } if(!ev->xexpose.count && display_func) { display_func(); } } break; case KeyPress: case KeyRelease: keysym = XLookupKeysym((XKeyEvent*)&ev->xkey, 0); if(keyb_func) { keyb_func(keysym & 0xff, ev->type == KeyPress); } break; case ClientMessage: if(ev->xclient.message_type == wm_prot) { if(ev->xclient.data.l[0] == wm_del) { return -1; } } break; case ConfigureNotify: win_xsz = ev->xconfigure.width; win_ysz = ev->xconfigure.height; if(reshape_func) { reshape_func(win_xsz, win_ysz); } break; default: break; } return 0; }
void APIENTRY glutMainLoop (void) { GLboolean idle; GLboolean have_event; XEvent evt; int visible = 0; glutPostRedisplay(); if (reshape_func) reshape_func(g_width, g_height); while (GL_TRUE) { idle = GL_TRUE; if (visible && idle_func) have_event = XCheckMaskEvent( dpy, ~0, &evt ); else have_event = XNextEvent( dpy, &evt ); if (have_event) { idle = GL_FALSE; switch(evt.type) { case MapNotify: if (visibility_func) { visibility_func(GLUT_VISIBLE); } visible = 1; break; case UnmapNotify: if (visibility_func) { visibility_func(GLUT_NOT_VISIBLE); } visible = 0; break; case Expose: g_redisplay = 1; break; } } if (visible && g_redisplay && display_func) { idle = GL_FALSE; g_redisplay = GL_FALSE; display_func(); } if (visible && idle && idle_func) { idle_func(); } } }
int wsys_process_events(void) { fd_set rds, wrs; int max_fd, nready, xsock; struct evcall *evnode; struct timeval tv = {0, 0}; static int called_first_reshape; if(!called_first_reshape) { if(reshape_func) reshape_func(win_xsz, win_ysz); called_first_reshape = 1; } FD_ZERO(&rds); FD_ZERO(&wrs); max_fd = xsock = ConnectionNumber(dpy); FD_SET(xsock, &rds); evnode = evlist; while(evnode) { if(evnode->func[EV_RD]) { FD_SET(evnode->fd, &rds); } if(evnode->func[EV_WR]) { FD_SET(evnode->fd, &wrs); } if(evnode->fd > max_fd) { max_fd = evnode->fd; } evnode = evnode->next; } do { nready = select(max_fd + 1, &rds, &wrs, 0, idle_func ? &tv : 0); } while(nready == -1 && errno == EINTR); evnode = evlist; while(evnode) { if(FD_ISSET(evnode->fd, &rds) && evnode->func[EV_RD]) { evnode->func[EV_RD](evnode->fd); } if(FD_ISSET(evnode->fd, &wrs) && evnode->func[EV_WR]) { evnode->func[EV_WR](evnode->fd); } evnode = evnode->next; } remove_empty_evcalls(); if(FD_ISSET(xsock, &rds)) { while(XPending(dpy)) { XEvent ev; XNextEvent(dpy, &ev); if(handle_event(dpy, &ev) == -1) { return -1; } } } if(idle_func) { idle_func(); } return 0; }