hackathon-dev #1
@ -2,7 +2,7 @@ BUILDUTILS=../buildutils
 | 
			
		||||
RESOURCES=../resources
 | 
			
		||||
SPLASHSCREEN=splash-vmwcblk.png
 | 
			
		||||
 | 
			
		||||
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_upiwin_tmp.o ep_util.o \
 | 
			
		||||
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_upiwin_tmp.o ep_util.o \
 | 
			
		||||
     fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o fbprimitive.o \
 | 
			
		||||
     log.o gpio.o msg_queue.o time_func.o config.o splash.o
 | 
			
		||||
LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										170
									
								
								src/dc_screen.c
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								src/dc_screen.c
									
									
									
									
									
								
							@ -1,5 +1,175 @@
 | 
			
		||||
#include "fbinit.h"
 | 
			
		||||
#include "devctxt.h"
 | 
			
		||||
#include "dc_screen.h"
 | 
			
		||||
 | 
			
		||||
inline static PUINT16 loc_from_coords(PSCREENPRIVDATA priv, INT32 x, INT32 y)
 | 
			
		||||
{
 | 
			
		||||
  return priv->pdata + (y * priv->pix_per_row) + x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline static UINT16 native_from_COLORREF(COLORREF cr)
 | 
			
		||||
{
 | 
			
		||||
  return (UINT16)(((cr << 8) & 0xF800) | ((cr >> 5) & 0x7E0) | ((cr >> 19) & 0x1F));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline static COLORREF COLORREF_from_native(UINT16 cr)
 | 
			
		||||
{
 | 
			
		||||
  UINT32 tmp = cr;
 | 
			
		||||
  return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen)
 | 
			
		||||
{
 | 
			
		||||
  switch (op)
 | 
			
		||||
  {
 | 
			
		||||
    case R2_BLACK:
 | 
			
		||||
	  return 0;
 | 
			
		||||
	case R2_NOTMERGEPEN:
 | 
			
		||||
	  return ~(disp | pen);
 | 
			
		||||
	case R2_MASKNOTPEN:
 | 
			
		||||
	  return disp & (~pen);
 | 
			
		||||
	case R2_NOTCOPYPEN:
 | 
			
		||||
	  return ~pen;
 | 
			
		||||
	case R2_MASKPENNOT;
 | 
			
		||||
	  return (~disp) & pen;
 | 
			
		||||
	case R2_NOT:
 | 
			
		||||
	  return ~disp;
 | 
			
		||||
    case R2_XORPEN:
 | 
			
		||||
	  return disp ^ pen;
 | 
			
		||||
	case R2_NOTMASKPEN:
 | 
			
		||||
	  return ~(disp & pen);
 | 
			
		||||
	case R2_MASKPEN:
 | 
			
		||||
	  return disp & pen;
 | 
			
		||||
	case R2_NOTXORPEN:
 | 
			
		||||
	  return ~(disp ^ pen);
 | 
			
		||||
    case R2_NOP:
 | 
			
		||||
	  return disp;
 | 
			
		||||
	case R2_MERGENOTPEN:
 | 
			
		||||
	  return disp | (~pen);
 | 
			
		||||
    case R2_COPYPEN:
 | 
			
		||||
	  return pen;
 | 
			
		||||
	case R2_MERGEPENNOT:
 | 
			
		||||
	  return (~disp) | pen;
 | 
			
		||||
	case R2_MERGEPEN:
 | 
			
		||||
	  return disp | pen;
 | 
			
		||||
	case R2_WHITE:
 | 
			
		||||
	  return (UINT16)(-1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op)
 | 
			
		||||
{
 | 
			
		||||
  PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
 | 
			
		||||
  UINT16 pencolor = native_from_COLORREF(color);
 | 
			
		||||
  PUINT16 loc = loc_from_coords(priv, x, y);
 | 
			
		||||
  UINT16 screen = *loc;
 | 
			
		||||
  *loc = apply_rop2(op, screen, pencolor);
 | 
			
		||||
  return COLORREF_from_native(screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op)
 | 
			
		||||
{
 | 
			
		||||
  PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
 | 
			
		||||
  UINT16 pencolor = native_from_COLORREF(color);
 | 
			
		||||
  INT32 dx = x2 - x1;
 | 
			
		||||
  INT32 dy = y2 - y1;
 | 
			
		||||
  INT32 tmp;
 | 
			
		||||
  PUINT16 loc;
 | 
			
		||||
  
 | 
			
		||||
  if (ABS(dx) < ABS(dy))
 | 
			
		||||
  {
 | 
			
		||||
    if (y1 > y2)
 | 
			
		||||
	{
 | 
			
		||||
	  tmp = x1;
 | 
			
		||||
	  x1 = x2;
 | 
			
		||||
	  x2 = tmp;
 | 
			
		||||
	  tmp = y1;
 | 
			
		||||
	  y1 = y2;
 | 
			
		||||
	  y2 = tmp;
 | 
			
		||||
	  dx = -dx;
 | 
			
		||||
	  dy = -dy;
 | 
			
		||||
	}
 | 
			
		||||
	loc = loc_from_coords(priv, x1, y1);
 | 
			
		||||
	tmp = x1;
 | 
			
		||||
	x1 << 16;
 | 
			
		||||
	dx = (dx << 16) / dy;
 | 
			
		||||
	while (y1 <= y2)
 | 
			
		||||
	{
 | 
			
		||||
	  *loc = apply_rop2(op, *loc, pencolor);
 | 
			
		||||
	  x1 += dx;
 | 
			
		||||
	  ++y1;
 | 
			
		||||
	  loc += priv->pix_per_row;
 | 
			
		||||
	  if (tmp != (x1 >> 16))
 | 
			
		||||
	  {
 | 
			
		||||
	    loc += ((x1 >> 16) - tmp);
 | 
			
		||||
		tmp = x1 >> 16;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (x1 > x2)
 | 
			
		||||
	{
 | 
			
		||||
	  tmp = x1;
 | 
			
		||||
	  x1 = x2;
 | 
			
		||||
	  x2 = tmp;
 | 
			
		||||
	  tmp = y1;
 | 
			
		||||
	  y1 = y2;
 | 
			
		||||
	  y2 = tmp;
 | 
			
		||||
	  dx = -dx;
 | 
			
		||||
	  dy = -dy;
 | 
			
		||||
	}
 | 
			
		||||
	loc = loc_from_coords(priv, x1, y1);
 | 
			
		||||
	tmp = y1;
 | 
			
		||||
    y1 <<= 16;
 | 
			
		||||
    dy = dx ? (dy << 16) / dx : 0;
 | 
			
		||||
	while (x1 <= x2)
 | 
			
		||||
	{
 | 
			
		||||
	  *loc = apply_rop2(op, *loc, pencolor);
 | 
			
		||||
	  y1 += dy;
 | 
			
		||||
	  ++x1;
 | 
			
		||||
	  ++loc;
 | 
			
		||||
	  if (tmp != (y1 >> 16))
 | 
			
		||||
	  {
 | 
			
		||||
	    loc += ((((y1 >> 16) - tmp) * priv->pix_per_row);
 | 
			
		||||
	    tmp = y1 >> 16;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const DCFUNTABLE screen_funtable = {
 | 
			
		||||
  screen_set_pixel,
 | 
			
		||||
  screen_line
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void screen_context_destroy(PVOID obj)
 | 
			
		||||
{
 | 
			
		||||
  PDCTXT pdctxt = (PDCTXT)obj;
 | 
			
		||||
  _DC_FinalizeCommon(pdctxt);
 | 
			
		||||
  free(pdctxt->privdata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PDCTXT DC_CreateScreenContext(void)
 | 
			
		||||
{
 | 
			
		||||
  PDCTXT rc;
 | 
			
		||||
  PSCREENPRIVDATA priv;
 | 
			
		||||
  
 | 
			
		||||
  priv = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA));
 | 
			
		||||
  if (!priv)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  priv->pix_per_row = Fb_Info->width;
 | 
			
		||||
  priv->pdata = Pb_Ptr;
 | 
			
		||||
  
 | 
			
		||||
  rc = _DC_Allocate(&screen_funtable, priv);
 | 
			
		||||
  if (rc)
 | 
			
		||||
  {
 | 
			
		||||
    rc->hdr.dtor = screen_context_destroy;
 | 
			
		||||
	rc->cliprect.left = rc->cliprect.top = 0;
 | 
			
		||||
	rc->cliprect.right = Fb_Info->width - 1;
 | 
			
		||||
	rc->cliprect.bottom = Fb_Info->height - 1;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
    free(priv);
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,4 +9,6 @@ typedef struct tagSCREENPRIVDATA {
 | 
			
		||||
	UINT16 *pdata;
 | 
			
		||||
} SCREENPRIVDATA, *PSCREENPRIVDATA;
 | 
			
		||||
 | 
			
		||||
extern PDCTXT DC_CreateScreenContext(void);
 | 
			
		||||
 | 
			
		||||
#endif /* __DC_SCREEN_H_INCLUDED */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								src/devctxt.c
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								src/devctxt.c
									
									
									
									
									
								
							@ -1,9 +1,171 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "gfxtype.h"
 | 
			
		||||
#include "gfxobj.h"
 | 
			
		||||
#include "devctxt.h"
 | 
			
		||||
 | 
			
		||||
inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
 | 
			
		||||
{
 | 
			
		||||
  BYTE rc = 0;
 | 
			
		||||
  if (y < ymin)
 | 
			
		||||
    rc |= 0x8;
 | 
			
		||||
  else if (y >= ymax)
 | 
			
		||||
    rc |= 0x4;
 | 
			
		||||
  if (x < xmin)
 | 
			
		||||
    rc |= 0x1;
 | 
			
		||||
  else if (x >= xmax)
 | 
			
		||||
    rc |= 0x2;
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
 | 
			
		||||
{
 | 
			
		||||
  BYTE outcode1, outcode2, tmpb;
 | 
			
		||||
  INT32 tmp;
 | 
			
		||||
  
 | 
			
		||||
  /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */
 | 
			
		||||
  for (;;)
 | 
			
		||||
  {
 | 
			
		||||
    outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax);
 | 
			
		||||
	outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax);
 | 
			
		||||
	if ((outcode1 & outcode2) != 0)
 | 
			
		||||
	  return FALSE; /* trivial rejection */
 | 
			
		||||
	else if ((outcode1 == 0) && (outcode2 == 0))
 | 
			
		||||
	  break; /* trivial acceptance */
 | 
			
		||||
	if (outcode1 == 0)
 | 
			
		||||
	{
 | 
			
		||||
	  tmp = x1;
 | 
			
		||||
	  x1 = x2;
 | 
			
		||||
	  x2 = tmp;
 | 
			
		||||
	  tmp = y1;
 | 
			
		||||
	  y1 = y2;
 | 
			
		||||
	  y2 = tmp;
 | 
			
		||||
	  tmpb = outcode1;
 | 
			
		||||
	  outcode1 = outcode2;
 | 
			
		||||
	  outcode2 = tmp;
 | 
			
		||||
	}
 | 
			
		||||
	if (outcode1 & 0x8)
 | 
			
		||||
	{
 | 
			
		||||
	  x1 += (x2 - x1) * (ymin - y1) / (y2 - y1);
 | 
			
		||||
	  y1 = ymin;
 | 
			
		||||
	}
 | 
			
		||||
	else if (outcode1 & 0x4)
 | 
			
		||||
	{
 | 
			
		||||
	  x1 += (x2 - x1) * (ymax - y1) / (y2 - y1);
 | 
			
		||||
	  y1 = ymax;
 | 
			
		||||
	}
 | 
			
		||||
	else if (outcode1 & 0x2)
 | 
			
		||||
	{
 | 
			
		||||
	  y1 += (y2 - y1) * (xmax - x1) / (x2 - x1);
 | 
			
		||||
	  x1 = xmax;
 | 
			
		||||
	}
 | 
			
		||||
	else if (outcode1 & 0x1)
 | 
			
		||||
	{
 | 
			
		||||
	  y1 += (y2 - y1) * (xmin - x1) / (x2 - x1);
 | 
			
		||||
	  x1 = xmin;
 | 
			
		||||
	}
 | 
			
		||||
  }
 | 
			
		||||
  output[0] = x1;
 | 
			
		||||
  output[1] = y1;
 | 
			
		||||
  output[2] = x2;
 | 
			
		||||
  output[3] = y2;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
 | 
			
		||||
{
 | 
			
		||||
  INT32 buffer[4];
 | 
			
		||||
  if (line_clip(buffer, x1 << 16, y1 << 16, x2 << 16, y2 << 16, pdctxt->cliprect.left << 16, pdctxt->cliprect.top << 16,
 | 
			
		||||
				pdctxt->cliprect.right << 16, pdctxt->cliprect.bottom << 16))
 | 
			
		||||
    return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> 16, buffer[1] >> 16, buffer[2] >> 16, buffer[3] >> 16, pdctxt->color, pdctxt->rop2);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata)
 | 
			
		||||
{
 | 
			
		||||
  PDCTXT rc = (PDCTXT)malloc(sizeof(DCTXT));
 | 
			
		||||
  if (!rc)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  memset(rc, 0, sizeof(DCTXT));
 | 
			
		||||
  _Go_init(&(rc->hdr), DCTXT_SIG_WORD, sizeof(DCTXT));
 | 
			
		||||
  rc->funcs = funcs;
 | 
			
		||||
  rc->privdata = privdata;
 | 
			
		||||
  rc->rop2 = R2_COPYPEN;
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _DC_FinalizeCommon(PDCTXT pdctxt)
 | 
			
		||||
{
 | 
			
		||||
  /* nothing here yet */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color)
 | 
			
		||||
{
 | 
			
		||||
  if (!G_coords_in_rect(&(pdctxt->cliprect), x, y))
 | 
			
		||||
	return (COLORREF)(-1);
 | 
			
		||||
  return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, xm, y, colorref, pdctxt->rop2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y)
 | 
			
		||||
{
 | 
			
		||||
  BOOL rc = internal_line(pdctxt, pdctxt->pos.x, pdctxt->pos.y, x, y);
 | 
			
		||||
  if (rc)
 | 
			
		||||
  {
 | 
			
		||||
    pdctxt->pos.x = x;
 | 
			
		||||
	pdctxt->pos.y = y;
 | 
			
		||||
  }
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt)
 | 
			
		||||
{
 | 
			
		||||
  if (oldpt)
 | 
			
		||||
    memcpy(oldpt, &(pdctxt->pos), sizeof(POINT));
 | 
			
		||||
  pdctxt->pos.x = x;
 | 
			
		||||
  pdctxt->pos.y = y;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom)
 | 
			
		||||
{
 | 
			
		||||
  internal_line(pdctxt, left, top, right - 1, top);
 | 
			
		||||
  internal_line(pdctxt, left, top + 1, left, bottom - 2);
 | 
			
		||||
  internal_line(pdctxt, right - 1, top + 1, right - 1, bottom - 2);
 | 
			
		||||
  internal_line(pdctxt, left, bottom - 1, right - 1, bottom - 1);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UINT32 DC_GetROP2(PDCTXT pdctxt)
 | 
			
		||||
{
 | 
			
		||||
  return pdctxt->rop2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop)
 | 
			
		||||
{
 | 
			
		||||
  UINT32 rc = pdctxt->rop2;
 | 
			
		||||
  pdctxt->rop2 = rop;
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
COLORREF DC_GetTextColor(PDCTXT pdctxt)
 | 
			
		||||
{
 | 
			
		||||
  return pdctxt->color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr)
 | 
			
		||||
{
 | 
			
		||||
  COLORREF rc = pdctxt->color;
 | 
			
		||||
  pdctxt->color = cr;
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect)
 | 
			
		||||
{
 | 
			
		||||
  memcpy(prect, &(pdctxt->cliprect), sizeof(RECT));
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect)
 | 
			
		||||
{
 | 
			
		||||
  memcpy(&(pdctxt->cliprect), prect, sizeof(RECT));
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,11 @@
 | 
			
		||||
#define R2_WHITE        16
 | 
			
		||||
 | 
			
		||||
typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op);
 | 
			
		||||
typedef BOOL (*DCtx_Line)(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op);
 | 
			
		||||
 | 
			
		||||
typedef struct tagDCFUNTABLE {
 | 
			
		||||
  DCtx_SetPixel set_pixel;   /* sets a single pixel on the display */
 | 
			
		||||
  DCtx_Line line;            /* draws a line on the display */
 | 
			
		||||
} DCFUNTABLE;
 | 
			
		||||
 | 
			
		||||
typedef const DCFUNTABLE *PDCFUNTABLE;
 | 
			
		||||
@ -43,6 +45,21 @@ typedef struct tagDCTXT {
 | 
			
		||||
  COLORREF color;     /* current drawing color (XXX replace with pens later) */
 | 
			
		||||
} DCTXT, *PDCTXT;
 | 
			
		||||
 | 
			
		||||
extern PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata);
 | 
			
		||||
extern void _DC_FinalizeCommon(PDCTXT pdctxt);
 | 
			
		||||
 | 
			
		||||
extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color);
 | 
			
		||||
extern BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y);
 | 
			
		||||
extern BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt);
 | 
			
		||||
extern BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom);
 | 
			
		||||
extern UINT32 DC_GetROP2(PDCTXT pdctxt);
 | 
			
		||||
extern UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop);
 | 
			
		||||
extern COLORREF DC_GetTextColor(PDCTXT pdctxt);
 | 
			
		||||
extern COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr);
 | 
			
		||||
extern BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect);
 | 
			
		||||
extern BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect);
 | 
			
		||||
 | 
			
		||||
#define DC_addref(pdctxt)   Go_addref(&(pdctxt->hdr))
 | 
			
		||||
#define DC_release(pdctxt)  Go_release(&(pdctxt->hdr))
 | 
			
		||||
 | 
			
		||||
#endif /* __DEVCTXT_H_INCLUDED */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										253
									
								
								src/ep_devctxt.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										253
									
								
								src/ep_devctxt.c
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,253 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define PY_SSIZE_T_CLEAN
 | 
			
		||||
#include <Python.h>
 | 
			
		||||
#include "wintype.h"
 | 
			
		||||
#include "scode.h"
 | 
			
		||||
#include "devctxt.h"
 | 
			
		||||
#include "dc_screen.h"
 | 
			
		||||
#include "ep_init.h"
 | 
			
		||||
 | 
			
		||||
typedef struct tagDevCtxtObject {
 | 
			
		||||
  PyObject_HEAD
 | 
			
		||||
  PDCTXT pdctxt;
 | 
			
		||||
} DevCtxtObject;
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  INT32 x, y;
 | 
			
		||||
  COLORREF color, rc;
 | 
			
		||||
  
 | 
			
		||||
  if (!PyArg_ParseTuple(args, "iik", &x, &y, &color))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  rc = DC_SetPixel(self->pdctxt, x, y, color);
 | 
			
		||||
  return PyLong_FromUnsignedLong(rc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_line_to(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  INT32 x, y;
 | 
			
		||||
  BOOL rc;
 | 
			
		||||
 | 
			
		||||
  if (!PyArg_ParseTuple(args, "ii", &x, &y))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  rc = DC_LineTo(self->pdctxt, x, y);
 | 
			
		||||
  return PyBool_FromLong(rc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_move_to(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  INT32 x, y;
 | 
			
		||||
  BOOL rc;
 | 
			
		||||
 | 
			
		||||
  if (!PyArg_ParseTuple(args, "ii", &x, &y))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  rc = DC_MoveTo(self->pdctxt, x, y, NULL);
 | 
			
		||||
  return PyBool_FromLong(rc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  INT32 left, top, right, bottom;
 | 
			
		||||
  BOOL rc;
 | 
			
		||||
  
 | 
			
		||||
  if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  rc = DC_Rectangle(self->pdctxt, left, top, right, bottom);
 | 
			
		||||
  return PyBool_FromLong(rc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  RECT rect;
 | 
			
		||||
  
 | 
			
		||||
  if (!PyArg_ParseTuple(args, ""))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  DC_GetClipRect(self->pdctxt, &rect);
 | 
			
		||||
  return Py_BuildValue("(i,i,i,i)", rect.left, rect.top, rect.right, rect.bottom);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
  RECT rect;
 | 
			
		||||
  BOOL rc;
 | 
			
		||||
  
 | 
			
		||||
  if (!PyArg_ParseTuple(args, "iiii", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  rc = DC_SetClipRect(self->pdctxt, &rect);
 | 
			
		||||
  return PyBool_FromLong(rc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyMethodDef DevCtxtMethods[] = {
 | 
			
		||||
  {"set_pixel", (PyCFunction)devctxt_set_pixel, METH_VARARGS,
 | 
			
		||||
   "Sets a single pixel on the display."},
 | 
			
		||||
  {"line_to", (PyCFunction)devctxt_line_to, METH_VARARGS,
 | 
			
		||||
   "Draws a line from the current position to the specified location."},
 | 
			
		||||
  {"move_to", (PyCFunction)devctxt_move_to, METH_VARARGS,
 | 
			
		||||
   "Draws a line from the current position to the specified location."},
 | 
			
		||||
  {"rectangle", (PyCFunction)devctxt_rectangle, METH_VARARGS,
 | 
			
		||||
   "Draws a rectangle."},
 | 
			
		||||
  {"get_clip_rect", (PyCFunction)devctxt_get_clip_rect, METH_VARARGS,
 | 
			
		||||
   "Returns the current clipping rectangle of the device context."},
 | 
			
		||||
  {"set_clip_rect", (PyCFunction)devctxt_set_clip_rect, METH_VARARGS,
 | 
			
		||||
   "Sets the current clipping rectangle of the device context."},
 | 
			
		||||
  {NULL, NULL, 0, NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure)
 | 
			
		||||
{
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  return PyLong_FromUnsignedLong(DC_GetROP2(self->pdctxt));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int devctxt_set_rop2(DevCtxtObject *self, PyObject *value, void *closure)
 | 
			
		||||
{
 | 
			
		||||
  UINT32 v;
 | 
			
		||||
  
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  if (value == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  v = PyLong_AsUnsignedLong(value);
 | 
			
		||||
  if (PyErr_Occurred())
 | 
			
		||||
    return -1;
 | 
			
		||||
  DC_SetROP2(self->pdctxt, v);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *devctxt_get_text_color(DevCtxtObject *self, void *closure)
 | 
			
		||||
{
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  return PyLong_FromUnsignedLong(DC_GetTextColor(self->pdctxt));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int devctxt_set_text_color(DevCtxtObject *self, PyObject *value, void *closure)
 | 
			
		||||
{
 | 
			
		||||
  COLORREF v;
 | 
			
		||||
  
 | 
			
		||||
  if (!(self->pdctxt))
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_RuntimeError, "bad device context");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  if (value == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  v = PyLong_AsUnsignedLong(value);
 | 
			
		||||
  if (PyErr_Occurred())
 | 
			
		||||
    return -1;
 | 
			
		||||
  DC_SetTextColor(self->pdctxt, v);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyGetSetDef DevCtxtProperties[] = {
 | 
			
		||||
  {"rop2", (getter)devctxt_get_rop2, (setter)devctxt_set_rop2,
 | 
			
		||||
   "Current raster operation", NULL},
 | 
			
		||||
  {"text_color", (getter)devctxt_get_text_color, (setter)devctxt_set_text_color,
 | 
			
		||||
   "Current text color", NULL},
 | 
			
		||||
  {NULL, NULL, NULL, NULL, NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void devctxt_dealloc(DevCtxtObject *self)
 | 
			
		||||
{
 | 
			
		||||
  if (self->pdctxt)
 | 
			
		||||
    DC_release(self->pdctxt);
 | 
			
		||||
  Py_TYPE(self)->tp_free((PyObject *)self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds)
 | 
			
		||||
{
 | 
			
		||||
  static char *kwlist[] = { "type" }
 | 
			
		||||
  char *type;
 | 
			
		||||
  
 | 
			
		||||
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type))
 | 
			
		||||
    return -1;
 | 
			
		||||
  if (stricmp(type, "screen") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    self->pdctxt = DC_CreateScreenContext();
 | 
			
		||||
	if (!(self->pdctxt))
 | 
			
		||||
    {
 | 
			
		||||
	  PyErr_SetString(PyExc_RuntimeError, "unable to create screen context");
 | 
			
		||||
	  return -1
 | 
			
		||||
	}
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type);
 | 
			
		||||
	return -1;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyTypeObject DevCtxtType = {
 | 
			
		||||
  PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
  .tp_name = "upiwin.DevCtxt",
 | 
			
		||||
  .tp_doc = "Device context object",
 | 
			
		||||
  .tp_basicsize = sizeof(DevCtxtObject),
 | 
			
		||||
  .tp_itemsize = 0,
 | 
			
		||||
  .tp_flags = Py_TPFLAGS_DEFAULT,
 | 
			
		||||
  .tp_new = PyType_GenericNew,
 | 
			
		||||
  .tp_init = (initproc)devctxt_init,
 | 
			
		||||
  .tp_dealloc = (destructor)devctxt_dealloc,
 | 
			
		||||
  .tp_methods = DevCtxtMethods,
 | 
			
		||||
  .tp_getset = DevCtxtProperties,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HRESULT Epython_register_devctxt(PyObject *module)
 | 
			
		||||
{
 | 
			
		||||
  if (PyType_Ready(&DevCtxtType) < 0)
 | 
			
		||||
	return E_FAIL;
 | 
			
		||||
  Py_INCREF(&DevCtxtType);
 | 
			
		||||
  if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    Py_DECREF(&DevCtxtType);
 | 
			
		||||
	return E_FAIL;
 | 
			
		||||
  }
 | 
			
		||||
  return S_OK;
 | 
			
		||||
}
 | 
			
		||||
@ -14,6 +14,8 @@ extern PyObject *UPIWIN_tmp_module;
 | 
			
		||||
extern PyObject *Epython_init_upiwin_module(void);
 | 
			
		||||
extern PyObject *Epython_init_upiwin_tmp_module(void);
 | 
			
		||||
 | 
			
		||||
extern HRESULT Epython_register_devctxt(PyObject *module);
 | 
			
		||||
 | 
			
		||||
extern HRESULT Epython_setup(void);
 | 
			
		||||
extern HRESULT Epython_run(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include "ep_init.h"
 | 
			
		||||
#include "ep_upiwin.h"
 | 
			
		||||
#include "ep_util.h"
 | 
			
		||||
#include "devctxt.h"
 | 
			
		||||
 | 
			
		||||
static PyMethodDef UPIWINMethods[] = {
 | 
			
		||||
  /* Backlight control functions */
 | 
			
		||||
@ -46,6 +47,23 @@ BEGIN_CONSTANT_TABLE(UPIWINConstants)
 | 
			
		||||
  CONSTANT_INT_MACRO(WM_TOUCHDOWN)
 | 
			
		||||
  CONSTANT_INT_MACRO(WM_TOUCHMOVE)
 | 
			
		||||
  CONSTANT_INT_MACRO(WM_TOUCHUP)
 | 
			
		||||
  /* Raster op constants */
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_BLACK)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOTMERGEPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MASKNOTPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOTCOPYPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MASKPENNOT)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOT)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_XORPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOTMASKPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MASKPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOTXORPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_NOP)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MERGENOTPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_COPYPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MERGEPENNOT)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_MERGEPEN)
 | 
			
		||||
  CONSTANT_INT_MACRO(R2_WHITE)
 | 
			
		||||
END_CONSTANT_TABLE
 | 
			
		||||
 | 
			
		||||
PyObject *Epython_init_upiwin_module(void)
 | 
			
		||||
@ -62,6 +80,12 @@ PyObject *Epython_init_upiwin_module(void)
 | 
			
		||||
	Py_DECREF(module);
 | 
			
		||||
	return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (FAILED(Epython_register_devctxt(module)))
 | 
			
		||||
  {
 | 
			
		||||
	Py_DECREF(module);
 | 
			
		||||
	return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* set up the module state */
 | 
			
		||||
  pstate = (PUPIWIN_STATE)PyModule_GetState(module);
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,15 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "gfxobj.h"
 | 
			
		||||
 | 
			
		||||
void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size)
 | 
			
		||||
{
 | 
			
		||||
  memset(obj, 0, sizeof(GFXOBJECT));
 | 
			
		||||
  obj->sig = sig;
 | 
			
		||||
  obj->size = size;
 | 
			
		||||
  obj->refcnt = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Go_unchain(PGFXOBJECT obj)
 | 
			
		||||
{
 | 
			
		||||
  if (!(obj->next || obj->prev))
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ typedef struct tagGFXOBJECT {
 | 
			
		||||
  struct tagGFXOBJECT *prev;
 | 
			
		||||
} GFXOBJECT, *PGFXOBJECT;
 | 
			
		||||
 | 
			
		||||
extern void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size);
 | 
			
		||||
extern void Go_unchain(PGFXOBJECT obj);
 | 
			
		||||
extern INT32 Go_addref(PGFXOBJECT obj);
 | 
			
		||||
extern INT32 Go_release(PGFXOBJECT obj);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user