Ejemplo n.º 1
0
void gwinPutChar(GHandle gh, char c) {
	#define gcw		((GConsoleObject *)gh)
	uint8_t			width, fy, fp;

	if (gh->vmt != &consoleVMT || !gh->font)
		return;

	fy = gdispGetFontMetric(gh->font, fontHeight);
	fp = gdispGetFontMetric(gh->font, fontCharPadding);

	#if GDISP_NEED_CLIP
		gdispSetClip(gh->x, gh->y, gh->width, gh->height);
	#endif
	
	if (c == '\n') {
		gcw->cx = 0;
		gcw->cy += fy;
		// We use lazy scrolling here and only scroll when the next char arrives
	} else if (c == '\r') {
		// gcw->cx = 0;
	} else {
		width = gdispGetCharWidth(c, gh->font) + fp;
		if (gcw->cx + width >= gh->width) {
			gcw->cx = 0;
			gcw->cy += fy;
		}

		if (gcw->cy + fy > gh->height) {
#if GDISP_NEED_SCROLL
			/* scroll the console */
			gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
			/* reset the cursor to the start of the last line */
			gcw->cx = 0;
			gcw->cy = (((coord_t)(gh->height/fy))-1)*fy;
#else
			/* clear the console */
			gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
			/* reset the cursor to the top of the window */
			gcw->cx = 0;
			gcw->cy = 0;
#endif
		}

#if GWIN_CONSOLE_USE_CLEAR_LINES
		/* clear to the end of the line */
		if (gcw->cx == 0)
			gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
#endif
#if GWIN_CONSOLE_USE_FILLED_CHARS
		gdispFillChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
#else
		gdispDrawChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
#endif

		/* update cursor */
		gcw->cx += width;
	}
	#undef gcw
}
Ejemplo n.º 2
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispFillArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
	}
Ejemplo n.º 3
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispFillEllipse(gh->x+x, gh->y+y, a, b, gh->color);
	}
Ejemplo n.º 4
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispDrawCircle(gh->x+x, gh->y+y, radius, gh->color);
	}
Ejemplo n.º 5
0
Archivo: gwin.c Proyecto: bunnie/uGFX
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
	if (!((gh->flags & GWIN_FLG_VISIBLE)))
		return;

	#if GDISP_NEED_CLIP
		gdispSetClip(gh->x, gh->y, gh->width, gh->height);
	#endif
	gdispBlitAreaEx(gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
}
Ejemplo n.º 6
0
Archivo: gwin.c Proyecto: bunnie/uGFX
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
	if (!((gh->flags & GWIN_FLG_VISIBLE)))
		return;

	#if GDISP_NEED_CLIP
		gdispSetClip(gh->x, gh->y, gh->width, gh->height);
	#endif
	gdispDrawLine(gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
}
Ejemplo n.º 7
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return defaultBgColor;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		return gdispGetPixelColor(gh->x+x, gh->y+y);
	}
Ejemplo n.º 8
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	static void _gwm_vis(GHandle gh) {
		if (gh->vmt->Redraw) {
			#if GDISP_NEED_CLIP
				gdispSetClip(gh->x, gh->y, gh->width, gh->height);
			#endif
			gh->vmt->Redraw(gh);
		} else
			gwinClear(gh);
	}
Ejemplo n.º 9
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispFillChar(gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
	}
Ejemplo n.º 10
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispFillConvexPoly(tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
	}
Ejemplo n.º 11
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)))
			return GDISP_IMAGE_ERR_OK;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy);
	}
Ejemplo n.º 12
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispFillStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
	}
Ejemplo n.º 13
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
		if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
			return;

		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		gdispDrawString(gh->x+x, gh->y+y, str, gh->font, gh->color);
	}
