Mercurial > MadButterfly
changeset 77:a6763f080da5
-
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 20 Aug 2008 00:32:11 +0800 |
parents | 8706356a61b4 |
children | 3645e29e4986 |
files | src/Makefile src/X_main.c src/X_supp.c src/mb_timer.h src/mb_types.h src/observer.c src/timertool.c src/tools.c |
diffstat | 8 files changed, 174 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Makefile Tue Aug 19 19:14:01 2008 +0800 +++ b/src/Makefile Wed Aug 20 00:32:11 2008 +0800 @@ -1,6 +1,6 @@ SRCS = coord.c geo.c shape_path.c shape_text.c shape_rect.c \ redraw_man.c timer.c animate.c paint.c event.c observer.c \ - X_supp.c tools.c + X_supp.c timertool.c tools.c OBJS = ${SRCS:C/(.*)\.c/\1.o/g} TESTCASE_OBJS = ${SRCS:C/(.*)\.c/testcase-\1.o/g} CFLAGS+= -Wall -I/usr/local/include `pkg-config --cflags cairo`
--- a/src/X_main.c Tue Aug 19 19:14:01 2008 +0800 +++ b/src/X_main.c Wed Aug 20 00:32:11 2008 +0800 @@ -58,9 +58,8 @@ hint_shape(rdman, shape); break; case Expose: - rdman_redraw_all(rdman); - /* rdman_redraw_area(rdman, evt.xexpose.x, evt.xexpose.y, - evt.xexpose.width, evt.xexpose.height); */ + rdman_redraw_area(rdman, evt.xexpose.x, evt.xexpose.y, + evt.xexpose.width, evt.xexpose.height); break; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/X_supp.c Wed Aug 20 00:32:11 2008 +0800 @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include "redraw_man.h" +#include "mb_timer.h" + + +/*! \brief Dispatch all events in the queue. + */ +static void handle_x_event(Display *display, + redraw_man_t *rdman, + mb_tman_t *tman) { + XEvent evt; + XMotionEvent *mevt; + mouse_event_t mouse_event; + shape_t *shape; + subject_t *subject; + ob_factory_t *factory; + co_aix x, y; + int in_stroke; + int but; + int r; + + while(XEventsQueued(display, QueuedAfterReading) > 0) { + r = XNextEvent(display, &evt); + if(r == -1) + break; + + switch(evt.type) { + case MotionNotify: + mevt = (XMotionEvent *)&evt; + x = mevt->x; + y = mevt->y; + but = 0; + if(mevt->state & Button1Mask) + but |= MOUSE_BUT1; + if(mevt->state & Button2Mask) + but |= MOUSE_BUT2; + if(mevt->state & Button3Mask) + but |= MOUSE_BUT3; + + mouse_event.event.type = EVT_MOUSE_MOVE; + mouse_event.x = x; + mouse_event.y = y; + mouse_event.button = but; + + shape = find_shape_at_pos(rdman, x, y, + &in_stroke); + subject = sh_get_mouse_event_subject(shape); + factory = rdman_get_ob_factory(rdman); + + subject_notify(factory, subject, (event_t *)&mouse_event); + break; + + case Expose: + rdman_redraw_area(rdman, evt.xexpose.x, evt.xexpose.y, + evt.xexpose.width, evt.xexpose.height); + break; + } + } + rdman_redraw_changed(rdman); + XFlush(display); +} + +/*! \brief Handle connection coming data and timeout of timers. + */ +void X_handle_connection(Display *display, + redraw_man_t *rdman, + mb_tman_t *tman) { + int fd; + mb_timeval_t now, tmo; + struct timeval tv; + fd_set rfds; + int nfds; + int r; + + fd = XConnectionNumber(display); + nfds = fd + 1; + while(1) { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + get_now(&now); + r = mb_tman_next_timeout(tman, &now, &tmo); + + if(r == 0) { + tv.tv_sec = MB_TIMEVAL_SEC(&tmo); + tv.tv_usec = MB_TIMEVAL_USEC(&tmo); + r = select(nfds, &rfds, NULL, NULL, &tv); + } else + r = select(nfds, &rfds, NULL, NULL, NULL); + + if(r == -1) { + perror("select"); + break; + } + + if(r == 0) { + get_now(&now); + mb_tman_handle_timeout(tman, &now); + rdman_redraw_changed(rdman); + XFlush(display); + } else if(FD_ISSET(fd, &rfds)){ + handle_x_event(display, rdman, tman); + } + } +}
--- a/src/mb_timer.h Tue Aug 19 19:14:01 2008 +0800 +++ b/src/mb_timer.h Wed Aug 20 00:32:11 2008 +0800 @@ -69,4 +69,7 @@ } while(0) +extern void get_now(mb_timeval_t *tmo); + + #endif /* __MB_TIMER_H_ */
--- a/src/mb_types.h Tue Aug 19 19:14:01 2008 +0800 +++ b/src/mb_types.h Wed Aug 20 00:32:11 2008 +0800 @@ -149,6 +149,8 @@ (sh)->geo->shape = NULL; \ (sh)->geo = NULL; \ } while(0) +#define sh_get_geo(sh) ((sh)->geo) +#define sh_get_mouse_event_subject(sh) ((sh)->geo->mouse_event) extern void sh_attach_coord(shape_t *sh, coord_t *coord); extern void sh_detach_coord(shape_t *sh);
--- a/src/observer.c Tue Aug 19 19:14:01 2008 +0800 +++ b/src/observer.c Wed Aug 20 00:32:11 2008 +0800 @@ -32,7 +32,9 @@ void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) { observer_t *observer; + evt->tgt = subject; while(subject) { + evt->cur_tgt = subject->obj; for(observer = STAILQ_HEAD(subject->observers); observer != NULL; observer = STAILQ_NEXT(observer_t, next, observer)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timertool.c Wed Aug 20 00:32:11 2008 +0800 @@ -0,0 +1,57 @@ +#include <sys/time.h> +#ifdef __FreeBSD__ +#include <machine/cpufunc.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#endif +#include "mb_timer.h" + + +#ifdef __FreeBSD__ +void get_now(mb_timeval_t *tmo) { + struct timeval tv; + static uint64_t cpufreq; + static mb_timeval_t tm = {0, 0}; + static uint64_t last_ts; + + mb_timeval_t diff_tm; + uint64_t ts, diff, udiff, sdiff; + size_t sysctl_sz; + + if(MB_TIMEVAL_SEC(&tm) == 0) { + sysctl_sz = sizeof(uint64_t); + cpufreq = sysctlbyname("kern.timecounter.tc.TSC.frequency", + &cpufreq, &sysctl_sz, + NULL, 0); + + gettimeofday(&tv, NULL); + last_ts = rdtsc(); + + MB_TIMEVAL_SET(tmo, tv.tv_sec, tv.tv_usec); + MB_TIMEVAL_CP(&tm, tmo); + diff = 0; + } else { + ts = rdtsc(); + diff += ts - last_ts; + sdiff = diff / cpufreq; + udiff = (diff % cpufreq) * 1000000 / cpufreq; + + MB_TIMEVAL_SET(&diff_tm, sdiff, udiff); + MB_TIMEVAL_CP(tmo, &tm); + MB_TIMEVAL_ADD(tmo, &diff_tm); + + MB_TIMEVAL_SET(&diff_tm, sdiff, 0); + MB_TIMEVAL_ADD(&tm, &diff_tm); + + last_ts += sdiff; + } +} +#else /* __FreeBSD__ */ +void get_now(mb_timeval_t *tmo) { + struct timeval tv; + + gettimeofday(&tv, NULL); + MB_TIMEVAL_SET(tmo, tv.tv_sec, tv.tv_usec); +} +#endif /* __FreeBSD__ */ +