Package: xserver-xorg-input-evtouch Version: 0.8.7-3 Severity: wishlist Tags: patch
This patch improves the debugging support in evtouch. Major changes: * Reimplementation of debug macros are less likely to cause unintended side effects (e.g. merging with adjacent statements, mismatched else's). * debug_level controls all debugging. * Globally changable reporting levels for features. * More features instrumented. * Live reporting mode for location information. Quortech open source packages can be found at: ftp://ftp.quortech.com/eclipse/deb-packages/ This patch is included in xf86-input-evtouch_0.8.7-3quortech3.dsc. -- System Information: Debian Release: 4.0 APT prefers stable APT policy: (500, 'stable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.22-14-generic Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
# Description: This patch improves the debugging support in evtouch. # # Changes # o Statements_M : Utility macro to make debugging macros simpler and # more robust. # o debug_level : Combine to single global provided by libtouch.c. # o DBG : Move to libtouch.h to be shared with evtouch.c. Make more # robust. Allow entire blocks of debugging statements to be skipped. # o DBGOUT : Move to evtouch.c, the only place it's currently used. # o DBGOUT : Local control through DebugLevel option of output. # Avoids uncontrolled output size in /var/log/Xorg.0.log with noisy # touch screen. Encapsulate debugging statements that weren't using. # o DBGOUT : Make robust to surrounding statements. # o DBGXF86, DBGLOC : Globally changable reporting levels for features. # o DBGXF86 : Instrument tracing of xf86 calls. # o dbg_loc : Report location information as received and transmitted. # o DBGLOC_INLINE : Overwrites location information in place on ASCII # terminal. Useful for live testing of accuracy of touch screen. # o EVTouchDumpPacketToLog : Reduce single usage to DBGOUT call. # # Feel free to send comments, critics, suggestions to w...@acm.org # To apply simply change into the toplevel directory of the source to be modified and enter: # patch -p1 < <PATH_TO_PATCH> # # All patches are available under the GNU GPL, I hope they might be useful for you (-: # - Brett Wuth # Index: xf86-input-evtouch-0.8.7/evtouch.c =================================================================== --- xf86-input-evtouch-0.8.7.orig/evtouch.c 2009-01-15 14:55:33.000000000 -0700 +++ xf86-input-evtouch-0.8.7/evtouch.c 2009-01-15 15:38:41.000000000 -0700 @@ -92,6 +92,14 @@ #include "libtouch.h" #include "evtouch.h" +/* The verbosity levels at which to output various */ +#define DBGXF86 (9) /* XF86 calls */ +#define DBGLOC (1) /* location information */ + +#define DBGLOC_INLINE (1) /* whether to display location information + * on one line continously updated (1), or + * on multiple lines (0) */ + /***************************************************************************** * Variables without includable headers ****************************************************************************/ @@ -106,7 +114,17 @@ static void EVTouchPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl); -static int debug_level = 0; +#ifdef EVDBG + /* Only output the debug statement if it meets *our* debug_level. + */ +#define DBGOUT(lvl, ...) DBG( (lvl), xf86ErrorFVerb( (lvl), __VA_ARGS__ ); ) +#else + /* Do nothing, but require the user to include trailing ";" + * so that syntax rules of normal statements are maintained. + * Compiler will optimize this statement away. + */ +#define DBGOUT(lvl, ...) Statements_M() +#endif InputDriverRec EVTOUCH = { 1, @@ -150,9 +168,12 @@ int *errmaj, int *errmin ) { - xf86AddModuleInfo(&EVTouchInfo, module); - xf86AddInputDriver(&EVTOUCH, module, 0); - return module; + DBGOUT( DBGXF86, "EVTouch: xf86AddModuleInfo(&EVTouchInfo, module)\n" ); + xf86AddModuleInfo(&EVTouchInfo, module); + + DBGOUT( DBGXF86, "EVTouch: xf86AddInputDriver(&EVTOUCH, module, 0)\n" ); + xf86AddInputDriver(&EVTOUCH, module, 0); + return module; } @@ -201,6 +222,39 @@ ****************************************************************************/ +/* Report the current location information as received and as sent on to X */ +static void +dbg_loc( int *in_x, /* the received X location, NULL if no change */ + int *in_y, /* the received Y location, NULL if no change */ + int *out_x, /* the sent X location, NULL if no change */ + int *out_y /* the sent Y location, NULL if no change */ + ) +{ + static int last_in_x, last_in_y, last_out_x, last_out_y; + + if (in_x) last_in_x = *in_x; + if (in_y) last_in_y = *in_y; + if (out_x) last_out_x = *out_x; + if (out_y) last_out_y = *out_y; + + /* Print the current location as received and sent. + * Fields that have been updated are marked with a leading '*'. + */ + DBGOUT( DBGLOC, + "EVTouch in = (%c%5d, %c%5d), out = (%c%5d, %c%5d)%c", + in_x ? '*' : ' ', + last_in_x, + in_y ? '*' : ' ', + last_in_y, + out_x ? '*' : ' ', + last_out_x, + out_y ? '*' : ' ', + last_out_y, + DBGLOC_INLINE ? '\r' : '\n' + ); +} + + static CARD32 emulate3Timer(OsTimerPtr timer, CARD32 now, pointer _local) { @@ -212,7 +266,9 @@ EVTouchPrivatePtr priv = (EVTouchPrivatePtr) local->private; + DBGOUT( DBGXF86, "EVTouch: xf86BlockSIGIO()\n" ); sigstate = xf86BlockSIGIO(); + DBGOUT( DBGXF86, "EVTouch: returned sigstate = %d\n", sigstate ); PostMotionEvent(local); @@ -240,6 +296,8 @@ } priv->emulate3_timer_expired = TRUE; + + DBGOUT( DBGXF86, "EVTouch: xf86UnblockSIGIO(sigstate=%d)\n", sigstate ); xf86UnblockSIGIO(sigstate); return 0; @@ -291,6 +349,8 @@ ev = &priv->ev; if ( (ev->code == ABS_X) || (ev->code == ABS_Z) ) { + dbg_loc( &ev->value, NULL, NULL, NULL ); + if ((priv->cur_x - ev->value < priv->move_limit) && (priv->cur_x - ev->value > -priv->move_limit)) return; @@ -299,6 +359,8 @@ } if ( (ev->code == ABS_Y) || (ev->code == ABS_RX) ) { + dbg_loc( NULL, &ev->value, NULL, NULL ); + if ((priv->cur_y - ev->value < priv->move_limit) && (priv->cur_y - ev->value > -priv->move_limit)) return; @@ -469,7 +531,9 @@ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); + DBGOUT( DBGXF86, "EVTouch: xf86OpenSerial(local->options)\n" ); local->fd = xf86OpenSerial(local->options); + DBGOUT( DBGXF86, "EVTouch: returned local->fd = %d\n", local->fd ); DBGOUT(2, "EVTouch: %s\n", __FUNCTION__ ); @@ -486,9 +550,10 @@ if (!priv->buffer) { - xf86CloseSerial(local->fd); - local->fd = -1; - return (!Success); + DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd=%d)\n", local->fd ); + xf86CloseSerial(local->fd); + local->fd = -1; + return (!Success); } if (QueryHardware(local) != Success) @@ -497,6 +562,7 @@ return (!Success); } + DBGOUT( DBGXF86, "EVTouch: xf86FlushInput(local->fd=%d)\n", local->fd ); xf86FlushInput(local->fd); if (ioctl(local->fd, EVIOCGRAB, (void *)1)) @@ -504,6 +570,7 @@ #ifndef XFREE86_V4 + DBGOUT( DBGXF86, "EVTouch: xf86AddEnabledDevice(local)\n" ); xf86AddEnabledDevice(local); #else AddEnabledDevice(local->fd); @@ -528,12 +595,14 @@ if (local->fd != -1) { ioctl(local->fd, EVIOCGRAB, (void *)0); - xf86RemoveEnabledDevice (local); + DBGOUT( DBGXF86, "EVTouch: xf86RemoveEnabledDevice(local)\n" ); + xf86RemoveEnabledDevice(local); if (priv->buffer) { XisbFree(priv->buffer); priv->buffer = NULL; } + DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd=%d)\n", local->fd ); xf86CloseSerial(local->fd); local->fd = -1; } @@ -605,6 +674,8 @@ DBGOUT(2, "EVTouch: %s btn_count=%d\n", __FUNCTION__, priv->btn_count); priv->btn_actions = xcalloc(priv->btn_count, sizeof(BtnAction)); + + DBGOUT( DBGXF86, "EVTouch: xf86memset(...)\n" ); xf86memset(priv->btn_actions, 0, priv->btn_count * sizeof(BtnAction)); @@ -627,26 +698,40 @@ return !Success; } #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2 + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" ); xf86InitValuatorAxisStruct(dev, 0, 0, priv->screen_width, 1024, EV_AXIS_MIN_RES /* min_res */ , EV_AXIS_MAX_RES /* max_res */ ); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,0)\n" ); xf86InitValuatorDefaults(dev, 0); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" ); xf86InitValuatorAxisStruct(dev, 1, 0, priv->screen_height, 1024, EV_AXIS_MIN_RES /* min_res */ , EV_AXIS_MAX_RES /* max_res */ ); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,1)\n" ); xf86InitValuatorDefaults(dev, 1); #else + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" ); xf86InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x, 1024, EV_AXIS_MIN_RES /* min_res */ , EV_AXIS_MAX_RES /* max_res */ ); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,0)\n" ); xf86InitValuatorDefaults(dev, 0); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" ); xf86InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y, 1024, EV_AXIS_MIN_RES /* min_res */ , EV_AXIS_MAX_RES /* max_res */ ); + + DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,1)\n" ); xf86InitValuatorDefaults(dev, 1); #endif /* Initial position of pointer on screen: Centered */ @@ -670,7 +755,8 @@ /* * Allocate the motion events buffer. */ - xf86MotionHistoryAllocate (local); + DBGOUT( DBGXF86, "EVTouch: xf86MotionHistoryAllocate(local)\n" ); + xf86MotionHistoryAllocate(local); return (Success); } @@ -708,9 +794,10 @@ static void EVTouchNewPacket (EVTouchPrivatePtr priv) { - xf86memset(&priv->ev, 0, sizeof(struct input_event)); - priv->packeti = 0; - priv->binary_pkt = FALSE; + DBGOUT( DBGXF86, "EVTouch: xf86memset(...)\n" ); + xf86memset(&priv->ev, 0, sizeof(struct input_event)); + priv->packeti = 0; + priv->binary_pkt = FALSE; } @@ -736,7 +823,11 @@ if (sizeof(priv->ev) == count) { count = 0; - EVTouchDumpPacketToLog(priv); +#ifdef LOG_RAW_PACKET + DBGOUT( 2, + "EVTOUCHPCKT type=0x%02x code=0x%02x value=0x%02x\n", + priv->ev.type, priv->ev.code, priv->ev.value ); +#endif return Success; } @@ -876,9 +967,6 @@ int xc = 0, yc = 0; int screen_width = 0; int screen_height = 0; -#ifdef EVDBG - int i = 0; -#endif EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); ScrnInfoPtr pScrn = xf86Screens[priv->screen_num]; @@ -1003,14 +1091,20 @@ #ifdef EVDBG - for (i=0; i<3; i++) - xf86ErrorFVerb(2, "cx[%d]=%f cy[%d]=%f\n", i, cx[i] - ,i, cy[i]); - - DBGOUT(2, "EVTouch: ViewPort_X0=%d ViewPort_Y0=%d\n", - *(priv->pViewPort_X0), - *(priv->pViewPort_Y0)); - DBGOUT(2, "EVTouch: dx=%f dy=%f\n", dx, dy); + DBG( 2, + { + int i = 0; + for (i=0; i<3; i++) + DBGOUT( 2, + "cx[%d]=%f cy[%d]=%f\n", + i, cx[i], i, cy[i] ); + + DBGOUT( 2, + "EVTouch: ViewPort_X0=%d ViewPort_Y0=%d\n", + *(priv->pViewPort_X0), + *(priv->pViewPort_Y0) ); + DBGOUT( 2, "EVTouch: dx=%f dy=%f\n", dx, dy ); + } ); #endif xc = ( ((float)xc / max_x) * screen_width ) + dx; @@ -1100,7 +1194,9 @@ if (!priv) return NULL; + DBGOUT( DBGXF86, "EVTouch: xf86AllocateInput(drv, 0)\n" ); local = xf86AllocateInput(drv, 0); + DBGOUT( DBGXF86, "EVTouch: returned local=%p\n", local ); if (!local) { xfree(priv); return NULL; @@ -1123,15 +1219,18 @@ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; local->conf_idev = dev; + + DBGOUT( DBGXF86, "EVTouch: xf86CollectInputOptions(local, default_options, NULL)\n" ); xf86CollectInputOptions(local, default_options, NULL); + DBGOUT( DBGXF86, "EVTouch: xf86OptionListReport(local->options)\n" ); xf86OptionListReport(local->options); priv->libtouch = xcalloc(1, sizeof(LibTouchRec)); libtouchInit(priv->libtouch, local,PostButtonEvent); - priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0 ); + priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0 ); priv->calibrate = xf86SetIntOption(local->options, "Calibrate", 0); @@ -1207,6 +1306,7 @@ } #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 + DBGOUT( DBGXF86, "EVTouch: xf86AlwaysCore(local, TRUE)\n" ); xf86AlwaysCore(local, TRUE); #endif priv->touch_flags = 0; @@ -1222,14 +1322,17 @@ if (priv->calibrate) { priv->fifo = open("/tmp/ev_calibrate", O_RDWR, 0); if (priv->fifo < 0) - xf86ErrorFVerb(2, "open FIFO FAILED\n"); + DBGOUT( 2, "open FIFO FAILED\n" ); } /* this results in an xstrdup that must be freed later */ local->name = xf86SetStrOption( local->options, "DeviceName", "EVTouch TouchScreen" ); + + DBGOUT( DBGXF86, "EVTouch: xf86ProcessCommonOptions(local, local->options)\n" ); xf86ProcessCommonOptions(local, local->options); local->flags |= XI86_CONFIGURED; + DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd = %d)\n", local->fd ); xf86CloseSerial(local->fd); local->fd = -1; @@ -1248,52 +1351,64 @@ static void PostMotionEvent(LocalDevicePtr local) { -int cur_x, cur_y; -EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); + int cur_x, cur_y; + EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); - cur_x = priv->cur_x; - cur_y = priv->cur_y; + cur_x = priv->cur_x; + cur_y = priv->cur_y; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2 - ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); + ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); #endif -xf86PostMotionEvent (local->dev, TRUE, 0, 2, cur_x, cur_y); + dbg_loc( NULL, NULL, &cur_x, &cur_y ); + + DBGOUT( DBGXF86, "EVTouch: xf86PostMotionEvent (local->dev, TRUE, 0, 2, cur_x=%d, cur_y=%d)\n", cur_x, cur_y ); + xf86PostMotionEvent (local->dev, TRUE, 0, 2, cur_x, cur_y); } static void PostProximityEvent(LocalDevicePtr local, int is_in) { -int cur_x, cur_y; -EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); + int cur_x, cur_y; + EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); - cur_x = priv->cur_x; - cur_y = priv->cur_y; + cur_x = priv->cur_x; + cur_y = priv->cur_y; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2 - ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); + ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); #endif -xf86PostProximityEvent(local->dev, is_in, 0, 2, cur_x,cur_y); + dbg_loc( NULL, NULL, &cur_x, &cur_y ); + + DBGOUT( DBGXF86, "EVTouch: xf86PostProximityEvent(local->dev, is_in=%d, 0, 2, cur_x=%d,cur_y=%d)\n", is_in, cur_x, cur_y ); + xf86PostProximityEvent(local->dev, is_in, 0, 2, cur_x,cur_y); } static void PostButtonEvent(LocalDevicePtr local, int button, int is_down,int x, int y) { #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2 - ConvertProc(local,0,2,x,y,0,0,0,0,&x,&y); + ConvertProc(local,0,2,x,y,0,0,0,0,&x,&y); #endif -xf86PostButtonEvent (local->dev, TRUE, button, is_down, 0, 2, x, y); + dbg_loc( NULL, NULL, &x, &y ); + + DBGOUT( DBGXF86, "EVTouch: xf86PostButtonEvent( local->dev, TRUE, button = %d, is_down = %d, 0, 2, x = %d, y = %d )\n", button, is_down, x, y ); + xf86PostButtonEvent( local->dev, TRUE, button, is_down, 0, 2, x, y ); } static void InputSetScreen(LocalDevicePtr local) { -int cur_x, cur_y; -EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); + int cur_x, cur_y; + EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private); - cur_x = priv->cur_x; - cur_y = priv->cur_y; + cur_x = priv->cur_x; + cur_y = priv->cur_y; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2 - ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); + ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y); #endif -xf86XInputSetScreen(local,priv->screen_num,cur_x,cur_y); + dbg_loc( NULL, NULL, &cur_x, &cur_y ); + + DBGOUT( DBGXF86, "EVTouch: xf86XInputSetScreen(local,priv->screen_num=%d,cur_x=%d,cur_y=%d)\n", priv->screen_num, cur_x, cur_y ); + xf86XInputSetScreen(local,priv->screen_num,cur_x,cur_y); } Index: xf86-input-evtouch-0.8.7/evtouch.h =================================================================== --- xf86-input-evtouch-0.8.7.orig/evtouch.h 2009-01-15 14:55:33.000000000 -0700 +++ xf86-input-evtouch-0.8.7/evtouch.h 2009-01-15 15:37:31.000000000 -0700 @@ -29,12 +29,6 @@ #define _evtouch_H_ -#ifdef EVDBG -#define DBGOUT(lvl, ...) (xf86ErrorFVerb(lvl, __VA_ARGS__)) -#else -#define DBGOUT(lvl, ...) -#endif - /****************************************************************************** * Definitions * structs, typedefs, #defines, enums @@ -148,12 +142,6 @@ * Declarations *****************************************************************************/ -#ifdef LOG_RAW_PACKET -#define EVTouchDumpPacketToLog(priv) ( xf86ErrorFVerb(2, "EVTOUCHPCKT type=0x%02x code=0x%02x value=0x%02x\n", priv->ev.type, priv->ev.code, priv->ev.value ) ) -#else -#define EVTouchDumpPacketToLog(priv) -#endif - void trigger_sm(EVTouchPrivatePtr priv); /* Index: xf86-input-evtouch-0.8.7/libtouch.c =================================================================== --- xf86-input-evtouch-0.8.7.orig/libtouch.c 2009-01-15 14:55:33.000000000 -0700 +++ xf86-input-evtouch-0.8.7/libtouch.c 2009-01-15 15:23:07.000000000 -0700 @@ -40,12 +40,8 @@ #include "libtouch.h" -#ifdef DBG -#undef DBG -#endif - -static int debug_level = 0; -#define DBG(lvl, f) {if ((lvl) <= debug_level) f;} +/* Maximum level of debug information to be displayed */ +extern int debug_level = 0; typedef struct state { void (*enter_state)(LibTouchRecPtr priv); Index: xf86-input-evtouch-0.8.7/libtouch.h =================================================================== --- xf86-input-evtouch-0.8.7.orig/libtouch.h 2009-01-15 14:55:33.000000000 -0700 +++ xf86-input-evtouch-0.8.7/libtouch.h 2009-01-15 15:23:07.000000000 -0700 @@ -3,6 +3,103 @@ #include <xf86_ansic.h> #include <os.h> +/* Macro to allow arbitrary statements to be executed as a single + * statement. This is a helper macro creating other macros. This + * macro must be followed by a ";" (like any other statement) and will + * accept only a ";" as the next character. Embedded Stmts must each + * be properly terminated. E.g.: + * + * Statements_M(); + * Statements_M( foo(); bar(); ); + * Statements_M( if (foo) bar(); ); + * Statements_M( { + * int foo; + * bar( &foo ); + * } ); + * Statements_M( if (foo) + * break; + * if (bar) + * continue; + * ); + * + * + * Warnings: + * + * Because the implementation use an if/else construct, if the caller + * uses something like: + * + * if (foo) Statements_M( ... ); + * + * some compilers will "helpfully" produce a warning like: + * + * warning: suggest explicit braces to avoid ambiguous 'else' + * + * For this macro, the warning is inappropriate and can be ignored. + * To avoid the warning, rewrite the code as: + * + * if (foo) { Statements_M( ... ); } + * + * FIXME: Investigate compiler-specific pragmas/markup to turn off + * just for this macro. + * + * + * Implementation: + * + * Squiggly brackets "{ ... }" handle arbitrary statements. + * + * "do ... while (0)" is optimized away but syntactically can only be + * followed by a ";". Other solutions could accidentally merge + * following statements if the ";" was forgotten by the caller. + * + * "if (1) ... else ..." composes the whole thing as a single + * statement. A following "else" won't match our "if", because it's + * already been matched. Embedded break and continue statements are + * allowed. The compiler will optimize the if statement away. + */ +#define Statements_M( Stmts ) \ + if (1) { Stmts } else do ; while (0) + + +/* Maximum level of debug information to be displayed */ +extern int debug_level; + +/* Only execute the debug statement(s) if it meets our debug_level. + * + * The ";" after the statement is optional, as has been the convention + * in earlier implementations of this macro. E.g.: + * + * DBG( 1, bar() ); + * + * More complex statements are also possible. E.g.: + * + * DBG( 1, bar(); ); + * DBG( 1, bar(); baz(); ); + * DBG( 1, while (foo) baz(); ); + * DBG( 1, { + * int i; + * for (i = 0; i < foo; i++) + * bar(); + * } ); + * + * + * Implementation: + * + * The ";" after the "f" makes including a ";" optional. + * + * "{ ... }" avoids: "warning: suggest explicit braces to avoid + * ambiguous 'else'" + */ +#ifdef DBG +#undef DBG +#endif +#define DBG( lvl, f ) \ + Statements_M( if ((lvl) <= debug_level) \ + { \ + Statements_M( f; ); \ + } \ + ) + + #define TOUCHED 0x01 #define X_COORD 0x02 #define Y_COORD 0x04