Ejemplo n.º 14
0
Archivo: gwin.c Proyecto: bunnie/uGFX
void gwinClear(GHandle gh) {
	if (!((gh->flags & GWIN_FLG_VISIBLE)))
		return;

	#if GDISP_NEED_CLIP
		gdispSetClip(gh->x, gh->y, gh->width, gh->height);
	#endif
	gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
	if (gh->vmt->AfterClear)
		gh->vmt->AfterClear(gh);
}
Ejemplo n.º 15
0
Archivo: gwin.c Proyecto: bunnie/uGFX
void gwinSetEnabled(GHandle gh, bool_t enabled) {
	if (enabled) {
		if (!(gh->flags & GWIN_FLG_ENABLED)) {
			gh->flags |= GWIN_FLG_ENABLED;
			if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) {
				#if GDISP_NEED_CLIP
					gdispSetClip(gh->x, gh->y, gh->width, gh->height);
				#endif
				gh->vmt->Redraw(gh);
			}
		}
	} else {
		if ((gh->flags & GWIN_FLG_ENABLED)) {
			gh->flags &= ~GWIN_FLG_ENABLED;
			if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) {
				#if GDISP_NEED_CLIP
					gdispSetClip(gh->x, gh->y, gh->width, gh->height);
				#endif
				gh->vmt->Redraw(gh);
			}
		}
	}
}
Ejemplo n.º 16
0
static void DrawHeader(const char *title, bool_t btnNext, bool_t btnPrev, bool_t btnPlusMinus) {
	#if GDISP_NEED_CLIP
		gdispSetClip(0, 0, swidth, sheight);
	#endif
	gdispFillStringBox(0, 0, swidth, bHeight, "Touch Calibration", font, uRed, White, justifyLeft);
	if (btnNext)
		gdispFillStringBox(swidth-1*bWidth, 0, bWidth  , bHeight, "Next", font, Black, Gray, justifyCenter);
	if (btnPrev)
		gdispFillStringBox(swidth-2*bWidth, 0, bWidth-1, bHeight, "Prev", font, Black, Gray, justifyCenter);
	if (btnPlusMinus) {
		gdispFillStringBox(swidth-2*bWidth-1*bWidth2, 0, bWidth2-1, bHeight, "+", font, Black, Gray, justifyCenter);
		gdispFillStringBox(swidth-2*bWidth-2*bWidth2, 0, bWidth2-1, bHeight, "-", font, Black, Gray, justifyCenter);
	}
	gwinClear(ghc);
	gwinSetColor(ghc, Yellow);
	gwinPrintf(ghc, "\n%s\n\n", title);
	gwinSetColor(ghc, White);
}
Ejemplo n.º 17
0
bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) {
	if (gdispImageIsOpen(&widget(gh)->image))
		gdispImageClose(&widget(gh)->image);

	if (!gdispImageSetBaseFileStreamReader(&widget(gh)->image, streamPtr))
		return FALSE;

	if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK)
		return FALSE;

	if ((gh->flags & GWIN_FLG_VISIBLE)) {
		// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
		//	but we put it in for safety anyway
		#if GDISP_NEED_CLIP
			gdispSetClip(gh->x, gh->y, gh->width, gh->height);
		#endif
		_redraw(gh);
	}

	return TRUE;
}
Ejemplo n.º 18
0
Archivo: gwin.c Proyecto: bunnie/uGFX
	static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t width, coord_t height) {
		gh->x = x; gh->y = y;
		gh->width = width; gh->height = height;
		if (gh->x < 0) { gh->width += gh->x; gh->x = 0; }
		if (gh->y < 0) { gh->height += gh->y; gh->y = 0; }
		if (gh->x > gdispGetWidth()-MIN_WIN_WIDTH)		gh->x = gdispGetWidth()-MIN_WIN_WIDTH;
		if (gh->y > gdispGetHeight()-MIN_WIN_HEIGHT)	gh->y = gdispGetHeight()-MIN_WIN_HEIGHT;
		if (gh->width < MIN_WIN_WIDTH) { gh->width = MIN_WIN_WIDTH; }
		if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; }
		if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x;
		if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y;

		// Redraw the window
		if ((gh->flags & GWIN_FLG_VISIBLE)) {
			if (gh->vmt->Redraw) {
				#if GDISP_NEED_CLIP
					gdispSetClip(gh->x, gh->y, gh->width, gh->height);
				#endif
				gh->vmt->Redraw(gh);
			}
		}
	}
