From cc00d7a5efc7ca27ffde4afa1ef3aec9a084fd3a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 10:14:20 -0700 Subject: [PATCH 001/101] changed the splash screen and added a test to make sure we run as root --- src/splash.png => resources/splash-erbosoft.png | Bin resources/splash-vmwcblk.png | Bin 0 -> 8055 bytes src/Makefile | 8 ++++++-- src/config.c | 6 ++++++ 4 files changed, 12 insertions(+), 2 deletions(-) rename src/splash.png => resources/splash-erbosoft.png (100%) create mode 100755 resources/splash-vmwcblk.png diff --git a/src/splash.png b/resources/splash-erbosoft.png similarity index 100% rename from src/splash.png rename to resources/splash-erbosoft.png diff --git a/resources/splash-vmwcblk.png b/resources/splash-vmwcblk.png new file mode 100755 index 0000000000000000000000000000000000000000..1b33a4e17b5792f627d177d70d1ee9c7d9fa564b GIT binary patch literal 8055 zcmb_>1yGw^w=RVWZ7Eu$P@p)4VntHC4W+nCaCdi4XiI<=*WyqlxVwcEcPZ|aV#R_5 z3j|KS```KRckX;M=ggTi^S)~`&))0ZYpuQ4-p|_ks;VsWxru>V=D&vz4ubB@PaIEI3wJ7VjNZFoHSk0SSr57aa$Z zGJ-E*I`U7Yd0)ugt>{>a{0j7X(n3O`(5_v1Xw&+L#@><3;oiGLoT{oi^;#0$TRGf^ zX3wcM*M?hrhiDGzt&|4Kw(ks%h#plH3W@WVOu>osK2dy^0xTK4;!DljxoGVym|plY zPz*ti{!GyGP&%~jkg^)-f6RkVRJ!3F<{d1x8J9^aL5B2N|J*?&4+y(1exqT67$6Yt zzo>MP)fv>RRBPXiGkO07ze0VcKYf5`@tgp|yYoz*+GU9!z{z&% zSN#W1+M>h`uBdQTTx^ptoT0oI3}|iL$MkPc?x!0k3YtIQ7Ruh|D-iX2_oxq5FmdR` zu_Az11{iw-+AFIa?H6Z;m3+0IT?j3YuowmTdV?*UZ!=$>p5wiOyM-^kZQj97%0m}f zU3VNDZl=H9J3cT;FD&@LLrzKh!5YCsk_V5pBW6;t&@&Hd9S&aA?it-oMlIncrWuHPAf$egAMJB~o|xU5Jv&Y>2eb9bL`4 zB&6-+xdQwO8a4X1^(86!Wk&nj`Ifq=mS*{^jH&BUoGmX}_O3<<2zUo?yWdfTu<)KP zUm-@%*B*;6q`Pm5Z8bzam2{)I^YK=hU=bJRE)@>33C`P(cm5@D?%e+i`j^B)|8B-Y z*iQe@@XvaG|KR_w-hVRW-**0ey#Iy+|5LrcN93O!H(5H*)VC6DdXsFusqGLkNDEO= z!7J-tHRE)bB4=m{p2}idpYnR?KXX6jp&787A|Ji96c(1cnM?VITU*Y5Ce?+iq+_p} zks-R*)+UbGhzBiPqm22rIxP}>N*kxyjefdd<(`NIeLD(xlxZ zMwq6iz5ppJH!obW{(`d86N#s>q<&1pVu*KMO;*V&O6@v36w#s-M91H!Xd)OA_#&4u znl<8Xcl4qceG4s^OF(Qk{^rV=twJ2WJD{qM^mXcJm6a@~DDakZFF}RQKHiO5IuhJ; z@@42+(H}D7^Pd?Y4;!4RNxJ2)GR(eq(EWiTR&l(eg84Yt1fxNSkp(sc6IYA(fG;N| zs8i=ZYwvMws}fwJHpqq~!E7Nph38(^^_YPEA5Sg_ILt>$HOPXT1C*a4n+m^km#1)vJXY(I7A)Y4$D9`Z; zau3fzkmJSnuYEtiL87hZ_aS~^rBH$oDrE)r<(K29qBLiQ2jVBRDtHMFj!n?-s%d#+ zt!wkCwC!UbBSt*y$Cok{qkKZ+xggisSFufWO@;^gy>m5A`Dx*iJ$y<%e`I9t-9?AZ zKs*v4$qug~J?a1{ADYU%2+R*tvT zkkN8wLjT@e%JDHj6HL9^RQ)zZdcq>mn#>%NJuSiK|GSAZ<#9brF=9zkiC{=6k~uCa z)LZ)l8W-C?QNDXkEO~ktbGK1LE@7Zegg2|8&Z@0!(nXi{M+ z(J|+`$7_G;c`wa4ldb_hcCb~=)ER)!pmE)0@%G~-!GL-Cmz$Q7*@4vF=Q{GCDqhGU z4Q4A6AayFUJgm4lpHHxc{lLl5Fg~H*;>#<7fJJF1ZpQmTsS=*o0HwH%m6geBGn9}0 zx8R8bCfkYqi)-|k=U9?F2NIdMg%J9il>GLLLGMU_^9z>V3iizEDdmJKJ@S2P zZi>MnG&4h0HO;7wHvQWm!J(0Ijg2(ll z+_Md@T_BntW3!Q=Ji$u3w^vKmA_^Ko#{;b1Y=dkP;-Yc-=iM4cDnpsFYMP*i>+>6W zu4yZ0KkgT1J3cUVUA3ia#N7MRB1bo)%iNxhQ3@Zi1{03>_GF56r^+k0c!N^}xe2fj zIlD`SF-SglvvjgU*;Us0(N0ag9bA|&0w+}jUU&Ar^~V~4?r4Dt((g-vU*sb11%}Un z#8{tCRFJYK4zx+cG_Jl^{t|35QEa`-?-&E)8hqlVOWw@$a^ zqPtbBhK5UNx1IsL!EI^8c17ZzaWo8hjkO=d;qc744CZ=4clWBJv&z7ZsXtRv&prV& zVGNRI%AK-p!A(*3Rist&+2vVx{hWKNc*+xsDuxq1Brh+!8>$DjIF4P-V$sFhLd~)9 zd!<|vcg4!IzrNxx2#^70_PDq9fg>I~Qh>TYQ>p%BH9Y)27Cln_O~TX6nK|8G^&5_B1)P?2Pu0t~Zm| zA~RmM8>xiOOpZg)Zpem);+st=1lk0B;VQIDcNQQ4kj(>B@|7}l0eMCHj4W(Rxqiv# zRquT+=2>&+6d@0C+RN|N73rL7|IoKuiOoYwX9}=qT>!K7sZ}9Y^k5D<2U4$p*l(`$ z$su;Uh|(4#CoeGh=JwhY-u1wm(GD%>G_ve~zTW`gosNFD?$)iKADvkeLkjdVEcsPA z3OU?d+o9>oY;0bAPsp%t5G-In@pbYb3*^kdyW{eZK{8_?os92OyNTklC$rt1`Z2R8 z_i9FH-ZFO%KKbi@r9G4FoI$k%*A(hMiuh{m30EpsQR~HlA}Ms_n^O3$wdABZbLWtY zF0E4(De&9KkwuLzGzKFR7vlH*{Kn6-w?*iwbhp?hgnidQUFkv5Gh3Ry!~!;3*I8%` zxQbF>d|@}Y29wj$rO@an_a&n*z1;1*mg%!N<%naz?!+2mQ{b$Qlu4{W*(+&~Jd}I? z`YfaG24K`n!Lbu-NhwTWP%sw3rcHa@&dsB2o{hPnA0(5sIS;z>} zp8O2ia_qEmC8|;qSX-ldI6uG+?5l7E83&HM$MA*Y)6#>vMA4lSfi>3Uu)2&J1*ruW zaTmUk4;4IV9A1?c#Zz|*l#UGEupPn!yTMuN;+2D5%3XIQR1`3{Nt9Y`h!a%oVvnf= z`&r^k4|85&_^-8#)>z{{Oheu|Jv{qn)OBPU%VprkS}q?;(DRbq76he*0(G)~P~%Zc z#W90d@F{NC*+zD~g02RjFYR@9V_juqD)Da{>s80u8Ru5JW~QuB7HGOy5_up)8gWjy zDNne|4ky2_B4rghL*Dm7b&P-?qDe{Z_dXwT!F&-Q{WXi$*>2c8lglo9R8=Oe#FuN> zvE+fkYr}5yhYVb0>XEprO8@{zS}F^a*gtl=5Q)%9+h65iglcL|A*j>%I^a9{7L4{9 z_k)UyZCk&k`)})M+xl`bbSc_2Vlr&1g#2SbL(PTQnQ#lv$tz_ocw19@y*JFx0}xFq zMe8jEAI^7vJhDS>sq z?I&$kc#`NU6BQmn%Qx-qeNmRnU~;$M&pCzPac0DM6t6|MGb{$q-Ey4`J2!UDOzU4c zJ2cesS-z$c^i%?`QyXg*7Rj?Tf#{wibW7j{!CdJ5HaUqDOnSaPb1V@LGB|+@vi%@eD_J zAJq11IIqz9tOT2*ws8=&R)C?51X)o6R9z&2hm7Z~wMyl>3pR7sQ8}>(cZL+d0OZ#&8Pc!CGDc=WL_fd`d&~xIWTgb8C0|Eq*^wsgL=UoZn=|=ywV5fW4YW z%*WBCL-omSElC@c*&mw|Wfs&{sF-{#~p6y>jlN^OM?qSAfb(!}k}aZ%CVf9!;_-hr#fIA8VcpQ?mJY?NCEA6w_o{jYVbP%)<9B}I{$ua*A6TjwOn3Ok3p;3kZ@?3d0RnRVK=#&A zK)DDcBT}^GtVp?PLOD*&M z<0TM~wRvaPwxvbKb~5H=SaUpx;%uZUI}V^wXF(Vc58mIZhV#+|pZ1$a$WD_Q-r6=KRuh7LS(9e5|SPYCJ_{Hes3FsE8(4)^b%ut6K+Z)wbUK0@~qLITs7cYYf)COz}{Ri4aBpjLYVg3 ziB%xaUI%4wuMFj3$jh!e?QbyO_I?Kbbo(X-NSH_9dAP6A$P-4G!@lEWI~>0oMKDzk z(YdqyH0#{MgGoF}9{=YAd8=^mshM30`h_Z%wHQBe7MqM}tj!-uZ+-0zip?m~{T`E~ zIZ?$iuB#BPgfDz7qf#+dRg;2^yn~Q^Kf%^IUJ-Zmb2M{}oBVdtW9)oi>?n%BK~9Tv z*TcS%1Bt;D{PQyb6Z5{$&t3q^8r@=c;Oa0&Xsz5lXYoz5#*UtRdtrGh<0RY&t=4cK zgid+jGxulvP(-A8pd@X?fTyU?Zfs^^dWP0wv-4)9oKT}k;Z0JxnoTXI7TZXETdTn5 zc9Zu?wW1nvXAX@_(IwLOms~eJKZM;&&e&u^{GQQlU;53Hjr07_ZA!hPFj$@}o<$YJ}&lkd0bk=eH(#2w?QZqK2$K^JaJ9X3uBh1w9R(_@~mEmYnA8#j^3^ z0YCoiY$SZ4j=8h|fV$Y$hi_vP^sPmC^r;3+RLQlTgiq79A%Ib*fKIZk1U z%20TuDtK~BTknQQW-@ddwAd{-}OQ=%?U zmY1i`JK0;G`kjiyw?m;w$qMlAsDwd^u&uEctEsx+?7p|x`3hargw z0aIZ4I`$yCi1v1wSo^Zih0g$(cr?`@H^R;co&7q58{GPJIm%=1qQ5Bf4l@sBc;>;c zy%<`c9>MF5SVuiMUoP<;3JX@BUr7NwR>DiUoBQ07xKKCu{S3^`dGw`KTUa zNm6gYBXvKgcTFD-q)4zt(z42o8xN-YzM!kWTz0LF_58NLcm zETs+CkMi;!Y|=|lRJkCkO9`epDT(~4OlYpfq2&a*Jc91Z{4URg$9&7sFIL+%tx1Lw z!_?;%`Et|~atgPy9>KC$2t(nUFA-O5-w-sv=D9bTI2)!$Bg$LOG(Wk?|9MDCr0*##vOKA1G^QrFJker_bkPPhb5A zWmdRUh@0-i5{i7_=NWs8T@dRZbd@2`7~WerqLmw$WW980)+`+gOR&q}`UVA^ff%Bu zHo9Blt-t}({z?wo%G;QXkcxPhUmY$)6aE<|>Ofhrxyr%JIL_cZA~S9QW@v4lr&xsT zLJ(+r{JFr3jtjw13W%@o5i)Nsixpii9>57Vmebc*k;gaX zrHb!;D5H03$yZ`WtuSDR&oJ>>Y$ej=;{0wh@$r!gK-3~g5{2kmVvZgtI?+WbMLass zRzNi7P(+?PNo$ESFmnv0bz6`Em9JB#Kul!^b8jp@FR6CV#3lFViogOhU$U1JGC>tH z)+IE1uuCNEHb4w>a?k6t8o;_OQc0aX@u@V%Tu!HU)@96*qA6OJx4huKy}c#SySDXI zfBNH1{gs1au(Ahr9)xO~|BDZ2$!B6Wk)n^>tMplXkY7E60YmSn^Pw^6pO0nEYG)tn z_%&azHjpf&k^<+MX|bCQQDBR*(MSOsf=8f2=8hz)^#kaLDKV6 z5y*3c_Qc)Reu{BSi*0&4kAA5Sks)c^q!+j6w>2%$RZT;-ITo2m!yr?ih?lVW!7%9j*dt@?*LoSu+;k~r&s*3FS~>{fSnPQjl- zkSKpD<*;&acNudWjiHx>RTRK&AY(p&v^@RGxHDxL{nZ2<5ZXGeSJ`mp0(OpPYEkIF zk=sNKAH#07e?(X2rZB_V_EP))+uEi+m6YM#*J${qdm_qRPQZyC%WIifUiKf-`af#wNJHA_78VRE)QgI#{i`ci-$x~t zX!S7zu&XY*Bxovd_v{aDx(>JS_0^R0NswRCqT=v^fXRp1w#VHi6bb|=|FG0N{nTI! zz3C;Ktjw9q9}m^H$~P~3&IHIUs>?gSdJA|-28fvNSPXO+)&VfbM1+}-WVc+c8PM$YWM;tKJJ$yamU7r&>;gu5AxpfQBHqiHZD##}^n zYCgl3q?1IVvF6WKFWbW0jC;`~u%9qpJ)^6Q8+XxoB;xE1SfOJC%e1WS9sBB0Sbe}g z7-M(Z2hoPQVBQSkV0`w~4mzul9`}V&qo*lRbyQ?@dvy{e4ujij1njTpqE?C4mAheDkMf2C zxJ$B&_B*CZt-Y^b(u}RHT1In+6$fNQmbS_!eTB9&PR>s8vfg_w34r&A07EsHP?Ct3i0_O^ z&_$rd44p*EKwO>YfC$TY)I54q)OVv-g-x<$f9UI8vlIExgKx463k~#*+Kk(*(7Y|p zH2e4y(7|5oYXftJ+OB)rvU29{=77I?DRYpsb% zNzNYBwyDy6PN)E5q^%wqub!`=(dTZ{s0u2RkohZtMe#(3s-l@%zfGs?~CcRFA zJUy`CP~{+pk)KK$?-V6p=x$f)YI-_OEO)(|ms#G#rAyM%SU?@M>r=)flb_jb|nEE3WJeoiRI;oA$Q0Rf+PJ?%~WVH8z8whx*E={xdZ0RGEZ5 zf}X?uDJ+za(2+;8J8lj`p7uMbJd5n|C2<7qDjkMBwe@u~lY&Io8tU3fK9^^M3#3sN z=l;-+^hj*LI)0}z0sPvAgOb8gBKnc2dj?$f|L6L?$wzP(TOH_8+3>MzNqer{oPc?X zTJuNXN6&gRLkW!)u)Y>243~{3M06+_r=x!POBEmt-u>)YkE{Nv2(Q$cqpD9nqV(M_Kb2 zNz?)Q({7=}If4^@?)n!>V)F6U44)SVmjDMVU;OyL@*@r&7W$X`3;K667Q%M=hlYP? z|NnY_|KR_w-ro)Rf9Cvsy#LyP|Eb=8ipW1WPBd_P2j5yc>UB?N9QHq1964#__vJv7 G&;J2>_*m-z literal 0 HcmV?d00001 diff --git a/src/Makefile b/src/Makefile index 835818e..16b5f0c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,7 @@ +BUILDUTILS=../buildutils +RESOURCES=../resources +SPLASHSCREEN=splash-vmwcblk.png + OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.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 @@ -18,8 +22,8 @@ splash.o: splash.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o -splash.bin: splash.png ../buildutils/mksplash - ../buildutils/mksplash splash.png splash.bin +splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mksplash + $(BUILDUTILS)/mksplash $(RESOURCES)/$(SPLASHSCREEN) splash.bin clean: rm -f upiwin *.o splash.bin *~ diff --git a/src/config.c b/src/config.c index 5345597..cc2b67f 100644 --- a/src/config.c +++ b/src/config.c @@ -187,6 +187,12 @@ HRESULT Config_setup(int argc, char *argv[]) HRESULT hr; GLOBAL_CONFIG from_commandline; + if (geteuid() != 0) + { + Log(LFATAL, "upiwin must be run with root privileges"); + return E_ACCESSDENIED; + } + if (atexit(run_exit_funcs)) { Log(LFATAL, "Unable to set up exit function mechanism"); From 69a4c42d6871ef2a88a96590dba78760a4d61ff4 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:18:24 -0700 Subject: [PATCH 002/101] added the rectangle functions and a "wait for input" mechanism to the system input thread --- src/Makefile | 2 +- src/gfxtype.h | 31 +++++++++++++++++ src/msg_queue.c | 9 +++++ src/msg_queue.h | 1 + src/rect.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sysinput.c | 79 +++++++++++++++++++++++++++++------------- src/sysinput.h | 1 + 7 files changed, 189 insertions(+), 25 deletions(-) create mode 100755 src/gfxtype.h create mode 100755 src/rect.c diff --git a/src/Makefile b/src/Makefile index 16b5f0c..bcc135c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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_upiwin_tmp.o ep_util.o fbinit.o fontengine.o fbprimitive.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o rect.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/gfxtype.h b/src/gfxtype.h new file mode 100755 index 0000000..e992d9e --- /dev/null +++ b/src/gfxtype.h @@ -0,0 +1,31 @@ +#ifndef __GFXTYPE_H_INCLUDED +#define __GFXTYPE_H_INCLUDED + +#include "wintype.h" + +typedef struct tagPOINT { + INT32 x; + INT32 y; +} POINT, *PPOINT; + +typedef struct tagRECT { + INT32 left; + INT32 top; + INT32 right; + INT32 bottom; +} RECT, *PRECT; + +typedef const POINT *PCPOINT; +typedef const RECT *PCRECT; + +extern BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom); +extern BOOL G_set_rect_empty(PRECT rect); +extern BOOL G_inflate_rect(PRECT rect, int dx, int dy); +extern BOOL G_offset_rect(PRECT rect, int dx, int dy); +extern BOOL G_is_rect_empty(PCRECT rect); +extern BOOL G_point_in_rect(PCRECT rect, PCPOINT pt); +extern BOOL G_rect_equal(PCRECT rect1, PCRECT rect2); +extern BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2); +extern BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2); + +#endif /* __GFXTYPE_H_INCLUDED */ diff --git a/src/msg_queue.c b/src/msg_queue.c index 61252ad..566dc0e 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -93,3 +93,12 @@ BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags) pthread_mutex_unlock(&(queue->mutex)); return rc; } + +BOOL Mq_is_empty(PMSG_QUEUE queue) +{ + BOOL rc; + pthread_mutex_lock(&(queue->mutex)); + rc = (queue->head == queue->tail); + pthread_mutex_unlock(&(queue->mutex)); + return rc; +} diff --git a/src/msg_queue.h b/src/msg_queue.h index 10c49ae..6ca5f75 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -26,6 +26,7 @@ extern void Mq_destroy(PMSG_QUEUE queue); extern void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs); extern void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2); extern BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags); +extern BOOL Mq_is_empty(PMSG_QUEUE queue); #define Mq_post0(q, tgt, msg) Mq_post2(q, tgt, msg, 0, 0) #define Mq_post1(q, tgt, msg, attr) Mq_post2(q, tgt, msg, attr, 0) diff --git a/src/rect.c b/src/rect.c new file mode 100755 index 0000000..b4cc505 --- /dev/null +++ b/src/rect.c @@ -0,0 +1,91 @@ +#include +#include "log.h" +#include "gfxtype.h" + +BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom) +{ + rect->left = left; + rect->top = top; + rect->right = right; + rect->bottom = bottom; + return TRUE; +} + +BOOL G_set_rect_empty(PRECT rect) +{ + memset(rect, 0, sizeof(RECT)); + return TRUE; +} + +BOOL G_inflate_rect(PRECT rect, int dx, int dy) +{ + rect->left += dx; + rect->top += dy; + rect->right -= dx; + rect->bottom -= dy; + return TRUE; +} + +BOOL G_offset_rect(PRECT rect, int dx, int dy) +{ + rect->left += dx; + rect->top += dy; + rect->right += dx; + rect->bottom += dy; + return TRUE; +} + +BOOL G_is_rect_empty(PCRECT rect) +{ + return (rect->right <= rect.left) || (rect->bottom <= rect.top); +} + +BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) +{ + return (rect->left <= pt->x) && (pt->x < rect->right) && (rect->top <= pt->y) && (pt->y < rect->bottom); +} + +BOOL G_rect_equal(PCRECT rect1, PCRECT rect2) +{ + return (memcmp(rect1, rect2, sizeof(RECT)) == 0); +} + +BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2) +{ + if (G_is_rect_empty(src1) || G_is_rect_empty(src2)) + { + memset(dest, 0, sizeof(RECT)); + return FALSE; + } + if ((src1->left >= src2->right) || (src2->left >= src1->right) || (src1->top >= src2->bottom) || (src2->top >= src1->bottom)) + { + memset(dest, 0, sizeof(RECT)); + return FALSE; + } + dest->left = MAX(src1->left, src2->left); + dest->top = MAX(src1->top, src2->top); + dest->right = MIN(src1->right, src2->right); + dest->bottom = MIN(src1->bottom, src2->bottom); + ASSERT(dest->left <= dest->right); + ASSERT(dest->top <= dest->bottom); + return TRUE; +} + +BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2) +{ + if (G_is_rect_empty(src1)) + { + memcpy(dest, src2, sizeof(RECT)); + return !G_is_rect_empty(src2); + } + else if (G_is_rect_empty(src2)) + { + memcpy(dest, src1, sizeof(RECT)); + return TRUE; + } + dest->left = MIN(src1->left, src2->left); + dest->top = MIN(src1->top, src2->top); + dest->right = MAX(src1->right, src2->right); + dest->bottom = MAX(src1->bottom, src2->bottom); + return TRUE; +} diff --git a/src/sysinput.c b/src/sysinput.c index 530489c..28e7864 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -21,6 +21,9 @@ static int ts_fd = 0; /* file descriptor for touchscreen */ static pthread_t ithread; /* input thread handle */ static volatile sig_atomic_t running = 1; /* "running" flag for input thread */ +static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER; /* mutex for waiting on input */ +static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for waiting on input */ + /* Local data for poll_buttons() */ static UINT32 last_bstate = 0; /* previous button state */ static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ @@ -30,8 +33,9 @@ static UINT_PTR touch_x = 0; /* X coordinate to send with next static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ -static void poll_buttons(void) +static BOOL poll_buttons(void) { + BOOL posted = FALSE; UINT32 st, down, up, mask; UINT_PTR attr; TIMESTAMP now; @@ -46,22 +50,28 @@ static void poll_buttons(void) for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { if (now < button_event_ok[attr - 1]) - continue; /* this is a "contact bounce" event, don't bother */ + continue; /* this is a "contact bounce" event, don't bother */ if (up & mask) { - /* reset contact bounce timer - only seems to happen after button releases */ - button_event_ok[attr - 1] = now + Gconfig.button_debounce; - Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + /* reset contact bounce timer - only seems to happen after button releases */ + button_event_ok[attr - 1] = now + Gconfig.button_debounce; + Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + posted = TRUE; } else if (down & mask) - Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + { + Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + posted = TRUE; + } } last_bstate = st; } + return posted; } -static void poll_touchscreen(void) +static BOOL poll_touchscreen(void) { + BOOL posted = FALSE; int nb, nev, xerrno, i; struct input_event buffer[INPUT_EVENT_BATCH]; @@ -89,33 +99,37 @@ static void poll_touchscreen(void) switch (buffer[i].type) { case EV_SYN: - if (buffer[i].code == SYN_REPORT) - { - Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); - touch_nextmsg = WM_TOUCHMOVE; - } - break; + if (buffer[i].code == SYN_REPORT) + { + Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); + touch_nextmsg = WM_TOUCHMOVE; + posted = TRUE; + } + break; case EV_ABS: - if (buffer[i].code == ABS_X) - touch_x = buffer[i].value; - else if (buffer[i].code == ABS_Y) - touch_y = buffer[i].value; - break; + if (buffer[i].code == ABS_X) + touch_x = buffer[i].value; + else if (buffer[i].code == ABS_Y) + touch_y = buffer[i].value; + break; case EV_KEY: - if (buffer[i].code == BTN_TOUCH) - touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP); - break; + if (buffer[i].code == BTN_TOUCH) + touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP); + break; default: - break; + break; } } + return posted; } static void *input_thread(void *arg) { + BOOL gotinput; + /* clear all state at startup */ last_bstate = 0; memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP)); @@ -124,8 +138,14 @@ static void *input_thread(void *arg) while (running) { - poll_buttons(); - poll_touchscreen(); + gotinput = poll_buttons(); + gotinput = poll_touchscreen() || gotinput; + if (gotinput) + { + pthread_mutex_lock(&wait_mutex); + pthread_cond_signal(&wait_cond); + pthread_mutex_unlock(&wait_mutex); + } } return NULL; } @@ -178,4 +198,15 @@ HRESULT Sys_enable_input(void) do_disable_input(); } return rc; + +error_0: + return rc; +} + +void Sys_wait_for_input(void) +{ + pthread_mutex_lock(&wait_mutex); + while (Mq_is_empty(Sys_Queue)) + pthread_cond_wait(&wait_cond); + pthread_mutex_unlock(&wait_mutex); } diff --git a/src/sysinput.h b/src/sysinput.h index 8f316d0..e39c6e1 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -7,5 +7,6 @@ extern PMSG_QUEUE Sys_Queue; extern HRESULT Sys_enable_input(void); +extern void Sys_wait_for_input(void); #endif /* __SYSINPUT_H_INCLUDED */ From 746962454d698f1a109bf6f4b184bf91db551a56 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:20:21 -0700 Subject: [PATCH 003/101] fixed build error --- src/sysinput.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index 28e7864..ebc0ae5 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -81,12 +81,12 @@ static BOOL poll_touchscreen(void) xerrno = errno; if ((xerrno != EAGAIN) && (xerrno != EWOULDBLOCK)) Log(LERROR, "Error reading from touchscreen device (%d)", xerrno); - return; + return FALSE; } else if (nb == 0) { Log(LERROR, "Unexpected end of file reading from touchscreen device"); - return; + return FALSE; } nev = nb / sizeof(struct input_event); @@ -207,6 +207,6 @@ void Sys_wait_for_input(void) { pthread_mutex_lock(&wait_mutex); while (Mq_is_empty(Sys_Queue)) - pthread_cond_wait(&wait_cond); + pthread_cond_wait(&wait_cond, &wait_mutex); pthread_mutex_unlock(&wait_mutex); } From 4bef88aecc404a239dd10cfe100412c558fef0fb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:23:06 -0700 Subject: [PATCH 004/101] finished restructuring Sys_enable_input --- src/sysinput.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index ebc0ae5..788547e 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -176,9 +176,8 @@ HRESULT Sys_enable_input(void) if (ts_fd < 0) { rc = ERRNO_AS_SCODE; - Mq_destroy(Sys_Queue); Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc); - return rc; + goto error_0; } running = 1; @@ -186,20 +185,20 @@ HRESULT Sys_enable_input(void) if (threadrc != 0) { rc = SCODE_FROM_ERRNO(threadrc); - close(ts_fd); - ts_fd = -1; - Mq_destroy(Sys_Queue); Log(LFATAL, "Unable to start system input thread (%08X).", rc); + goto error_1; } - if (SUCCEEDED(rc)) - { - rc = Config_exitfunc(do_disable_input); - if (FAILED(rc)) - do_disable_input(); - } - return rc; + rc = Config_exitfunc(do_disable_input); + if (FAILED(rc)) + do_disable_input(); + return rc; + +error_1: + close(ts_fd); + ts_fd = -1; error_0: + Mq_destroy(Sys_Queue); return rc; } From c97b0f7194479cebb16590813b8e6a51547b2db3 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:24:19 -0700 Subject: [PATCH 005/101] fixed build error in rect --- src/rect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rect.c b/src/rect.c index b4cc505..2f1c318 100755 --- a/src/rect.c +++ b/src/rect.c @@ -37,7 +37,7 @@ BOOL G_offset_rect(PRECT rect, int dx, int dy) BOOL G_is_rect_empty(PCRECT rect) { - return (rect->right <= rect.left) || (rect->bottom <= rect.top); + return (rect->right <= rect->left) || (rect->bottom <= rect->top); } BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) From 5ff7bd08585617ffed3c478f14057489406c7b1c Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:28:28 -0700 Subject: [PATCH 006/101] added constant registration capability --- scripts/tmp_main.py | 31 +++++++++++-------------------- src/ep_upiwin_tmp.c | 21 +++++++++++++++++++++ src/ep_util.c | 30 ++++++++++++++++++++++++++++++ src/ep_util.h | 19 +++++++++++++++++++ 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index e694840..9152af5 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,25 +1,16 @@ # Initial test script import upiwin_tmp -FBPRIMCLR_BLACK = 0x0000 -FBPRIMCLR_RED = 0xF800 -FBPRIMCLR_GREEN = 0x07E0 -FBPRIMCLR_BLUE = 0x001F -FBPRIMCLR_YELLOW = 0xFFE0 -FBPRIMCLR_CYAN = 0x07FF -FBPRIMCLR_MAGENTA = 0xF81F -FBPRIMCLR_WHITE = 0xFFFF +upiwin_tmp.filled_rectangle(10, 10, 50, 50, upiwin_tmp.FBPRIMCLR_RED, False) +upiwin_tmp.filled_rectangle(60, 10, 100, 50, upiwin_tmp.FBPRIMCLR_GREEN, False) +upiwin_tmp.filled_rectangle(110, 10, 150, 50, upiwin_tmp.FBPRIMCLR_BLUE, False) +upiwin_tmp.filled_rectangle(10, 60, 50, 100, upiwin_tmp.FBPRIMCLR_CYAN, False) +upiwin_tmp.filled_rectangle(60, 60, 100, 100, upiwin_tmp.FBPRIMCLR_MAGENTA, False) +upiwin_tmp.filled_rectangle(110, 60, 150, 100, upiwin_tmp.FBPRIMCLR_YELLOW, False) +upiwin_tmp.rectangle(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 150, 150, 110, upiwin_tmp.FBPRIMCLR_WHITE, False) -upiwin_tmp.filled_rectangle(10, 10, 50, 50, FBPRIMCLR_RED, False) -upiwin_tmp.filled_rectangle(60, 10, 100, 50, FBPRIMCLR_GREEN, False) -upiwin_tmp.filled_rectangle(110, 10, 150, 50, FBPRIMCLR_BLUE, False) -upiwin_tmp.filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, False) -upiwin_tmp.filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, False) -upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False) -upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False) -upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False) -upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False) - -upiwin_tmp.line(0, 180, 319, 180, FBPRIMCLR_RED, False); -upiwin_tmp.line(0, 196, 319, 196, FBPRIMCLR_RED, False); +upiwin_tmp.line(0, 180, 319, 180, upiwin_tmp.FBPRIMCLR_RED, False); +upiwin_tmp.line(0, 196, 319, 196, upiwin_tmp.FBPRIMCLR_RED, False); upiwin_tmp.textout(10, 180, 'Amy was here!!!') diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 339f72a..51adcfb 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -3,6 +3,7 @@ #include "scode.h" #include "fbprimitive.h" #include "ep_init.h" +#include "ep_util.h" static PyObject *do_setpixel(PyObject *self, PyObject *args) { @@ -84,10 +85,30 @@ static PyModuleDef DefUPIWIN_tmp = { NULL /* no free function */ }; +BEGIN_CONSTANT_TABLE(UPIWIN_tmpConstants) + /* primitive color values */ + CONSTANT_INT_MACRO(FBPRIMCLR_BLACK) + CONSTANT_INT_MACRO(FBPRIMCLR_RED) + CONSTANT_INT_MACRO(FBPRIMCLR_GREEN) + CONSTANT_INT_MACRO(FBPRIMCLR_BLUE) + CONSTANT_INT_MACRO(FBPRIMCLR_YELLOW) + CONSTANT_INT_MACRO(FBPRIMCLR_CYAN) + CONSTANT_INT_MACRO(FBPRIMCLR_MAGENTA) + CONSTANT_INT_MACRO(FBPRIMCLR_WHITE) +END_CONSTANT_TABLE + PyObject *Epython_init_upiwin_tmp_module(void) { PyObject *module; module = PyModule_Create(&DefUPIWIN_tmp); + if (module) + { + if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants))) + { + Py_DECREF(module); + module = NULL; + } + } return module; } diff --git a/src/ep_util.c b/src/ep_util.c index ee12f4a..61184af 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -42,3 +42,33 @@ HRESULT Epython_trace_exception(void) Py_DECREF(traceback); return hr; } + +HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) +{ + HRESULT hr = S_OK; + int i = 0, rc; + + while (const_table[i].name) + { + switch (const_table[i].regtype) + { + case 'i': + rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival); + break; + case 's': + rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval); + break; + default; + Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); + return E_UNEXPECTED; + } + if (!rc) + { + hr = E_FAIL; + break; + } + ++i; + } + + return hr; +} diff --git a/src/ep_util.h b/src/ep_util.h index 5644889..0406aca 100644 --- a/src/ep_util.h +++ b/src/ep_util.h @@ -5,7 +5,26 @@ #include #include "wintype.h" +typedef struct tagREGCONSTANT { + CHAR regtype; + PCSTR name; + union { + LONG ival; + PCSTR sval; + } value; +} REGCONSTANT, *PREGCONSTANT; + +typedef const REGCONSTANT *PCREGCONSTANT; + extern void Epython_log_object(int level, const char *label, PyObject *object); extern HRESULT Epython_trace_exception(void); +extern HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table); + +#define BEGIN_CONSTANT_TABLE(name) static const REGCONSTANT name[] = { +#define CONSTANT_INT(name, value) { 'i', name, { .ival = value } }, +#define CONSTANT_INT_MACRO(mac) CONSTANT_INT(#mac, mac) +#define CONSTANT_STRING(name, value) { 's', name, { .sval = value } }, +#define CONSTANT_STRING_MACRO(mac) CONSTANT_STRING(#mac, mac) +#define END_CONSTANT_TABLE { 0, NULL, { .sval = NULL } } }; #endif /* __EP_UTIL_H_INCLUDED */ From ccde6c71f92814191f7b5b6a69e919182e0eb885 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Mon, 9 Dec 2019 12:30:27 -0700 Subject: [PATCH 007/101] fixed typo --- src/ep_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_util.c b/src/ep_util.c index 61184af..456b5a8 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -58,7 +58,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) case 's': rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval); break; - default; + default: Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); return E_UNEXPECTED; } From 4c2e9d9e15e01cb27dbc67e29f66522c7b0cf94d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:30:54 -0700 Subject: [PATCH 008/101] added a log message on failure --- src/ep_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ep_util.c b/src/ep_util.c index 456b5a8..f4a1c3a 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -64,6 +64,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) } if (!rc) { + Log(LERROR, "Failed to register constant %s", const_table[i].name); hr = E_FAIL; break; } From f74e663658fc29526a767b9e7d93cb5023b9b3ae Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:35:15 -0700 Subject: [PATCH 009/101] got a test backwards --- src/ep_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_util.c b/src/ep_util.c index f4a1c3a..44a49c8 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -62,7 +62,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); return E_UNEXPECTED; } - if (!rc) + if (rc) { Log(LERROR, "Failed to register constant %s", const_table[i].name); hr = E_FAIL; From a96a427e498e9b43357ff6fb4c7fe1d481752e24 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:29:37 -0700 Subject: [PATCH 010/101] moved the main message loop entirely into Python --- scripts/tmp_main.py | 26 +++++++++++++++++ src/Makefile | 3 +- src/ep_msg.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/ep_upiwin.c | 26 ++++++++++++++++- src/ep_upiwin.h | 7 +++++ src/main.c | 57 ++----------------------------------- src/msg.h | 1 + src/sysinput.c | 1 + src/sysinput.h | 1 + 9 files changed, 133 insertions(+), 57 deletions(-) create mode 100755 src/ep_msg.c diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 9152af5..0e656b9 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,6 +1,9 @@ # Initial test script import upiwin_tmp +def log_touch(event, x, y): + print("Touch {0} at ({1), {2})\n".format(event, x, y)) + upiwin_tmp.filled_rectangle(10, 10, 50, 50, upiwin_tmp.FBPRIMCLR_RED, False) upiwin_tmp.filled_rectangle(60, 10, 100, 50, upiwin_tmp.FBPRIMCLR_GREEN, False) upiwin_tmp.filled_rectangle(110, 10, 150, 50, upiwin_tmp.FBPRIMCLR_BLUE, False) @@ -14,3 +17,26 @@ upiwin_tmp.line(10, 150, 150, 110, upiwin_tmp.FBPRIMCLR_WHITE, False) upiwin_tmp.line(0, 180, 319, 180, upiwin_tmp.FBPRIMCLR_RED, False); upiwin_tmp.line(0, 196, 319, 196, upiwin_tmp.FBPRIMCLR_RED, False); upiwin_tmp.textout(10, 180, 'Amy was here!!!') + +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_HWBUTTONDOWN: + print("Button {0} was pressed.\n".format(msg['attrs'][0]) + elif msg['message'] == upiwin.WM_HWBUTTONUP: + print("Button {0} was released.\n".format(msg['attrs'][0]) + bn = msg['attrs'][0] + if bn == 1: + print("Backlight ON.\n") + upiwin.set_backlight(True) + elif bn == 2: + print("Backlight OFF.\n") + upiwin.set_backlight(True) + elif bn == 4: + print("Quitting the application.\n") + upiwin.post_quit_message(0) + elif msg['message'] == upiwin.WM_TOUCHDOWN: + log_touch('DOWN', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHMOVE: + log_touch('MOVE', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHUP: + log_touch('UP', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/Makefile b/src/Makefile index bcc135c..393fa29 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,8 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o rect.o fontengine.o fbprimitive.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_upiwin_tmp.o ep_util.o \ + fbinit.o rect.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/ep_msg.c b/src/ep_msg.c new file mode 100755 index 0000000..c00fe51 --- /dev/null +++ b/src/ep_msg.c @@ -0,0 +1,68 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "msg_queue.h" +#include "sysinput.h" +#include "ep_upiwin.h" +#include "ep_init.h" + +static HRESULT convert_msg(PyDictObject *target, PMSG source) +{ + PyObject *attr; + + PyDict_Clear(target); + attr = PyLong_FromUnsignedLong(source->target); + if (!attr) + return E_FAIL; + if (PyDict_SetItemString(target, "target", attr)) + return E_FAIL; + attr = PyLong_FromUnsignedLong(source->message); + if (!attr) + return E_FAIL; + if (PyDict_SetItemString(target, "message", attr)) + return E_FAIL; + attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]); + if (!attr) + return E_FAIL; + if (PyDict_SetItemString(target, "attrs", attr)) + return E_FAIL; + attr = PyLong_FromUnsignedLongLong(source->timestamp); + if (!attr) + return E_FAIL; + if (PyDict_SetItemString(target, "timestamp", attr)) + return E_FAIL; + return S_OK; +} + +PyObject *Epython_get_message(PyObject *self, PyObject *args) +{ + PyDictObject *out; + MSG msg; + + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out)) + return NULL; + + /* release the GIL to allow us to block waiting for input if necessary */ + Py_BEGIN_ALLOW_THREADS + while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) + Sys_wait_for_input(); + Py_END_ALLOW_THREADS + + if (FAILED(convert_msg(out, &msg))) + { + PyErr_SetString(PyExc_RuntimeError, "could not convert received message"); + return NULL; + } + return PyBool_FromLong(msg.message != WM_QUIT); +} + +PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) +{ + INT32 exitcode; + + if (!PyArg_ParseTuple(args, "i", &exitcode)) + return NULL; + Sys_Exit_Code = exitcode; + Mq_post1(Sys_Queue, NULL, WM_QUIT, exitcode); + Py_RETURN_NONE; +} diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 9c99dc3..4c51e34 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -1,9 +1,11 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" -#include "ep_init.h" +#include "msg.h" #include "gpio.h" +#include "ep_init.h" #include "ep_upiwin.h" +#include "ep_util.h" static PyMethodDef UPIWINMethods[] = { /* Backlight control functions */ @@ -15,6 +17,11 @@ static PyMethodDef UPIWINMethods[] = { "Returns the current intensity level of the backlight."}, {"set_backlight_level", Epython_set_backlight_level, METH_VARARGS, "Sets the current intensity level of the backlight. Returns a SCODE."}, + /* Message functions */ + {"get_message", Epython_get_message, METH_VARARGS, + "Retrieves a message from the message queue, blocking if necessary."}, + {"post_quit_message", Epython_post_quit_message, METH_VARARGS, + "Posts a WM_QUIT message to the message queue, with an exit code."}, {NULL, NULL, 0, NULL} }; @@ -30,6 +37,17 @@ static PyModuleDef DefUPIWIN = { NULL /* no free function */ }; +BEGIN_CONSTANT_TABLE(UPIWINConstants) + /* Message constants */ + CONSTANT_INT_MACRO(WM_NULL) + CONSTANT_INT_MACRO(WM_QUIT) + CONSTANT_INT_MACRO(WM_HWBUTTONDOWN) + CONSTANT_INT_MACRO(WM_HWBUTTONUP) + CONSTANT_INT_MACRO(WM_TOUCHDOWN) + CONSTANT_INT_MACRO(WM_TOUCHMOVE) + CONSTANT_INT_MACRO(WM_TOUCHUP) +END_CONSTANT_TABLE + PyObject *Epython_init_upiwin_module(void) { PyObject *module; @@ -38,6 +56,12 @@ PyObject *Epython_init_upiwin_module(void) module = PyModule_Create(&DefUPIWIN); if (!module) return NULL; + + if (FAILED(Epython_register_constants(module, UPIWINConstants))) + { + Py_DECREF(module); + return NULL; + } /* set up the module state */ pstate = (PUPIWIN_STATE)PyModule_GetState(module); diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index fa41b43..b6dbe14 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -11,9 +11,16 @@ typedef struct tagUPIWIN_STATE { } UPIWIN_STATE, *PUPIWIN_STATE; /* method definitions go here */ + +/* ep_backlight.c */ extern PyObject *Epython_get_backlight(PyObject *self, PyObject *args); extern PyObject *Epython_set_backlight(PyObject *self, PyObject *args); extern PyObject *Epython_get_backlight_level(PyObject *self, PyObject *args); extern PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args); +/* ep_msg.c */ +extern PyObject *Epython_get_message(PyObject *self, PyObject *args); +extern PyObject *Epython_post_quit_message(PyObject *self, PyObject *args); + + #endif /* __EP_UPIWIN_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 21e8622..29a4b87 100644 --- a/src/main.c +++ b/src/main.c @@ -12,11 +12,6 @@ #include "ep_init.h" #include "sysinput.h" -static void log_touch(const char *event, UINT_PTR x, UINT_PTR y) -{ - Log(LINFO, "Touch %s at (%u, %u)", event, x, y); -} - int main(int argc, char *argv[]) { HRESULT hr; @@ -47,54 +42,6 @@ int main(int argc, char *argv[]) if (FAILED(Epython_run())) return EXIT_FAILURE; - Log(LINFO, "Script returned and event loop ready."); - - while (running) - { - if (Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) - { - switch (msg.message) - { - case WM_HWBUTTONDOWN: - Log(LINFO, "Button %d was pressed.", (int)(msg.attrs[0])); - break; - - case WM_HWBUTTONUP: - Log(LINFO, "Button %d was released.", (int)(msg.attrs[0])); - if (msg.attrs[0] == 1) - { - Log(LINFO, "Backlight ON."); - Gpio_set_backlight(GSB_BACKLIGHT_MAX); - } - if (msg.attrs[0] == 2) - { - Log(LINFO, "Backlight OFF."); - Gpio_set_backlight(0); - } - if (msg.attrs[0] == 4) - { - Log(LINFO, "Quitting the message loop."); - running = 0; - } - break; - - case WM_TOUCHDOWN: - log_touch("DOWN", msg.attrs[0], msg.attrs[1]); - break; - - case WM_TOUCHMOVE: - log_touch("MOVE", msg.attrs[0], msg.attrs[1]); - break; - - case WM_TOUCHUP: - log_touch("UP", msg.attrs[0], msg.attrs[1]); - break; - - default: - break; - } - } - } - - return EXIT_SUCCESS; + Log(LINFO, "Script returned with exit code %d", Sys_Exit_Code); + return Sys_Exit_Code; } diff --git a/src/msg.h b/src/msg.h index 03f91c2..7778bde 100644 --- a/src/msg.h +++ b/src/msg.h @@ -13,6 +13,7 @@ typedef struct tagMSG { } MSG, *PMSG; #define WM_NULL 0x0000 +#define WM_QUIT 0x0001 #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 diff --git a/src/sysinput.c b/src/sysinput.c index 788547e..44335bd 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -16,6 +16,7 @@ #define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */ PMSG_QUEUE Sys_Queue = NULL; /* system message queue */ +INT32 Sys_Exit_Code = -1; /* system exit code, set on WM_QUIT */ static int ts_fd = 0; /* file descriptor for touchscreen */ static pthread_t ithread; /* input thread handle */ diff --git a/src/sysinput.h b/src/sysinput.h index e39c6e1..e191b66 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -5,6 +5,7 @@ #include "msg_queue.h" extern PMSG_QUEUE Sys_Queue; +extern INT32 Sys_Exit_Code; extern HRESULT Sys_enable_input(void); extern void Sys_wait_for_input(void); From 6f27ec7af89c046ae335ba84a1fae2a135b8bd67 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:33:23 -0700 Subject: [PATCH 011/101] cleaned up some compiler warnings --- src/ep_msg.c | 6 ++++-- src/main.c | 5 +---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ep_msg.c b/src/ep_msg.c index c00fe51..d5c533b 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -1,15 +1,17 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" +#include "log.h" #include "msg_queue.h" #include "sysinput.h" #include "ep_upiwin.h" #include "ep_init.h" -static HRESULT convert_msg(PyDictObject *target, PMSG source) +static HRESULT convert_msg(PyObject *target, PMSG source) { PyObject *attr; + ASSERT(PyDict_CheckExact(target)); PyDict_Clear(target); attr = PyLong_FromUnsignedLong(source->target); if (!attr) @@ -63,6 +65,6 @@ PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i", &exitcode)) return NULL; Sys_Exit_Code = exitcode; - Mq_post1(Sys_Queue, NULL, WM_QUIT, exitcode); + Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Py_RETURN_NONE; } diff --git a/src/main.c b/src/main.c index 29a4b87..99b9a63 100644 --- a/src/main.c +++ b/src/main.c @@ -2,11 +2,10 @@ #include #include #include "scode.h" +#include "log.h" #include "config.h" #include "gpio.h" -#include "log.h" #include "fbinit.h" -#include "fbprimitive.h" #include "fontengine.h" #include "time_func.h" #include "ep_init.h" @@ -15,8 +14,6 @@ int main(int argc, char *argv[]) { HRESULT hr; - int running = 1; - MSG msg; /* initialization sequence */ Time_init(); From c0c4242dfc28ee2491b036452e3ed9fe909697bb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:34:49 -0700 Subject: [PATCH 012/101] cleared up another warning --- src/ep_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_msg.c b/src/ep_msg.c index d5c533b..c647533 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -38,7 +38,7 @@ static HRESULT convert_msg(PyObject *target, PMSG source) PyObject *Epython_get_message(PyObject *self, PyObject *args) { - PyDictObject *out; + PyObject *out; MSG msg; if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out)) From 351e2a2b47edc305a3a1b6e3f4304bbb4c0f71d8 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:37:02 -0700 Subject: [PATCH 013/101] error in Python script now --- scripts/tmp_main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 0e656b9..90c6f58 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -21,9 +21,9 @@ upiwin_tmp.textout(10, 180, 'Amy was here!!!') msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_HWBUTTONDOWN: - print("Button {0} was pressed.\n".format(msg['attrs'][0]) + print("Button {0} was pressed.\n".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: - print("Button {0} was released.\n".format(msg['attrs'][0]) + print("Button {0} was released.\n".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: print("Backlight ON.\n") From bb8b27fb2484ac1f42ffae14efa67f6df1a27619 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:38:01 -0700 Subject: [PATCH 014/101] forgot the Python import --- scripts/tmp_main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 90c6f58..c799dd4 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,4 +1,5 @@ # Initial test script +import upiwin import upiwin_tmp def log_touch(event, x, y): From 68be55a8f560331a56044dde9b416ef300a6975f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:42:55 -0700 Subject: [PATCH 015/101] tracing backlight problem and fixing a typo in a function definition --- scripts/tmp_main.py | 14 +++++++------- src/ep_backlight.c | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index c799dd4..815aa44 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -3,7 +3,7 @@ import upiwin import upiwin_tmp def log_touch(event, x, y): - print("Touch {0} at ({1), {2})\n".format(event, x, y)) + print("Touch {0} at ({1}, {2})".format(event, x, y)) upiwin_tmp.filled_rectangle(10, 10, 50, 50, upiwin_tmp.FBPRIMCLR_RED, False) upiwin_tmp.filled_rectangle(60, 10, 100, 50, upiwin_tmp.FBPRIMCLR_GREEN, False) @@ -22,18 +22,18 @@ upiwin_tmp.textout(10, 180, 'Amy was here!!!') msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_HWBUTTONDOWN: - print("Button {0} was pressed.\n".format(msg['attrs'][0])) + print("Button {0} was pressed.".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: - print("Button {0} was released.\n".format(msg['attrs'][0])) + print("Button {0} was released.".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: - print("Backlight ON.\n") + print("Backlight ON.") upiwin.set_backlight(True) elif bn == 2: - print("Backlight OFF.\n") - upiwin.set_backlight(True) + print("Backlight OFF.") + upiwin.set_backlight(False) elif bn == 4: - print("Quitting the application.\n") + print("Quitting the application.") upiwin.post_quit_message(0) elif msg['message'] == upiwin.WM_TOUCHDOWN: log_touch('DOWN', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/ep_backlight.c b/src/ep_backlight.c index af4327b..bb37f07 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -1,6 +1,7 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" +#include "log.h" #include "gpio.h" #include "ep_upiwin.h" #include "ep_init.h" @@ -23,6 +24,7 @@ PyObject *Epython_set_backlight(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "p", &new_state)) return NULL; pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + Log(LDEBUG, "set_backlight: old=%d, new=%d (level=%u)", pstate->backlight_on, new_state, pstate->backlight_level); if (new_state && !(pstate->backlight_on)) Gpio_set_backlight(pstate->backlight_level); else if (!new_state && pstate->backlight_on) From ee292d3aab2943be3a1a0ed1c55eafd5eed413eb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 17:02:04 -0700 Subject: [PATCH 016/101] starting to build device-independent drawing functions (work in progress) --- src/Makefile | 2 +- src/dc_screen.c | 5 +++++ src/dc_screen.h | 12 ++++++++++++ src/devctxt.c | 9 +++++++++ src/devctxt.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/ep_backlight.c | 1 - src/ep_msg.c | 1 + src/gfxobj.c | 30 +++++++++++++++++++++++++++++ src/gfxobj.h | 23 ++++++++++++++++++++++ src/gfxtype.h | 9 +++++++++ src/rect.c | 7 ++++++- 11 files changed, 144 insertions(+), 3 deletions(-) create mode 100755 src/dc_screen.c create mode 100755 src/dc_screen.h create mode 100755 src/devctxt.c create mode 100755 src/devctxt.h create mode 100755 src/gfxobj.c create mode 100755 src/gfxobj.h diff --git a/src/Makefile b/src/Makefile index 393fa29..1e3d59c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ 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 \ - fbinit.o rect.o fontengine.o fbprimitive.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/dc_screen.c b/src/dc_screen.c new file mode 100755 index 0000000..84fced2 --- /dev/null +++ b/src/dc_screen.c @@ -0,0 +1,5 @@ +#include "dc_screen.h" + +static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op) +{ +} diff --git a/src/dc_screen.h b/src/dc_screen.h new file mode 100755 index 0000000..4c4ad6e --- /dev/null +++ b/src/dc_screen.h @@ -0,0 +1,12 @@ +#ifndef __DC_SCREEN_H_INCLUDED +#define __DC_SCREEN_H_INCLUDED + +#include "wintype.h" +#include "gfxtype.h" + +typedef struct tagSCREENPRIVDATA { + UINT32 pix_per_row; + UINT16 *pdata; +} SCREENPRIVDATA, *PSCREENPRIVDATA; + +#endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c new file mode 100755 index 0000000..982325a --- /dev/null +++ b/src/devctxt.c @@ -0,0 +1,9 @@ +#include "gfxtype.h" +#include "devctxt.h" + +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); +} diff --git a/src/devctxt.h b/src/devctxt.h new file mode 100755 index 0000000..2e8f528 --- /dev/null +++ b/src/devctxt.h @@ -0,0 +1,48 @@ +#ifndef __DEVCTXT_H_INCLUDED +#define __DEVCTXT_H_INCLUDED + +#include "wintype.h" +#include "gfxtype.h" +#include "gfxobj.h" + +#define DCTXT_SIG_WORD 0x78744344 /* "DCtx */ + +/* Raster operation codes */ +#define R2_BLACK 1 +#define R2_NOTMERGEPEN 2 +#define R2_MASKNOTPEN 3 +#define R2_NOTCOPYPEN 4 +#define R2_MASKPENNOT 5 +#define R2_NOT 6 +#define R2_XORPEN 7 +#define R2_NOTMASKPEN 8 +#define R2_MASKPEN 9 +#define R2_NOTXORPEN 10 +#define R2_NOP 11 +#define R2_MERGENOTPEN 12 +#define R2_COPYPEN 13 +#define R2_MERGEPENNOT 14 +#define R2_MERGEPEN 15 +#define R2_WHITE 16 + +typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op); + +typedef struct tagDCFUNTABLE { + DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ +} DCFUNTABLE; + +typedef const DCFUNTABLE *PDCFUNTABLE; + +typedef struct tagDCTXT { + GFXOBJECT hdr; /* the header of all objects */ + PDCFUNTABLE funcs; /* device context functions */ + PVOID privdata; /* private data for the type of DC */ + RECT cliprect; /* clipping rectangle */ + POINT pos; /* current position */ + UINT32 rop2; /* current raster operation */ + COLORREF color; /* current drawing color (XXX replace with pens later) */ +} DCTXT, *PDCTXT; + +extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color); + +#endif /* __DEVCTXT_H_INCLUDED */ diff --git a/src/ep_backlight.c b/src/ep_backlight.c index bb37f07..e78cb58 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -24,7 +24,6 @@ PyObject *Epython_set_backlight(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "p", &new_state)) return NULL; pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); - Log(LDEBUG, "set_backlight: old=%d, new=%d (level=%u)", pstate->backlight_on, new_state, pstate->backlight_level); if (new_state && !(pstate->backlight_on)) Gpio_set_backlight(pstate->backlight_level); else if (!new_state && pstate->backlight_on) diff --git a/src/ep_msg.c b/src/ep_msg.c index c647533..9cf072b 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -68,3 +68,4 @@ PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Py_RETURN_NONE; } + diff --git a/src/gfxobj.c b/src/gfxobj.c new file mode 100755 index 0000000..882ca1a --- /dev/null +++ b/src/gfxobj.c @@ -0,0 +1,30 @@ +#include +#include "gfxobj.h" + +void Go_unchain(PGFXOBJECT obj) +{ + if (!(obj->next || obj->prev)) + return; + if (obj->next) + obj->next->prev = obj->prev; + if (obj->prev) + obj->prev->next = obj->next; + obj->prev = obj->next = NULL; +} + +INT32 Go_addref(PGFXOBJECT obj) +{ + return ++(obj->refcnt); +} + +INT32 Go_release(PGFXOBJECT obj) +{ + int rc = --(obj->refcnt); + if (rc == 0) + { + if (obj->dtor) + (*(obj->dtor))(obj); + free(obj); + } + return rc; +} diff --git a/src/gfxobj.h b/src/gfxobj.h new file mode 100755 index 0000000..19d5926 --- /dev/null +++ b/src/gfxobj.h @@ -0,0 +1,23 @@ +#ifndef __GFXOBJ_H_INCLUDED +#define __GFXOBJ_H_INCLUDED + +#include "wintype.h" + +/* type definition for a graphics destructor */ +typedef void (*GFX_DTOR)(PVOID obj); + +/* A graphics object in memory always starts with this. */ +typedef struct tagGFXOBJECT { + UINT32 sig; /* signature so we know what something is */ + UINT32 size; /* size of total allocated memory in block */ + INT32 refcnt; /* reference count */ + GFX_DTOR dtor; /* destructor function called when we're no longer needed */ + struct tagGFXOBJECT *next; /* support double linked lists of obejcts */ + struct tagGFXOBJECT *prev; +} GFXOBJECT, *PGFXOBJECT; + +extern void Go_unchain(PGFXOBJECT obj); +extern INT32 Go_addref(PGFXOBJECT obj); +extern INT32 Go_release(PGFXOBJECT obj); + +#endif /* __GFXOBJ_H_INCLUDED */ diff --git a/src/gfxtype.h b/src/gfxtype.h index e992d9e..efc02db 100755 --- a/src/gfxtype.h +++ b/src/gfxtype.h @@ -18,14 +18,23 @@ typedef struct tagRECT { typedef const POINT *PCPOINT; typedef const RECT *PCRECT; +typedef UINT32 COLORREF; +typedef PUINT32 PCOLORREF; + extern BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom); extern BOOL G_set_rect_empty(PRECT rect); extern BOOL G_inflate_rect(PRECT rect, int dx, int dy); extern BOOL G_offset_rect(PRECT rect, int dx, int dy); extern BOOL G_is_rect_empty(PCRECT rect); +extern BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y); extern BOOL G_point_in_rect(PCRECT rect, PCPOINT pt); extern BOOL G_rect_equal(PCRECT rect1, PCRECT rect2); extern BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2); extern BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2); +#define RGB(r, g, b) ((((UINT32)(r)) & 0xFF) | ((((UINT32)(g)) & 0xFF) << 8) | ((((UINT32)(b)) & 0xFF) << 16)) +#define GetRValue(cr) ((UINT32)((cr) & 0xFF)) +#define GetGValue(cr) ((UINT32)(((cr) >> 8) & 0xFF)) +#define GetBValue(cr) ((UINT32)(((cr) >> 16) & 0xFF)) + #endif /* __GFXTYPE_H_INCLUDED */ diff --git a/src/rect.c b/src/rect.c index 2f1c318..eae408a 100755 --- a/src/rect.c +++ b/src/rect.c @@ -40,9 +40,14 @@ BOOL G_is_rect_empty(PCRECT rect) return (rect->right <= rect->left) || (rect->bottom <= rect->top); } +BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y) +{ + return (rect->left <= x) && (x < rect->right) && (rect->top <= y) && (y < rect->bottom); +} + BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) { - return (rect->left <= pt->x) && (pt->x < rect->right) && (rect->top <= pt->y) && (pt->y < rect->bottom); + return G_coords_in_rect(rect, pt->x, pt->y); } BOOL G_rect_equal(PCRECT rect1, PCRECT rect2) From c3b3e0a3508acd6e36298ea8f4f3f173c4115327 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 12:42:58 -0700 Subject: [PATCH 017/101] first pass at the device-independent drawing system, including the Python representation of a device context --- src/Makefile | 2 +- src/dc_screen.c | 170 +++++++++++++++++++++++++++++++ src/dc_screen.h | 2 + src/devctxt.c | 162 ++++++++++++++++++++++++++++++ src/devctxt.h | 17 ++++ src/ep_devctxt.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++ src/ep_init.h | 2 + src/ep_upiwin.c | 24 +++++ src/gfxobj.c | 9 ++ src/gfxobj.h | 1 + 10 files changed, 641 insertions(+), 1 deletion(-) create mode 100755 src/ep_devctxt.c diff --git a/src/Makefile b/src/Makefile index 1e3d59c..86ff8a0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 diff --git a/src/dc_screen.c b/src/dc_screen.c index 84fced2..8e37e98 100755 --- a/src/dc_screen.c +++ b/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; } diff --git a/src/dc_screen.h b/src/dc_screen.h index 4c4ad6e..ecd4f31 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -9,4 +9,6 @@ typedef struct tagSCREENPRIVDATA { UINT16 *pdata; } SCREENPRIVDATA, *PSCREENPRIVDATA; +extern PDCTXT DC_CreateScreenContext(void); + #endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c index 982325a..df89755 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,9 +1,171 @@ +#include #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; +} diff --git a/src/devctxt.h b/src/devctxt.h index 2e8f528..1b8d3a4 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -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 */ diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c new file mode 100755 index 0000000..f8b3069 --- /dev/null +++ b/src/ep_devctxt.c @@ -0,0 +1,253 @@ +#include +#define PY_SSIZE_T_CLEAN +#include +#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; +} diff --git a/src/ep_init.h b/src/ep_init.h index 82ec538..e394470 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -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); diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 4c51e34..9878d3c 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -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); diff --git a/src/gfxobj.c b/src/gfxobj.c index 882ca1a..c721f43 100755 --- a/src/gfxobj.c +++ b/src/gfxobj.c @@ -1,6 +1,15 @@ #include +#include #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)) diff --git a/src/gfxobj.h b/src/gfxobj.h index 19d5926..0f7a6b6 100755 --- a/src/gfxobj.h +++ b/src/gfxobj.h @@ -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); From 519e58fd779e2cda88da40af7d9442e92ab1cbd9 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 10 Dec 2019 12:55:32 -0700 Subject: [PATCH 018/101] fixed compile errors --- src/dc_screen.c | 11 +++++++---- src/devctxt.c | 5 +++-- src/ep_devctxt.c | 8 ++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index 8e37e98..31b3197 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,3 +1,4 @@ +#include #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" @@ -30,7 +31,7 @@ static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) return disp & (~pen); case R2_NOTCOPYPEN: return ~pen; - case R2_MASKPENNOT; + case R2_MASKPENNOT: return (~disp) & pen; case R2_NOT: return ~disp; @@ -55,6 +56,7 @@ static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) case R2_WHITE: return (UINT16)(-1); } + return pen; /* last ditch default */ } static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op) @@ -91,7 +93,7 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, } loc = loc_from_coords(priv, x1, y1); tmp = x1; - x1 << 16; + x1 <<= 16; dx = (dx << 16) / dy; while (y1 <= y2) { @@ -131,11 +133,12 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, ++loc; if (tmp != (y1 >> 16)) { - loc += ((((y1 >> 16) - tmp) * priv->pix_per_row); + loc += (((y1 >> 16) - tmp) * priv->pix_per_row); tmp = y1 >> 16; } } } + return TRUE; } static const DCFUNTABLE screen_funtable = { @@ -159,7 +162,7 @@ PDCTXT DC_CreateScreenContext(void) if (!priv) return NULL; priv->pix_per_row = Fb_Info->width; - priv->pdata = Pb_Ptr; + priv->pdata = Fb_Ptr; rc = _DC_Allocate(&screen_funtable, priv); if (rc) diff --git a/src/devctxt.c b/src/devctxt.c index df89755..83fc8ab 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,4 +1,5 @@ #include +#include #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" @@ -41,7 +42,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT y2 = tmp; tmpb = outcode1; outcode1 = outcode2; - outcode2 = tmp; + outcode2 = tmpb; } if (outcode1 & 0x8) { @@ -102,7 +103,7 @@ 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); + return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2); } BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index f8b3069..ae05cdc 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -203,18 +203,18 @@ static void devctxt_dealloc(DevCtxtObject *self) static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "type" } + static char *kwlist[] = { "type" }; char *type; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) return -1; - if (stricmp(type, "screen") == 0) + if (strcmp(type, "screen") == 0) { self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { PyErr_SetString(PyExc_RuntimeError, "unable to create screen context"); - return -1 + return -1; } } else @@ -237,7 +237,7 @@ static PyTypeObject DevCtxtType = { .tp_dealloc = (destructor)devctxt_dealloc, .tp_methods = DevCtxtMethods, .tp_getset = DevCtxtProperties, -} +}; HRESULT Epython_register_devctxt(PyObject *module) { From eef55f71b3f6f76eefef6c9ae4bdea9644dfca59 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:04:24 -0700 Subject: [PATCH 019/101] added a script to test clipping of drawn lines --- scripts/test_clipping.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 scripts/test_clipping.py diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py new file mode 100755 index 0000000..bdbba35 --- /dev/null +++ b/scripts/test_clipping.py @@ -0,0 +1,23 @@ +# Test of line clipping +import upiwin + +hdc = upiwin.DevCtxt(type='screen') +hdc.text_color = 0xFFFFFF # white +hdc.rectangle(100, 100, 199, 199) + +clip = hdc.get_clip_rect() +hdc.set_clip_rect(100, 100, 200, 200) + +hdc.text_color = 0xFF0000 # red +hdc.move_to(0, 200) +hdc.line_to(200, 0) + +hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) + +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_HWBUTTONUP: + bn = msg['attrs'][0] + if bn == 4: + print("Quitting the application.") + upiwin.post_quit_message(0) From f41356cca4bb55cd41e6a9e1ee6a15a2d1f17182 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 10 Dec 2019 13:10:43 -0700 Subject: [PATCH 020/101] prepare for disco debugging --- scripts/test_clipping.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index bdbba35..651cc47 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,9 +1,12 @@ # Test of line clipping import upiwin +print('**GOT HERE 1') hdc = upiwin.DevCtxt(type='screen') +print('**GOT HERE 2') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) +print('**GOT HERE 3') clip = hdc.get_clip_rect() hdc.set_clip_rect(100, 100, 200, 200) From 9746ad1ab3ad6ec13b977043e72316079b0d14be Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:13:56 -0700 Subject: [PATCH 021/101] disco debugging, yay! --- src/ep_devctxt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index ae05cdc..63250fa 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -3,6 +3,7 @@ #include #include "wintype.h" #include "scode.h" +#include "log.h" #include "devctxt.h" #include "dc_screen.h" #include "ep_init.h" @@ -206,10 +207,13 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = { "type" }; char *type; + Log(LDEBUG, "Creating a new DevCtxt object"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) return -1; + Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) { + Log(LDEBUG, "doing what we expect on screen context"); self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { From 12bd14e1e7140993487c8beb77d5b4fd59af8310 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:17:46 -0700 Subject: [PATCH 022/101] more disco debugging --- src/ep_devctxt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 63250fa..f87bc85 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -204,11 +204,11 @@ static void devctxt_dealloc(DevCtxtObject *self) static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "type" }; - char *type; + static char *kwlist[] = { "type", NULL }; + const char *type; Log(LDEBUG, "Creating a new DevCtxt object"); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type)) return -1; Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) From 3dd2e037ffe70926ec122886589f232bda686560 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:21:24 -0700 Subject: [PATCH 023/101] finished debugging parameter error, now test drawing without resetting clip --- scripts/test_clipping.py | 9 +++------ src/ep_devctxt.c | 3 --- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 651cc47..2650ed2 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,21 +1,18 @@ # Test of line clipping import upiwin -print('**GOT HERE 1') hdc = upiwin.DevCtxt(type='screen') -print('**GOT HERE 2') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) -print('**GOT HERE 3') -clip = hdc.get_clip_rect() -hdc.set_clip_rect(100, 100, 200, 200) +#clip = hdc.get_clip_rect() +#hdc.set_clip_rect(100, 100, 200, 200) hdc.text_color = 0xFF0000 # red hdc.move_to(0, 200) hdc.line_to(200, 0) -hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) +#hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} while upiwin.get_message(msg): diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index f87bc85..651f317 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -207,13 +207,10 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = { "type", NULL }; const char *type; - Log(LDEBUG, "Creating a new DevCtxt object"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type)) return -1; - Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) { - Log(LDEBUG, "doing what we expect on screen context"); self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { From a14acdb0edbad1b9d5c64192f6305100fe8b93c9 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:25:36 -0700 Subject: [PATCH 024/101] the clipping looks like it worked, my geometry was just off :) --- scripts/test_clipping.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 2650ed2..72df4a1 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -5,14 +5,18 @@ hdc = upiwin.DevCtxt(type='screen') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) -#clip = hdc.get_clip_rect() -#hdc.set_clip_rect(100, 100, 200, 200) +clip = hdc.get_clip_rect() +hdc.set_clip_rect(100, 100, 200, 200) -hdc.text_color = 0xFF0000 # red -hdc.move_to(0, 200) -hdc.line_to(200, 0) +hdc.text_color = 0x0000FF # red +hdc.move_to(50, 199) +hdc.line_to(199, 50) -#hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) +hdc.text_color = 0x00FF00 # green +hdc.move_to(250, 199) +hdc.line_to(100, 50) + +hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} while upiwin.get_message(msg): From 3d40bb294395ca2548e83d8553e26c072bf1e4d9 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:40:23 -0700 Subject: [PATCH 025/101] now disco debugging the clipping algorithm --- src/dc_screen.c | 10 ++++++++++ src/devctxt.c | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/dc_screen.c b/src/dc_screen.c index 31b3197..37d173e 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,4 +1,5 @@ #include +#include "log.h" #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" @@ -78,6 +79,15 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tmp; PUINT16 loc; + ASSERT(x1 >= 0); + ASSERT(x1 < Fb_Info->width); + ASSERT(y1 >= 0); + ASSERT(y1 < Fb_Info->height); + ASSERT(x2 >= 0); + ASSERT(x2 < Fb_Info->width); + ASSERT(y2 >= 0); + ASSERT(y2 < Fb_Info->height); + if (ABS(dx) < ABS(dy)) { if (y1 > y2) diff --git a/src/devctxt.c b/src/devctxt.c index 83fc8ab..c501005 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,5 +1,6 @@ #include #include +#include "log.h" #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" @@ -23,17 +24,27 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT BYTE outcode1, outcode2, tmpb; INT32 tmp; + Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, + xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); + /* 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) + { + Log.debug("*REJECT*"); return FALSE; /* trivial rejection */ + } else if ((outcode1 == 0) && (outcode2 == 0)) + { + Log.debug("*ACCEPT*"); break; /* trivial acceptance */ + } if (outcode1 == 0) { + Log(LDEBUG, "exchange points") tmp = x1; x1 = x2; x2 = tmp; @@ -48,23 +59,28 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); y1 = ymin; + Log.debug("clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); y1 = ymax; + Log.debug("clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); x1 = xmax; + Log.debug("clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); x1 = xmin; + Log.debug("clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } } + Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); output[0] = x1; output[1] = y1; output[2] = x2; From ddc005ed8b0523954c499c817336d973d3b23c3e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:42:40 -0700 Subject: [PATCH 026/101] logging needed work :) --- src/devctxt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c501005..f98c2bb 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -44,7 +44,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 == 0) { - Log(LDEBUG, "exchange points") + Log(LDEBUG, "exchange points"); tmp = x1; x1 = x2; x2 = tmp; @@ -59,25 +59,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); y1 = ymin; - Log.debug("clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); y1 = ymax; - Log.debug("clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); x1 = xmax; - Log.debug("clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); x1 = xmin; - Log.debug("clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 48415ab947ab4855eaf31c4cd3a5ffc012ffb4cc Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:43:30 -0700 Subject: [PATCH 027/101] again... --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index f98c2bb..bff4a34 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -34,12 +34,12 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) { - Log.debug("*REJECT*"); + Log(LDEBUG,"*REJECT*"); return FALSE; /* trivial rejection */ } else if ((outcode1 == 0) && (outcode2 == 0)) { - Log.debug("*ACCEPT*"); + Log(LDEBUG,"*ACCEPT*"); break; /* trivial acceptance */ } if (outcode1 == 0) From 7ed0dea017ea76b611db40129acde24661fd7f66 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:49:21 -0700 Subject: [PATCH 028/101] possible that numeric ordering is b0rking it? --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index bff4a34..e858330 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -57,25 +57,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); + x1 += (x2 - x1) * ((ymin - y1) / (y2 - y1)); y1 = ymin; Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { - x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); + x1 += (x2 - x1) * ((ymax - y1) / (y2 - y1)); y1 = ymax; Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { - y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); + y1 += (y2 - y1) * ((xmax - x1) / (x2 - x1)); x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { - y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); + y1 += (y2 - y1) * ((xmin - x1) / (x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } From 38219886106f8ad55d865be85b280a9004163e55 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:53:33 -0700 Subject: [PATCH 029/101] I think I reversed a sign somewhere --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index e858330..2fd12a4 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -69,13 +69,13 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x2) { - y1 += (y2 - y1) * ((xmax - x1) / (x2 - x1)); + y1 -= (y2 - y1) * ((xmax - x1) / (x2 - x1)); x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { - y1 += (y2 - y1) * ((xmin - x1) / (x2 - x1)); + y1 -= (y2 - y1) * ((xmin - x1) / (x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } From 3b7f326768abea95a571208e6a1992438798b3ba Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:59:27 -0700 Subject: [PATCH 030/101] more tracing --- src/devctxt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 2fd12a4..dc77110 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -57,27 +57,31 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - x1 += (x2 - x1) * ((ymin - y1) / (y2 - y1)); + tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); + x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x4) { - x1 += (x2 - x1) * ((ymax - y1) / (y2 - y1)); + tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); + x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x2) { - y1 -= (y2 - y1) * ((xmax - x1) / (x2 - x1)); + tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); + y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x1) { - y1 -= (y2 - y1) * ((xmin - x1) / (x2 - x1)); + tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); + y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 85144de58fe4da83f14d44179a7cf90c83e574a7 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:01:36 -0700 Subject: [PATCH 031/101] look at the unshifted d values --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index dc77110..ed6f0ed 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -60,28 +60,28 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x4) { tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x2) { tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x1) { tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 962f13dc1a01662fef0e224f9870216adeefd44e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:06:23 -0700 Subject: [PATCH 032/101] ever closer to a solution --- src/devctxt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index ed6f0ed..6c7bfe9 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -21,7 +21,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I 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; + BYTE outcode1, outcode2; INT32 tmp; Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, @@ -51,9 +51,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = y1; y1 = y2; y2 = tmp; - tmpb = outcode1; - outcode1 = outcode2; - outcode2 = tmpb; + outcode1 = outcode2; /* we don't reference outcode2 in the rest of the loop */ } if (outcode1 & 0x8) { @@ -78,6 +76,10 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x1) { + int term1 = y2 - y1; + int term2 = xmin - x1; + int term3 = x2 - x1; + Log(LDEBUG, "term1=%d term2=%d term3=%d", term1 >> 16, term2 >> 16, term3 >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; From 406c4fd85d394db4d8f16e3c6486627b5ab2daca Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:08:20 -0700 Subject: [PATCH 033/101] checking math again --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index 6c7bfe9..d98f96e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -79,7 +79,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT int term1 = y2 - y1; int term2 = xmin - x1; int term3 = x2 - x1; - Log(LDEBUG, "term1=%d term2=%d term3=%d", term1 >> 16, term2 >> 16, term3 >> 16); + Log(LDEBUG, "term1=%d term2=%d term3=%d i1=%d i2=%d", term1 >> 16, term2 >> 16, term3 >> 16, (term1 * term2) >> 16, (term2 / term3) >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; From d66aa4de24b117a587d3744c57c1a3b1fe6adafe Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:13:38 -0700 Subject: [PATCH 034/101] try with higher-precision variables --- src/devctxt.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index d98f96e..323aa5b 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -5,7 +5,7 @@ #include "gfxobj.h" #include "devctxt.h" -inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) { BYTE rc = 0; if (y < ymin) @@ -19,12 +19,12 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) { BYTE outcode1, outcode2; - INT32 tmp; + INT64 tmp; - Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, + Log(LDEBUG, "clipping line from (%lld, %lld) to (%lld, %lld) against bounding box (%lld, %lld, %lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ @@ -58,39 +58,35 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against top to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x4) { tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against bottom to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x2) { tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against right to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x1) { - int term1 = y2 - y1; - int term2 = xmin - x1; - int term3 = x2 - x1; - Log(LDEBUG, "term1=%d term2=%d term3=%d i1=%d i2=%d", term1 >> 16, term2 >> 16, term3 >> 16, (term1 * term2) >> 16, (term2 / term3) >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against left to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } } - Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); - output[0] = x1; - output[1] = y1; - output[2] = x2; - output[3] = y2; + Log(LDEBUG, "final line is from (%lld, %lld) to (%lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); + output[0] = (INT32)x1; + output[1] = (INT32)y1; + output[2] = (INT32)x2; + output[3] = (INT32)y2; return TRUE; } From 3996501cf086fb08f8ebb9240d660816f1678261 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:30:45 -0700 Subject: [PATCH 035/101] I don't understand fixed point arithmetic - this fixed that, I hope --- src/devctxt.c | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 323aa5b..e2ee2a7 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -5,7 +5,7 @@ #include "gfxobj.h" #include "devctxt.h" -inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) +inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { BYTE rc = 0; if (y < ymin) @@ -19,13 +19,19 @@ inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, I return rc; } -static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) +#define CPX 16 /* clipping precision in bits */ + +/* these macros keep the number of bits straight when doing fixed-point multiply & divide */ +#define M(a, b) ((((a) * (b))) >> CPX) +#define D(a, b) (((a) << CPX) / (b)) + +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; - INT64 tmp; + INT32 tmp; - Log(LDEBUG, "clipping line from (%lld, %lld) to (%lld, %lld) against bounding box (%lld, %lld, %lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, - xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); + Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, + xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) @@ -55,47 +61,47 @@ static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT } if (outcode1 & 0x8) { - tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); + tmp = M(x2 - x1, D(ymin - y1, y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x4) { - tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); + tmp = M(x2 - x1, D(ymax - y1, y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); + tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { - tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); + tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } } - Log(LDEBUG, "final line is from (%lld, %lld) to (%lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); - output[0] = (INT32)x1; - output[1] = (INT32)y1; - output[2] = (INT32)x2; - output[3] = (INT32)y2; + Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); + 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); + if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, + pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) + return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From da9658408aabb5d0b076d61770effce3fa410ed5 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:32:24 -0700 Subject: [PATCH 036/101] use lesser precision in hope it works --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index e2ee2a7..130b7de 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 16 /* clipping precision in bits */ +#define CPX 4 /* clipping precision in bits */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) From f5cab0010e73fda9a42f87a2b01ed43ef114531b Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:36:38 -0700 Subject: [PATCH 037/101] OK, NOW i think I'm on the right track - re-reverse the signs --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 130b7de..f6fb92b 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -76,14 +76,14 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT else if (outcode1 & 0x2) { tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); - y1 -= tmp; + y1 += tmp; x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); - y1 -= tmp; + y1 += tmp; x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } From 2b9853fd4c69e8844114e5815fdd1be683041353 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:41:41 -0700 Subject: [PATCH 038/101] boundary condition on right, attempting to bypass --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index f6fb92b..bafd68e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -100,7 +100,7 @@ static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) { INT32 buffer[4]; if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, - pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) + (pdctxt->cliprect.right - 1) << CPX, (pdctxt->cliprect.bottom - 1) << CPX)) return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From eee409d4e73d9676cbf8bec3aa71c4cd2a83a79a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:45:02 -0700 Subject: [PATCH 039/101] add an infinite loop detector --- src/devctxt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/devctxt.c b/src/devctxt.c index bafd68e..c6a41bb 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -29,6 +29,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { BYTE outcode1, outcode2; INT32 tmp; + int nloop = 0; Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); @@ -36,6 +37,11 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) { + if (++nloop == 20) + { + Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING"); + return FALSE; + } outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) From ab16513e3a710e173958de4c03ebc6b31d144177 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:48:02 -0700 Subject: [PATCH 040/101] 8-bit precision may be needed here --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c6a41bb..e16cbb3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 4 /* clipping precision in bits */ +#define CPX 8 /* clipping precision in bits */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) @@ -106,7 +106,7 @@ static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) { INT32 buffer[4]; if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, - (pdctxt->cliprect.right - 1) << CPX, (pdctxt->cliprect.bottom - 1) << CPX)) + pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From cfc7519727b0bb8ce19c7494c307ba89a3bce72f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:51:53 -0700 Subject: [PATCH 041/101] a fencepost error --- src/devctxt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index e16cbb3..234ac5e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,9 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 8 /* clipping precision in bits */ +#define CPX 4 /* clipping precision in bits */ + +#define ONE (1 << CPX) /* constant for mathematics */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) @@ -74,16 +76,16 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x4) { - tmp = M(x2 - x1, D(ymax - y1, y2 - y1)); + tmp = M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); x1 += tmp; - y1 = ymax; + y1 = ymax - ONE; Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); + tmp = M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); y1 += tmp; - x1 = xmax; + x1 = xmax - ONE; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) From d711df60bddac87fe1dc87105ca3c5095ce9abb6 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:55:26 -0700 Subject: [PATCH 042/101] try it with 8-bit precision --- src/devctxt.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 234ac5e..88a1f89 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 4 /* clipping precision in bits */ +#define CPX 8 /* clipping precision in bits */ #define ONE (1 << CPX) /* constant for mathematics */ @@ -69,29 +69,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - tmp = M(x2 - x1, D(ymin - y1, y2 - y1)); - x1 += tmp; + x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x4) { - tmp = M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); - x1 += tmp; + x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); - y1 += tmp; + y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { - tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); - y1 += tmp; + y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } From 02c8ede681add977ae0d9d18377441f9625bc737 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:56:48 -0700 Subject: [PATCH 043/101] remove use of tmp some places --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 88a1f89..9971cbc 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -71,25 +71,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x4) { x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x2) { y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x1) { y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> CPX, y1 >> CPX); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); From 59c8dcc6389de592d6c6e969247d5f1c21f39b57 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 15:00:51 -0700 Subject: [PATCH 044/101] a more extensive clipping test --- scripts/test_clipping.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 72df4a1..083cb9b 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -3,19 +3,27 @@ import upiwin hdc = upiwin.DevCtxt(type='screen') hdc.text_color = 0xFFFFFF # white -hdc.rectangle(100, 100, 199, 199) +hdc.rectangle(99, 99, 200, 200) clip = hdc.get_clip_rect() hdc.set_clip_rect(100, 100, 200, 200) hdc.text_color = 0x0000FF # red -hdc.move_to(50, 199) -hdc.line_to(199, 50) +hdc.move_to(50, 200) +hdc.line_to(200, 50) hdc.text_color = 0x00FF00 # green -hdc.move_to(250, 199) +hdc.move_to(250, 200) hdc.line_to(100, 50) +hdc.text_color = 0xFF0000 # blue +hdc.move_to(50, 100) +hdc.line_to(200, 250) + +hdc.text_color = 0x00FFFF # yellow +hdc.move_to(250, 100) +hdc.line_to(100, 250) + hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} From b390886277cf4b4211f3f53038a8d8f5726750da Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 17:09:16 -0700 Subject: [PATCH 045/101] work in progress - support for bitmaps and BitBlt --- src/Makefile | 2 +- src/bitmap.c | 25 ++++++++++++ src/bitmap.h | 19 +++++++++ src/dc_screen.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-- src/dc_screen.h | 1 + src/devctxt.c | 61 ++++++++++++++++++++++++++- src/devctxt.h | 23 ++++++++++- src/ep_devctxt.c | 52 +++++++++++++++++++++++- 8 files changed, 278 insertions(+), 9 deletions(-) create mode 100755 src/bitmap.c create mode 100755 src/bitmap.h diff --git a/src/Makefile b/src/Makefile index 86ff8a0..df44460 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png 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 \ + fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o bitmap.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/bitmap.c b/src/bitmap.c new file mode 100755 index 0000000..180d3f8 --- /dev/null +++ b/src/bitmap.c @@ -0,0 +1,25 @@ +#include +#include +#include "bitmap.h" + +PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits) +{ + PBITMAP rc; + UINT32 tot_size = sizeof(BITMAP) + (width * height * sizeof(UINT16)); + + rc = (PBITMAP)malloc(tot_size); + if (!rc) + return NULL; + memset(rc, 0, tot_size); + _Go_init(&(rc->hdr), BMP_SIG_WORD, tot_size); + rc->width = width; + rc->height = height; + if (bits) + memcpy(rc->bits, bits, width * height * sizeof(UINT16)); + return rc; +} + +void BMP_Delete(PBITMAP pbmp) +{ + Go_release(&(pbmp->hdr)); +} diff --git a/src/bitmap.h b/src/bitmap.h new file mode 100755 index 0000000..db09917 --- /dev/null +++ b/src/bitmap.h @@ -0,0 +1,19 @@ +#ifndef __BITMAP_H_INCLUDED +#define __BITMAP_H_INCLUDED + +#include "wintype.h" +#include "gfxobj.h" + +#define BMP_SIG_WORD 0x706D4221 /* !Bmp */ + +typedef struct tagBITMAP { + GFXOBJECT hdr; + INT32 width; + INT32 height; + UINT16 bits[0]; +} BITMAP, *PBITMAP; + +extern PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits); +extern void BMP_Delete(PBITMAP pbmp); + +#endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/dc_screen.c b/src/dc_screen.c index 37d173e..caf5595 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -3,6 +3,7 @@ #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" +#include "bitmap.h" inline static PUINT16 loc_from_coords(PSCREENPRIVDATA priv, INT32 x, INT32 y) { @@ -151,9 +152,97 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, return TRUE; } +static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 op) +{ + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + UINT16 pencolor = native_from_COLORREF(color); + PUINT16 ps, p; + int y, x; + + ps = loc_from_coords(rect->left, rect->top); + for (y = rect->top; y < rect->bottom; y++) + { + p = ps; + for (x = rect->left; x < rect->right; x++) + { + *p = apply_rop2(op, *p, pencolor); + ++p; + } + ps += priv->pix_per_row; + } + return TRUE; +} + +static PDCTXT screen_create_compat(PVOID privdata) +{ + PSCREENPRIVDATA priv_new; + PBITMAP pbmp; + + pbmp = BMP_Create(1, 1, NULL); + if (!pbmp) + return NULL; + priv_new = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA)); + if (!priv_new) + { + Go_release(&(pbmp->hdr)); + return NULL; + } + priv_new->pix_per_row = pbmp->width; + priv_new->pdata = pbmp->bits; + + rc = _DC_Allocate(&screen_funtable, priv_new); + if (rc) + { + rc->hdr.dtor = screen_context_destroy; + rc->flags = DCFLG_IS_MEMORY; + rc->baserect.left = rc->baserect.top = 0; + rc->baserect.right = pbmp->width; + rc->baserect.bottom = pbmp->height; + memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); + rc->cur_bitmap = pbmp; + } + else + { + free(priv); + Go_release(&(pbmp->hdr)); + } + return rc; +} + +BOOL screen_new_bitmap(PVOID privdata, PBITMAP pbmp) +{ + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + priv->pix_per_row = pbmp->width; + priv->pdata = pbmp->bits; + return TRUE; +} + +BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op) +{ + PSCREENPRIVDATA dest = (PSCREENPRIVDATA)p_dest; + PSCREENPRIVDATA src = (PSCREENPRIVDATA)p_src; + PUINT16 pd, ps; + INT32 width, i; + + pd = loc_from_coords(dest, r_dest->left, r_dest->top); + ps = loc_from_coords(src, r_src->left, r_src->top); + width = r_src->right - r_src->left; + for (i = r_src->top; i < r_src->bottom; ++i) + { + memcpy(pd, ps, width * sizeof(UINT16)); + pd += dest->pix_per_row; + ps += src->pix_per_row; + } + return TRUE; +} + static const DCFUNTABLE screen_funtable = { screen_set_pixel, - screen_line + screen_line, + screen_solid_rect, + screen_create_compat, + screen_new_bitmap, + screen_bitblt }; static void screen_context_destroy(PVOID obj) @@ -178,11 +267,18 @@ PDCTXT DC_CreateScreenContext(void) 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; + rc->flags = DCFLG_IS_SCREEN; + rc->baserect.left = rc->baserect.top = 0; + rc->baserect.right = Fb_Info->width; + rc->baserect.bottom = Fb_Info->height; + memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); } else free(priv); return rc; } + +PDCTXT _DC_CreateScreenCompatibleContext(void) +{ + return screen_create_compat(NULL); +} diff --git a/src/dc_screen.h b/src/dc_screen.h index ecd4f31..560187c 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -10,5 +10,6 @@ typedef struct tagSCREENPRIVDATA { } SCREENPRIVDATA, *PSCREENPRIVDATA; extern PDCTXT DC_CreateScreenContext(void); +extern PDCTXT _DC_CreateScreenCompatibleContext(void); #endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c index 9971cbc..9e954d3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -4,6 +4,8 @@ #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" +#include "bitmap.h" +#include "dc_screen.h" inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { @@ -124,7 +126,8 @@ PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata) void _DC_FinalizeCommon(PDCTXT pdctxt) { - /* nothing here yet */ + if (pdctxt->cur_bitmap) + Go_release(&(pdctxt->cur_bitmap->hdr)); } COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) @@ -163,6 +166,15 @@ BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 botto return TRUE; } +BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom) +{ + RECT rect, actual; + G_set_rect(&rect, left, top, right, bottom); + if (!G_intersect_rect(&actual, &rect, &(pdctxt->cliprect))) + return TRUE; + return (*(pdctxt->funcs-solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); +} + UINT32 DC_GetROP2(PDCTXT pdctxt) { return pdctxt->rop2; @@ -198,3 +210,50 @@ BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect) memcpy(&(pdctxt->cliprect), prect, sizeof(RECT)); return TRUE; } + +PDCTXT DC_CreateCompatible(PDCTXT pdctxt) +{ + if (pdctxt) + return (*(pdctxt->funcs->create_compat))(pdctxt->privdata); + return _DC_CreateScreenCompatibleContext(); +} + +PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) +{ + if (pobj->sig == BMP_SIG_WORD) + { + if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY) + { + RECT rtmp; + PBITMAP rbmp = pdctxt->cur_bitmap; + Go_addref(pobj); + if ((*(pdctxt->funcs->new_bitmap))(pdctxt->privdata, (PBITMAP)pobj)) + { + pdctxt->cur_bitmap = (PBITMAP)pobj; + pdctxt->baserect.left = pdctxt->baserect.top = 0; + pdctxt->baserect.right = ((PBITMAP)pobj)->width; + pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; + G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); + memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); + return rbmp; + } + Go_release(pobj); + } + } + return NULL; +} + +BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop) +{ + RECT destrect, actualdest, srcrect, actualsrc; + + G_set_rect(&destrect, x, y, x + width, y + height); + if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect))) + return TRUE; /* no-op */ + G_set_rect(&srcrect, x1, y1, x1 + (actualdest.right - actualdest.left), y1 + (actualdest.bottom - actualdest.top)); + if (!G_rect_intersect(&actualsrc, &srcrect, &(src->baserect))) + return TRUE; + actualdest.right = actualdest.left + (actualsrc.right - actualsrc.left); + actualdest.bottom = actualdest.top + (actualsrc.bottom - actualsrc.top); + return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, src->privdata, &actualsrc, rop); +} diff --git a/src/devctxt.h b/src/devctxt.h index 1b8d3a4..327aab3 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -27,10 +27,18 @@ 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 BOOL (*DCtx_SolidRect)(PVOID privdata, PRECT rect, COLORREF color, INT32 op); +typedef PDCTXT (*DCtx_CreateCompat)(PVOID privdata); +typedef BOOL (*DCtx_NewBitmap)(PVOID privdata, PBITMAP pbmp); +typedef BOOL (*DCtx_BitBlt)(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op); typedef struct tagDCFUNTABLE { - DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ - DCtx_Line line; /* draws a line on the display */ + DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ + DCtx_Line line; /* draws a line on the display */ + DCtx_SolidRect solid_rect; /* draws a solid rectangle on the display */ + DCtx_CreateCompat create_compat; /* create a memory DC compatible with this one */ + DCtx_NewBitmap new_bitmap; /* new bitmap selected notification */ + DCtx_BitBlt bitblt; /* bit block transfer */ } DCFUNTABLE; typedef const DCFUNTABLE *PDCFUNTABLE; @@ -39,12 +47,19 @@ typedef struct tagDCTXT { GFXOBJECT hdr; /* the header of all objects */ PDCFUNTABLE funcs; /* device context functions */ PVOID privdata; /* private data for the type of DC */ + UINT32 flags; /* flags for the DC */ + RECT baserect; /* base rectangle */ RECT cliprect; /* clipping rectangle */ POINT pos; /* current position */ UINT32 rop2; /* current raster operation */ COLORREF color; /* current drawing color (XXX replace with pens later) */ + PBITMAP cur_bitmap; /* current selected bitmap */ } DCTXT, *PDCTXT; +#define DCFLG_TYPES 0x03 +#define DCFLG_IS_SCREEN 0x00 +#define DCFLG_IS_MEMORY 0x01 + extern PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata); extern void _DC_FinalizeCommon(PDCTXT pdctxt); @@ -52,12 +67,16 @@ 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 BOOL DC_SolidRectangle(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); +extern PDCTXT DC_CreateCompatible(PDCTXT pdctxt); +extern PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj); +extern BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop); #define DC_addref(pdctxt) Go_addref(&(pdctxt->hdr)) #define DC_release(pdctxt) Go_release(&(pdctxt->hdr)) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 651f317..e61611e 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -13,6 +13,8 @@ typedef struct tagDevCtxtObject { PDCTXT pdctxt; } DevCtxtObject; +PyTypeObject DevCtxtType; /* forward declaration */ + static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args) { INT32 x, y; @@ -77,6 +79,41 @@ static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args) return PyBool_FromLong(rc); } +static PyObject *devctxt_solid_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_SolidRectangle(self->pdctxt, left, top, right, bottom); + return PyBool_FromLong(rc); +} + +static PyObject *devctxt_bitblt(DevCtxtObject *self, PyObject *args) +{ + INT32 x, y, width, height, x1, y1; + UINT32 rop; + DevCtxtObject *source; + BOOL rc; + + if (!PyArg_ParseTuple(args, "iiiiO!iik", &x, &y, &width, &height, &DevCtxtType, &source, &x1, &y1, &rop)) + return NULL; + if (!(self->pdctxt) || !(source->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + + rc = DC_BitBlt(self->pdctxt, x, y, width, height, source->pdctxt, x1, y1, rop); + return PyBool_FromLong(rc); +} + static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args) { RECT rect; @@ -117,6 +154,10 @@ static PyMethodDef DevCtxtMethods[] = { "Draws a line from the current position to the specified location."}, {"rectangle", (PyCFunction)devctxt_rectangle, METH_VARARGS, "Draws a rectangle."}, + {"solid_rectangle", (PyCFunction)devctxt_solid_rectangle, METH_VARARGS, + "Draws a solid rectangle."}, + {"bitblt", (PyCFunction)devctxt_bitblt, METH_VARARGS, + "Copy bits from one device context to another."}, {"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, @@ -218,6 +259,15 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) return -1; } } + else if (strcmp(type, "memory") == 0) + { + self->pdctxt = _DC_CreateScreenCompatibleContext(); + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "unable to create memory context"); + return -1; + } + } else { PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type); @@ -226,7 +276,7 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) return 0; } -static PyTypeObject DevCtxtType = { +PyTypeObject DevCtxtType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "upiwin.DevCtxt", .tp_doc = "Device context object", From 20ed16a9ae7ab900a1ea92e24c0d8759e5913a71 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:45:45 -0700 Subject: [PATCH 046/101] sending over all the bitmap and select_object work for compile check --- src/Makefile | 6 +-- src/dc_screen.c | 1 + src/devctxt.c | 15 ------ src/ep_bitmap.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ src/ep_devctxt.c | 59 +++++++++++++++++++---- src/ep_types.h | 28 +++++++++++ 6 files changed, 202 insertions(+), 26 deletions(-) create mode 100755 src/ep_bitmap.c create mode 100755 src/ep_types.h diff --git a/src/Makefile b/src/Makefile index df44460..eb11555 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,9 +2,9 @@ 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_devctxt.o ep_upiwin_tmp.o ep_util.o \ - fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o bitmap.o fbprimitive.o \ - log.o gpio.o msg_queue.o time_func.o config.o splash.o +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o + ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ + bitmap.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT diff --git a/src/dc_screen.c b/src/dc_screen.c index caf5595..e6f5149 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -89,6 +89,7 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, ASSERT(y2 >= 0); ASSERT(y2 < Fb_Info->height); + /* uses Bresenham's line algorithm with 16-bit fixed-point arithmetic */ if (ABS(dx) < ABS(dy)) { if (y1 > y2) diff --git a/src/devctxt.c b/src/devctxt.c index 9e954d3..4d342f7 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -35,9 +35,6 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT INT32 tmp; int nloop = 0; - Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, - xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); - /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) { @@ -49,18 +46,11 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) - { - Log(LDEBUG,"*REJECT*"); return FALSE; /* trivial rejection */ - } else if ((outcode1 == 0) && (outcode2 == 0)) - { - Log(LDEBUG,"*ACCEPT*"); break; /* trivial acceptance */ - } if (outcode1 == 0) { - Log(LDEBUG, "exchange points"); tmp = x1; x1 = x2; x2 = tmp; @@ -73,28 +63,23 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x4) { x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; - Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x2) { y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; - Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x1) { y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> CPX, y1 >> CPX); } } - Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); output[0] = x1; output[1] = y1; output[2] = x2; diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c new file mode 100755 index 0000000..9f99ac6 --- /dev/null +++ b/src/ep_bitmap.c @@ -0,0 +1,119 @@ +#include +#define PY_SSIZE_T_CLEAN +#include +#include "gfxobj.h" +#include "bitmap.h" +#include "ep_types.h" + +static PyMethodDef BitmapMethods[] = { + {NULL, NULL, 0, NULL} +}; + +static PyObject *bitmap_get_width(BitmapObject *self, void *closure) +{ + if (!(self->pbmp)) + { + PyErr_SetString(PyExc_RuntimeError, "bad bitmap object"); + return NULL; + } + return PyLong_FromUnsignedLong(self->pbmp->width); +} + +static PyObject *bitmap_get_height(BitmapObject *self, void *closure) +{ + if (!(self->pbmp)) + { + PyErr_SetString(PyExc_RuntimeError, "bad bitmap object"); + return NULL; + } + return PyLong_FromUnsignedLong(self->pbmp->height); +} + +static PyGetSetDef BitmapProperties[] = { + {"width", (getter)bitmap_get_width, NULL, + "Width of this bitmap", NULL}, + {"height", (getter)bitmap_get_height, NULL, + "Height of this bitmap", NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = { "width", "height", NULL }; + int width = 0, height = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$ii", kwlist, &width, &height)) + return -1; + + width = MAX(1, width); + height = MAX(1, height); + self->pbmp = BMP_Create(width, height, NULL); + if (!(self->bmp)) + { + PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); + return -1; + } + return 0; +} + +static void bitmap_dealloc(BitmapObject *self) +{ + if (self->pbmp) + BMP_Delete(self->pbmp); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +PyTypeObject BitmapType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "upiwin.Bitmap", + .tp_doc = "Bitmap object", + .tp_basicsize = sizeof(BitmapObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)bitmap_init, + .tp_dealloc = (destructor)bitmap_dealloc, + .tp_methods = BitmapMethods, + .tp_getset = BitmapProperties, +}; + +HRESULT Epython_register_bitmap(PyObject *module) +{ + if (PyType_Ready(&BitmapType) < 0) + return E_FAIL; + Py_INCREF(&BitmapType); + if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0) + { + Py_DECREF(&BitmapType); + return E_FAIL; + } + return S_OK; +} + +PyObject *Epython_wrap_bitmap(PBITMAP pbmp) +{ + PyObject *rc = NULL, *args, *kwargs; + BitmapObject *pbitmapobj; + + args = PyTuple_New(0); + if (args) + { + kwargs = PyDict_New(); + if (kwargs) + { + rc = PyType_GenericNew(&BitmapType, args, kwargs); + if (rc) + { + pbitmapobj = (BitmapObject)rc; + BMP_Delete(pbitmapobj->pbmp); + pbitmapobj->pbmp = pbmp; + } + Py_DECREF(kwargs); + } + Py_DECREF(args); + } + + if (!rc) + PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); + return rc; +} diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index e61611e..09c0687 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -7,13 +7,7 @@ #include "devctxt.h" #include "dc_screen.h" #include "ep_init.h" - -typedef struct tagDevCtxtObject { - PyObject_HEAD - PDCTXT pdctxt; -} DevCtxtObject; - -PyTypeObject DevCtxtType; /* forward declaration */ +#include "ep_types.h" static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args) { @@ -145,6 +139,54 @@ static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args) return PyBool_FromLong(rc); } +static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp) +{ + BitmapObject *old_bitmap = NULL; + PBITMAP old_pbmp; + + if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) + { + PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); + return NULL; + } + old_bitmap = self->selected_bitmap; + old_pbmp = DC_SelectObject(self->pdctxt, newbmp->pbmp); + if (!old_bitmap) + { + old_bitmap = Epython_wrap_bitmap(old_pbmp); + if (!old_bitmap) + { + DC_SelectObject(self->pdctxt, old_pbmp); + return NULL; + } + else + PY_INCREF(old_bitmap); + } + Py_DECREF(self->selected_bitmap); + self->selected_bitmap = newbmp; + Py_INCREF(self->selected_bitmap); + return old_bitmap; +} + +static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) +{ + PyObject *obj; + PBITMAP old_bitmap; + BitmapObject *old_bmp_object, *new_bmp_object; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + if (!obj) + { + PyErr_SetString(PyExc_RuntimeError, "bad object selected"); + return NULL; + } + if (PyObject_TypeCheck(obj, &BitmapType)) + return devctxt_select_bitmap(self, (BitmapObject *)obj); + PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); + return NULL; +} + static PyMethodDef DevCtxtMethods[] = { {"set_pixel", (PyCFunction)devctxt_set_pixel, METH_VARARGS, "Sets a single pixel on the display."}, @@ -158,6 +200,8 @@ static PyMethodDef DevCtxtMethods[] = { "Draws a solid rectangle."}, {"bitblt", (PyCFunction)devctxt_bitblt, METH_VARARGS, "Copy bits from one device context to another."}, + {"select_object", (PyCFunction)devctxt_select_object, METH_VARARGS, + "Selects a graphic object into the device context."}, {"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, @@ -165,7 +209,6 @@ static PyMethodDef DevCtxtMethods[] = { {NULL, NULL, 0, NULL} }; - static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure) { if (!(self->pdctxt)) diff --git a/src/ep_types.h b/src/ep_types.h new file mode 100755 index 0000000..55d2eae --- /dev/null +++ b/src/ep_types.h @@ -0,0 +1,28 @@ +#ifndef __EP_TYPES_H_INCLUDED +#define __EP_TYPES_H_INCLUDED + +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "gfxtype.h" +#include "gfxobj.h" +#include "devctxt.h" +#include "bitmap.h" + +typedef struct tagBitmapObject { + PyObject_HEAD + PBITMAP pbmp; +} BitmapObject; + +typedef struct tagDevCtxtObject { + PyObject_HEAD + PDCTXT pdctxt; + BitmapObject *selected_bitmap; +} DevCtxtObject; + +extern PyTypeObject DevCtxtType; +extern PyTypeObject BitmapType; + +extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp); + +#endif /* __EP_TYPES_H_INCLUDED */ From ee3df7bffcfcacbd489ec90cf18c7e21ac680bed Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:47:45 -0700 Subject: [PATCH 047/101] forgot to add the registration of the Bitmap type --- src/ep_upiwin.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 9878d3c..a8e33e9 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -81,6 +81,12 @@ PyObject *Epython_init_upiwin_module(void) return NULL; } + if (FAILED(Epython_register_bitmap(module))) + { + Py_DECREF(module); + return NULL; + } + if (FAILED(Epython_register_devctxt(module))) { Py_DECREF(module); From 76269f51897fdc0dbd9ed9e7bcf4240800a670d1 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Wed, 11 Dec 2019 10:50:59 -0700 Subject: [PATCH 048/101] fix to makefile --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index eb11555..dd7ba89 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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_devctxt.o ep_bitmap.o +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.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 From 379bcab8851aee6ec58872d511cf65f0dde38733 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:50:39 -0700 Subject: [PATCH 049/101] fixes to some headers that were missing stuff --- src/devctxt.h | 1 + src/ep_init.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/devctxt.h b/src/devctxt.h index 327aab3..f83fa2b 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -4,6 +4,7 @@ #include "wintype.h" #include "gfxtype.h" #include "gfxobj.h" +#include "bitmap.h" #define DCTXT_SIG_WORD 0x78744344 /* "DCtx */ diff --git a/src/ep_init.h b/src/ep_init.h index e394470..5e68ef4 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -15,6 +15,7 @@ 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_register_bitmap(PyObject *module); extern HRESULT Epython_setup(void); extern HRESULT Epython_run(void); From 4745d51361d5979688f6bcd3a1fde5d292809509 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:54:09 -0700 Subject: [PATCH 050/101] fix some compile errors --- src/bitmap.c | 2 +- src/bitmap.h | 2 +- src/devctxt.h | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/bitmap.c b/src/bitmap.c index 180d3f8..fa517ea 100755 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -2,7 +2,7 @@ #include #include "bitmap.h" -PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits) +PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits) { PBITMAP rc; UINT32 tot_size = sizeof(BITMAP) + (width * height * sizeof(UINT16)); diff --git a/src/bitmap.h b/src/bitmap.h index db09917..f7500b5 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -13,7 +13,7 @@ typedef struct tagBITMAP { UINT16 bits[0]; } BITMAP, *PBITMAP; -extern PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits); +extern PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits); extern void BMP_Delete(PBITMAP pbmp); #endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/devctxt.h b/src/devctxt.h index f83fa2b..017e70a 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -26,10 +26,12 @@ #define R2_MERGEPEN 15 #define R2_WHITE 16 +struct tagDCTXT; /* forward declaration */ + 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 BOOL (*DCtx_SolidRect)(PVOID privdata, PRECT rect, COLORREF color, INT32 op); -typedef PDCTXT (*DCtx_CreateCompat)(PVOID privdata); +typedef struct tagDCTXT *(*DCtx_CreateCompat)(PVOID privdata); typedef BOOL (*DCtx_NewBitmap)(PVOID privdata, PBITMAP pbmp); typedef BOOL (*DCtx_BitBlt)(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op); From 864360f9faa5680367c9d9cae322af1d6e4892f1 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:57:07 -0700 Subject: [PATCH 051/101] compile errors in new stuff --- src/ep_bitmap.c | 3 ++- src/ep_devctxt.c | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 9f99ac6..4f4f3a6 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -1,6 +1,7 @@ #include #define PY_SSIZE_T_CLEAN #include +#include "scode.h" #include "gfxobj.h" #include "bitmap.h" #include "ep_types.h" @@ -48,7 +49,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); - if (!(self->bmp)) + if (!(self->pbmp)) { PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); return -1; diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 09c0687..1300692 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -165,14 +165,12 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); - return old_bitmap; + return (PyObject *)old_bitmap; } static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - PBITMAP old_bitmap; - BitmapObject *old_bmp_object, *new_bmp_object; if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; From 971826e1189df203f8145415d7f9e17c6b07e55d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:59:14 -0700 Subject: [PATCH 052/101] more pushing of errors --- src/ep_bitmap.c | 2 +- src/ep_devctxt.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 4f4f3a6..abb2406 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -105,7 +105,7 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) rc = PyType_GenericNew(&BitmapType, args, kwargs); if (rc) { - pbitmapobj = (BitmapObject)rc; + pbitmapobj = (BitmapObject *)rc; BMP_Delete(pbitmapobj->pbmp); pbitmapobj->pbmp = pbmp; } diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 1300692..4e77134 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -156,11 +156,11 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp old_bitmap = Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { - DC_SelectObject(self->pdctxt, old_pbmp); + DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } else - PY_INCREF(old_bitmap); + Py_INCREF(old_bitmap); } Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; From e59e6e0bae8512d313a0f6ba3f7b210d85cdeb85 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:04:09 -0700 Subject: [PATCH 053/101] more compile errors --- src/devctxt.c | 6 +++--- src/ep_devctxt.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 4d342f7..c1ea7e3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -220,7 +220,7 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); - return rbmp; + return (PGFXOBJECT)rbmp; } Go_release(pobj); } @@ -236,9 +236,9 @@ BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect))) return TRUE; /* no-op */ G_set_rect(&srcrect, x1, y1, x1 + (actualdest.right - actualdest.left), y1 + (actualdest.bottom - actualdest.top)); - if (!G_rect_intersect(&actualsrc, &srcrect, &(src->baserect))) + if (!G_rect_intersect(&actualsrc, &srcrect, &(source->baserect))) return TRUE; actualdest.right = actualdest.left + (actualsrc.right - actualsrc.left); actualdest.bottom = actualdest.top + (actualsrc.bottom - actualsrc.top); - return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, src->privdata, &actualsrc, rop); + return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, source->privdata, &actualsrc, rop); } diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 4e77134..9449865 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -150,7 +150,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp return NULL; } old_bitmap = self->selected_bitmap; - old_pbmp = DC_SelectObject(self->pdctxt, newbmp->pbmp); + old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); if (!old_bitmap) { old_bitmap = Epython_wrap_bitmap(old_pbmp); From c388dbc1d265625fd3b1519c7b52e8e3d7438da8 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:05:36 -0700 Subject: [PATCH 054/101] more errors --- src/devctxt.c | 4 ++-- src/ep_devctxt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c1ea7e3..2830f13 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -155,9 +155,9 @@ BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 { RECT rect, actual; G_set_rect(&rect, left, top, right, bottom); - if (!G_intersect_rect(&actual, &rect, &(pdctxt->cliprect))) + if (!G_rect_intersect(&actual, &rect, &(pdctxt->cliprect))) return TRUE; - return (*(pdctxt->funcs-solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); + return (*(pdctxt->funcs->solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); } UINT32 DC_GetROP2(PDCTXT pdctxt) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 9449865..87a407c 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -153,7 +153,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); if (!old_bitmap) { - old_bitmap = Epython_wrap_bitmap(old_pbmp); + old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); From d7439be3206265400df7fcaca43e316a4e544bee Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:09:40 -0700 Subject: [PATCH 055/101] still plugging away at errors --- src/dc_screen.c | 6 ++++-- src/devctxt.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index e6f5149..d248013 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,4 +1,5 @@ #include +#inlcude #include "log.h" #include "fbinit.h" #include "devctxt.h" @@ -160,7 +161,7 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 PUINT16 ps, p; int y, x; - ps = loc_from_coords(rect->left, rect->top); + ps = loc_from_coords(priv, rect->left, rect->top); for (y = rect->top; y < rect->bottom; y++) { p = ps; @@ -178,6 +179,7 @@ static PDCTXT screen_create_compat(PVOID privdata) { PSCREENPRIVDATA priv_new; PBITMAP pbmp; + PDCTXT rc; pbmp = BMP_Create(1, 1, NULL); if (!pbmp) @@ -204,7 +206,7 @@ static PDCTXT screen_create_compat(PVOID privdata) } else { - free(priv); + free(priv_new); Go_release(&(pbmp->hdr)); } return rc; diff --git a/src/devctxt.c b/src/devctxt.c index 2830f13..217a0e3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -218,7 +218,7 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) pdctxt->baserect.left = pdctxt->baserect.top = 0; pdctxt->baserect.right = ((PBITMAP)pobj)->width; pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; - G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); + G_rect_intersect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); return (PGFXOBJECT)rbmp; } From 899be01f288eef596949e4db44baab25e985ae0f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:12:15 -0700 Subject: [PATCH 056/101] should be most of it now --- src/dc_screen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index d248013..29c4050 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,5 +1,5 @@ #include -#inlcude +#include #include "log.h" #include "fbinit.h" #include "devctxt.h" @@ -175,6 +175,9 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 return TRUE; } +static const DCFUNTABLE screen_funtable; /* forward declaration */ +static void screen_context_destroy(PVOID obj); + static PDCTXT screen_create_compat(PVOID privdata) { PSCREENPRIVDATA priv_new; From 7c844e6b69f18a4978f7888637bff5f47ea993ce Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:13:44 -0700 Subject: [PATCH 057/101] use -Werror to make all warnings into errors (should have done this already) --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index dd7ba89..95a4c9e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,7 +7,7 @@ OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt. bitmap.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 CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ - -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT + -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \ -Wl,-Bsymbolic-functions From 65999084c442d6d4334ecc04e2c774e36d0e12bf Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:32:19 -0700 Subject: [PATCH 058/101] added "click" events for both buttons and touch --- scripts/tmp_main.py | 4 ++++ src/config.c | 2 ++ src/config.h | 2 ++ src/ep_upiwin.c | 2 ++ src/msg.h | 2 ++ src/sysinput.c | 21 +++++++++++++++++++++ 6 files changed, 33 insertions(+) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 815aa44..902d767 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -25,6 +25,8 @@ while upiwin.get_message(msg): print("Button {0} was pressed.".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: print("Button {0} was released.".format(msg['attrs'][0])) + elif msg['message'] == upiwin.WM_HWBUTTONCLICK: + print("Button {0} was clicked.".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: print("Backlight ON.") @@ -41,3 +43,5 @@ while upiwin.get_message(msg): log_touch('MOVE', msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_TOUCHUP: log_touch('UP', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHCLICK: + log_touch('CLICK', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/config.c b/src/config.c index cc2b67f..7f5dfe7 100644 --- a/src/config.c +++ b/src/config.c @@ -70,6 +70,8 @@ static void init_defaults(void) Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; + Gconfig.click_time = 200; + Gconfig.click_radius = 2; } static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) diff --git a/src/config.h b/src/config.h index 0a514a7..22253ac 100644 --- a/src/config.h +++ b/src/config.h @@ -12,6 +12,8 @@ typedef struct tagGLOBAL_CONFIG { PCSTR python_loc; /* location of the Python3 executable */ UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ UINT32 sys_mq_length; /* length of system message queue */ + UINT32 click_time; /* time between button/touch DOWN and UP to be considered a "click" (ms) */ + UINT32 click_radius; /* maximum number of pixels a touch can "drift" to be considered a "click" */ PCSTR script_name; /* script name to be run */ INT32 script_arg_count; /* number of arguments to pass to the script */ PPCSTR script_args; /* arguments to pass to the script */ diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index a8e33e9..1354d06 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -44,9 +44,11 @@ BEGIN_CONSTANT_TABLE(UPIWINConstants) CONSTANT_INT_MACRO(WM_QUIT) CONSTANT_INT_MACRO(WM_HWBUTTONDOWN) CONSTANT_INT_MACRO(WM_HWBUTTONUP) + CONSTANT_INT_MACRO(WM_HWBUTTONCLICK) CONSTANT_INT_MACRO(WM_TOUCHDOWN) CONSTANT_INT_MACRO(WM_TOUCHMOVE) CONSTANT_INT_MACRO(WM_TOUCHUP) + CONSTANT_INT_MACRO(WM_TOUCHCLICK) /* Raster op constants */ CONSTANT_INT_MACRO(R2_BLACK) CONSTANT_INT_MACRO(R2_NOTMERGEPEN) diff --git a/src/msg.h b/src/msg.h index 7778bde..afff6a9 100644 --- a/src/msg.h +++ b/src/msg.h @@ -17,9 +17,11 @@ typedef struct tagMSG { #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 +#define WM_HWBUTTONCLICK 0x0022 #define WM_TOUCHDOWN 0x0030 #define WM_TOUCHMOVE 0x0031 #define WM_TOUCHUP 0x0032 +#define WM_TOUCHCLICK 0x0033 #endif /* __MSG_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index 44335bd..9419d5d 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -28,11 +28,14 @@ static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for /* Local data for poll_buttons() */ static UINT32 last_bstate = 0; /* previous button state */ static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ +static TIMESTAMP button_down_time[GPIO_BUTTON_COUNT]; /* timestamps for click detection */ /* Local data for poll_touchscreen() */ static UINT_PTR touch_x = 0; /* X coordinate to send with next message */ static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ +static UINT_PTR touch_down_x, touch_down_y; /* location of the touch-down event for click detection */ +static TIMESTAMP touch_down_time; /* timestamp for click detection */ static BOOL poll_buttons(void) { @@ -57,11 +60,14 @@ static BOOL poll_buttons(void) /* reset contact bounce timer - only seems to happen after button releases */ button_event_ok[attr - 1] = now + Gconfig.button_debounce; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + if ((now - button_down_time[attr - 1]) <= Gconfig.click_time) + Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr); posted = TRUE; } else if (down & mask) { Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + button_down_time[attr - 1] = now; posted = TRUE; } } @@ -74,6 +80,7 @@ static BOOL poll_touchscreen(void) { BOOL posted = FALSE; int nb, nev, xerrno, i; + TIMESTAMP now; struct input_event buffer[INPUT_EVENT_BATCH]; nb = read(ts_fd, buffer, INPUT_EVENT_BATCH * sizeof(struct input_event)); @@ -102,7 +109,21 @@ static BOOL poll_touchscreen(void) case EV_SYN: if (buffer[i].code == SYN_REPORT) { + now = Time_since_start(); Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); + if (touch_nextmsg == WM_TOUCHDOWN) + { + touch_down_x = touch_x; + touch_down_y = touch_y; + touch_down_time = now; + } + else if (touch_nextmsg = WM_TOUCHUP) + { + if ( ((now - touch_down_time) <= Gconfig.click_time) + && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) + && (ABS((INT32)touch_y - (INT32)touch_down_y) <= Gconfig.click_radius)) + Mq_post2(Sys_Queue, 0, WM_TOUCHCLICK, touch_x, touch_y); + } touch_nextmsg = WM_TOUCHMOVE; posted = TRUE; } From 1088f630a0e2df70660c6b3a1a41f6ddf39b0b38 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:05:53 -0700 Subject: [PATCH 059/101] added the rgb function to upiwin and started building the demo script --- scripts/demo1.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile | 2 +- src/ep_graphics.c | 13 +++++++++++ src/ep_upiwin.c | 3 +++ src/ep_upiwin.h | 2 ++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100755 scripts/demo1.py create mode 100755 src/ep_graphics.c diff --git a/scripts/demo1.py b/scripts/demo1.py new file mode 100755 index 0000000..1c30f00 --- /dev/null +++ b/scripts/demo1.py @@ -0,0 +1,58 @@ +# Demo script that implements a simple drawing program +import upiwin + +# Save off some color values. +WHITE = upiwin.rgb(255, 255, 255) +LTGRAY = upiwin.rgb(204, 204, 204) +YELLOW = upiwin.rgb(255, 255, 0) + +hdc = upiwin.DevCtxt(type='screen') + +# divide the screen into "drawing" and "command" areas +drawing_rect = hdc.get_clip_rect() +command_rect = drawing_rect +drawing_rect[2] -= 60; +command_rect[0] = drawing_rect[2] + 1 + +# further divide up the "command" area +cmd1_rect = command_rect +cmd2_rect = command_rect +cmd3_rect = command_rect +cmd4_rect = command_rect +cmd1_rect[3] = 60; +cmd2_rect[1] = 60; +cmd2_rect[3] = 120; +cmd3_rect[1] = 120; +cmd3_rect[3] = 180; +cmd4_rect[1] = 180; + +def point_in_rect(rect, x, y): + return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + + + + +# --- Initialize and start message loop --- + +# Draw the basic layout. +hdc.set_text_color(LTGRAY) +hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) +hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) +hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) +hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) + +# Main message loop +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_TOUCHCLICK: + if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 1") + elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 2") + elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 3") + elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 4") + elif msg['message'] == upiwin.WM_HWBUTTONCLICK: + if msg['attrs'][0] == 4: # Button 4 = Exit app + upiwin.post_quit_message(0) diff --git a/src/Makefile b/src/Makefile index 95a4c9e..e9843a7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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_devctxt.o ep_bitmap.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.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 diff --git a/src/ep_graphics.c b/src/ep_graphics.c new file mode 100755 index 0000000..3643889 --- /dev/null +++ b/src/ep_graphics.c @@ -0,0 +1,13 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "gfxtype.h" + +PyObject *Epython_rgb(PyObject *self, PyObject *args) +{ + UINT32 r, g, b; + + if (!PyArg_ParseTuple(args, "kkk", &r, &g, &b)) + return NULL; + return PyLong_FromUnsignedLong(RGB(r, g, b)); +} diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 1354d06..16ca9ed 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -23,6 +23,9 @@ static PyMethodDef UPIWINMethods[] = { "Retrieves a message from the message queue, blocking if necessary."}, {"post_quit_message", Epython_post_quit_message, METH_VARARGS, "Posts a WM_QUIT message to the message queue, with an exit code."}, + /* Graphics functions */ + {"rgb", Epython_rgb, METH_VARARGS, + "Creates a color value from separate red, green, and blue indexes."}, {NULL, NULL, 0, NULL} }; diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index b6dbe14..b80fd0c 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -22,5 +22,7 @@ extern PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args); extern PyObject *Epython_get_message(PyObject *self, PyObject *args); extern PyObject *Epython_post_quit_message(PyObject *self, PyObject *args); +/* ep_graphics.c */ +extern PyObject *Epython_rgb(PyObject *self, PyObject *args); #endif /* __EP_UPIWIN_H_INCLUDED */ From 0d6b6ba8b40e952e66844dc00f392fda5cd1a121 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Wed, 11 Dec 2019 12:07:17 -0700 Subject: [PATCH 060/101] minor fix to sysinput --- src/sysinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysinput.c b/src/sysinput.c index 9419d5d..a616063 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -117,7 +117,7 @@ static BOOL poll_touchscreen(void) touch_down_y = touch_y; touch_down_time = now; } - else if (touch_nextmsg = WM_TOUCHUP) + else if (touch_nextmsg == WM_TOUCHUP) { if ( ((now - touch_down_time) <= Gconfig.click_time) && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) From 9fbb7be7172b190a45ea6976aecc1995904f3bf4 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:12:33 -0700 Subject: [PATCH 061/101] I forgot you can't alter the elements of tuples --- scripts/demo1.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 1c30f00..bd59231 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -9,22 +9,15 @@ YELLOW = upiwin.rgb(255, 255, 0) hdc = upiwin.DevCtxt(type='screen') # divide the screen into "drawing" and "command" areas -drawing_rect = hdc.get_clip_rect() -command_rect = drawing_rect -drawing_rect[2] -= 60; -command_rect[0] = drawing_rect[2] + 1 +screen_rect = hdc.get_clip_rect() +drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect[3]) +command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) # further divide up the "command" area -cmd1_rect = command_rect -cmd2_rect = command_rect -cmd3_rect = command_rect -cmd4_rect = command_rect -cmd1_rect[3] = 60; -cmd2_rect[1] = 60; -cmd2_rect[3] = 120; -cmd3_rect[1] = 120; -cmd3_rect[3] = 180; -cmd4_rect[1] = 180; +cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) +cmd2_rect = (command_rect[0], 60, command_rect[2], 120) +cmd3_rect = (command_rect[0], 120, command_rect[2], 180) +cmd3_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) From c309e4dc0f3b755cc91798632e0d2d9275309c6e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:13:35 -0700 Subject: [PATCH 062/101] now I forgot that text_color is an ATTRIBUTE of a DC --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index bd59231..022eb2a 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -28,7 +28,7 @@ def point_in_rect(rect, x, y): # --- Initialize and start message loop --- # Draw the basic layout. -hdc.set_text_color(LTGRAY) +hdc.text_color = LTGRAY hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) From acc7aacf7b16e2859e480bc03f7cf84f8ea9fa06 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:14:55 -0700 Subject: [PATCH 063/101] fixed another typo --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 022eb2a..7eb0e21 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -17,7 +17,7 @@ command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) cmd2_rect = (command_rect[0], 60, command_rect[2], 120) cmd3_rect = (command_rect[0], 120, command_rect[2], 180) -cmd3_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) +cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) From 1ea7a740fec568d062227c9cd1e4e353bdacfbe3 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:19:48 -0700 Subject: [PATCH 064/101] disco debugging the script --- scripts/demo1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 7eb0e21..b1035fc 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -38,6 +38,7 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: + print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): print("Click command 1") elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): From 8441949e3d44d0aa1adae8e8ecc2ba1dd88dd1df Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:21:03 -0700 Subject: [PATCH 065/101] script had a syntax error --- scripts/demo1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index b1035fc..5c83439 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -39,13 +39,13 @@ msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) - if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): + if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 1") - elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 2") - elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 3") - elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 4") elif msg['message'] == upiwin.WM_HWBUTTONCLICK: if msg['attrs'][0] == 4: # Button 4 = Exit app From 46213020ddc9d263ce280bfec76093074bf4b925 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:26:05 -0700 Subject: [PATCH 066/101] separate out the message handlers for clarity --- scripts/demo1.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 5c83439..fbdf056 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -23,7 +23,22 @@ def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) +# --- Message handlers --- +def on_touchclick(x, y): + print("Click at {0},{1}".format(x, y)) + if point_in_rect(cmd1_rect, x, y): + print("Click command 1") + elif point_in_rect(cmd2_rect, x, y): + print("Click command 2") + elif point_in_rect(cmd3_rect, x, y): + print("Click command 3") + elif point_in_rect(cmd4_rect, x, y): + print("Click command 4") + +def on_button_click(button): + if button == 4: # Button 4 = Exit app + upiwin.post_quit_message(0) # --- Initialize and start message loop --- @@ -38,15 +53,6 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: - print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) - if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 1") - elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 2") - elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 3") - elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 4") + on_touchclick(msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_HWBUTTONCLICK: - if msg['attrs'][0] == 4: # Button 4 = Exit app - upiwin.post_quit_message(0) + on_button_click(msg['attrs'][0]) From a62364082aeec7602401c4cf34011ad8b7402f6a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:31:32 -0700 Subject: [PATCH 067/101] try to fix the coordinates returned by touch events --- src/sysinput.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index a616063..cdc0d01 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -11,6 +11,7 @@ #include "log.h" #include "msg_queue.h" #include "gpio.h" +#include "fbinit.h" #include "time_func.h" #define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */ @@ -130,10 +131,12 @@ static BOOL poll_touchscreen(void) break; case EV_ABS: + /* Note that the touchscreen driver assumes the screen is "vertical," so swap the x and y axes */ + /* Also it thinks origin is lower left with up = +y */ if (buffer[i].code == ABS_X) - touch_x = buffer[i].value; + touch_y = Fb_Info->height - buffer[i].value; else if (buffer[i].code == ABS_Y) - touch_y = buffer[i].value; + touch_x = buffer[i].value; break; case EV_KEY: From 0dce80f1e3113bbb6809c1a3cb1b5caf01b0e69d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:33:18 -0700 Subject: [PATCH 068/101] lengthen the click time --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 7f5dfe7..02f8c3e 100644 --- a/src/config.c +++ b/src/config.c @@ -70,7 +70,7 @@ static void init_defaults(void) Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; - Gconfig.click_time = 200; + Gconfig.click_time = 500; Gconfig.click_radius = 2; } From fee3619ee18be030e64be0bc715f9974e5bb38e0 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:46:26 -0700 Subject: [PATCH 069/101] first try at rubberband feedback --- scripts/demo1.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index fbdf056..2e7ae70 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -23,8 +23,45 @@ def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + +# --- Graphic feedback -- + +origin_x = 0 +origin_y = 0 +current_x = 0 +current_y = 0 + +def rubberband_rectangle(x, y, down, up) + hdc.text_color = YELLOW + hdc.rop2 = upiwin.R2_XORPEN + if not down: + hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) + current_x = x; + current_y = y; + if not up: + hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) + + + + + + # --- Message handlers --- +def on_touchdown(x, y): + if point_in_rect(drawing_rect, x, y): + origin_x = x; + origin_y = y; + rubberband_rectangle(x, y, True, False) + +def on_touchmove(x, y): + if point_in_rect(drawing_rect, x, y): + rubberband_rectangle(x, y, False, False) + +def on_touchup(x, y): + if point_in_rect(drawing_rect, x, y): + rubberband_rectangle(x, y, False, True) + def on_touchclick(x, y): print("Click at {0},{1}".format(x, y)) if point_in_rect(cmd1_rect, x, y): @@ -52,6 +89,12 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) # Main message loop msg = {} while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_TOUCHDOWN: + on_touchdown(msg['attrs'][0], msg['attrs'][1]) + if msg['message'] == upiwin.WM_TOUCHMOVE: + on_touchmove(msg['attrs'][0], msg['attrs'][1]) + if msg['message'] == upiwin.WM_TOUCHUP: + on_touchup(msg['attrs'][0], msg['attrs'][1]) if msg['message'] == upiwin.WM_TOUCHCLICK: on_touchclick(msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_HWBUTTONCLICK: From 2c0a1374d962c60f841160a0cd4d00867c3cbdec Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:50:10 -0700 Subject: [PATCH 070/101] guess I need to declare certain things as global --- scripts/demo1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2e7ae70..7e3a5c0 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -31,13 +31,14 @@ origin_y = 0 current_x = 0 current_y = 0 -def rubberband_rectangle(x, y, down, up) +def rubberband_rectangle(x, y, down, up): + global current_x, current_y hdc.text_color = YELLOW hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) - current_x = x; - current_y = y; + current_x = x + current_y = y if not up: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) @@ -49,9 +50,10 @@ def rubberband_rectangle(x, y, down, up) # --- Message handlers --- def on_touchdown(x, y): + global origin_x, origin_y if point_in_rect(drawing_rect, x, y): - origin_x = x; - origin_y = y; + origin_x = x + origin_y = y rubberband_rectangle(x, y, True, False) def on_touchmove(x, y): From b7e9de7d7eb0015cf9b33a9669a7309063e1f905 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:59:45 -0700 Subject: [PATCH 071/101] now try rubberbanding lines --- scripts/demo1.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 7e3a5c0..93a7fe7 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -42,6 +42,18 @@ def rubberband_rectangle(x, y, down, up): if not up: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) +def rubberband_line(x, y, down, up): + global current_x, current_y + hdc.text_color = YELLOW + hdc.rop2 = upiwin.R2_XORPEN + if not down: + hdc.move_to(origin_x, origin_y) + hdc_line_to(current_x, current_y) + current_x = x + current_y = y + if not up: + hdc.move_to(origin_x, origin_y) + hdc_line_to(current_x, current_y) @@ -54,15 +66,15 @@ def on_touchdown(x, y): if point_in_rect(drawing_rect, x, y): origin_x = x origin_y = y - rubberband_rectangle(x, y, True, False) + rubberband_line(x, y, True, False) def on_touchmove(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_rectangle(x, y, False, False) + rubberband_line(x, y, False, False) def on_touchup(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_rectangle(x, y, False, True) + rubberband_line(x, y, False, True) def on_touchclick(x, y): print("Click at {0},{1}".format(x, y)) From 8c820221685386261115bc24b2302c2c9cb4ef68 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:00:38 -0700 Subject: [PATCH 072/101] typos --- scripts/demo1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 93a7fe7..5a1c37e 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -48,12 +48,12 @@ def rubberband_line(x, y, down, up): hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.move_to(origin_x, origin_y) - hdc_line_to(current_x, current_y) + hdc.line_to(current_x, current_y) current_x = x current_y = y if not up: hdc.move_to(origin_x, origin_y) - hdc_line_to(current_x, current_y) + hdc.line_to(current_x, current_y) From 2526184dfebe6168275b00d0fddfc3d24140c4ae Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:04:00 -0700 Subject: [PATCH 073/101] rename mksplash to mkgfx because it's really more general than just for splash screen graphics --- buildutils/Makefile | 8 ++++---- buildutils/{mksplash.c => mkgfx.c} | 0 src/Makefile | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename buildutils/{mksplash.c => mkgfx.c} (100%) diff --git a/buildutils/Makefile b/buildutils/Makefile index 296377c..4a3e2d4 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,7 +1,7 @@ -all: mksplash +all: mkgfx -mksplash: mksplash.c - gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng16 -lz +mkgfx: mkgfx.c + gcc -o mkgfx -O -Wall -I/usr/include/libpng mkgfx.c -lpng16 -lz clean: - rm -f *.o mksplash + rm -f *.o mkgfx diff --git a/buildutils/mksplash.c b/buildutils/mkgfx.c similarity index 100% rename from buildutils/mksplash.c rename to buildutils/mkgfx.c diff --git a/src/Makefile b/src/Makefile index e9843a7..3324d2b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,8 +23,8 @@ splash.o: splash.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o -splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mksplash - $(BUILDUTILS)/mksplash $(RESOURCES)/$(SPLASHSCREEN) splash.bin +splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/$(SPLASHSCREEN) splash.bin clean: rm -f upiwin *.o splash.bin *~ From 62204682af643bd0cf20306d0fd21e2d79b5e721 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:20:45 -0700 Subject: [PATCH 074/101] adding the four "tool" icons to bind into the executable (this works for now) --- resources/i_fillrect.png | Bin 0 -> 672 bytes resources/i_freehand.png | Bin 0 -> 813 bytes resources/i_line.png | Bin 0 -> 783 bytes resources/i_rect.png | Bin 0 -> 666 bytes src/Makefile | 19 ++++++++++++++++--- 5 files changed, 16 insertions(+), 3 deletions(-) create mode 100755 resources/i_fillrect.png create mode 100755 resources/i_freehand.png create mode 100755 resources/i_line.png create mode 100755 resources/i_rect.png diff --git a/resources/i_fillrect.png b/resources/i_fillrect.png new file mode 100755 index 0000000000000000000000000000000000000000..5225d17311bb6e82a17343091bf6d1171b78d649 GIT binary patch literal 672 zcmV;R0$=@!P)EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt767mtEr0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zib+I4R9M69*s%?OAQXh*6D{f3#d#Qw0hq*uid7uIj*`M?a+?2@P`oc(AbBjUHQ7|H zHCSmR1uKoDZ7lWP9b`t40s1Ito9yMBU+P*)A+k3j8+F9^NVEMsxn+O=0RjXF5FkK+ z05NskoEC`8A+pH?PGo=p0s8&JIDYmmPRK_iX-z3vMRoz0h#8n6iep&-0000EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3ls|!tn{yz0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbO z7fD1xR9M69m_ZVQAPhw#%?-FZAJiYr&%raPuXEe1&FpH`Nj^7uc5;IeHS!L)T< z0~8Gr1t=OK;@q|GI|3PyWjBznab-+I>My61W&mAs6i?b>8Ca%Yz^G*vUkV5jvC?VD zM@L5F`JzrP% zz6Ldh(QJh-9S>0QxC3?E0vJRXccAWM5kQ>sQfRyaVb`GPNb3P1Zrp=EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt0*1Pv5c0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN z`AI}UR9M69*uf3MAPfaiCuIW`WHb-JDx6p-hgKY#v;kv(xhgqDoSrcH*leW~a`WY! zcUKxB+FfagD72+os|T5*k}c4Wg2Lr$O6mE-%)WN0$sCmoY`O-$RSIePxIHbhNGxA9F1|!TgkklB{*wq0r4c}$fCduV$Y7*Y|cCjgMKa3)3svoj2 z%{FN2v8mHBDw@<|x+el$e%h%ve<*#UwoYj%PME<^wT N002ovPDHLkV1iP&QCt83 literal 0 HcmV?d00001 diff --git a/resources/i_rect.png b/resources/i_rect.png new file mode 100755 index 0000000000000000000000000000000000000000..08ff61c0695cf91377eb1c36444ae41c5d134711 GIT binary patch literal 666 zcmV;L0%iS)P)EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt4IQGYc_0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zgh@m}R9M69*ue?FAP_{+iLnD4v@{E_6;C#lo5x^4VI+T#dhoF$!g{sVWK*@)V5N~1 ztTdA1Sn9ny$c!QbbSNmk?B$#{omxsEvK^7lbof)v+yNp31PBlyK!5-N0tD!fQ^&rE zk;v9YwrV~kGC+U;o%k@0pM8rC`Di5FDJ84O9+&VKn$e5RJOBUy07*qoM6N<$f@nDy Axc~qF literal 0 HcmV?d00001 diff --git a/src/Makefile b/src/Makefile index 3324d2b..0f77f94 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,8 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ - bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o + bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ + i_freehand.o i_line.o i_rect.o i_fillrect.o splash.o LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT @@ -19,12 +20,24 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< -splash.o: splash.bin +.bin.o: objcopy -I binary -O elf32-littlearm -B arm --rename-section \ - .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o + .data=.rodata,alloc,load,readonly,data,contents $< $@ splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/$(SPLASHSCREEN) splash.bin +i_freehand.bin: $(RESOURCES)/i_freehand.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_freehand.png i_freehand.bin + +i_line.bin: $(RESOURCES)/i_line.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_line.png i_line.bin + +i_rect.bin: $(RESOURCES)/i_rect.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_rect.png i_rect.bin + +i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin + clean: rm -f upiwin *.o splash.bin *~ From 1b4cbfae633a4750fc841eee04fe7e2abcd77449 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:22:39 -0700 Subject: [PATCH 075/101] try makefile another way --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 0f77f94..99774fa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< -.bin.o: +%.o: %.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents $< $@ From 51fda759cc5c35b47ee212715119b28e33c12912 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:23:53 -0700 Subject: [PATCH 076/101] take out the test for size in mkgfx.c to make it more general --- buildutils/mkgfx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/buildutils/mkgfx.c b/buildutils/mkgfx.c index 62e3edc..68e3ee2 100644 --- a/buildutils/mkgfx.c +++ b/buildutils/mkgfx.c @@ -211,14 +211,6 @@ int do_convert(const char *infilename, const char *outfilename) return -1; } - if ((image_width != 320) || (image_height != 240)) - { - readpng_cleanup(1); - fclose(fpin); - fprintf(stderr, "%s: image is %lux%lu, should be 320x240\n", infilename, image_width, image_height); - return -1; - } - if (readpng_get_bgcolor(infilename, &bg_red, &bg_green, &bg_blue)) { readpng_cleanup(1); From ed9fd9320c97124480a7043032dfb9044d7b4074 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:03:11 -0700 Subject: [PATCH 077/101] added stock bitmap handling and support for it in the demo script --- scripts/demo1.py | 10 ++++++++++ src/Makefile | 2 +- src/bitmap.h | 2 ++ src/ep_bitmap.c | 25 +++++++++++++++++++------ src/stockobj.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 7 deletions(-) create mode 100755 src/stockobj.c diff --git a/scripts/demo1.py b/scripts/demo1.py index 5a1c37e..3c3c5cd 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -6,7 +6,14 @@ WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) +# Get the stock bitmaps. +bmp_freehand = upiwin.Bitmap(stock='freehand') +bmp_line = upiwin.Bitmap(stock='line') +bmp_rect = upiwin.Bitmap(stock='rect') +bmp_fillrect = upiwin.Bitmap(stock='fillrect') + hdc = upiwin.DevCtxt(type='screen') +hdc_bits = upiwin.DevCtxt(type='memory') # divide the screen into "drawing" and "command" areas screen_rect = hdc.get_clip_rect() @@ -100,6 +107,9 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +hdc_bits.select_object(bmp_freehand) +hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + # Main message loop msg = {} while upiwin.get_message(msg): diff --git a/src/Makefile b/src/Makefile index 99774fa..b8289c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ - bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ + bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ i_freehand.o i_line.o i_rect.o i_fillrect.o splash.o LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/bitmap.h b/src/bitmap.h index f7500b5..4a306e2 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -16,4 +16,6 @@ typedef struct tagBITMAP { extern PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits); extern void BMP_Delete(PBITMAP pbmp); +extern PBITMAP _BMP_GetStock(PCSTR name); + #endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index abb2406..dfeef62 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -40,19 +40,32 @@ static PyGetSetDef BitmapProperties[] = { static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "width", "height", NULL }; + static char *kwlist[] = { "stock", "width", "height", NULL }; + const char *stock; int width = 0, height = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "$ii", kwlist, &width, &height)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$sii", kwlist, &stock, &width, &height)) return -1; - width = MAX(1, width); - height = MAX(1, height); - self->pbmp = BMP_Create(width, height, NULL); - if (!(self->pbmp)) + if (stock) { + self->pbmp = _BMP_GetStock(stock); + if (!(self->pbmp)) + { + PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock); + return -1; + } + } + else + { + width = MAX(1, width); + height = MAX(1, height); + self->pbmp = BMP_Create(width, height, NULL); + if (!(self->pbmp)) + { PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); return -1; + } } return 0; } diff --git a/src/stockobj.c b/src/stockobj.c new file mode 100755 index 0000000..272d390 --- /dev/null +++ b/src/stockobj.c @@ -0,0 +1,46 @@ +#include +#include +#include "wintype.h" +#include "bitmap.h" + +/* references to the icon data */ +extern uint8_t _binary_i_freehand_bin_start[]; +extern uint8_t _binary_i_freehand_bin_end; +extern uint8_t _binary_i_freehand_bin_size; + +extern uint8_t _binary_i_line_bin_start[]; +extern uint8_t _binary_i_line_bin_end; +extern uint8_t _binary_i_line_bin_size; + +extern uint8_t _binary_i_rect_bin_start[]; +extern uint8_t _binary_i_rect_bin_end; +extern uint8_t _binary_i_rect_bin_size; + +extern uint8_t _binary_i_fillrect_bin_start[]; +extern uint8_t _binary_i_fillrect_bin_end; +extern uint8_t _binary_i_fillrect_bin_size; + +typedef struct tagSTOCKBITMAPDESC { + PCSTR name; + INT32 width; + INT32 height; + const void *data; +} STOCKBITMAPDESC; + +static const STOCKBITMAPDESC stock_bitmaps = { + {"freehand", 48, 48, _binary_i_freehand_bin_start }, + {"line", 48, 48, _binary_i_line_bin_start }, + {"rect", 48, 48, _binary_i_rect_bin_start }, + {"fillrect", 48, 48, _binary_i_fillrect_bin_start }, + {NULL, 0, 0, NULL } +}; + +PBITMAP _BMP_GetStock(PCSTR name) +{ + INT32 i; + + for (i = 0; stock_bitmaps[i].name; ++i) + if (strcmp(name, stock_bitmaps[i].name) == 0) + return BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data); + return NULL; +} From b96527139f4c6598ac8eb6cb9cdc30c532344b45 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:04:24 -0700 Subject: [PATCH 078/101] forgot brackets --- src/stockobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stockobj.c b/src/stockobj.c index 272d390..82350d8 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -27,7 +27,7 @@ typedef struct tagSTOCKBITMAPDESC { const void *data; } STOCKBITMAPDESC; -static const STOCKBITMAPDESC stock_bitmaps = { +static const STOCKBITMAPDESC stock_bitmaps[] = { {"freehand", 48, 48, _binary_i_freehand_bin_start }, {"line", 48, 48, _binary_i_line_bin_start }, {"rect", 48, 48, _binary_i_rect_bin_start }, From 79088d4893b09ae336031e8525a52a4a085d827e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:06:26 -0700 Subject: [PATCH 079/101] change spec of arguments to bitmap init --- src/ep_bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index dfeef62..5eac856 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -44,7 +44,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "$sii", kwlist, &stock, &width, &height)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) From c283d06c12a27c5313537d47bdd6594730e17548 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:08:33 -0700 Subject: [PATCH 080/101] disco debugging the demo script --- scripts/demo1.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 3c3c5cd..f8e779b 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -7,10 +7,13 @@ LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. +print('GOT HERE 1') bmp_freehand = upiwin.Bitmap(stock='freehand') +print('GOT HERE 1A') bmp_line = upiwin.Bitmap(stock='line') bmp_rect = upiwin.Bitmap(stock='rect') bmp_fillrect = upiwin.Bitmap(stock='fillrect') +print('GOT HERE 2') hdc = upiwin.DevCtxt(type='screen') hdc_bits = upiwin.DevCtxt(type='memory') @@ -107,8 +110,11 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +print('GOT HERE 3') hdc_bits.select_object(bmp_freehand) +print('GOT HERE 4') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) +print('GOT HERE 5') # Main message loop msg = {} From 0dd8d458980674d40f5504b47d0ee0889f5a3eef Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:14:17 -0700 Subject: [PATCH 081/101] now probing into the Python interface for devctx --- scripts/demo1.py | 9 +++------ src/ep_devctxt.c | 9 ++++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index f8e779b..767f327 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -7,13 +7,10 @@ LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. -print('GOT HERE 1') bmp_freehand = upiwin.Bitmap(stock='freehand') -print('GOT HERE 1A') bmp_line = upiwin.Bitmap(stock='line') bmp_rect = upiwin.Bitmap(stock='rect') bmp_fillrect = upiwin.Bitmap(stock='fillrect') -print('GOT HERE 2') hdc = upiwin.DevCtxt(type='screen') hdc_bits = upiwin.DevCtxt(type='memory') @@ -110,11 +107,11 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -print('GOT HERE 3') +print('GOT HERE 1') hdc_bits.select_object(bmp_freehand) -print('GOT HERE 4') +print('GOT HERE 2') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) -print('GOT HERE 5') +print('GOT HERE 3') # Main message loop msg = {} diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 87a407c..ab4f274 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -144,15 +144,19 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp BitmapObject *old_bitmap = NULL; PBITMAP old_pbmp; + Log(LDEBUG, "select_bitmap entry"); if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) { PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); return NULL; } + Log(LDEBUG, "verified 1"); old_bitmap = self->selected_bitmap; old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); + Log(LDEBUG, "old_bitmap present=%d, old_pbmp present=%d", !!old_bitmap, !!old_pbmp); if (!old_bitmap) { + Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { @@ -162,6 +166,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp else Py_INCREF(old_bitmap); } + Log(LDEBUG, "replacement sequence"); Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); @@ -171,7 +176,8 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - + + Log(LDEBUG, "select_object entry"); if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; if (!obj) @@ -179,6 +185,7 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "bad object selected"); return NULL; } + Log(LDEBUG, "ready to comb objects"); if (PyObject_TypeCheck(obj, &BitmapType)) return devctxt_select_bitmap(self, (BitmapObject *)obj); PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); From a8a5206b892fd6265d0a12d08580d71551bf427e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:16:25 -0700 Subject: [PATCH 082/101] is the problem in Epython_wrap_bitmap? --- src/ep_devctxt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index ab4f274..74e99e0 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -158,8 +158,10 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp { Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); + Log(LDEBUG, "wrapper finished"); if (!old_bitmap) { + Log(LDEBUG, "wrapper failed"); DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } From b90c2efe2f33f5714393bfd0ae85ad879a902316 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:19:51 -0700 Subject: [PATCH 083/101] dig into the bitmap creation --- src/ep_bitmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 5eac856..203e784 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -2,6 +2,7 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" +#include "log.h" #include "gfxobj.h" #include "bitmap.h" #include "ep_types.h" @@ -44,11 +45,13 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; + Log(LDEBUG, "Bitmap init entry"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) { + Log(LDEBUG, "stock bitmap"); self->pbmp = _BMP_GetStock(stock); if (!(self->pbmp)) { @@ -58,6 +61,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) } else { + Log(LDEBUG, "basic bitmap"); width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); @@ -115,11 +119,15 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) kwargs = PyDict_New(); if (kwargs) { + Log(LDEBUG, "gonna create it"); rc = PyType_GenericNew(&BitmapType, args, kwargs); + Log(LDEBUG, "created it"); if (rc) { pbitmapobj = (BitmapObject *)rc; + Log(LDEBUG, "gonna delete bitmap"); BMP_Delete(pbitmapobj->pbmp); + Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } Py_DECREF(kwargs); From 9318d27b2b80cb7e4570cc798bc61e05103eeb08 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:21:27 -0700 Subject: [PATCH 084/101] null check before deleting bitmap? --- src/ep_bitmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 203e784..160ada9 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -126,7 +126,8 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) { pbitmapobj = (BitmapObject *)rc; Log(LDEBUG, "gonna delete bitmap"); - BMP_Delete(pbitmapobj->pbmp); + if (pbitmapobj->pbmp) + BMP_Delete(pbitmapobj->pbmp); Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } From b5fd4c287904c87c01bd277786923e57281b5d5f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:23:23 -0700 Subject: [PATCH 085/101] OK, another null problem needs fixing --- src/ep_devctxt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 74e99e0..b906ab5 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -166,7 +166,10 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp return NULL; } else + { Py_INCREF(old_bitmap); + self->selected_bitmap = old_bitmap; + } } Log(LDEBUG, "replacement sequence"); Py_DECREF(self->selected_bitmap); From 372f48eab7237447f1c8e50fce8cd338f4e6368a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:25:05 -0700 Subject: [PATCH 086/101] assert that everything is present --- src/ep_devctxt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index b906ab5..33d6913 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -172,6 +172,9 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp } } Log(LDEBUG, "replacement sequence"); + ASSERT(old_bitmap); + ASSERT(self->selected_bitmap); + ASSERT(newbmp); Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); From 6a4938e4ee7070c8603c073fd003204228e93a21 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:27:14 -0700 Subject: [PATCH 087/101] finished disco debugging --- scripts/demo1.py | 3 --- src/ep_bitmap.c | 7 ------- src/ep_devctxt.c | 9 --------- 3 files changed, 19 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 767f327..3c3c5cd 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -107,11 +107,8 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -print('GOT HERE 1') hdc_bits.select_object(bmp_freehand) -print('GOT HERE 2') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) -print('GOT HERE 3') # Main message loop msg = {} diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 160ada9..fbc6da6 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -45,13 +45,11 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; - Log(LDEBUG, "Bitmap init entry"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) { - Log(LDEBUG, "stock bitmap"); self->pbmp = _BMP_GetStock(stock); if (!(self->pbmp)) { @@ -61,7 +59,6 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) } else { - Log(LDEBUG, "basic bitmap"); width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); @@ -119,16 +116,12 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) kwargs = PyDict_New(); if (kwargs) { - Log(LDEBUG, "gonna create it"); rc = PyType_GenericNew(&BitmapType, args, kwargs); - Log(LDEBUG, "created it"); if (rc) { pbitmapobj = (BitmapObject *)rc; - Log(LDEBUG, "gonna delete bitmap"); if (pbitmapobj->pbmp) BMP_Delete(pbitmapobj->pbmp); - Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } Py_DECREF(kwargs); diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 33d6913..070a2b6 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -144,24 +144,18 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp BitmapObject *old_bitmap = NULL; PBITMAP old_pbmp; - Log(LDEBUG, "select_bitmap entry"); if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) { PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); return NULL; } - Log(LDEBUG, "verified 1"); old_bitmap = self->selected_bitmap; old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); - Log(LDEBUG, "old_bitmap present=%d, old_pbmp present=%d", !!old_bitmap, !!old_pbmp); if (!old_bitmap) { - Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); - Log(LDEBUG, "wrapper finished"); if (!old_bitmap) { - Log(LDEBUG, "wrapper failed"); DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } @@ -171,7 +165,6 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp self->selected_bitmap = old_bitmap; } } - Log(LDEBUG, "replacement sequence"); ASSERT(old_bitmap); ASSERT(self->selected_bitmap); ASSERT(newbmp); @@ -185,7 +178,6 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - Log(LDEBUG, "select_object entry"); if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; if (!obj) @@ -193,7 +185,6 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "bad object selected"); return NULL; } - Log(LDEBUG, "ready to comb objects"); if (PyObject_TypeCheck(obj, &BitmapType)) return devctxt_select_bitmap(self, (BitmapObject *)obj); PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); From 90da46505edf456f7972306648f14c1933fd8b4d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:44:35 -0700 Subject: [PATCH 088/101] the basic tool and color selection code --- scripts/demo1.py | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 3c3c5cd..9099847 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -4,6 +4,11 @@ import upiwin # Save off some color values. WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) +RED = upiwin.rgb(255, 0, 0) +GREEN = upiwin.rgb(0, 255, 0) +BLUE = upiwin.rgb(0, 0, 255) +CYAN = upiwin.rgb(0, 255, 255) +MAGENTA = upiwin.rgb(255, 0, 255) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. @@ -29,6 +34,21 @@ cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) +# --- Color selections --- + +color_list = [WHITE, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW] +current_color = 0 + +def draw_current_color(): + hdc.text_color = color_list[current_color] + hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) + +def select_next_color(): + current_color += 1 + if current_color == len(color_list): + current_color = 0 + draw_current_color() + # --- Graphic feedback -- @@ -63,8 +83,26 @@ def rubberband_line(x, y, down, up): hdc.line_to(current_x, current_y) +# --- Tool definitions --- +tool_list = [ + { 'icon': bmp_freehand }, + { 'icon': bmp_line }, + { 'icon': bmp_rect }, + { 'icon': bmp_fillrect } + ] +current_tool = 0 + +def draw_current_tool(): + hdc_bits.select_object(tool_list[current_tool]['icon']) + hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + +def select_next_tool(): + current_tool += 1 + if current_tool == len(tool_list): + current_tool = 0 + draw_current_tool() # --- Message handlers --- @@ -84,11 +122,10 @@ def on_touchup(x, y): rubberband_line(x, y, False, True) def on_touchclick(x, y): - print("Click at {0},{1}".format(x, y)) if point_in_rect(cmd1_rect, x, y): - print("Click command 1") + select_next_tool() elif point_in_rect(cmd2_rect, x, y): - print("Click command 2") + select_next_color() elif point_in_rect(cmd3_rect, x, y): print("Click command 3") elif point_in_rect(cmd4_rect, x, y): @@ -107,8 +144,8 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -hdc_bits.select_object(bmp_freehand) -hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) +draw_current_tool() +draw_current_color() # Main message loop msg = {} From 35a12760d7e7e71f7534ce00b596cd6044ae44f2 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:45:59 -0700 Subject: [PATCH 089/101] global variable definitions again --- scripts/demo1.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 9099847..2f4037d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -44,6 +44,7 @@ def draw_current_color(): hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) def select_next_color(): + global current_color current_color += 1 if current_color == len(color_list): current_color = 0 @@ -99,6 +100,7 @@ def draw_current_tool(): hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) def select_next_tool(): + global current_tool current_tool += 1 if current_tool == len(tool_list): current_tool = 0 From b620f55420a72b09e1d4e13b6205bbb63f03a374 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:52:32 -0700 Subject: [PATCH 090/101] adding feedback for each of the tools --- scripts/demo1.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2f4037d..ab1d7a8 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -50,8 +50,6 @@ def select_next_color(): current_color = 0 draw_current_color() - - # --- Graphic feedback -- origin_x = 0 @@ -59,9 +57,17 @@ origin_y = 0 current_x = 0 current_y = 0 +def freehand_draw(x, y, down, up): + global current_x, current_y + hdc.text_color = color_list[current_color] + hdc.move_to(current_x, current_y) + hdc.line_to(x, y) + current_x = x + current_y = y + def rubberband_rectangle(x, y, down, up): global current_x, current_y - hdc.text_color = YELLOW + hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) @@ -72,7 +78,7 @@ def rubberband_rectangle(x, y, down, up): def rubberband_line(x, y, down, up): global current_x, current_y - hdc.text_color = YELLOW + hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.move_to(origin_x, origin_y) @@ -83,14 +89,13 @@ def rubberband_line(x, y, down, up): hdc.move_to(origin_x, origin_y) hdc.line_to(current_x, current_y) - # --- Tool definitions --- tool_list = [ - { 'icon': bmp_freehand }, - { 'icon': bmp_line }, - { 'icon': bmp_rect }, - { 'icon': bmp_fillrect } + { 'icon': bmp_freehand, 'feedback': freehand_draw }, + { 'icon': bmp_line, 'feedback': rubberband_line }, + { 'icon': bmp_rect, 'feedback': rubberband_rect }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rect } ] current_tool = 0 @@ -113,15 +118,15 @@ def on_touchdown(x, y): if point_in_rect(drawing_rect, x, y): origin_x = x origin_y = y - rubberband_line(x, y, True, False) + tool_list[current_tool]['feedback'](x, y, True, False) def on_touchmove(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_line(x, y, False, False) + tool_list[current_tool]['feedback'](x, y, False, False) def on_touchup(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_line(x, y, False, True) + tool_list[current_tool]['feedback'](x, y, False, True) def on_touchclick(x, y): if point_in_rect(cmd1_rect, x, y): From e7f191a9e02e2aafd4fe5733318402fcaf6c021a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:53:47 -0700 Subject: [PATCH 091/101] wrong procedure name stored in tool list --- scripts/demo1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index ab1d7a8..69eb17a 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -94,8 +94,8 @@ def rubberband_line(x, y, down, up): tool_list = [ { 'icon': bmp_freehand, 'feedback': freehand_draw }, { 'icon': bmp_line, 'feedback': rubberband_line }, - { 'icon': bmp_rect, 'feedback': rubberband_rect }, - { 'icon': bmp_fillrect, 'feedback': rubberband_rect } + { 'icon': bmp_rect, 'feedback': rubberband_rectangle }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle } ] current_tool = 0 From 85e89eae4cdeb3dd89549b12a6034cf68ae52f1b Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:55:34 -0700 Subject: [PATCH 092/101] revised the feedback for freehand --- scripts/demo1.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 69eb17a..31b781d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -59,11 +59,15 @@ current_y = 0 def freehand_draw(x, y, down, up): global current_x, current_y - hdc.text_color = color_list[current_color] - hdc.move_to(current_x, current_y) - hdc.line_to(x, y) - current_x = x - current_y = y + if down: + current_x = origin_x + current_y = origin_y + else: + hdc.text_color = color_list[current_color] + hdc.move_to(current_x, current_y) + hdc.line_to(x, y) + current_x = x + current_y = y def rubberband_rectangle(x, y, down, up): global current_x, current_y From 2a5a6dbe4e1268c042a415037ef65b1bb3085522 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:18:33 -0700 Subject: [PATCH 093/101] now we're actually saving the objects and drawing them properly --- scripts/demo1.py | 73 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 31b781d..955c17d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -41,6 +41,7 @@ current_color = 0 def draw_current_color(): hdc.text_color = color_list[current_color] + hdc.rop2 = upiwin.R2_COPYPEN hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) def select_next_color(): @@ -50,24 +51,58 @@ def select_next_color(): current_color = 0 draw_current_color() +# --- Object drawing --- + +def draw_freehand(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.move_to(data[0][0], data[0][1]) + for pt in data[1:len(data) - 1]: + hdc.line_to(pt[0], pt[1]) + +def draw_line(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.move_to(data[0][0], data[0][1]) + hdc.line_to(data[1][0], data[1][1]) + +def draw_rectangle(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.rectangle(data[0], data[1], data[2], data[3]) + +def draw_filled_rectangle(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.solid_rectangle(data[0], data[1], data[2], data[3]) + +def draw_object(obj): + obj['draw'](obj['color'], obj['data']) + +# --- Master object list --- + +objects_drawn = [] + # --- Graphic feedback -- origin_x = 0 origin_y = 0 current_x = 0 current_y = 0 +freehand_points = [] def freehand_draw(x, y, down, up): - global current_x, current_y + global current_x, current_y, freehand_points if down: - current_x = origin_x - current_y = origin_y + freehand_points = [] else: hdc.text_color = color_list[current_color] + hdc.rop2 = upiwin.R2_COPYPEN hdc.move_to(current_x, current_y) hdc.line_to(x, y) - current_x = x - current_y = y + current_x = x + current_y = y + freehand_points += [(x, y)] def rubberband_rectangle(x, y, down, up): global current_x, current_y @@ -95,11 +130,25 @@ def rubberband_line(x, y, down, up): # --- Tool definitions --- +def save_freehand(): + return { 'draw': draw_freehand, 'color': color_list[current_color], 'data': freehand_points } + +def save_line(): + return { 'draw': draw_line, 'color': color_list[current_color], 'data': [(origin_x, origin_y), (current_x, current_y)] } + +def save_rectangle(): + return { 'draw': draw_rectangle, 'color': color_list[current_color], + 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) } + +def save_filled_rectangle(): + return { 'draw': draw_filled_rectangle, 'color': color_list[current_color], + 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) } + tool_list = [ - { 'icon': bmp_freehand, 'feedback': freehand_draw }, - { 'icon': bmp_line, 'feedback': rubberband_line }, - { 'icon': bmp_rect, 'feedback': rubberband_rectangle }, - { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle } + { 'icon': bmp_freehand, 'feedback': freehand_draw, 'save': save_freehand, 'dodraw': False }, + { 'icon': bmp_line, 'feedback': rubberband_line, 'save': save_line, 'dodraw': True }, + { 'icon': bmp_rect, 'feedback': rubberband_rectangle, 'save': save_rectangle, 'dodraw': True }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle, 'save': save_filled_rectangle, 'dodraw': True } ] current_tool = 0 @@ -129,8 +178,13 @@ def on_touchmove(x, y): tool_list[current_tool]['feedback'](x, y, False, False) def on_touchup(x, y): + global objects_drawn if point_in_rect(drawing_rect, x, y): tool_list[current_tool]['feedback'](x, y, False, True) + object = tool_list[current_tool]['save']() + if tool_list[current_tool]['dodraw']: + draw_object(object) + objects_drawn += [object] def on_touchclick(x, y): if point_in_rect(cmd1_rect, x, y): @@ -150,6 +204,7 @@ def on_button_click(button): # Draw the basic layout. hdc.text_color = LTGRAY +hdc.rop2 = upiwin.R2_COPYPEN hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) From 59ee61200c9bce3b2e977303e034fc4fb6194282 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:27:29 -0700 Subject: [PATCH 094/101] added the backlight control and some code for doing repaints --- scripts/demo1.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 955c17d..2f71408 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -2,6 +2,7 @@ import upiwin # Save off some color values. +BLACK = upiwin.rgb(0, 0, 0) WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) RED = upiwin.rgb(255, 0, 0) @@ -33,6 +34,21 @@ cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + +# --- Backlight control --- + +backlight_level_list = [1023, 768, 512, 256] +current_backlight = 0 + +def do_backlight(): + upiwin.set_backlight_level(backlight_level_list[current_backlight]) + +def select_next_backlight(): + global current_backlight + current_backlight += 1 + if (current_backlight == len(backlight_level_list): + current_backlight = 0 + do_backlight() # --- Color selections --- @@ -83,6 +99,14 @@ def draw_object(obj): objects_drawn = [] +def repaint(): + global drawing_rect, objects_drawn + hdc.text_color = BLACK + hdc.rop2 = upiwin.R2_COPYPEN + hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3]) + for obj in objects_drawn: + draw_object(obj) + # --- Graphic feedback -- origin_x = 0 @@ -197,11 +221,15 @@ def on_touchclick(x, y): print("Click command 4") def on_button_click(button): + if button == 1: # Button 1 = Set backlight level + select_next_backlight() if button == 4: # Button 4 = Exit app upiwin.post_quit_message(0) # --- Initialize and start message loop --- +do_backlight() + # Draw the basic layout. hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN From 416438f6c8d9ba6eaea67ae9ea5eeb575c8f721c Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:28:45 -0700 Subject: [PATCH 095/101] typo --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2f71408..b6350d8 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -46,7 +46,7 @@ def do_backlight(): def select_next_backlight(): global current_backlight current_backlight += 1 - if (current_backlight == len(backlight_level_list): + if current_backlight == len(backlight_level_list): current_backlight = 0 do_backlight() From 4d5b53fcdca200c93e95b5fbaba3bec08fa5dd57 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:34:12 -0700 Subject: [PATCH 096/101] cleanup of the script elements --- scripts/demo1.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index b6350d8..2015ec0 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -27,8 +27,8 @@ drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) # further divide up the "command" area -cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) -cmd2_rect = (command_rect[0], 60, command_rect[2], 120) +tool_select_rect = (command_rect[0], command_rect[1], command_rect[2], 60) +color_select_rect = (command_rect[0], 60, command_rect[2], 120) cmd3_rect = (command_rect[0], 120, command_rect[2], 180) cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) @@ -58,7 +58,7 @@ current_color = 0 def draw_current_color(): hdc.text_color = color_list[current_color] hdc.rop2 = upiwin.R2_COPYPEN - hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) + hdc.solid_rectangle(color_select_rect[0] + 6, color_select_rect[1] + 6, color_select_rect[0] + 54, color_select_rect[1] + 54) def select_next_color(): global current_color @@ -73,7 +73,7 @@ def draw_freehand(color, data): hdc.text_color = color hdc.rop2 = upiwin.R2_COPYPEN hdc.move_to(data[0][0], data[0][1]) - for pt in data[1:len(data) - 1]: + for pt in data[1:]: hdc.line_to(pt[0], pt[1]) def draw_line(color, data): @@ -179,7 +179,7 @@ current_tool = 0 def draw_current_tool(): hdc_bits.select_object(tool_list[current_tool]['icon']) - hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + hdc.bitblt(tool_select_rect[0] + 6, tool_select_rect[1] + 6, tool_select_rect[0] + 54, tool_select_rect[1] + 54, hdc_bits, 0, 0, 0) def select_next_tool(): global current_tool @@ -211,9 +211,9 @@ def on_touchup(x, y): objects_drawn += [object] def on_touchclick(x, y): - if point_in_rect(cmd1_rect, x, y): + if point_in_rect(tool_select_rect, x, y): select_next_tool() - elif point_in_rect(cmd2_rect, x, y): + elif point_in_rect(color_select_rect, x, y): select_next_color() elif point_in_rect(cmd3_rect, x, y): print("Click command 3") @@ -233,8 +233,8 @@ do_backlight() # Draw the basic layout. hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN -hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) -hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) +hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3]) +hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) From cb9ecc89ca3edf6db99ed17c407867ca55dfebca Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:52:49 -0700 Subject: [PATCH 097/101] add the undo and clear commands with their icons --- resources/i_clear.png | Bin 0 -> 3927 bytes resources/i_undo.png | Bin 0 -> 3348 bytes scripts/demo1.py | 36 ++++++++++++++++++++++++++++-------- src/Makefile | 8 +++++++- src/stockobj.c | 10 ++++++++++ 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100755 resources/i_clear.png create mode 100755 resources/i_undo.png diff --git a/resources/i_clear.png b/resources/i_clear.png new file mode 100755 index 0000000000000000000000000000000000000000..3d5a4a2be03ad5fc48f071a273aae2c8d177fd10 GIT binary patch literal 3927 zcmZ8kS2P?7*Bzrq7rl=XQ9=fzMK@|h8>1(#az_n8Mvpd#Fr!4f4AEj3y+?1+dk>>U ziztZ}K_d9whkvc_`yTe$XYIAlemLjl>{w$%9U4jwN&o;rqo=D0yJhgdpa9<11v}44 z0D$T;2yTgl+53aMd|o)YK1YC%fnEp@BEZ!N00>x|v$pXQ%dh-1FFa1K2IA>iZ~m0o z&3!F0l~~AqU(xUD*Tvx0cd}%KrO9fq`){uNr^Aktwldm!nS3b7=yF50QF24i6KicN zj`w|)m#-PFJC=)o5ci9pPf0~zU3Z0O2d^GBw&$WQPfFe^ozd<6jI8zVb>+3|45Qxq zCL6vRtb;flJXWdwd|i1t$X9$ph`I`PI>>z}x2C#__J12m!l`VloW%z1zwGVTxu_WV z&F_4bGyDGi{%0fvF&Z0FH(qYB>a=Tz8mZiQ_mk3M-Rx+!HGF;yHkuA#FA6^oJQvU6 z<^4RCqhb^ma|PW0H6HphOec$$33$lcM4tLFFeK>n@YED>IaRBXKnybBRrABXVds?H zaHE?E!c4YfUF8KJrN?vDemE$`&#b+ngZT&}M6a81q@Bw?L1G2*D#>yZ%^7nV3HPyn z(JJn@SW`JB`(*0J+8eQ#0)G2WK(@>!)YATpVFI8-kz!iL_~W`n?#mkYg|^r3vYCcO zHV_1QJXP$4>TV;=*XgJRp?4i0+bpeOtk|e7exjVzddF8vYPnu1@$$x%5u<9Cv+e98 z(>_R)F3|Zjlh#9_-M)-9@gau*iI0=0AvN$S7SOj4&aSoXBF>cwFz%iu1Xikb#d!?~ z5)@ehv=B_q@jDj_Q-{#WbrQ{@%jbWNCons5;~xKx?nodPOYehTaUqjH*^IOrPLdCi*luUFp!zix@`RS z>d?TBaO{f7W^}47=Du4K=jK%OoELu_JH6uzq5u*%HR@jT(I>U5b^OH{nWM(hU?CAo z!^Su^`qQ4;C&3Pl0y;+#BjK82H4cblu4l%W;wL7r4K2Cw(vn|U3(!Rt|B zgV@i1?fyj*8r+WT&8STM_UtX~%VIHbU42AJ1W7YZ%D_>LZhZ}Pz0CWqg<5EUz&6Yp zaE4u4JPL%UQWdz;HfW1zP2zmTvB1NkCJkz^lSLh;S<);dgPFUF@pJ z9ui`hV&9ZCBeNzyFiLbMhHBdI#DkJgetTU*OP|puK1fT@E#zYneHloLFsohW_!0YM z%vz~-m|~<(EjaFBeKUbio}1R9;|p1g{uf>@+7FIecO7Dz4AJ0%mw4!>r!bL>N2?CL zNp@=7WL2@P5b|=t^gE=ObSL%mH2s-1S8EZ$)kJp3^O=|fwHKUf*Q=r*YZ4Qt7J#v| z&tdu>ij{Ck^%$11zAt!CTpuLYdwq33xZVo5BNHs?zYl>n$uWJl9*Qh zCkHwjqQyXi9>j#&`6>vsj?0*2P$2K2zR4tLo%Q+NVD_c&@i4lO>2b{f47zHFq7l$s zf&>KvB{c@|z-y0;8kHIYYopFvcwe;*VOA4(9tDf!1N+v#h+$k;yIAUSW!bT_Cwitu zGK#XC*W|KXa~kA;yDu*gy8XWneyKN|@>Re;dPVr$P*C*s+ox*w!l-zVsJX5}t(wJ(W9)OzP>A1oUqIYg1LP!bvKK^E(H{hIsI`K(W9v9I zl?}-&x*(&x^bvYhgZ&lOSBpo#!cFd`x29Pi%u8O*=M#6?p=(0@JufXPtz> z?(8B1uO@ygvM%DrU)gk3;%zb%f-t4KehP!R6c!uhpeCXNV5Qd`abXXkM`*BtQ}ntx zG-=LV?cCCw`T^msYrGq)2={v<_LjW90}+wi*`fl*3nn#)R56Me-Fd2}*IWu;AT zP@eb=e#(~oIJEH2Yf*`UJkEbbTX_Df1s;V30bgYFxOjad#qr-d9oi zSC@&iUAz|mJN6%5WumM4q^Bs#P$r`GJQS~%+C%)B4#Oms=!FT%-?kP#GjMe|xHkjo zigBM76B5eIYBEV<_Eb~-uoShFc5^yzy~BR9JMYf-&0CRe&ch{Rm-Y7yr+$9%X|Y_o zhS9E3=f=%HQI}?9r()cH9CkHd?5@Xh?T9NYy(JEr?wJW$NL;E;ZX-3RBjxLS-t%W! z&zR`TH#A8Zwhv8WjvjuD!m-*q{^NR=U(j!Bp?OY-=s7jDtQ~pI{s)GBvQJml_g4Kn zD!8*8#T(mfJqRHcZ;8ZYFM>Rf#5|!M$e9F#{w-zxL6dvnqg8XkE?L#UZ_&!Bw0jjE zvN!<8fr>;;K^vG`(o?nSY?p6v*GYVv~Fc@}JbmG1KPcCV#25j3RvCzoR$Q}C^=vuJ>P6k9g|X?(NTWi+u-ozBA{_qW5A)sDY6UM(Tp zH=k$zIRWB1dQMQ8_R%l`;8a4ulM8@KNmo1&s1Od%cRMZ*v;kIRqP|}~5xbA4$>)gR zk&+ytF*MCs6r8SqVjUt6w)oSzc*Eqs+ET$$D-OBuKa#^eJ-H_C5v?rC=ja1ln!T0M zH00zGieWq3{l{?1W`E|BB(a?$DMR~714Q=6ysTmQXmzF*^9ydZBvD8)C?1jK1ko8!%eQ- zy~<~5u_;hZ)$rFpje+gh|N8k(nxT9j5Bbl`u{+3V}ePl&(P!{gO)RrSw{-3#sp_F8j72H?cuBVfTFofNd{T zECH=7R7#c&;_d9V5yNcyhnxO~PRJ5Z@43(4ep*c3ZI?Lj-pBDbrVhirJ14L|f#~a> zk+LD3?^GK3 zUdfzk8cXhqpZskN)?S)$NtJJ&_0*pA7&0f1TwjZCN`_B*e@8D;@Uml*p>7%rmP}I& zEjg5tPtPm`-2sd}4%_|oj2jNR8K&H5i*NG~V?Ih?C6+T$mQy9UsK6_Nw5V4!Fio`{ z4*O2=3kH}X<`z*{eC&oZidRtC4@~<$aGi%xUEoNsu!f0Ihjxwe1t~`gZBS!K(Wd}n z!lUj_WX(oR&`+81D(yM)l4Iu;*{A3R`9Ni#h;I0t(B7{i0I2X+H{S&1pNxn+vh(!eB4(jk;lTu3( zDqO{6Y2*;@ugO9_J#TNOr&P3|56rorX8ZbjF_U!D(X(3I*J2ep4%5rm!jKPK1^6F& zpVQLsA&RivjNzqL+EOgc(gZWfqc~6yI9!tCp3~m(tOG~R=01-~$EsF9`gyaePF1or z`x;~H*9=d~Ud~?Wtn~4~T>0L(WQ|vbN}iLXvAoR^t$+HP*Q&duq1ulWjJWt&s5~At zN{Vra9z(n>O=N~yr6k0%8|BNsh`O()bb>Qx%wbQ96)@58CZiN}T z)1k9Hs#_O~TggLaK!E|Es4<^H=#lEhN=0Ta7MX%F$@|gwK~+1vOJWjFI6JTLkTV3_ zNPFQL{-iwuU+M)_;Gz@5J3Q7lT5v2-fcX)niAJs>3aN#t7Xskzi_4;~z^j3k7wOhW&QThPr7BMKR_I#-N%`?qo)dijxh{ z3F0-vsxV7(Lb_%84aF@6r9WHGH;`ND*nFrm9y!Jq9rh{WF2z!1;wYb$gW#r>#>Y39 zZLfy4`7OKx>G#mFEKwN?W*^9$JEhIG1I%@Jg5Gu7t(3>DZYZxLM3Uo)Z2X2ng;b_Y z%lr4!y)LuPR#Td84`TMCW9Qk7E}<#teje4z^MoOaGbN;~Sf(XD{7h9YH#eJ6AeU-Q zMcGwDQ<9DGDdaG2*h1IIFry#}S!aL`?y)wc<;^ literal 0 HcmV?d00001 diff --git a/resources/i_undo.png b/resources/i_undo.png new file mode 100755 index 0000000000000000000000000000000000000000..62b023366ead39554dc0d96223c646d0b9c39adc GIT binary patch literal 3348 zcmV+v4eRoWP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3#rb|fJVg#UAjIRg7~9M<>d26O!RM3S|1+wRR( zb|pn60u)jxNHzcW-=+S;%O&TP4=KkIqvqv{FSgRi`g+y5C8Z?&w+PG_9n zpY~d%V+*dhDn0uXSMeEWd*1RHuhl9bV+pj&@vYTgzCK&MdR_j3{SDSf%Y4#*&{j7J z(VidN4=BaQ^}~J>ZbLu7y0LqiIp)XAZ~Zns0KA-i!zcf1jl9;pc2|95%kgaL-pX!q zUlVWbQIU7jQ4xfhhP(^!Oj>keY3QyS?{12*K)H-J!&I}(+}Cb8OZ0Zy#MRoatlOO# zFpBLPZUNStWfQ;;mjS*L5{_Q`Sc}=ymOWiJSr4U$;Z|!fCb9C@Z}q!3uALLc==|^% z>#`DctU?>$mkYOnh*`&}VLSMK|M(JI9SDZ)=FA4GZt618f_Vm)+dw;R3|y}yHfbCK zxQM9(iy>jW(UFWXkrgFtlQB3l15jn@)_L1Nz=U82i?rUk2sq?0b2BEHeX9-j>V^zq zND?qYm03~~u)Gh%Px6@~qL5 zr<`-iwbbaL*haGN^ z$0Lq3@+hNDGYO^XXP9xOnP-`G5o*gVzrurUz>D zrgWPyLMK5m12O9jfG1D`F#=mK)7f}$1v$Y?7fV(I%OZn-GmIbxf_@qsmU&=zkW+Z^ zTX0h;Z`|y^BBunp-$d?b+&)5WNO|rXu`3P5soIf!%a3X^e^kxSuj*Gf{ON2NKH6)YjKFx{{|k2yx9Xu)ByUqIHzXrLEKN7q)JF?H`SFr4cy)a+9XDm5KOhgZ9|usO4! zKz%V||4qy$DwI^%o(oBwbq+qG zSiGb>4CWB~q&xX*&T1G2Awsi#x^~BPi2*i58OMRvlm&HZZRRD zXcc(Rw>1^in4|-}n-Jk}s%#|T5Q3 zCEu+Pc0(NQ>y6cPzAr7&qs%B_c9RkT#Bar$j8}7~7;`!>%vob&#%0>d&8=l!2vv44 zQn5HA$HlgX`qIUIAVV;ZH#6kCie0f+R|I|=C|Hzx#5F?FsgdcP(FAJ7NX@2h<8~n> ze*#IP{>gXLgzRd`{#r(N_r%76lZ~~2JfcG z8u!|$?bIpMOuJwRR1wNLw|33ZX_PDxtVxUb^!Z$zCOKH7M=%e`0XI%8qdT;>YVKgJ zq(R-mJcN0cxJEC+f$0MZN2d4GGR_l7AeQa+ktmyy4N3sdC}Ih3SEK?CNt58Z!ZB~p zbeJM-k4v@|AqsCj!9`If0}G09yWCY(Oh$E0!D2y%0414lqPLcIM{koE=bG*cUgLk5 zUk!mf%a2Q@Z}!T~ZRyx~v%-BpTfvBW-^OhRwP1~G=i)tBOmd~ni}yru8W0n7MORcv zQgNJ3#Ojhq8##41Vv#hHp_ZXmU`GTJL{JTJ06(EiQx;s3{1Fv0NWBm(qhLy)CA0{N ze20^M@T};+lX=BmyqVp_o2sC2ggE_0oY1I-0&*NXW)MHA#X!oz@5oBgmj&_6+1`l$ zF%osF5ZtPUJ@StBvS9mXu-md1XL9L`eJuiG&O-(lDX6u%0f`8D6{W9+%juLub znL`cXeF${6JmH5eHp1Ac!Zth;K;B zxY4uZu7hO5u7-zIC}{D?D#}s}Ic`%?U_Mgl;X-$cpkJ5QDS}c1tA_&E`L2OcxX4Hi zT*^qjnz8;-s(+B_iW(xd^by3d#@8Soh;{UPx{9}7DQw(Oyz3P+4B7nN@x(AmNi~xp z#?IXIkgzBO_Oqb&o5-?J7n_izJGnLm33X=pU_~fsQ-$HoqnkOZplb%cWfg#l>MDodtAjz9~ zse|R9%t_|29Ga^Ong%5HzS7*4hWV>|s6w@lC}bsD z7Rr;zDH!d7ux;qg=vV#*#hG?XOf1=OJAP?rIL_rL<+HDUT{` zby6{Ixnv*GMQV#s7??p|du}L9v`_i!5TPE2hIQ40TdSRNpl^||%fZ%aQV!1KJ&L^B z38^lqgcmWF z&5p{c>hH?Ny9MppzH!X8#U`z=IAu$tGDbA;7Hk38CvpvEi(F$Ho{=-;N5Z=_T7G{GY;8 z;JRvT-Nhg6v~KyM?h{43P6N|k2MWl`CE<~+Dz+f;FZuu;*;K1f1%@GoefB|f{96rB zpK$-|ryXH_O?$~mBtm^<{mz3jksKN)Ix!@LW>IH-g zg1&c}${#)fP~Y@u682XDR0P33_jl3E9n@1v#tNNx#BVy>)AwK@? z^F!6XNpW!$Tni3F%=a_C-#2dsjo0iUbpE$&dl0tk= zJZ{hhi66NxyZpwv;IP0mLq<9|PaGl^3vDd7F)JD>@icK*Q8mgJGA=8ew>YciDr?@8 zzc857R#IH2IgA*V5Jv(cWK>Z?85Sb6YNVJ*(tgy#KjiomeSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{007`gL_t(o!|j;M z5yT(}h6%BQG?>yXz*anYvYWkSoQyA6vted`ZZX1qfDp+RVJZ(R9K-!mEPjYat>{|%rDs*6 z9oKLBMWJGai{AUb_3GQnP_Z=Bla5xQXPEfW+Ey@e$HbCOGt95D%2xHgp={S|Uk-|` z*p%y1#J+CMSv6pR0000= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) @@ -106,6 +108,19 @@ def repaint(): hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3]) for obj in objects_drawn: draw_object(obj) + +def undo_last(): + global objects_drawn + if len(objects_drawn) > 0: + last = len(objects_drawn) - 1 + del objects_drawn[last] + repaint() + +def clear_all(): + global objects_drawn + if len(objects_drawn) > 0: + objects_drawn.clear() + repaint() # --- Graphic feedback -- @@ -215,10 +230,10 @@ def on_touchclick(x, y): select_next_tool() elif point_in_rect(color_select_rect, x, y): select_next_color() - elif point_in_rect(cmd3_rect, x, y): - print("Click command 3") - elif point_in_rect(cmd4_rect, x, y): - print("Click command 4") + elif point_in_rect(undo_rect, x, y): + undo_last() + elif point_in_rect(clear_rect, x, y): + clear_all() def on_button_click(button): if button == 1: # Button 1 = Set backlight level @@ -235,12 +250,17 @@ hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3]) hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3]) -hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) -hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +hdc.rectangle(undo_rect[0], undo_rect[1], undo_rect[2], undo_rect[3]) +hdc.rectangle(clear_rect[0], clear_rect[1], clear_rect[2], clear_rect[3]) draw_current_tool() draw_current_color() +hdc_bits.select_object(bmp_undo) +hdc.bitblt(undo_rect[0] + 6, undo_rect[1] + 6, undo_rect[0] + 54, undo_rect[1] + 54, hdc_bits, 0, 0, 0) +hdc_bits.select_object(bmp_clear) +hdc.bitblt(clear_rect[0] + 6, clear_rect[1] + 6, clear_rect[0] + 54, clear_rect[1] + 54, hdc_bits, 0, 0, 0) + # Main message loop msg = {} while upiwin.get_message(msg): diff --git a/src/Makefile b/src/Makefile index b8289c8..aff9c9b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ - i_freehand.o i_line.o i_rect.o i_fillrect.o splash.o + i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.o splash.o LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT @@ -39,5 +39,11 @@ i_rect.bin: $(RESOURCES)/i_rect.png $(BUILDUTILS)/mkgfx i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin +i_undo.bin: $(RESOURCES)/i_undo.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png undo.bin + +i_clear.bin: $(RESOURCES)/i_clear.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_clear.png i_clear.bin + clean: rm -f upiwin *.o splash.bin *~ diff --git a/src/stockobj.c b/src/stockobj.c index 82350d8..394195a 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -20,6 +20,14 @@ extern uint8_t _binary_i_fillrect_bin_start[]; extern uint8_t _binary_i_fillrect_bin_end; extern uint8_t _binary_i_fillrect_bin_size; +extern uint8_t _binary_i_undo_bin_start[]; +extern uint8_t _binary_i_undo_bin_end; +extern uint8_t _binary_i_undo_bin_size; + +extern uint8_t _binary_i_clear_bin_start[]; +extern uint8_t _binary_i_clear_bin_end; +extern uint8_t _binary_i_clear_bin_size; + typedef struct tagSTOCKBITMAPDESC { PCSTR name; INT32 width; @@ -32,6 +40,8 @@ static const STOCKBITMAPDESC stock_bitmaps[] = { {"line", 48, 48, _binary_i_line_bin_start }, {"rect", 48, 48, _binary_i_rect_bin_start }, {"fillrect", 48, 48, _binary_i_fillrect_bin_start }, + {"undo", 48, 48, _binary_i_undo_bin_start }, + {"clear", 48, 48, _binary_i_clear_bin_start }, {NULL, 0, 0, NULL } }; From 91c466eae7433f83b475dbdff4a6cc90d401bd68 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:54:21 -0700 Subject: [PATCH 098/101] typo in makefile --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index aff9c9b..81342ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -40,7 +40,7 @@ i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin i_undo.bin: $(RESOURCES)/i_undo.png $(BUILDUTILS)/mkgfx - $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png undo.bin + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png i_undo.bin i_clear.bin: $(RESOURCES)/i_clear.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_clear.png i_clear.bin From d1369964d7398ca1ff790fc5b27fda1c17bab7d2 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:24:58 -0700 Subject: [PATCH 099/101] The code has to be GPL'd, because the license of the BCM2835 library requires it. Add the license document and the header on all source files. --- LICENSE.md | 336 +++++++++++++++++++++++++++++++ Makefile | 17 ++ buildutils/Makefile | 17 ++ buildutils/mkgfx.c | 19 ++ docs/templates/license_header.c | 19 ++ docs/templates/license_header.mk | 17 ++ docs/templates/license_header.py | 17 ++ scripts/demo1.py | 19 +- scripts/test_clipping.py | 19 +- scripts/tmp_main.py | 19 +- src/Makefile | 17 ++ src/bitmap.c | 19 ++ src/bitmap.h | 19 ++ src/config.c | 19 ++ src/config.h | 19 ++ src/dc_screen.c | 19 ++ src/dc_screen.h | 19 ++ src/devctxt.c | 19 ++ src/devctxt.h | 19 ++ src/ep_backlight.c | 19 ++ src/ep_bitmap.c | 19 ++ src/ep_devctxt.c | 19 ++ src/ep_graphics.c | 19 ++ src/ep_init.c | 19 ++ src/ep_init.h | 19 ++ src/ep_msg.c | 19 ++ src/ep_types.h | 19 ++ src/ep_upiwin.c | 19 ++ src/ep_upiwin.h | 19 ++ src/ep_upiwin_tmp.c | 19 ++ src/ep_util.c | 19 ++ src/ep_util.h | 19 ++ src/fbinit.c | 19 ++ src/fbinit.h | 19 ++ src/fbprimitive.c | 19 ++ src/fbprimitive.h | 19 ++ src/fontengine.c | 19 ++ src/fontengine.h | 19 ++ src/gfxobj.c | 19 ++ src/gfxobj.h | 19 ++ src/gfxtype.h | 19 ++ src/gpio.c | 19 ++ src/gpio.h | 19 ++ src/log.c | 19 ++ src/log.h | 19 ++ src/main.c | 19 ++ src/msg.h | 19 ++ src/msg_queue.c | 19 ++ src/msg_queue.h | 19 ++ src/rect.c | 19 ++ src/scode.h | 19 ++ src/stockobj.c | 19 ++ src/sysinput.c | 19 ++ src/sysinput.h | 19 ++ src/time_func.c | 19 ++ src/time_func.h | 19 ++ src/wintype.h | 19 ++ 57 files changed, 1387 insertions(+), 3 deletions(-) create mode 100755 LICENSE.md create mode 100755 docs/templates/license_header.c create mode 100755 docs/templates/license_header.mk create mode 100755 docs/templates/license_header.py diff --git a/LICENSE.md b/LICENSE.md new file mode 100755 index 0000000..25f9fd4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,336 @@ +GNU General Public License +========================== + +_Version 2, June 1991_ +_Copyright © 1989, 1991 Free Software Foundation, Inc.,_ +_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_ + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +### Preamble + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: **(1)** copyright the software, and +**(2)** offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +**0.** This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The “Program”, below, +refers to any such program or work, and a “work based on the Program” +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term “modification”.) Each licensee is addressed as “you”. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +**1.** You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +**2.** You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +* **a)** You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. +* **b)** You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. +* **c)** If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +**3.** You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +* **a)** Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, +* **b)** Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +* **c)** Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +**4.** You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +**5.** You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +**6.** Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +**7.** If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +**8.** If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +**9.** The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and “any +later version”, you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +**10.** If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +### NO WARRANTY + +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +### How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w` and `show c` should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w` and `show c`; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/Makefile b/Makefile index 1273313..f951f9f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ all: make -C buildutils all make -C src all diff --git a/buildutils/Makefile b/buildutils/Makefile index 4a3e2d4..0a2906f 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ all: mkgfx mkgfx: mkgfx.c diff --git a/buildutils/mkgfx.c b/buildutils/mkgfx.c index 68e3ee2..2d7ba04 100644 --- a/buildutils/mkgfx.c +++ b/buildutils/mkgfx.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/docs/templates/license_header.c b/docs/templates/license_header.c new file mode 100755 index 0000000..f15cf34 --- /dev/null +++ b/docs/templates/license_header.c @@ -0,0 +1,19 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ diff --git a/docs/templates/license_header.mk b/docs/templates/license_header.mk new file mode 100755 index 0000000..d1adfbb --- /dev/null +++ b/docs/templates/license_header.mk @@ -0,0 +1,17 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ diff --git a/docs/templates/license_header.py b/docs/templates/license_header.py new file mode 100755 index 0000000..55d4e3d --- /dev/null +++ b/docs/templates/license_header.py @@ -0,0 +1,17 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ diff --git a/scripts/demo1.py b/scripts/demo1.py index 4e9a180..a823860 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -1,4 +1,21 @@ -# Demo script that implements a simple drawing program +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Demo script that implements a simple drawing program import upiwin # Save off some color values. diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 083cb9b..a9db639 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,4 +1,21 @@ -# Test of line clipping +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Test of line clipping import upiwin hdc = upiwin.DevCtxt(type='screen') diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 902d767..3fcc94e 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,4 +1,21 @@ -# Initial test script +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Initial test script import upiwin import upiwin_tmp diff --git a/src/Makefile b/src/Makefile index 81342ea..1d581ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png diff --git a/src/bitmap.c b/src/bitmap.c index fa517ea..1a62055 100755 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "bitmap.h" diff --git a/src/bitmap.h b/src/bitmap.h index 4a306e2..a904868 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __BITMAP_H_INCLUDED #define __BITMAP_H_INCLUDED diff --git a/src/config.c b/src/config.c index 02f8c3e..8199b18 100644 --- a/src/config.c +++ b/src/config.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/config.h b/src/config.h index 22253ac..23e45b6 100644 --- a/src/config.h +++ b/src/config.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __CONFIG_H_INCLUDED #define __CONFIG_H_INCLUDED diff --git a/src/dc_screen.c b/src/dc_screen.c index 29c4050..7ca7790 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "log.h" diff --git a/src/dc_screen.h b/src/dc_screen.h index 560187c..575655b 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __DC_SCREEN_H_INCLUDED #define __DC_SCREEN_H_INCLUDED diff --git a/src/devctxt.c b/src/devctxt.c index 217a0e3..7c6ea5d 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "log.h" diff --git a/src/devctxt.h b/src/devctxt.h index 017e70a..f714c66 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __DEVCTXT_H_INCLUDED #define __DEVCTXT_H_INCLUDED diff --git a/src/ep_backlight.c b/src/ep_backlight.c index e78cb58..188294f 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index fbc6da6..89e70e0 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #define PY_SSIZE_T_CLEAN #include diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 070a2b6..bc58dcd 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #define PY_SSIZE_T_CLEAN #include diff --git a/src/ep_graphics.c b/src/ep_graphics.c index 3643889..a029b08 100755 --- a/src/ep_graphics.c +++ b/src/ep_graphics.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "wintype.h" diff --git a/src/ep_init.c b/src/ep_init.c index 3eba18b..9e23517 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/ep_init.h b/src/ep_init.h index 5e68ef4..340b1bf 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_INIT_H_INCLUDED #define __EP_INIT_H_INCLUDED diff --git a/src/ep_msg.c b/src/ep_msg.c index 9cf072b..c2fbca5 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_types.h b/src/ep_types.h index 55d2eae..751cc5a 100755 --- a/src/ep_types.h +++ b/src/ep_types.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_TYPES_H_INCLUDED #define __EP_TYPES_H_INCLUDED diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 16ca9ed..91a418a 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index b80fd0c..2f5fe99 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_UPIWIN_H_INCLUDED #define __EP_UPIWIN_H_INCLUDED diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 51adcfb..97a9f62 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_util.c b/src/ep_util.c index 44a49c8..a08d5b1 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_util.h b/src/ep_util.h index 0406aca..c5d415c 100644 --- a/src/ep_util.h +++ b/src/ep_util.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_UTIL_H_INCLUDED #define __EP_UTIL_H_INCLUDED diff --git a/src/fbinit.c b/src/fbinit.c index 11bbcd3..84491c1 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/fbinit.h b/src/fbinit.h index 66e4f35..1575ce0 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FBINIT_H_INCLUDED #define __FBINIT_H_INCLUDED diff --git a/src/fbprimitive.c b/src/fbprimitive.c index fe3e6ab..fad520f 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "wintype.h" diff --git a/src/fbprimitive.h b/src/fbprimitive.h index a9c4e52..3e82ddd 100644 --- a/src/fbprimitive.h +++ b/src/fbprimitive.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FBPRIMITIVE_H_INCLUDED #define __FBPRIMITIVE_H_INCLUDED diff --git a/src/fontengine.c b/src/fontengine.c index ddc663d..7bc5c5f 100644 --- a/src/fontengine.c +++ b/src/fontengine.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include FT_FREETYPE_H #include "scode.h" diff --git a/src/fontengine.h b/src/fontengine.h index 5fa9187..841fa36 100644 --- a/src/fontengine.h +++ b/src/fontengine.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FONTENGINE_H_INCLUDED #define __FONTENGINE_H_INCLUDED diff --git a/src/gfxobj.c b/src/gfxobj.c index c721f43..b701bbc 100755 --- a/src/gfxobj.c +++ b/src/gfxobj.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "gfxobj.h" diff --git a/src/gfxobj.h b/src/gfxobj.h index 0f7a6b6..9b3e3dc 100755 --- a/src/gfxobj.h +++ b/src/gfxobj.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GFXOBJ_H_INCLUDED #define __GFXOBJ_H_INCLUDED diff --git a/src/gfxtype.h b/src/gfxtype.h index efc02db..b969193 100755 --- a/src/gfxtype.h +++ b/src/gfxtype.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GFXTYPE_H_INCLUDED #define __GFXTYPE_H_INCLUDED diff --git a/src/gpio.c b/src/gpio.c index ff877c4..5c8aea3 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "config.h" diff --git a/src/gpio.h b/src/gpio.h index e368291..2a5f833 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GPIO_H_INCLUDED #define __GPIO_H_INCLUDED diff --git a/src/log.c b/src/log.c index a239fc9..88d8ccf 100644 --- a/src/log.c +++ b/src/log.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/log.h b/src/log.h index a0871ca..c2f82d5 100644 --- a/src/log.h +++ b/src/log.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __LOG_H_INCLUDED #define __LOG_H_INCLUDED diff --git a/src/main.c b/src/main.c index 99b9a63..c9c3456 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/msg.h b/src/msg.h index afff6a9..2733c19 100644 --- a/src/msg.h +++ b/src/msg.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __MSG_H_INCLUDED #define __MSG_H_INCLUDED diff --git a/src/msg_queue.c b/src/msg_queue.c index 566dc0e..62a4124 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/msg_queue.h b/src/msg_queue.h index 6ca5f75..99ee867 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __MSG_QUEUE_H_INCLUDED #define __MSG_QUEUE_H_INCLUDED diff --git a/src/rect.c b/src/rect.c index eae408a..0a9608f 100755 --- a/src/rect.c +++ b/src/rect.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include "log.h" #include "gfxtype.h" diff --git a/src/scode.h b/src/scode.h index 06cca67..acd472b 100644 --- a/src/scode.h +++ b/src/scode.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __SCODE_H_INCLUDED #define __SCODE_H_INCLUDED diff --git a/src/stockobj.c b/src/stockobj.c index 394195a..cb12205 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "wintype.h" diff --git a/src/sysinput.c b/src/sysinput.c index cdc0d01..0682c49 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/sysinput.h b/src/sysinput.h index e191b66..d3ecb20 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __SYSINPUT_H_INCLUDED #define __SYSINPUT_H_INCLUDED diff --git a/src/time_func.c b/src/time_func.c index f7603ff..4c0907e 100644 --- a/src/time_func.c +++ b/src/time_func.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "time_func.h" diff --git a/src/time_func.h b/src/time_func.h index 635ca03..2648d85 100644 --- a/src/time_func.h +++ b/src/time_func.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __TIMEFUNC_H_INCLUDED #define __TIMEFUNC_H_INCLUDED diff --git a/src/wintype.h b/src/wintype.h index 19aa6df..9e1d6dc 100644 --- a/src/wintype.h +++ b/src/wintype.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __WINTYPE_H_INCLUDED #define __WINTYPE_H_INCLUDED From a7378504163a77865e4de5ccdd83e8fb6ec326aa Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:33:31 -0700 Subject: [PATCH 100/101] And, since we have to include a license, we should include the official Erbosoft Project Code of Conduct. :) --- CODE-OF-CONDUCT.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 CODE-OF-CONDUCT.md diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100755 index 0000000..fd0edab --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,57 @@ +# The Erbosoft Project Code of Conduct +## (Revised December 2019) + +For the purposes of this project, the Owner is Amy G. Bowersox/Erbosoft Metaverse Design Solutions. + +1. *The Owner owns this project.* Not you. The Owner's decisions about any aspect of the project +are *final.* +2. This Code of Conduct contains harsh language. Tough shit. Suck it up, Buttercup. +3. Anyone who is an *asshole* is **banned** *from this project.* **Permanently.** +4. This project has certain objectives. Anything outside of those objectives is *irrelevant,* +unless and until the *Owner* changes the objectives. Not you. In particular, if you’re a Social +Justice Warrior trying to join this project to spread your *bullshit,* you are *automatically +declared an asshole.* And you’re *gone.* +5. The Owner reserves the right to change this Code of Conduct as they see fit. If, however, you try +to force the Owner to change it in ways that are *offensive to them,* or that try to advance +“social justice” ideals in any way, shape, or form, you’re an *asshole.* And you’re *gone.* +6. In particular, this project explicitly *rejects* the “Open Code of Conduct” by the TODO Group, +the “Contributor Code of Merit” by Coraline Ada Ehmke, the “Citizen Code of Conduct” by +Stumptown Syndicate, and any similar “codes of conduct” that may be promulgated. Anyone complaining +about this is an *asshole,* because *who the fuck are you* to tell *the Owner* how *they* should +run *their* goddamn project? And you’re *gone.* +7. The *one and only* criterion that will be used to determine whether a contribution to this project +will be accepted is *the quality of the contribution and how well it solves the problem it was +contributed to solve.* **Period.** (“Contribution” may include code, documentation, testing, or fundraising.) +8. The *one and only* criterion that will be used to judge your worth in relation to this project is +*the quality of your contributions (as defined above) to this project.* **Period.** +9. The Owner hereby does not give *one milli-micro-nano-fraction of a* **fuck** what race you are, +what gender you are or identify as, who you want to sleep with, how old you are, what your height or +weight is, what if anything may be different about your body or brain, what language you speak, +what country you’re from, what God you pray to, where you work, how much money you have, +et fucking cetera. Is your contribution any *good?* That’s all that matters. +10. If your contribution is not accepted, and you start *whining* about how it’s “actually” because you’re +of some-or-other gender/race/religion/nationality/whatthefuckever, you are attempting to have the deck +stacked in your favor because you’re “special.” That makes you an *asshole.* And you’re *gone.* +11. Only those people who have contributed a sufficient quantity of good work to the project, +*as determined in the Owner's sole discretion,* will be allowed to assume any board position, +administrative position, or management-related role. And, any position that the Owner gives, they can +also *take away,* for any reason. Anyone who complains about this is an *asshole.* And they’re *gone.* +12. You will do your own work. If you try to pass off the work of others as your own, you’re a +fucking *plagiarist,* and also an *asshole.* And you’re *gone.* +13. If there’s a discussion that cannot be resolved within the scope of the project, +*take that shit somewhere else.* The Owner does not want your bullshit here. If you continue to spread +your bullshit here, you’re an *asshole.* And you’re *gone.* +14. As noted above, the Owner's decisions about any aspect of the project are *final.* Anyone +*pissing the Owner off* by getting all up in their face about said decisions is an *asshole.* +And they’re *gone.* +15. Any advisory boards, committees, etc., having to do with this project will answer to *the Owner.* +The Owner reserves the right to disband any such whenever the hell they feel like it. As always, anyone +complaining about this is an *asshole.* And they’re *gone.* +16. Anyone who does not approve of the objectives, direction, or attitude of this project is +free to *get the fuck out* at any time. Bye Felicia! + +Acknowlegements: +- [Why Hackers Must Eject the SJWs](http://esr.ibiblio.org/?p=6918), Eric S. Raymond +- [OSS Code of Merit](http://voxday.blogspot.com/2016/01/code-of-merit.html), Vox Day +- [A contribution policy for open source that works](https://medium.com/@jmaynard/a-contribution-policy-for-open-source-that-works-bfc4600c9d83#.dslxcx1fc), Jay Maynard +- [The Code of Merit](https://github.com/rosarior/Code-of-Merit/blob/master/CODE_OF_MERIT.md), Roberto Rosario \ No newline at end of file From cd453f0839207f3b39e5a15aab428277fcf05260 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:37:31 -0700 Subject: [PATCH 101/101] and give VMW/CB a grateful acknowledgement in the README --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22e1f59..357eabc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ # UPIWIN - Micro Pi Windows Kernel -Requirements: -- Raspberry Pi 3 with PiTFT touchscreen +This project involves the development of a framework for running self-contained applications in Python +on a Raspberry Pi with LCD graphical output and touchscreen input. The ultimate goal is to produce a +framework which is flexible enough to serve any number of “appliance” needs, by using different Python +scripts over the same native-code substrate, deployed on an inexpensive embedded platform. + +## Hardware requirements + +- Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423) + +## Acknowledgements + +A good portion of this code was written during the VMware Carbon Black Hackathon 3.3, December 6-13 2019. +Grateful acknowledgement is provided to VMware Carbon Black for the time to accomplish this coding.