Ejemplo n.º 19
0
static msg_t notepadThread(void *param) {

  GEventMouse		*pem;
  GEventGWinButton	*peb;
  GHandle			ghc;

  (void)param;

  /* Get the display dimensions */
  swidth = gdispGetWidth();
  sheight = gdispGetHeight();

  font = gdispOpenFont("UI2");

  /* Initialize the mouse */
  geventListenerInit(&gl);
  ginputGetMouse(0);

  initButtons();

  /* Configure the GIF decoder with the toolbar Icon images */
  gdispImageSetMemoryReader(&toolbarImageFilmstrip, toolbarIcons);
  gdispImageOpen(&toolbarImageFilmstrip);

  /* Set clip to the entire screen */
  gdispSetClip(0, 0, swidth, sheight);

  /* Clear the screen with the window background
   * Also, draw the title bars */
  gdispClear(nCurColorScheme.winBgColor);
  gdispDrawBox(0, 0, swidth, sheight, nCurColorScheme.titleBarColor);
  gdispFillArea(0, 0, swidth, NPAD_TITLEBAR_HEIGHT, nCurColorScheme.titleBarColor);
  gdispDrawStringBox(NPAD_TITLETEXT_START_X,
                     NPAD_TITLETEXT_START_Y,
                     swidth,
                     NPAD_TITLEBAR_HEIGHT,
                     NPAD_TITLETEXT_STR,
                     font,
                     nCurColorScheme.titleTextColor,
                     justifyLeft);

  /* Create the drawing window, draw its border */
  gdispDrawBox(NPAD_DRAWING_AREA_START_X - 1,
               NPAD_DRAWING_AREA_START_Y - 1,
  			   NPAD_DRAWING_AREA_WIDTH + 2,
  			   NPAD_DRAWING_AREA_HEIGHT + 2,
  			   nCurColorScheme.drawingWinBorder);

  nDrawingArea = gwinCreateWindow(NULL,
								  NPAD_DRAWING_AREA_START_X,
								  NPAD_DRAWING_AREA_START_Y,
								  NPAD_DRAWING_AREA_WIDTH,
								  NPAD_DRAWING_AREA_HEIGHT);

  /* Create the bottom status bar console */
  ghc = gwinCreateConsole(NULL,
                          NPAD_STATUSBAR_START_X,
						  NPAD_STATUSBAR_START_Y,
                          NPAD_STATUSBAR_WIDTH,
                          NPAD_STATUSBAR_HEIGHT,
                          font);

  gdispImageDraw(&toolbarImageFilmstrip,
                 NPAD_STATUSBAR_ICON_START_X,
                 NPAD_STATUSBAR_ICON_START_Y,
                 NPAD_ICON_WIDTH,
                 NPAD_ICON_HEIGHT,
                 NPAD_ICON_START(12),
                 0);

  gwinSetBgColor(ghc, nCurColorScheme.winBgColor);
  gwinSetColor(ghc, Black);

  gstatusConsole = gwinGetConsoleStream(ghc);

  /* draw the buttons */
  gwinSetColor(nDrawingArea, Black);
  gwinSetBgColor(nDrawingArea, White);

  gwinClear(nDrawingArea);
  gwinClear(ghc);

  drawButtons();
  drawVButtons();

  chprintf(gstatusConsole, "Welcome to ChibiOS/GFX Notepad demo.");

  ncoreSpawnDrawThread(nDrawingArea, gstatusConsole);

  while(TRUE) {
	  pem = (GEventMouse *) geventEventWait(&gl, TIME_INFINITE);

	  /* button pressed... */
	  if (pem->type == GEVENT_GWIN_BUTTON) {
		peb = (GEventGWinButton *)pem;

		if (peb->button == H(btnNew)) {
		  // Reset all the settings
		  selColorIndex = 0;
		  selPenWidth = 0;
		  ncoreSetMode(NCORE_MODE_DRAW);

		  gwinSetColor(nDrawingArea, Black);
		  gwinSetBgColor(nDrawingArea, White);

		  // Refresh the buttons
		  drawButtons();
		  drawVButtons();

		  gwinClear(nDrawingArea);
		  chprintf(gstatusConsole, "\nScreen Cleared.");
		}
		else if (peb->button == H(btnOpen)) {
		  chprintf(gstatusConsole, "\nFile Open not implemented.");
		}
		else if (peb->button == H(btnSave)) {
		  chprintf(gstatusConsole, "\nFile Save not implemented.");
		}
		else if (peb->button == H(btnPencil)) {
		  ncoreSetMode(NCORE_MODE_DRAW);
		  drawVButtons();
		  chprintf(gstatusConsole, "\nPencil Tool Selected.");
		}
		else if (peb->button == H(btnEraser)) {
		  ncoreSetMode(NCORE_MODE_ERASE);
		  drawVButtons();
		  chprintf(gstatusConsole, "\nEraser Tool Selected.");
		}
		else if (peb->button == H(btnFill)) {
		  ncoreSetMode(NCORE_MODE_FILL);
		  drawVButtons();
		  chprintf(gstatusConsole, "\nFill Tool Selected.");
		}
		else if (peb->button == H(btnClose)) {
		  break;
		}
	  }
  }

  gwinDestroyWindow(ghc);
  // No need to destroy the buttons as they are statically allocated
  gdispCloseFont(font);
  ncoreTerminateDrawThread();
  gdispImageClose(&toolbarImageFilmstrip);

  return 0;
}
Ejemplo n.º 20
0
bool_t ginputCalibrateMouse(uint16_t instance) {
	#if !GINPUT_MOUSE_NEED_CALIBRATION
		(void) instance;
		
		return FALSE;
	#else

		const coord_t height  =  gdispGetHeight();
		const coord_t width  =  gdispGetWidth();
		const MousePoint cross[]  =  {{(width / 4), (height / 4)},
										{(width - (width / 4)) , (height / 4)},
										{(width - (width / 4)) , (height - (height / 4))},
										{(width / 2), (height / 2)}}; /* Check point */
		MousePoint points[GINPUT_MOUSE_CALIBRATION_POINTS];
		const MousePoint	*pc;
		MousePoint *pt;
		int32_t px, py;
		unsigned i, j;
		font_t	font1, font2;
		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
			unsigned	err;
		#endif

		if (instance || (MouseConfig.flags & FLG_IN_CAL))
			return FALSE;

		font1 = gdispOpenFont(GINPUT_MOUSE_CALIBRATION_FONT);
		font2 = gdispOpenFont(GINPUT_MOUSE_CALIBRATION_FONT2);

		MouseConfig.flags |= FLG_IN_CAL;
		gtimerStop(&MouseTimer);
		MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED);

		#if GDISP_NEED_CONTROL
			gdispSetOrientation(GDISP_ROTATE_0);
		#endif

		#if GDISP_NEED_CLIP
			gdispSetClip(0, 0, width, height);
		#endif

		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
			while(1) {
		#endif
				gdispClear(Blue);

				gdispFillStringBox(0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, font1,  White, Blue, justifyCenter);

				for(i = 0, pt = points, pc = cross; i < GINPUT_MOUSE_CALIBRATION_POINTS; i++, pt++, pc++) {
					_tsDrawCross(pc);

					do {

						/* Wait for the mouse to be pressed */
						while(get_raw_reading(&MouseConfig.t), !(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT))
							chThdSleepMilliseconds(20);

						/* Average all the samples while the mouse is down */
						for(px = py = 0, j = 0;
								chThdSleepMilliseconds(20),			/* Settling time between readings */
								get_raw_reading(&MouseConfig.t),
								(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT);
								j++) {
							px += MouseConfig.t.x;
							py += MouseConfig.t.y;
						}

					} while(!j);

					pt->x = px / j;
					pt->y = py / j;

					_tsClearCross(pc);

					if (i >= 1 && pt->x == (pt-1)->x && pt->y == (pt-1)->y) {
						gdispFillStringBox(0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_SAME_TEXT, font2,  Red, Yellow, justifyCenter);
						chThdSleepMilliseconds(5000);
						gdispFillArea(0, 35, width, 40, Blue);
					}

				}

				/* Apply 3 point calibration algorithm */
				_tsDo3PointCalibration(cross, points, &MouseConfig.caldata);

				 /* Verification of correctness of calibration (optional) :
				 *  See if the 4th point (Middle of the screen) coincides with the calibrated
				 *  result. If point is within +/- Squareroot(ERROR) pixel margin, then successful calibration
				 *  Else, start from the beginning.
				 */
		#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
				/* Transform the co-ordinates */
				MouseConfig.t.x = points[3].x;
				MouseConfig.t.y = points[3].y;
				_tsTransform(&MouseConfig.t, &MouseConfig.caldata);

				/* Calculate the delta */
				err = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +
					(MouseConfig.t.y - cross[3].y) * (MouseConfig.t.y - cross[3].y);

				if (err <= GINPUT_MOUSE_MAX_CALIBRATION_ERROR * GINPUT_MOUSE_MAX_CALIBRATION_ERROR)
					break;

				gdispFillStringBox(0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_ERROR_TEXT, font2,  Red, Yellow, justifyCenter);
				chThdSleepMilliseconds(5000);
			}
		#endif

		// Restart everything
		gdispCloseFont(font1);
		gdispCloseFont(font2);
		MouseConfig.flags |= FLG_CAL_OK;
		MouseConfig.last_buttons = 0;
		get_calibrated_reading(&MouseConfig.t);
		MouseConfig.flags &= ~FLG_IN_CAL;
		if ((MouseConfig.flags & FLG_INIT_DONE))
			gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
		
		// Save the calibration data (if possible)
		if (MouseConfig.fnsavecal) {
			MouseConfig.fnsavecal(instance, (const uint8_t *)&MouseConfig.caldata, sizeof(MouseConfig.caldata));
			MouseConfig.flags |= FLG_CAL_SAVED;
		}
	
		return TRUE;
	#endif
}
Ejemplo n.º 21
0
/* Core thread */
static msg_t ncoreDrawThread(void *msg) {

  GEventMouse ev, evPrev;
  coord_t dx, dy;

  int state = 0, dist;

  (void)msg;

  ginputGetMouseStatus(0, &evPrev);

  while (1) {

	// Exit signal received? If yes, terminate.
	if (chThdShouldTerminate())
	  return 0;

	ginputGetMouseStatus(0, &ev);
	switch(state) {
	  case 0:	if (ev.meta == GMETA_MOUSE_DOWN) {
				  state = 1;
				  if (nMode == NCORE_MODE_FILL && PEN_IN_DRAWING_AREA(ev)) {
					// Set bgcolor to current color, clear the display.
					ncoreDrawingArea->bgcolor = ncoreDrawingArea->color;
					gwinClear(ncoreDrawingArea);
				  }
				}
				else
				  chThdYield();
				break;


	  case 1:   if (ev.meta == GMETA_MOUSE_UP) {
				  state = 0;
				  //chprintf(nStatusConsole, "\nPen Up: (%d, %d)", ev.x, ev.y);
				  break;
				}

				dx = abs(ev.x - evPrev.x);
				dy = abs(ev.y - evPrev.y);

				dist = dx * dx + dy * dy;

				if (dist > 0)
				{
				   gdispSetClip(ncoreDrawingArea->x,
				                ncoreDrawingArea->y,
				                ncoreDrawingArea->width,
				                ncoreDrawingArea->height);

				   if (PEN_IN_DRAWING_AREA(ev)){
					// Do Interpolation
					if (dist <= 2) {
					  draw_point(ev.x, ev.y);
					}
					else if (dist <= 5) {
					  // Line drawing does not give good results for this case.
					  // So draw two pixels directly
					  draw_point(ev.x, ev.y);
					  draw_point((ev.x + evPrev.x) / 2,	(ev.y + evPrev.y) / 2);
					}
					else if (dx * dx <= MAX_DX && dy * dy <= MAX_DY) {
					  draw_line(ev.x, ev.y,	evPrev.x, evPrev.y);
					}
				  }

				  //chprintf(nStatusConsole, "\nPen Down: (%d, %d)", ev.x, ev.y);
				}
				break;
	}
	evPrev = ev;
  }

  return 0;
}