Compare commits

..

31 Commits

Author SHA1 Message Date
c899952cb2 added a couple of additional packages to be installed 2021-08-30 21:45:35 -06:00
8cbfccdd8b fixed local func definition 2021-08-30 21:42:03 -06:00
48f62edc39 factored out some wrapping code to avoid name collisions 2021-08-30 21:39:07 -06:00
12c9082666 added the Python backing code for managing resources 2021-08-30 21:31:56 -06:00
4ef55a700d makefile fix 2021-08-29 22:50:00 -06:00
44ee44b7fa alas, root privs are required after all, for the GPIO stuff 2021-08-29 22:37:07 -06:00
e44619cea6 may not need root privs anymore...test this 2021-08-29 22:31:55 -06:00
df9c5954f8 no longer link splash screen in as an object module (it's in sysresources) 2021-08-29 22:27:57 -06:00
42d88749a0 need extra cast 2021-08-29 22:25:32 -06:00
c30d15742c frame buffer init now reads splash screen data from resources 2021-08-29 22:24:37 -06:00
bda9fc6883 fixed typecasts and changed Rsrc_load_file to use zip sources 2021-08-29 22:07:45 -06:00
333e40827e UINT32 type needs to be used 2021-08-29 22:00:42 -06:00
bcd4ec7bd2 type fix 2021-08-29 21:57:43 -06:00
8aa4b9a2ed first batch of resource-handling functions 2021-08-29 21:56:16 -06:00
8fb7d0ac0b add libzip to UPIWIN libraries 2021-08-29 18:29:35 -06:00
76b808551f missing semicolon 2021-08-29 18:28:34 -06:00
14e240af17 fix a cast on the size of the resources 2021-08-29 18:27:05 -06:00
46c2d5ce27 need to include some more files 2021-08-29 18:25:58 -06:00
9348673adb tied resource initialization into the main control flow 2021-08-29 18:21:51 -06:00
751c0674d1 added resource management code (start of it, anyway) 2021-08-29 18:19:43 -06:00
758af85d84 construct the "sysresources.zip" datablock to be bound into the executable 2021-08-29 16:56:38 -06:00
6b62d0e4f1 updated documentation 2021-08-29 16:42:21 -06:00
2cdc0a3dcc create an "output" directory to copy the finished build to 2021-08-29 16:37:15 -06:00
71e9a4ff4e indent fixes 2021-08-26 00:40:19 -06:00
e15bd3ab90 adjusted the touchscreen coordinate system again to match the driver 2021-08-25 22:24:06 -06:00
f436cf9200 newer touchscreen driver interprets orientation differently 2021-08-25 22:21:32 -06:00
e536685f56 added hardware assembly and OS install documentation; switched splash screen 2021-08-24 23:33:40 -06:00
d8c38cd08a indent fixes 2021-08-18 21:50:15 -06:00
a0993bceca fixed code indents and quote marks in text files 2021-08-18 21:46:19 -06:00
Amy Bowersox
79a777b22d added a copy of the blog post report to the docs directory 2019-12-13 08:36:21 -07:00
Amy Bowersox
d9f5d7f282 Merge branch 'release-0.1' into develop 2019-12-12 14:00:34 -07:00
35 changed files with 1321 additions and 529 deletions

4
.gitignore vendored
View File

@ -2,4 +2,6 @@
*.o *.o
src/upiwin src/upiwin
src/splash.bin src/splash.bin
buildutils/mksplash src/i_*.bin
buildutils/mkgfx
output/

42
CODE-OF-CONDUCT.md Normal file → Executable file
View File

@ -1,8 +1,6 @@
# The Erbosoft Project Code of Conduct # The Erbosoft Project Code of Conduct
## (Revised December 2019) ## (Revised December 2019)
_This document may be redistributed freely in its unmodified form by anyone. The only part which may be freely modified is the designation of the Owner in the following sentence, which should be changed to reflect the ownership of the project this Code of Conduct is being applied to._
For the purposes of this project, the Owner is Amy G. Bowersox/Erbosoft Metaverse Design Solutions. 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 1. *The Owner owns this project.* Not you. The Owner's decisions about any aspect of the project
@ -10,45 +8,45 @@ are *final.*
2. This Code of Conduct contains harsh language. Tough shit. Suck it up, Buttercup. 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.** 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,* 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 youre a Social 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 Justice Warrior trying to join this project to spread your *bullshit,* you are *automatically
declared an asshole.* And youre *gone.* 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 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 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, youre an *asshole.* And youre *gone.* "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, 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 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 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 about this is an *asshole,* because *who the fuck are you* to tell *the Owner* how *they* should
run *their* goddamn project? And youre *gone.* 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 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 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.) 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 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.** *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, 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 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, weight is, what if anything may be different about your body or brain, what language you speak,
what country youre from, what God you pray to, where you work, how much money you have, 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?* Thats all that matters. 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 its “actually” because youre 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 of some-or-other gender/race/religion/nationality/whatthefuckever, you are attempting to have the deck
stacked in your favor because youre “special.” That makes you an *asshole.* And youre *gone.* 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, 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, *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 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 theyre *gone.* 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, youre a 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 youre *gone.* fucking *plagiarist,* and also an *asshole.* And you're *gone.*
13. If theres a discussion that cannot be resolved within the scope of the project, 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 *take that shit somewhere else.* The Owner does not want your bullshit here. If you continue to spread
your bullshit here, youre an *asshole.* And youre *gone.* 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 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.* *pissing the Owner off* by getting all up in their face about said decisions is an *asshole.*
And theyre *gone.* And they're *gone.*
15. Any advisory boards, committees, etc., having to do with this project will answer to *the Owner.* 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 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 theyre *gone.* 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 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! free to *get the fuck out* at any time. Bye Felicia!
@ -56,4 +54,4 @@ Acknowlegements:
- [Why Hackers Must Eject the SJWs](http://esr.ibiblio.org/?p=6918), Eric S. Raymond - [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 - [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 - [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 - [The Code of Merit](https://github.com/rosarior/Code-of-Merit/blob/master/CODE_OF_MERIT.md), Roberto Rosario

View File

@ -2,7 +2,7 @@ GNU General Public License
========================== ==========================
_Version 2, June 1991_ _Version 2, June 1991_
_Copyright © 1989, 1991 Free Software Foundation, Inc.,_ _Copyright © 1989, 1991 Free Software Foundation, Inc.,_
_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_ _51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
@ -62,13 +62,13 @@ modification follow.
**0.** This License applies to any program or other work which contains **0.** This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The “Program”, below, 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” 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: 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, that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in language. (Hereinafter, translation is included without limitation in
the term “modification”.) Each licensee is addressed as “you”. the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of covered by this License; they are outside its scope. The act of
@ -237,8 +237,8 @@ be similar in spirit to the present version, but may differ in detail to
address new problems or concerns. address new problems or concerns.
Each version is given a distinguishing version number. If the Program Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and any 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 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 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 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 this License, you may choose any version ever published by the Free Software
@ -257,7 +257,7 @@ of promoting the sharing and reuse of software generally.
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS 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 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
@ -285,21 +285,21 @@ 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 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 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 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. the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> <one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author> Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along 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., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -320,12 +320,12 @@ be called something other than `show w` and `show c`; they could even be
mouse-clicks or menu items--whatever suits your program. mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your 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 school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names: necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker. `Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 <signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice Ty Coon, President of Vice
@ -333,4 +333,4 @@ This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the 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 library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. Public License instead of this License.

View File

@ -18,7 +18,14 @@
all: all:
make -C buildutils all make -C buildutils all
make -C src all make -C src all
make output
output:
mkdir -p output
cp src/upiwin output
cp scripts/*.py output
clean: clean:
-rm -rf output
make -C buildutils clean make -C buildutils clean
make -C src clean make -C src clean

View File

@ -4,12 +4,14 @@
This project involves the development of a framework for running self-contained applications in Python 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 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 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. scripts over the same native-code substrate, deployed on an inexpensive embedded platform.
## Hardware requirements ## Hardware requirements
- Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423) - Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423). See
[Building the Hardware to Run UPIWIN](docs/hardware-instructions.md) to assemble the hardware, and
[Preparing the Operating System for UPIWIN](docs/os-instructions.md) for the system software.
## Acknowledgements ## Acknowledgements

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -96,12 +96,12 @@ int readpng_get_bgcolor(const char *fname, uch *red, uch *green, uch *blue)
fprintf(stderr, "%s: unspecified error in background reading\n", fname); fprintf(stderr, "%s: unspecified error in background reading\n", fname);
return -1; return -1;
} }
if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
return 0; return 0;
png_get_bKGD(png_ptr, info_ptr, &pBackground); png_get_bKGD(png_ptr, info_ptr, &pBackground);
if (bit_depth == 16) if (bit_depth == 16)
{ {
*red = pBackground->red >> 8; *red = pBackground->red >> 8;
@ -139,7 +139,7 @@ uch *readpng_get_image(const char *fname, double display_exponent, int *pChannel
fprintf(stderr, "%s: unspecified error in image data reading\n", fname); fprintf(stderr, "%s: unspecified error in image data reading\n", fname);
return NULL; return NULL;
} }
if (color_type == PNG_COLOR_TYPE_PALETTE) if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr); png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
@ -158,14 +158,14 @@ uch *readpng_get_image(const char *fname, double display_exponent, int *pChannel
*pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
*pChannels = (int)png_get_channels(png_ptr, info_ptr); *pChannels = (int)png_get_channels(png_ptr, info_ptr);
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) if ((image_data = (uch *)malloc(rowbytes*height)) == NULL)
{ {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fprintf(stderr, "%s: could not allocate image buffer\n", fname); fprintf(stderr, "%s: could not allocate image buffer\n", fname);
return NULL; return NULL;
} }
if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL)
{ {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
@ -249,7 +249,7 @@ int do_convert(const char *infilename, const char *outfilename)
fprintf(stderr, "%s: could not open file\n", outfilename); fprintf(stderr, "%s: could not open file\n", outfilename);
return -1; return -1;
} }
for (row = 0; row < image_height; ++row) for (row = 0; row < image_height; ++row)
{ {
src = image_data + (row * image_rowbytes); src = image_data + (row * image_rowbytes);
@ -257,34 +257,34 @@ int do_convert(const char *infilename, const char *outfilename)
{ {
if (image_channels == 3) if (image_channels == 3)
{ {
bred = *src++; bred = *src++;
bgreen = *src++; bgreen = *src++;
bblue = *src++; bblue = *src++;
} }
else if (image_channels == 4) else if (image_channels == 4)
{ {
br = *src++; br = *src++;
bg = *src++; bg = *src++;
bb = *src++; bb = *src++;
ba = *src++; ba = *src++;
if (ba == 255) if (ba == 255)
{ {
bred = br; bred = br;
bgreen = bg; bgreen = bg;
bblue = bb; bblue = bb;
} }
else if (ba == 0) else if (ba == 0)
{ {
bred = bg_red; bred = bg_red;
bgreen = bg_green; bgreen = bg_green;
bblue = bg_blue; bblue = bg_blue;
} }
else else
{ {
png_composite(bred, br, ba, bg_red); png_composite(bred, br, ba, bg_red);
png_composite(bgreen, bg, ba, bg_green); png_composite(bgreen, bg, ba, bg_green);
png_composite(bblue, bb, ba, bg_blue); png_composite(bblue, bb, ba, bg_blue);
} }
} }
bred = (bred >> 3) & 0x1F; bred = (bred >> 3) & 0x1F;
bgreen = (bgreen >> 2) & 0x3F; bgreen = (bgreen >> 2) & 0x3F;
@ -292,10 +292,10 @@ int do_convert(const char *infilename, const char *outfilename)
buf = (bred << 11) | (bgreen << 5) | bblue; buf = (bred << 11) | (bgreen << 5) | bblue;
if (write(fdout, &buf, sizeof(uint16_t)) < 0) if (write(fdout, &buf, sizeof(uint16_t)) < 0)
{ {
close(fdout); close(fdout);
free(image_data); free(image_data);
fprintf(stderr, "%s: error writing image data\n", outfilename); fprintf(stderr, "%s: error writing image data\n", outfilename);
return -1; return -1;
} }
} }
} }

BIN
docs/UPIWIN-report.odt Executable file

Binary file not shown.

BIN
docs/complete.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,37 @@
# Building the Hardware to Run UPIWIN
UPIWIN is designed for a hardware configuration with a miniature capacitive-touch touchscreen mounted on a
Raspberry Pi computer, making for a compact assembly. This document describes how to assemble one.
## Parts List
- Raspberry Pi 3 Model B+ computer
- PiTFT Plus 320x240 2.8" Capacitive Touch Touchscreen (Adafruit part number 2423)
- Pi Model B+/Pi 2 Case Base - Clear (Adafruit part number 2253)
- PiTFT Faceplate and Buttons (Adafruit part number 2807)
- 2x Brass M2.5 Standoffs (Adafruit part number 2337)
- Additional Raspberry Pi hardware (MicroSD card, power supply, keyboard and display connections)
## Assembly Instructions
1. On the back of the PiTFT, solder closed the jumper pads labeled "#18". This will allow the use of GPIO line 18 as
a PWM backlight control.
2. Attach two standoffs to the underside of the PiTFT (pointing in the same direction as the 40-pin connector), on the
right side (the side with the pushbutton switches). Secure with the included nuts.
3. Attach the PiTFT to the Raspberry Pi, pressing down hard to seat the 40-pin connector atop the Pi's GPIO pins.
4. Seat the completed assembly inside the case base, lining up the holes for the USB and Ethernet ports on the left
side. Press down to snap the latches into place.
5. Holding the faceplate upside down, insert four plastic buttons into the four small rectangular slots. Invert the
case assembly and snap it together with the faceplate, lining the buttons up with the pushbutton switches.
6. Connect the Pi to keyboard, display, power, and network (if necessary). Insert the MicroSD card with the operating
system installed, and boot as usual.
## Illustrations
### Completed subassembly
![Completed subassembly](subassembly.jpg)
### Completed Assembly
![Completed assembly](complete.jpg)

64
docs/os-instructions.md Normal file
View File

@ -0,0 +1,64 @@
# Preparing the Operating System for UPIWIN
The Raspberry Pi OS needs to be configured with the appropriate device tree support, software, and libraries to compile
and run UPIWIN successfully. This document describes the process.
## Preparing the Operating System
1. Download an image of Raspberry Pi OS from
[the Raspberry Pi Foundation](https://downloads.raspberrypi.org/raspios_armhf/images/). The most-recent version of
Raspberry Pi OS that is known to work with the PiTFT is
[the December 4, 2020 image](https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2020-12-04/).
2. Unzip the `.zip` file for your image and write th included `.img` file to a fresh MicroSD card using one of the
methods described on [this page](https://www.raspberrypi.org/documentation/computers/getting-started.html).
3. Connect your UPIWIN-compatible Raspberry Pi (RPi 3B+ with PiTFT) to power, HDMI display, keyboard, and network
(if necessary). Insert the freshly-written MicroSD card into the Pi.
4. Turn on the Pi, boot into Raspberry Pi OS, and set it up. Make sure to get updates installed.
## Installing the PiTFT Drivers
1. In a terminal window, enter the command `sudo -i` to get a root command prompt.
2. Enter the following commands:
pip3 install --upgrade adafruit-python-shell click
git clone https://github.com/adafruit/Raspberry-Pi-Installer-Scripts.git
cd Raspberry-Pi-Installer-Scripts
python3 adafruit-pitft.py --display=28c --rotation=90
3. Answer "N" to the questions about the console appearing on the PiTFT display and mirroring HDMI to the PiTFT
display.
4. Reboot the Pi when prompted.
## Installing Libraries for UPIWIN
1. Use `sudo -i` to get a root command prompt.
2. Execute the command to install packaged libraries and utilities:
apt install python3-dev libfreetype6-dev libpng-dev libzip-dev ttf-mscorefonts-installer zip
3. Execute the commands to install the BCM2835 library:
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz
tar xzvf bcm2835-1.68.tar.gz
cd bcm2835-1.68
./configure
make
make check
make install
4. Copy the Arial font to where the code expects to see it:
mkdir /usr/local/share/fonts/truetype
cp /usr/share/fonts/truetype/msttcorefonts/arial.ttf /usr/local/share/fonts/truetype
## Building the Source
After cloning the repository for UPIWIN, enter the following commands:
cd upiwin
make
The resulting executable and demo scripts will be placed into the `output` directory.
To execute, change to the `output` directory and enter the command `sudo ./upiwin` followed by the name of the script
to be run. For example, `sudo ./upiwin demo1.py`.

BIN
docs/subassembly.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -17,13 +17,13 @@
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
BUILDUTILS=../buildutils BUILDUTILS=../buildutils
RESOURCES=../resources RESOURCES=../resources
SPLASHSCREEN=splash-vmwcblk.png SPLASHSCREEN=splash-erbosoft.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 \ 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 \ ep_resources.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 \ resources.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 i_undo.o i_clear.o splash.o i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.o sysresources.o
LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lzip -lpthread -ldl -lutil -lm
CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ 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 -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 \ LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \
@ -37,6 +37,14 @@ upiwin: $(OBJS)
.c.o: .c.o:
gcc -c $(CFLAGS) $< gcc -c $(CFLAGS) $<
sysresources.o: sysresources.zip
objcopy -I binary -O elf32-littlearm -B arm --rename-section \
.data=.rodata,alloc,load,readonly,data,contents sysresources.zip sysresources.o
sysresources.zip: splash.bin
-rm sysresources.zip
zip -j sysresources.zip splash.bin
%.o: %.bin %.o: %.bin
objcopy -I binary -O elf32-littlearm -B arm --rename-section \ objcopy -I binary -O elf32-littlearm -B arm --rename-section \
.data=.rodata,alloc,load,readonly,data,contents $< $@ .data=.rodata,alloc,load,readonly,data,contents $< $@

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -66,7 +66,7 @@ static void run_exit_funcs(void)
{ {
int i; int i;
PEXITFUNCBLOCK p; PEXITFUNCBLOCK p;
while (exitfuncs) while (exitfuncs)
{ {
p = exitfuncs; p = exitfuncs;
@ -109,36 +109,36 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
switch (c) switch (c)
{ {
case 'F': /* frame buffer device name */ case 'F': /* frame buffer device name */
pstr = strdup(optarg); pstr = strdup(optarg);
if (!pstr) if (!pstr)
{ {
Log(LERROR, "Out of memory in parse_cmdline"); Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (parsed->framebuffer_device) if (parsed->framebuffer_device)
free((PVOID)(parsed->framebuffer_device)); free((PVOID)(parsed->framebuffer_device));
parsed->framebuffer_device = pstr; parsed->framebuffer_device = pstr;
break; break;
case 'h': /* show help */ case 'h': /* show help */
help = TRUE; help = TRUE;
break; break;
case 'T': /* touchscreen device name */ case 'T': /* touchscreen device name */
pstr = strdup(optarg); pstr = strdup(optarg);
if (!pstr) if (!pstr)
{ {
Log(LERROR, "Out of memory in parse_cmdline"); Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (parsed->touchscreen_device) if (parsed->touchscreen_device)
free((PVOID)(parsed->touchscreen_device)); free((PVOID)(parsed->touchscreen_device));
parsed->touchscreen_device = pstr; parsed->touchscreen_device = pstr;
break; break;
default: default:
fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c); fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c);
return E_UNEXPECTED; return E_UNEXPECTED;
} }
} }
if (help) if (help)
@ -167,17 +167,17 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
pargs = (PPCSTR)malloc(sizeof(PCSTR) * parsed->script_arg_count); pargs = (PPCSTR)malloc(sizeof(PCSTR) * parsed->script_arg_count);
if (!pargs) if (!pargs)
{ {
Log(LERROR, "Out of memory in parse_cmdline"); Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
for (c = 0; c < parsed->script_arg_count; c++) for (c = 0; c < parsed->script_arg_count; c++)
{ {
pargs[c] = strdup(argv[optind++]); pargs[c] = strdup(argv[optind++]);
if (!(pargs[c])) if (!(pargs[c]))
{ {
Log(LERROR, "Out of memory in parse_cmdline"); Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
} }
parsed->script_args = pargs; parsed->script_args = pargs;
} }
@ -187,7 +187,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
fprintf(stderr, "%s: no script specified\n", argv[0]); fprintf(stderr, "%s: no script specified\n", argv[0]);
return UPIWIN_E_NOSCRIPT; return UPIWIN_E_NOSCRIPT;
} }
return S_OK; return S_OK;
} }
@ -207,13 +207,13 @@ HRESULT Config_setup(int argc, char *argv[])
{ {
HRESULT hr; HRESULT hr;
GLOBAL_CONFIG from_commandline; GLOBAL_CONFIG from_commandline;
if (geteuid() != 0) if (geteuid() != 0)
{ {
Log(LFATAL, "upiwin must be run with root privileges"); Log(LFATAL, "upiwin must be run with root privileges");
return E_ACCESSDENIED; return E_ACCESSDENIED;
} }
if (atexit(run_exit_funcs)) if (atexit(run_exit_funcs))
{ {
Log(LFATAL, "Unable to set up exit function mechanism"); Log(LFATAL, "Unable to set up exit function mechanism");
@ -236,7 +236,7 @@ HRESULT Config_setup(int argc, char *argv[])
HRESULT Config_exitfunc(PEXITFUNC pfn) HRESULT Config_exitfunc(PEXITFUNC pfn)
{ {
PEXITFUNCBLOCK p; PEXITFUNCBLOCK p;
if (!exitfuncs || (exitfuncs->num_funcs == EXITFUNCBLOCK_FUNCCOUNT)) if (!exitfuncs || (exitfuncs->num_funcs == EXITFUNCBLOCK_FUNCCOUNT))
{ {
p = (PEXITFUNCBLOCK)malloc(sizeof(EXITFUNCBLOCK)); p = (PEXITFUNCBLOCK)malloc(sizeof(EXITFUNCBLOCK));

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -41,42 +41,42 @@ inline static COLORREF COLORREF_from_native(UINT16 cr)
return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800)); return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800));
} }
static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) inline static UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen)
{ {
switch (op) switch (op)
{ {
case R2_BLACK: case R2_BLACK:
return 0; return 0;
case R2_NOTMERGEPEN: case R2_NOTMERGEPEN:
return ~(disp | pen); return ~(disp | pen);
case R2_MASKNOTPEN: case R2_MASKNOTPEN:
return disp & (~pen); return disp & (~pen);
case R2_NOTCOPYPEN: case R2_NOTCOPYPEN:
return ~pen; return ~pen;
case R2_MASKPENNOT: case R2_MASKPENNOT:
return (~disp) & pen; return (~disp) & pen;
case R2_NOT: case R2_NOT:
return ~disp; return ~disp;
case R2_XORPEN: case R2_XORPEN:
return disp ^ pen; return disp ^ pen;
case R2_NOTMASKPEN: case R2_NOTMASKPEN:
return ~(disp & pen); return ~(disp & pen);
case R2_MASKPEN: case R2_MASKPEN:
return disp & pen; return disp & pen;
case R2_NOTXORPEN: case R2_NOTXORPEN:
return ~(disp ^ pen); return ~(disp ^ pen);
case R2_NOP: case R2_NOP:
return disp; return disp;
case R2_MERGENOTPEN: case R2_MERGENOTPEN:
return disp | (~pen); return disp | (~pen);
case R2_COPYPEN: case R2_COPYPEN:
return pen; return pen;
case R2_MERGEPENNOT: case R2_MERGEPENNOT:
return (~disp) | pen; return (~disp) | pen;
case R2_MERGEPEN: case R2_MERGEPEN:
return disp | pen; return disp | pen;
case R2_WHITE: case R2_WHITE:
return (UINT16)(-1); return (UINT16)(-1);
} }
return pen; /* last ditch default */ return pen; /* last ditch default */
} }
@ -99,7 +99,7 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
INT32 dy = y2 - y1; INT32 dy = y2 - y1;
INT32 tmp; INT32 tmp;
PUINT16 loc; PUINT16 loc;
ASSERT(x1 >= 0); ASSERT(x1 >= 0);
ASSERT(x1 < Fb_Info->width); ASSERT(x1 < Fb_Info->width);
ASSERT(y1 >= 0); ASSERT(y1 >= 0);
@ -108,67 +108,67 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
ASSERT(x2 < Fb_Info->width); ASSERT(x2 < Fb_Info->width);
ASSERT(y2 >= 0); ASSERT(y2 >= 0);
ASSERT(y2 < Fb_Info->height); ASSERT(y2 < Fb_Info->height);
/* uses Bresenham's line algorithm with 16-bit fixed-point arithmetic */ /* uses Bresenham's line algorithm with 16-bit fixed-point arithmetic */
if (ABS(dx) < ABS(dy)) if (ABS(dx) < ABS(dy))
{ {
if (y1 > y2) if (y1 > y2)
{ {
tmp = x1; tmp = x1;
x1 = x2; x1 = x2;
x2 = tmp; x2 = tmp;
tmp = y1; tmp = y1;
y1 = y2; y1 = y2;
y2 = tmp; y2 = tmp;
dx = -dx; dx = -dx;
dy = -dy; dy = -dy;
} }
loc = loc_from_coords(priv, x1, y1); loc = loc_from_coords(priv, x1, y1);
tmp = x1; tmp = x1;
x1 <<= 16; x1 <<= 16;
dx = (dx << 16) / dy; dx = (dx << 16) / dy;
while (y1 <= y2) while (y1 <= y2)
{ {
*loc = apply_rop2(op, *loc, pencolor); *loc = apply_rop2(op, *loc, pencolor);
x1 += dx; x1 += dx;
++y1; ++y1;
loc += priv->pix_per_row; loc += priv->pix_per_row;
if (tmp != (x1 >> 16)) if (tmp != (x1 >> 16))
{ {
loc += ((x1 >> 16) - tmp); loc += ((x1 >> 16) - tmp);
tmp = x1 >> 16; tmp = x1 >> 16;
} }
} }
} }
else else
{ {
if (x1 > x2) if (x1 > x2)
{ {
tmp = x1; tmp = x1;
x1 = x2; x1 = x2;
x2 = tmp; x2 = tmp;
tmp = y1; tmp = y1;
y1 = y2; y1 = y2;
y2 = tmp; y2 = tmp;
dx = -dx; dx = -dx;
dy = -dy; dy = -dy;
} }
loc = loc_from_coords(priv, x1, y1); loc = loc_from_coords(priv, x1, y1);
tmp = y1; tmp = y1;
y1 <<= 16; y1 <<= 16;
dy = dx ? (dy << 16) / dx : 0; dy = dx ? (dy << 16) / dx : 0;
while (x1 <= x2) while (x1 <= x2)
{ {
*loc = apply_rop2(op, *loc, pencolor); *loc = apply_rop2(op, *loc, pencolor);
y1 += dy; y1 += dy;
++x1; ++x1;
++loc; ++loc;
if (tmp != (y1 >> 16)) if (tmp != (y1 >> 16))
{ {
loc += (((y1 >> 16) - tmp) * priv->pix_per_row); loc += (((y1 >> 16) - tmp) * priv->pix_per_row);
tmp = y1 >> 16; tmp = y1 >> 16;
} }
} }
} }
return TRUE; return TRUE;
} }
@ -179,17 +179,17 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32
UINT16 pencolor = native_from_COLORREF(color); UINT16 pencolor = native_from_COLORREF(color);
PUINT16 ps, p; PUINT16 ps, p;
int y, x; int y, x;
ps = loc_from_coords(priv, rect->left, rect->top); ps = loc_from_coords(priv, rect->left, rect->top);
for (y = rect->top; y < rect->bottom; y++) for (y = rect->top; y < rect->bottom; y++)
{ {
p = ps; p = ps;
for (x = rect->left; x < rect->right; x++) for (x = rect->left; x < rect->right; x++)
{ {
*p = apply_rop2(op, *p, pencolor); *p = apply_rop2(op, *p, pencolor);
++p; ++p;
} }
ps += priv->pix_per_row; ps += priv->pix_per_row;
} }
return TRUE; return TRUE;
} }
@ -202,7 +202,7 @@ static PDCTXT screen_create_compat(PVOID privdata)
PSCREENPRIVDATA priv_new; PSCREENPRIVDATA priv_new;
PBITMAP pbmp; PBITMAP pbmp;
PDCTXT rc; PDCTXT rc;
pbmp = BMP_Create(1, 1, NULL); pbmp = BMP_Create(1, 1, NULL);
if (!pbmp) if (!pbmp)
return NULL; return NULL;
@ -214,22 +214,22 @@ static PDCTXT screen_create_compat(PVOID privdata)
} }
priv_new->pix_per_row = pbmp->width; priv_new->pix_per_row = pbmp->width;
priv_new->pdata = pbmp->bits; priv_new->pdata = pbmp->bits;
rc = _DC_Allocate(&screen_funtable, priv_new); rc = _DC_Allocate(&screen_funtable, priv_new);
if (rc) if (rc)
{ {
rc->hdr.dtor = screen_context_destroy; rc->hdr.dtor = screen_context_destroy;
rc->flags = DCFLG_IS_MEMORY; rc->flags = DCFLG_IS_MEMORY;
rc->baserect.left = rc->baserect.top = 0; rc->baserect.left = rc->baserect.top = 0;
rc->baserect.right = pbmp->width; rc->baserect.right = pbmp->width;
rc->baserect.bottom = pbmp->height; rc->baserect.bottom = pbmp->height;
memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT));
rc->cur_bitmap = pbmp; rc->cur_bitmap = pbmp;
} }
else else
{ {
free(priv_new); free(priv_new);
Go_release(&(pbmp->hdr)); Go_release(&(pbmp->hdr));
} }
return rc; return rc;
} }
@ -248,7 +248,7 @@ BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32
PSCREENPRIVDATA src = (PSCREENPRIVDATA)p_src; PSCREENPRIVDATA src = (PSCREENPRIVDATA)p_src;
PUINT16 pd, ps; PUINT16 pd, ps;
INT32 width, i; INT32 width, i;
pd = loc_from_coords(dest, r_dest->left, r_dest->top); pd = loc_from_coords(dest, r_dest->left, r_dest->top);
ps = loc_from_coords(src, r_src->left, r_src->top); ps = loc_from_coords(src, r_src->left, r_src->top);
width = r_src->right - r_src->left; width = r_src->right - r_src->left;
@ -256,7 +256,7 @@ BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32
{ {
memcpy(pd, ps, width * sizeof(UINT16)); memcpy(pd, ps, width * sizeof(UINT16));
pd += dest->pix_per_row; pd += dest->pix_per_row;
ps += src->pix_per_row; ps += src->pix_per_row;
} }
return TRUE; return TRUE;
} }
@ -281,22 +281,22 @@ PDCTXT DC_CreateScreenContext(void)
{ {
PDCTXT rc; PDCTXT rc;
PSCREENPRIVDATA priv; PSCREENPRIVDATA priv;
priv = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA)); priv = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA));
if (!priv) if (!priv)
return NULL; return NULL;
priv->pix_per_row = Fb_Info->width; priv->pix_per_row = Fb_Info->width;
priv->pdata = Fb_Ptr; priv->pdata = Fb_Ptr;
rc = _DC_Allocate(&screen_funtable, priv); rc = _DC_Allocate(&screen_funtable, priv);
if (rc) if (rc)
{ {
rc->hdr.dtor = screen_context_destroy; rc->hdr.dtor = screen_context_destroy;
rc->flags = DCFLG_IS_SCREEN; rc->flags = DCFLG_IS_SCREEN;
rc->baserect.left = rc->baserect.top = 0; rc->baserect.left = rc->baserect.top = 0;
rc->baserect.right = Fb_Info->width; rc->baserect.right = Fb_Info->width;
rc->baserect.bottom = Fb_Info->height; rc->baserect.bottom = Fb_Info->height;
memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT));
} }
else else
free(priv); free(priv);

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -53,51 +53,51 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT
BYTE outcode1, outcode2; BYTE outcode1, outcode2;
INT32 tmp; INT32 tmp;
int nloop = 0; int nloop = 0;
/* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */
for (;;) for (;;)
{ {
if (++nloop == 20) if (++nloop == 20)
{ {
Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING"); Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING");
return FALSE; return FALSE;
} }
outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax);
outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax);
if ((outcode1 & outcode2) != 0) if ((outcode1 & outcode2) != 0)
return FALSE; /* trivial rejection */ return FALSE; /* trivial rejection */
else if ((outcode1 == 0) && (outcode2 == 0)) else if ((outcode1 == 0) && (outcode2 == 0))
break; /* trivial acceptance */ break; /* trivial acceptance */
if (outcode1 == 0) if (outcode1 == 0)
{ {
tmp = x1; tmp = x1;
x1 = x2; x1 = x2;
x2 = tmp; x2 = tmp;
tmp = y1; tmp = y1;
y1 = y2; y1 = y2;
y2 = tmp; y2 = tmp;
outcode1 = outcode2; /* we don't reference outcode2 in the rest of the loop */ outcode1 = outcode2; /* we don't reference outcode2 in the rest of the loop */
} }
if (outcode1 & 0x8) if (outcode1 & 0x8)
{ {
x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); x1 += M(x2 - x1, D(ymin - y1, y2 - y1));
y1 = ymin; y1 = ymin;
} }
else if (outcode1 & 0x4) else if (outcode1 & 0x4)
{ {
x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1));
y1 = ymax - ONE; y1 = ymax - ONE;
} }
else if (outcode1 & 0x2) else if (outcode1 & 0x2)
{ {
y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1));
x1 = xmax - ONE; x1 = xmax - ONE;
} }
else if (outcode1 & 0x1) else if (outcode1 & 0x1)
{ {
y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); y1 += M(y2 - y1, D(xmin - x1, x2 - x1));
x1 = xmin; x1 = xmin;
} }
} }
output[0] = x1; output[0] = x1;
output[1] = y1; output[1] = y1;
@ -137,7 +137,7 @@ void _DC_FinalizeCommon(PDCTXT pdctxt)
COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color)
{ {
if (!G_coords_in_rect(&(pdctxt->cliprect), x, y)) if (!G_coords_in_rect(&(pdctxt->cliprect), x, y))
return (COLORREF)(-1); return (COLORREF)(-1);
return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2); return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2);
} }
@ -147,7 +147,7 @@ BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y)
if (rc) if (rc)
{ {
pdctxt->pos.x = x; pdctxt->pos.x = x;
pdctxt->pos.y = y; pdctxt->pos.y = y;
} }
return rc; return rc;
} }
@ -227,22 +227,22 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj)
if (pobj->sig == BMP_SIG_WORD) if (pobj->sig == BMP_SIG_WORD)
{ {
if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY) if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY)
{ {
RECT rtmp; RECT rtmp;
PBITMAP rbmp = pdctxt->cur_bitmap; PBITMAP rbmp = pdctxt->cur_bitmap;
Go_addref(pobj); Go_addref(pobj);
if ((*(pdctxt->funcs->new_bitmap))(pdctxt->privdata, (PBITMAP)pobj)) if ((*(pdctxt->funcs->new_bitmap))(pdctxt->privdata, (PBITMAP)pobj))
{ {
pdctxt->cur_bitmap = (PBITMAP)pobj; pdctxt->cur_bitmap = (PBITMAP)pobj;
pdctxt->baserect.left = pdctxt->baserect.top = 0; pdctxt->baserect.left = pdctxt->baserect.top = 0;
pdctxt->baserect.right = ((PBITMAP)pobj)->width; pdctxt->baserect.right = ((PBITMAP)pobj)->width;
pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; pdctxt->baserect.bottom = ((PBITMAP)pobj)->height;
G_rect_intersect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); G_rect_intersect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect));
memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT));
return (PGFXOBJECT)rbmp; return (PGFXOBJECT)rbmp;
} }
Go_release(pobj); Go_release(pobj);
} }
} }
return NULL; return NULL;
} }
@ -250,7 +250,7 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj)
BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop) 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; RECT destrect, actualdest, srcrect, actualsrc;
G_set_rect(&destrect, x, y, x + width, y + height); G_set_rect(&destrect, x, y, x + width, y + height);
if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect))) if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect)))
return TRUE; /* no-op */ return TRUE; /* no-op */

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -25,7 +25,7 @@
#include "gfxobj.h" #include "gfxobj.h"
#include "bitmap.h" #include "bitmap.h"
#define DCTXT_SIG_WORD 0x78744344 /* "DCtx */ #define DCTXT_SIG_WORD 0x78744344 /* "DCtx" */
/* Raster operation codes */ /* Raster operation codes */
#define R2_BLACK 1 #define R2_BLACK 1

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -63,18 +63,18 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = { "stock", "width", "height", NULL }; static char *kwlist[] = { "stock", "width", "height", NULL };
const char *stock; const char *stock;
int width = 0, height = 0; 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; return -1;
if (stock) if (stock)
{ {
self->pbmp = _BMP_GetStock(stock); self->pbmp = _BMP_GetStock(stock);
if (!(self->pbmp)) if (!(self->pbmp))
{ {
PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock); PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock);
return -1; return -1;
} }
} }
else else
{ {
@ -83,8 +83,8 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
self->pbmp = BMP_Create(width, height, NULL); self->pbmp = BMP_Create(width, height, NULL);
if (!(self->pbmp)) if (!(self->pbmp))
{ {
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
return -1; return -1;
} }
} }
return 0; return 0;
@ -114,12 +114,12 @@ PyTypeObject BitmapType = {
HRESULT Epython_register_bitmap(PyObject *module) HRESULT Epython_register_bitmap(PyObject *module)
{ {
if (PyType_Ready(&BitmapType) < 0) if (PyType_Ready(&BitmapType) < 0)
return E_FAIL; return E_FAIL;
Py_INCREF(&BitmapType); Py_INCREF(&BitmapType);
if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0) if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0)
{ {
Py_DECREF(&BitmapType); Py_DECREF(&BitmapType);
return E_FAIL; return E_FAIL;
} }
return S_OK; return S_OK;
} }
@ -128,26 +128,26 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp)
{ {
PyObject *rc = NULL, *args, *kwargs; PyObject *rc = NULL, *args, *kwargs;
BitmapObject *pbitmapobj; BitmapObject *pbitmapobj;
args = PyTuple_New(0); args = PyTuple_New(0);
if (args) if (args)
{ {
kwargs = PyDict_New(); kwargs = PyDict_New();
if (kwargs) if (kwargs)
{ {
rc = PyType_GenericNew(&BitmapType, args, kwargs); rc = PyType_GenericNew(&BitmapType, args, kwargs);
if (rc) if (rc)
{ {
pbitmapobj = (BitmapObject *)rc; pbitmapobj = (BitmapObject *)rc;
if (pbitmapobj->pbmp) if (pbitmapobj->pbmp)
BMP_Delete(pbitmapobj->pbmp); BMP_Delete(pbitmapobj->pbmp);
pbitmapobj->pbmp = pbmp; pbitmapobj->pbmp = pbmp;
} }
Py_DECREF(kwargs); Py_DECREF(kwargs);
} }
Py_DECREF(args); Py_DECREF(args);
} }
if (!rc) if (!rc)
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
return rc; return rc;

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -32,7 +32,7 @@ static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args)
{ {
INT32 x, y; INT32 x, y;
COLORREF color, rc; COLORREF color, rc;
if (!PyArg_ParseTuple(args, "iik", &x, &y, &color)) if (!PyArg_ParseTuple(args, "iik", &x, &y, &color))
return NULL; return NULL;
if (!(self->pdctxt)) if (!(self->pdctxt))
@ -80,7 +80,7 @@ static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args)
{ {
INT32 left, top, right, bottom; INT32 left, top, right, bottom;
BOOL rc; BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom)) if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom))
return NULL; return NULL;
if (!(self->pdctxt)) if (!(self->pdctxt))
@ -96,7 +96,7 @@ static PyObject *devctxt_solid_rectangle(DevCtxtObject *self, PyObject *args)
{ {
INT32 left, top, right, bottom; INT32 left, top, right, bottom;
BOOL rc; BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom)) if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom))
return NULL; return NULL;
if (!(self->pdctxt)) if (!(self->pdctxt))
@ -114,7 +114,7 @@ static PyObject *devctxt_bitblt(DevCtxtObject *self, PyObject *args)
UINT32 rop; UINT32 rop;
DevCtxtObject *source; DevCtxtObject *source;
BOOL rc; BOOL rc;
if (!PyArg_ParseTuple(args, "iiiiO!iik", &x, &y, &width, &height, &DevCtxtType, &source, &x1, &y1, &rop)) if (!PyArg_ParseTuple(args, "iiiiO!iik", &x, &y, &width, &height, &DevCtxtType, &source, &x1, &y1, &rop))
return NULL; return NULL;
if (!(self->pdctxt) || !(source->pdctxt)) if (!(self->pdctxt) || !(source->pdctxt))
@ -130,7 +130,7 @@ static PyObject *devctxt_bitblt(DevCtxtObject *self, PyObject *args)
static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args) static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args)
{ {
RECT rect; RECT rect;
if (!PyArg_ParseTuple(args, "")) if (!PyArg_ParseTuple(args, ""))
return NULL; return NULL;
if (!(self->pdctxt)) if (!(self->pdctxt))
@ -146,7 +146,7 @@ static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args)
{ {
RECT rect; RECT rect;
BOOL rc; BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))) if (!PyArg_ParseTuple(args, "iiii", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)))
return NULL; return NULL;
if (!(self->pdctxt)) if (!(self->pdctxt))
@ -162,27 +162,27 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp
{ {
BitmapObject *old_bitmap = NULL; BitmapObject *old_bitmap = NULL;
PBITMAP old_pbmp; PBITMAP old_pbmp;
if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY)
{ {
PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context");
return NULL; return NULL;
} }
old_bitmap = self->selected_bitmap; old_bitmap = self->selected_bitmap;
old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp));
if (!old_bitmap) if (!old_bitmap)
{ {
old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp);
if (!old_bitmap) if (!old_bitmap)
{ {
DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp);
return NULL; return NULL;
} }
else else
{ {
Py_INCREF(old_bitmap); Py_INCREF(old_bitmap);
self->selected_bitmap = old_bitmap; self->selected_bitmap = old_bitmap;
} }
} }
ASSERT(old_bitmap); ASSERT(old_bitmap);
ASSERT(self->selected_bitmap); ASSERT(self->selected_bitmap);
@ -202,7 +202,7 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args)
if (!obj) if (!obj)
{ {
PyErr_SetString(PyExc_RuntimeError, "bad object selected"); PyErr_SetString(PyExc_RuntimeError, "bad object selected");
return NULL; return NULL;
} }
if (PyObject_TypeCheck(obj, &BitmapType)) if (PyObject_TypeCheck(obj, &BitmapType))
return devctxt_select_bitmap(self, (BitmapObject *)obj); return devctxt_select_bitmap(self, (BitmapObject *)obj);
@ -245,7 +245,7 @@ static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure)
static int devctxt_set_rop2(DevCtxtObject *self, PyObject *value, void *closure) static int devctxt_set_rop2(DevCtxtObject *self, PyObject *value, void *closure)
{ {
UINT32 v; UINT32 v;
if (!(self->pdctxt)) if (!(self->pdctxt))
{ {
PyErr_SetString(PyExc_RuntimeError, "bad device context"); PyErr_SetString(PyExc_RuntimeError, "bad device context");
@ -276,7 +276,7 @@ static PyObject *devctxt_get_text_color(DevCtxtObject *self, void *closure)
static int devctxt_set_text_color(DevCtxtObject *self, PyObject *value, void *closure) static int devctxt_set_text_color(DevCtxtObject *self, PyObject *value, void *closure)
{ {
COLORREF v; COLORREF v;
if (!(self->pdctxt)) if (!(self->pdctxt))
{ {
PyErr_SetString(PyExc_RuntimeError, "bad device context"); PyErr_SetString(PyExc_RuntimeError, "bad device context");
@ -313,31 +313,31 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds)
{ {
static char *kwlist[] = { "type", NULL }; static char *kwlist[] = { "type", NULL };
const char *type; const char *type;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type)) if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type))
return -1; return -1;
if (strcmp(type, "screen") == 0) if (strcmp(type, "screen") == 0)
{ {
self->pdctxt = DC_CreateScreenContext(); self->pdctxt = DC_CreateScreenContext();
if (!(self->pdctxt)) if (!(self->pdctxt))
{ {
PyErr_SetString(PyExc_RuntimeError, "unable to create screen context"); PyErr_SetString(PyExc_RuntimeError, "unable to create screen context");
return -1; return -1;
} }
} }
else if (strcmp(type, "memory") == 0) else if (strcmp(type, "memory") == 0)
{ {
self->pdctxt = _DC_CreateScreenCompatibleContext(); self->pdctxt = _DC_CreateScreenCompatibleContext();
if (!(self->pdctxt)) if (!(self->pdctxt))
{ {
PyErr_SetString(PyExc_RuntimeError, "unable to create memory context"); PyErr_SetString(PyExc_RuntimeError, "unable to create memory context");
return -1; return -1;
} }
} }
else else
{ {
PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type); PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type);
return -1; return -1;
} }
return 0; return 0;
} }
@ -359,12 +359,12 @@ PyTypeObject DevCtxtType = {
HRESULT Epython_register_devctxt(PyObject *module) HRESULT Epython_register_devctxt(PyObject *module)
{ {
if (PyType_Ready(&DevCtxtType) < 0) if (PyType_Ready(&DevCtxtType) < 0)
return E_FAIL; return E_FAIL;
Py_INCREF(&DevCtxtType); Py_INCREF(&DevCtxtType);
if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0) if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0)
{ {
Py_DECREF(&DevCtxtType); Py_DECREF(&DevCtxtType);
return E_FAIL; return E_FAIL;
} }
return S_OK; return S_OK;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -131,29 +131,29 @@ HRESULT Epython_run(void)
{ {
for (i=0; i<Gconfig.script_arg_count; i++) for (i=0; i<Gconfig.script_arg_count; i++)
{ {
args[i + 1] = Py_DecodeLocale(Gconfig.script_args[i], NULL); args[i + 1] = Py_DecodeLocale(Gconfig.script_args[i], NULL);
if (!(args[i + 1])) if (!(args[i + 1]))
{ {
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
break; break;
} }
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
PySys_SetArgvEx(Gconfig.script_arg_count + 1, args, 1); PySys_SetArgvEx(Gconfig.script_arg_count + 1, args, 1);
PyRun_SimpleFile(fp, Gconfig.script_name); PyRun_SimpleFile(fp, Gconfig.script_name);
} }
else else
Log(LERROR, "out of memory running script %s", Gconfig.script_name); Log(LERROR, "out of memory running script %s", Gconfig.script_name);
} }
else else
{ {
Log(LERROR, "out of memory running script %s", Gconfig.script_name); Log(LERROR, "out of memory running script %s", Gconfig.script_name);
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
} }
for (i = 0; i<(Gconfig.script_arg_count + 1); i++) for (i = 0; i<(Gconfig.script_arg_count + 1); i++)
if (args[i]) if (args[i])
PyMem_RawFree(args[i]); PyMem_RawFree(args[i]);
fclose(fp); fclose(fp);
} }
else else

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -35,6 +35,7 @@ extern PyObject *Epython_init_upiwin_tmp_module(void);
extern HRESULT Epython_register_devctxt(PyObject *module); extern HRESULT Epython_register_devctxt(PyObject *module);
extern HRESULT Epython_register_bitmap(PyObject *module); extern HRESULT Epython_register_bitmap(PyObject *module);
extern HRESULT Epython_register_resources(PyObject *module);
extern HRESULT Epython_setup(void); extern HRESULT Epython_setup(void);
extern HRESULT Epython_run(void); extern HRESULT Epython_run(void);

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -29,29 +29,29 @@
static HRESULT convert_msg(PyObject *target, PMSG source) static HRESULT convert_msg(PyObject *target, PMSG source)
{ {
PyObject *attr; PyObject *attr;
ASSERT(PyDict_CheckExact(target)); ASSERT(PyDict_CheckExact(target));
PyDict_Clear(target); PyDict_Clear(target);
attr = PyLong_FromUnsignedLong(source->target); attr = PyLong_FromUnsignedLong(source->target);
if (!attr) if (!attr)
return E_FAIL; return E_FAIL;
if (PyDict_SetItemString(target, "target", attr)) if (PyDict_SetItemString(target, "target", attr))
return E_FAIL; return E_FAIL;
attr = PyLong_FromUnsignedLong(source->message); attr = PyLong_FromUnsignedLong(source->message);
if (!attr) if (!attr)
return E_FAIL; return E_FAIL;
if (PyDict_SetItemString(target, "message", attr)) if (PyDict_SetItemString(target, "message", attr))
return E_FAIL; return E_FAIL;
attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]); attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]);
if (!attr) if (!attr)
return E_FAIL; return E_FAIL;
if (PyDict_SetItemString(target, "attrs", attr)) if (PyDict_SetItemString(target, "attrs", attr))
return E_FAIL; return E_FAIL;
attr = PyLong_FromUnsignedLongLong(source->timestamp); attr = PyLong_FromUnsignedLongLong(source->timestamp);
if (!attr) if (!attr)
return E_FAIL; return E_FAIL;
if (PyDict_SetItemString(target, "timestamp", attr)) if (PyDict_SetItemString(target, "timestamp", attr))
return E_FAIL; return E_FAIL;
return S_OK; return S_OK;
} }
@ -59,20 +59,20 @@ PyObject *Epython_get_message(PyObject *self, PyObject *args)
{ {
PyObject *out; PyObject *out;
MSG msg; MSG msg;
if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out)) if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out))
return NULL; return NULL;
/* release the GIL to allow us to block waiting for input if necessary */ /* release the GIL to allow us to block waiting for input if necessary */
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE))
Sys_wait_for_input(); Sys_wait_for_input();
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (FAILED(convert_msg(out, &msg))) if (FAILED(convert_msg(out, &msg)))
{ {
PyErr_SetString(PyExc_RuntimeError, "could not convert received message"); PyErr_SetString(PyExc_RuntimeError, "could not convert received message");
return NULL; return NULL;
} }
return PyBool_FromLong(msg.message != WM_QUIT); return PyBool_FromLong(msg.message != WM_QUIT);
} }
@ -80,11 +80,10 @@ PyObject *Epython_get_message(PyObject *self, PyObject *args)
PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) PyObject *Epython_post_quit_message(PyObject *self, PyObject *args)
{ {
INT32 exitcode; INT32 exitcode;
if (!PyArg_ParseTuple(args, "i", &exitcode)) if (!PyArg_ParseTuple(args, "i", &exitcode))
return NULL; return NULL;
Sys_Exit_Code = exitcode; Sys_Exit_Code = exitcode;
Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode);
Py_RETURN_NONE; Py_RETURN_NONE;
} }

247
src/ep_resources.c Normal file
View File

@ -0,0 +1,247 @@
/*
* 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 <string.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
#include "scode.h"
#include "log.h"
#include "resources.h"
#include "ep_init.h"
#include "ep_types.h"
static PyObject *wrap_resource_file_handle(HRESFILE handle)
{
PyObject *rc = NULL, *args, *kwargs;
ResFileObject *presfile;
args = PyTuple_New(0);
if (args)
{
kwargs = PyDict_New();
if (kwargs)
{
rc = PyType_GenericNew(&ResFileType, args, kwargs);
if (rc)
{
presfile = (ResFileObject *)rc;
presfile->hresfile = handle;
}
Py_DECREF(kwargs);
}
Py_DECREF(args);
}
return rc;
}
static PyObject *resfile_load_classmethod(PyTypeObject *cls, PyObject *args)
{
const char *filename;
PyObject *rc = NULL;
HRESULT hr;
HRESFILE handle;
if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
hr = Rsrc_load_file((PCSTR)filename, &handle);
if (SUCCEEDED(hr))
{
rc = wrap_resource_file_handle(handle);
if (!rc)
{
Rsrc_close_file(handle);
PyErr_SetString(PyExc_RuntimeError, "unable to create new resource file object");
}
}
else
PyErr_Format(PyExc_RuntimeError, "unable to load resource file '%s' (%08x)", filename, hr);
return rc;
}
static PyObject *resfile_close(ResFileObject *self, PyObject *args)
{
if (self->hresfile)
Rsrc_close_file(self->hresfile);
self->hresfile = (HRESFILE)NULL;
return NULL;
}
static PyObject *wrap_resource_handle(HRSRC hrsrc)
{
PyObject *rc = NULL, *args, *kwargs;
ResourceObject *pres;
args = PyTuple_New(0);
if (args)
{
kwargs = PyDict_New();
if (kwargs)
{
rc = PyType_GenericNew(&ResourceType, args, kwargs);
if (rc)
{
pres = (ResourceObject *)rc;
pres->hrsrc = hrsrc;
}
Py_DECREF(kwargs);
}
Py_DECREF(args);
}
return rc;
}
static PyObject *resfile_find_resource(ResFileObject *self, PyObject *args)
{
const char *name;
PyObject *rc = NULL;
HRSRC hrsrc;
HRESULT hr;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
hr = Rsrc_find_resource(self->hresfile, (PCSTR)name, NULL, &hrsrc);
if (SUCCEEDED(hr))
{
rc = wrap_resource_handle(hrsrc);
if (!rc)
{
Rsrc_free_resource(hrsrc);
PyErr_SetString(PyExc_RuntimeError, "unable to create new resource object");
}
}
else
PyErr_Format(PyExc_RuntimeError, "unable to load resource ''%s' (%08x)", name, hr);
return rc;
}
static PyMethodDef ResFileMethods[] = {
{"load", (PyCFunction)resfile_load_classmethod, METH_VARARGS|METH_CLASS,
"Load a resource file."},
{"close", (PyCFunction)resfile_close, METH_VARARGS,
"Close the resource file."},
{"find_resource", (PyCFunction)resfile_find_resource, METH_VARARGS,
"Find a resource within the resource file."},
{NULL, NULL, 0, NULL}
};
static void resfile_dealloc(ResFileObject *self)
{
if (self->hresfile)
Rsrc_close_file(self->hresfile);
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int resfile_init(ResFileObject *self, PyObject *args, PyObject *kwds)
{
self->hresfile = (HRESFILE)NULL;
return 0;
}
PyTypeObject ResFileType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "upiwin.ResFile",
.tp_doc = "Resource file object",
.tp_basicsize = sizeof(ResFileObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)resfile_init,
.tp_dealloc = (destructor)resfile_dealloc,
.tp_methods = ResFileMethods
};
static PyObject *resource_close(ResourceObject *self, PyObject *args)
{
if (self->hrsrc)
Rsrc_free_resource(self->hrsrc);
self->hrsrc = (HRESFILE)NULL;
return NULL;
}
static PyMethodDef ResourceMethods[] = {
{"close", (PyCFunction)resource_close, METH_VARARGS,
"Close and free the resource."},
{NULL, NULL, 0, NULL}
};
static PyObject *resource_get_size(ResourceObject *self, void *closure)
{
if (!(self->hrsrc))
{
PyErr_SetString(PyExc_RuntimeError, "bad resource object");
return NULL;
}
return PyLong_FromUnsignedLong(Rsrc_sizeof_resource(self->hrsrc));
}
static PyGetSetDef ResourceProperties[] = {
{"size", (getter)resource_get_size, NULL, "Size of the resource in bytes", NULL},
{NULL, NULL, NULL, NULL, NULL}
};
static void resource_dealloc(ResourceObject *self)
{
if (self->hrsrc)
Rsrc_free_resource(self->hrsrc);
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int resource_init(ResourceObject *self, PyObject *args, PyObject *kwds)
{
self->hrsrc = (HRSRC)NULL;
return 0;
}
PyTypeObject ResourceType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "upiwin.Resource",
.tp_doc = "Resource object",
.tp_basicsize = sizeof(ResourceObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)resource_init,
.tp_dealloc = (destructor)resource_dealloc,
.tp_methods = ResourceMethods,
.tp_getset = ResourceProperties
};
HRESULT Epython_register_resources(PyObject *module)
{
if (PyType_Ready(&ResFileType) < 0)
return E_FAIL;
if (PyType_Ready(&ResourceType) < 0)
return E_FAIL;
Py_INCREF(&ResFileType);
if (PyModule_AddObject(module, "ResFile", (PyObject *)(&ResFileType)) < 0)
{
Py_DECREF(&ResFileType);
return E_FAIL;
}
Py_INCREF(&ResourceType);
if (PyModule_AddObject(module, "Resource", (PyObject *)(&ResourceType)) < 0)
{
Py_DECREF(&ResourceType);
return E_FAIL;
}
return S_OK;
}

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -27,6 +27,7 @@
#include "gfxobj.h" #include "gfxobj.h"
#include "devctxt.h" #include "devctxt.h"
#include "bitmap.h" #include "bitmap.h"
#include "resources.h"
typedef struct tagBitmapObject { typedef struct tagBitmapObject {
PyObject_HEAD PyObject_HEAD
@ -39,8 +40,20 @@ typedef struct tagDevCtxtObject {
BitmapObject *selected_bitmap; BitmapObject *selected_bitmap;
} DevCtxtObject; } DevCtxtObject;
typedef struct tagResFileObject {
PyObject_HEAD
HRESFILE hresfile;
} ResFileObject;
typedef struct tagResourceObject {
PyObject_HEAD
HRSRC hrsrc;
} ResourceObject;
extern PyTypeObject DevCtxtType; extern PyTypeObject DevCtxtType;
extern PyTypeObject BitmapType; extern PyTypeObject BitmapType;
extern PyTypeObject ResFileType;
extern PyTypeObject ResourceType;
extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp); extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp);

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -94,33 +94,39 @@ PyObject *Epython_init_upiwin_module(void)
{ {
PyObject *module; PyObject *module;
PUPIWIN_STATE pstate; PUPIWIN_STATE pstate;
module = PyModule_Create(&DefUPIWIN); module = PyModule_Create(&DefUPIWIN);
if (!module) if (!module)
return NULL; return NULL;
if (FAILED(Epython_register_constants(module, UPIWINConstants))) if (FAILED(Epython_register_constants(module, UPIWINConstants)))
{ {
Py_DECREF(module); Py_DECREF(module);
return NULL; return NULL;
} }
if (FAILED(Epython_register_bitmap(module))) if (FAILED(Epython_register_bitmap(module)))
{ {
Py_DECREF(module); Py_DECREF(module);
return NULL; return NULL;
} }
if (FAILED(Epython_register_devctxt(module))) if (FAILED(Epython_register_devctxt(module)))
{ {
Py_DECREF(module); Py_DECREF(module);
return NULL; return NULL;
}
if (FAILED(Epython_register_resources(module)))
{
Py_DECREF(module);
return NULL;
} }
/* set up the module state */ /* set up the module state */
pstate = (PUPIWIN_STATE)PyModule_GetState(module); pstate = (PUPIWIN_STATE)PyModule_GetState(module);
pstate->backlight_on = TRUE; pstate->backlight_on = TRUE;
pstate->backlight_level = GSB_BACKLIGHT_DEFAULT; pstate->backlight_level = GSB_BACKLIGHT_DEFAULT;
return module; return module;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -119,15 +119,15 @@ END_CONSTANT_TABLE
PyObject *Epython_init_upiwin_tmp_module(void) PyObject *Epython_init_upiwin_tmp_module(void)
{ {
PyObject *module; PyObject *module;
module = PyModule_Create(&DefUPIWIN_tmp); module = PyModule_Create(&DefUPIWIN_tmp);
if (module) if (module)
{ {
if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants))) if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants)))
{ {
Py_DECREF(module); Py_DECREF(module);
module = NULL; module = NULL;
} }
} }
return module; return module;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -46,7 +46,7 @@ void Epython_log_object(int level, const char *label, PyObject *object)
HRESULT Epython_trace_exception(void) HRESULT Epython_trace_exception(void)
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
PyObject *type, *value, *traceback; PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback); PyErr_Fetch(&type, &value, &traceback);
if (!type) if (!type)
@ -66,29 +66,29 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
int i = 0, rc; int i = 0, rc;
while (const_table[i].name) while (const_table[i].name)
{ {
switch (const_table[i].regtype) switch (const_table[i].regtype)
{ {
case 'i': case 'i':
rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival); rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival);
break; break;
case 's': case 's':
rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval); rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval);
break; break;
default: default:
Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype);
return E_UNEXPECTED; return E_UNEXPECTED;
} }
if (rc) if (rc)
{ {
Log(LERROR, "Failed to register constant %s", const_table[i].name); Log(LERROR, "Failed to register constant %s", const_table[i].name);
hr = E_FAIL; hr = E_FAIL;
break; break;
} }
++i; ++i;
} }
return hr; return hr;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -29,11 +29,7 @@
#include "log.h" #include "log.h"
#include "fbinit.h" #include "fbinit.h"
#include "scode.h" #include "scode.h"
#include "resources.h"
/* references to splash screen data in splash.o/splash.bin */
extern uint8_t _binary_splash_bin_start[];
extern uint8_t _binary_splash_bin_end;
extern uint8_t _binary_splash_bin_size;
static int fb_fd = -1; /* framebuffer file descriptor */ static int fb_fd = -1; /* framebuffer file descriptor */
@ -52,9 +48,9 @@ static void do_cleanup(void)
{ {
/* black out the display */ /* black out the display */
memset(Fb_Ptr, 0, local_info.screenbytes); memset(Fb_Ptr, 0, local_info.screenbytes);
munmap((void *)Fb_Ptr, local_info.screenbytes); munmap((void *)Fb_Ptr, local_info.screenbytes);
Fb_Ptr = NULL; Fb_Ptr = NULL;
close(fb_fd); close(fb_fd);
fb_fd = -1; fb_fd = -1;
} }
@ -62,9 +58,11 @@ static void do_cleanup(void)
HRESULT Fb_setup(void) HRESULT Fb_setup(void)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
HRESULT hr2 = S_OK;
HRSRC splash;
struct fb_fix_screeninfo fixed; struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
fb_fd = open(Gconfig.framebuffer_device, O_RDWR); fb_fd = open(Gconfig.framebuffer_device, O_RDWR);
if (fb_fd == -1) if (fb_fd == -1)
{ {
@ -84,7 +82,7 @@ HRESULT Fb_setup(void)
local_info.linebytes = fixed.line_length; local_info.linebytes = fixed.line_length;
local_info.screenbytes = fixed.smem_len; local_info.screenbytes = fixed.smem_len;
/* variable info is used to get scren geometry and color info */ /* variable info is used to get screen geometry and color info */
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
{ {
hr = ERRNO_AS_SCODE; hr = ERRNO_AS_SCODE;
@ -118,8 +116,16 @@ HRESULT Fb_setup(void)
return hr; return hr;
} }
/* display the splash screen */ /* The splash screen is in the system resources. Use the resource API to load it straight to the frame buffer. */
memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size)); hr2 = Rsrc_find_resource((HRESFILE)NULL, "splash.bin", NULL, &splash);
if (SUCCEEDED(hr2))
{
ASSERT(Rsrc_sizeof_resource(splash) == fixed.smem_len);
hr2 = Rsrc_read_resource_here(splash, Fb_Ptr, fixed.smem_len, NULL);
Rsrc_free_resource(splash);
}
if (FAILED(hr2))
Log(LWARN, "splash screen rendering failed (%08X)", hr2);
hr = Config_exitfunc(do_cleanup); hr = Config_exitfunc(do_cleanup);
if (FAILED(hr)) if (FAILED(hr))

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -129,9 +129,9 @@ void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, B
for (tmp = x1; tmp <= x2; tmp++) for (tmp = x1; tmp <= x2; tmp++)
{ {
if (xor) if (xor)
*p++ ^= color; *p++ ^= color;
else else
*p++ = color; *p++ = color;
} }
ps += Fb_Info->width; ps += Fb_Info->width;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -32,7 +32,7 @@ void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size)
void Go_unchain(PGFXOBJECT obj) void Go_unchain(PGFXOBJECT obj)
{ {
if (!(obj->next || obj->prev)) if (!(obj->next || obj->prev))
return; return;
if (obj->next) if (obj->next)
obj->next->prev = obj->prev; obj->next->prev = obj->prev;
if (obj->prev) if (obj->prev)
@ -50,9 +50,9 @@ INT32 Go_release(PGFXOBJECT obj)
int rc = --(obj->refcnt); int rc = --(obj->refcnt);
if (rc == 0) if (rc == 0)
{ {
if (obj->dtor) if (obj->dtor)
(*(obj->dtor))(obj); (*(obj->dtor))(obj);
free(obj); free(obj);
} }
return rc; return rc;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -25,6 +25,7 @@
#include "config.h" #include "config.h"
#include "gpio.h" #include "gpio.h"
#include "fbinit.h" #include "fbinit.h"
#include "resources.h"
#include "fontengine.h" #include "fontengine.h"
#include "time_func.h" #include "time_func.h"
#include "ep_init.h" #include "ep_init.h"
@ -41,6 +42,8 @@ int main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
else if (hr != S_OK) else if (hr != S_OK)
return EXIT_SUCCESS; return EXIT_SUCCESS;
if (FAILED(Rsrc_setup()))
return EXIT_FAILURE;
if (FAILED(Fb_setup())) if (FAILED(Fb_setup()))
return EXIT_FAILURE; return EXIT_FAILURE;
if (FAILED(FontEng_setup())) if (FAILED(FontEng_setup()))
@ -57,7 +60,7 @@ int main(int argc, char *argv[])
Fb_clear(); Fb_clear();
if (FAILED(Epython_run())) if (FAILED(Epython_run()))
return EXIT_FAILURE; return EXIT_FAILURE;
Log(LINFO, "Script returned with exit code %d", Sys_Exit_Code); Log(LINFO, "Script returned with exit code %d", Sys_Exit_Code);
return Sys_Exit_Code; return Sys_Exit_Code;
} }

310
src/resources.c Normal file
View File

@ -0,0 +1,310 @@
/*
* 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 <stdlib.h>
#include <string.h>
#include <zip.h>
#include "wintype.h"
#include "scode.h"
#include "config.h"
#include "log.h"
#include "resources.h"
typedef struct tagRESFILE {
struct tagRESFILE *next;
struct tagRESFILE *prev;
zip_t *resource;
} RESFILE, *PRESFILE;
typedef struct tagRESOURCEINFO {
zip_t *resource_file;
zip_stat_t entryinfo;
} RESOURCEINFO, *PRESOURCEINFO;
/* conversion table from zip error codes to our HRESULT values */
static const struct tagCONVERSIONTABLE {
int zip_err_code;
HRESULT sys_err_code;
} conversion_table[] = {
{ ZIP_ER_OK, S_OK },
{ ZIP_ER_SEEK, STG_E_SEEKERROR },
{ ZIP_ER_READ, STG_E_READFAULT },
{ ZIP_ER_WRITE, STG_E_WRITEFAULT },
{ ZIP_ER_NOENT, STG_E_FILENOTFOUND },
{ ZIP_ER_MEMORY, E_OUTOFMEMORY },
{ ZIP_ER_INVAL, E_INVALIDARG },
{ ZIP_ER_INTERNAL, E_UNEXPECTED },
{ -1, 0 }
};
/* references to system resource data in zip format */
extern uint8_t _binary_sysresources_zip_start[];
extern uint8_t _binary_sysresources_zip_end;
extern uint8_t _binary_sysresources_zip_size;
static zip_t *sysresource = NULL; /* system resource file */
static PRESFILE resfiles = NULL; /* all open resource files */
static HRESULT ziperror_to_hresult(zip_error_t *errinfo)
{
register int i;
for (i = 0; conversion_table[i].zip_err_code >= 0; i++)
if (conversion_table[i].zip_err_code == errinfo->zip_err)
return conversion_table[i].sys_err_code;
return MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, errinfo->zip_err);
}
static BOOL check_in_list(PRESFILE presfile)
{
register PRESFILE p = resfiles;
do
{
if (p == presfile)
return TRUE;
p = p->next;
} while (p != resfiles);
return FALSE;
}
HRESULT Rsrc_load_file(PCSTR filename, PHRESFILE newhandle)
{
HRESULT hr = S_OK;
PRESFILE pfile = NULL;
zip_source_t *source;
zip_error_t errinfo;
if (!newhandle)
return E_POINTER;
*newhandle = (HRESFILE)NULL;
pfile = (PRESFILE)malloc(sizeof(RESFILE));
if (!pfile)
return E_OUTOFMEMORY;
memset(pfile, 0, sizeof(RESFILE));
zip_error_init(&errinfo);
source = zip_source_file_create(filename, 0, 0, &errinfo);
if (source)
{
pfile->resource = zip_open_from_source(source, ZIP_RDONLY, &errinfo);
if (!(pfile->resource))
zip_source_free(source);
}
if (!(pfile->resource))
hr = ziperror_to_hresult(&errinfo);
zip_error_fini(&errinfo);
if (SUCCEEDED(hr))
{
if (resfiles)
{
pfile->next = resfiles;
pfile->prev = resfiles->prev;
resfiles->prev->next = pfile;
resfiles->prev = pfile;
}
else
pfile->next = pfile->prev = pfile;
resfiles = pfile;
*newhandle = (HRESFILE)pfile;
}
return hr;
}
static HRESULT internal_close(PRESFILE presfile)
{
HRESULT hr = S_OK;
if (zip_close(presfile->resource))
hr = ziperror_to_hresult(zip_get_error(presfile->resource));
if (resfiles == presfile)
{
resfiles = presfile->next;
if (resfiles == presfile)
resfiles = NULL;
}
presfile->prev->next = presfile->next;
presfile->next->prev = presfile->prev;
free(presfile);
return hr;
}
HRESULT Rsrc_close_file(HRESFILE handle)
{
if (check_in_list((PRESFILE)handle))
return internal_close((PRESFILE)handle);
return E_HANDLE;
}
HRESULT Rsrc_find_resource(HRESFILE hfile, PCSTR name, PCSTR type, PHRSRC presource)
{
HRESULT hr = S_OK;
PRESFILE pfile = (PRESFILE)hfile;
PRESOURCEINFO info = NULL;
zip_t *theresource;
zip_int64_t index;
if (pfile)
{
if (check_in_list(pfile))
theresource = pfile->resource;
else
return E_HANDLE;
}
else
theresource = sysresource;
ASSERT(theresource);
if (!name)
return E_INVALIDARG;
if (!presource)
return E_POINTER;
*presource = (HRSRC)NULL;
index = zip_name_locate(theresource, name, ZIP_FL_NOCASE);
if (index < 0)
hr = ziperror_to_hresult(zip_get_error(theresource));
if (SUCCEEDED(hr))
{
info = (PRESOURCEINFO)malloc(sizeof(RESOURCEINFO));
if (info)
{
if (zip_stat_index(theresource, index, ZIP_FL_NOCASE, &(info->entryinfo)))
hr = ziperror_to_hresult(zip_get_error(theresource));
if (SUCCEEDED(hr))
{
info->entryinfo.index = index;
info->entryinfo.valid |= ZIP_STAT_INDEX;
info->resource_file = theresource;
*presource = (HRSRC)info;
}
if (FAILED(hr))
free(info);
}
else
hr = E_OUTOFMEMORY;
}
return hr;
}
HRESULT Rsrc_free_resource(HRSRC resource)
{
if (!resource)
return E_HANDLE;
free((PRESOURCEINFO)resource);
return S_OK;
}
UINT32 Rsrc_sizeof_resource(HRSRC resource)
{
PRESOURCEINFO p = (PRESOURCEINFO)resource;
if (!p)
return 0;
if (p->entryinfo.valid & ZIP_STAT_SIZE)
return (UINT32)(p->entryinfo.size);
return 0;
}
HRESULT Rsrc_read_resource_here(HRSRC resource, PVOID buffer, UINT32 size, PUINT32 actual_read)
{
HRESULT hr = S_OK;
PRESOURCEINFO p = (PRESOURCEINFO)resource;
UINT32 max_size = size;
UINT32 already_read = 0;
PBYTE pbuffer = (PBYTE)buffer;
zip_int64_t nread;
zip_file_t *fp;
if (!p)
return E_HANDLE;
if (!buffer)
return E_POINTER;
if (p->entryinfo.valid & ZIP_STAT_SIZE)
{
if ((UINT32)(p->entryinfo.size) < max_size)
max_size = (UINT32)(p->entryinfo.size);
else if ((UINT32)(p->entryinfo.size) > max_size)
hr = UPIWIN_S_PARTIALRSRC;
}
fp = zip_fopen_index(p->resource_file, p->entryinfo.index, ZIP_FL_NOCASE);
if (fp)
{
while (SUCCEEDED(hr) && (max_size > 0))
{
nread = zip_fread(fp, pbuffer, max_size);
if (nread < 0)
{
hr = ziperror_to_hresult(zip_get_error(p->resource_file));
break;
}
pbuffer += (UINT_PTR)nread;
max_size -= (UINT32)nread;
already_read += (UINT32)nread;
}
zip_fclose(fp);
}
else
hr = ziperror_to_hresult(zip_get_error(p->resource_file));
if (actual_read)
*actual_read = already_read;
return hr;
}
static void rsrc_cleanup(void)
{
while (resfiles)
internal_close(resfiles);
zip_close(sysresource);
sysresource = NULL;
}
HRESULT Rsrc_setup(void)
{
HRESULT hr = S_OK;
zip_source_t *syssource;
zip_error_t errinfo;
Log(LDEBUG, "system resource length = %u", (UINT_PTR)(&_binary_sysresources_zip_size));
zip_error_init(&errinfo);
syssource = zip_source_buffer_create(_binary_sysresources_zip_start, (UINT_PTR)(&_binary_sysresources_zip_size),
0, &errinfo);
if (!syssource)
{
hr = ziperror_to_hresult(&errinfo);
goto error_0;
}
sysresource = zip_open_from_source(syssource, ZIP_RDONLY, &errinfo);
if (!sysresource)
{
hr = ziperror_to_hresult(&errinfo);
goto error_1;
}
hr = Config_exitfunc(rsrc_cleanup);
if (FAILED(hr))
rsrc_cleanup();
return hr;
error_1:
zip_source_free(syssource);
error_0:
zip_error_fini(&errinfo);
return hr;
}

40
src/resources.h Normal file
View File

@ -0,0 +1,40 @@
/*
* 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 __RESOURCES_H_INCLUDED
#define __RESOURCES_H_INCLUDED
#include "wintype.h"
typedef HANDLE HRESFILE; /* handle to resource file */
typedef HANDLE HRSRC; /* handle to resource */
typedef HRESFILE *PHRESFILE;
typedef HRSRC *PHRSRC;
extern HRESULT Rsrc_load_file(PCSTR filename, PHRESFILE newhandle);
extern HRESULT Rsrc_close_file(HRESFILE handle);
extern HRESULT Rsrc_find_resource(HRESFILE hfile, PCSTR name, PCSTR type, PHRSRC presource);
extern HRESULT Rsrc_free_resource(HRSRC resource);
extern UINT32 Rsrc_sizeof_resource(HRSRC resource);
extern HRESULT Rsrc_read_resource_here(HRSRC resource, PVOID buffer, UINT32 size, PUINT32 actual_read);
extern HRESULT Rsrc_setup(void);
#endif /* __RESOURCES_H_INCLUDED */

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -47,6 +47,7 @@
#define FACILITY_ITF 4 #define FACILITY_ITF 4
#define FACILITY_UNIX 5 #define FACILITY_UNIX 5
#define FACILITY_UPIWIN 6 #define FACILITY_UPIWIN 6
#define FACILITY_ZIP 78
#define SUCCEEDED(s) (((s) & SEVERITY_ERROR) == 0) #define SUCCEEDED(s) (((s) & SEVERITY_ERROR) == 0)
#define FAILED(s) (((s) & SEVERITY_ERROR) != 0) #define FAILED(s) (((s) & SEVERITY_ERROR) != 0)
@ -82,8 +83,57 @@
#define E_ILLEGAL_METHOD_CALL SCODE_CAST(0x8000000E) /* illegal method call */ #define E_ILLEGAL_METHOD_CALL SCODE_CAST(0x8000000E) /* illegal method call */
#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */ #define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */
/* Storage error codes */
#define STG_E_INVALIDFUNCTION SCODE_CAST(0x80030001) /* invalid function */
#define STG_E_FILENOTFOUND SCODE_CAST(0x80030002) /* file not found */
#define STG_E_PATHNOTFOUND SCODE_CAST(0x80030003) /* path not found */
#define STG_E_TOOMANYOPENFILES SCODE_CAST(0x80030004) /* too many open files */
#define STG_E_ACCESSDENIED SCODE_CAST(0x80030005) /* access denied */
#define STG_E_INVALIDHANDLE SCODE_CAST(0x80030006) /* invalid handle */
#define STG_E_INSUFFICIENTMEMORY SCODE_CAST(0x80030008) /* insufficient memory */
#define STG_E_INVALIDPOINTER SCODE_CAST(0x80030009) /* invalid pointer */
#define STG_E_NOMOREFILES SCODE_CAST(0x80030012) /* no more files to return */
#define STG_E_DISKISWRITEPROTECTED SCODE_CAST(0x80030013) /* disk is write protected */
#define STG_E_SEEKERROR SCODE_CAST(0x80030019) /* error in seek operation */
#define STG_E_WRITEFAULT SCODE_CAST(0x8003001D) /* error in write operation */
#define STG_E_READFAULT SCODE_CAST(0x8003001E) /* error in read operation */
#define STG_E_SHAREVIOLATION SCODE_CAST(0x80030020) /* sharing violation */
#define STG_E_LOCKVIOLATION SCODE_CAST(0x80030021) /* lock violation */
#define STG_E_INVALIDPARAMETER SCODE_CAST(0x80030057) /* invalid parameter */
#define STG_E_MEDIUMFULL SCODE_CAST(0x80030070) /* insufficient disk space */
#define STG_E_UNKNOWN SCODE_CAST(0x800300FD) /* unexpected error */
/* UPIWIN-specific errorcodes */ /* UPIWIN-specific errorcodes */
#define UPIWIN_E_INVALIDSCRIPT SCODE_CAST(0x80060000) /* invalid script file */ #define UPIWIN_E_INVALIDSCRIPT SCODE_CAST(0x80060000) /* invalid script file */
#define UPIWIN_E_NOSCRIPT SCODE_CAST(0x80060001) /* no script specified */ #define UPIWIN_E_NOSCRIPT SCODE_CAST(0x80060001) /* no script specified */
#define UPIWIN_S_PARTIALRSRC SCODE_CAST(0x00060000) /* partial resource read */
/* libzip error codes */
#define ZIP_E_MULTIDISK MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 1) /* multidisk not supported */
#define ZIP_E_RENAME MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 2) /* rename temp file failed */
#define ZIP_E_CLOSE MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 3) /* close failed */
#define ZIP_E_CRC MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 7) /* CRC error */
#define ZIP_E_WASCLOSED MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 8) /* zip file was closed */
#define ZIP_E_EXISTS MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 10) /* file already exists */
#define ZIP_E_OPEN MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 11) /* unable to open */
#define ZIP_E_TMPOPEN MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 12) /* unable to open temp file */
#define ZIP_E_ZLIB MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 13) /* Zlib error */
#define ZIP_E_CHANGED MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 15) /* entry was changed */
#define ZIP_E_NOCMP MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 16) /* compression method unsupported */
#define ZIP_E_EOF MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 17) /* hit end of file */
#define ZIP_E_NOTZIP MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 19) /* not a ZIP file */
#define ZIP_E_INCONSISTENT MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 21) /* inconsistent archive */
#define ZIP_E_REMOVE MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 22) /* remove failed */
#define ZIP_E_DELETED MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 23) /* entry deleted */
#define ZIP_E_NOCRYPT MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 24) /* encryption not supported */
#define ZIP_E_RDONLY MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 25) /* read-only archive */
#define ZIP_E_NOPASSWD MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 26) /* no password */
#define ZIP_E_BADPASSWD MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 27) /* wrong password */
#define ZIP_E_NOTSUPPORTED MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 28) /* operation not supported */
#define ZIP_E_BUSY MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 29) /* still in use */
#define ZIP_E_TELL MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 30) /* tell failed */
#define ZIP_E_CMPDATA MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 31) /* compressed data invalid */
#define ZIP_E_CANCELLED MAKE_SCODE(SEVERITY_ERROR, FACILITY_ZIP, 32) /* operation canceled */
#endif /* __SCODE_H_INCLUDED */ #endif /* __SCODE_H_INCLUDED */

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -67,9 +67,9 @@ static const STOCKBITMAPDESC stock_bitmaps[] = {
PBITMAP _BMP_GetStock(PCSTR name) PBITMAP _BMP_GetStock(PCSTR name)
{ {
INT32 i; INT32 i;
for (i = 0; stock_bitmaps[i].name; ++i) for (i = 0; stock_bitmaps[i].name; ++i)
if (strcmp(name, stock_bitmaps[i].name) == 0) if (strcmp(name, stock_bitmaps[i].name) == 0)
return BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data); return BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data);
return NULL; return NULL;
} }

View File

@ -1,12 +1,12 @@
/* /*
* UPIWIN - Micro Pi Windowing Framework Kernel * UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -74,22 +74,22 @@ static BOOL poll_buttons(void)
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
{ {
if (now < button_event_ok[attr - 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) if (up & mask)
{ {
/* reset contact bounce timer - only seems to happen after button releases */ /* reset contact bounce timer - only seems to happen after button releases */
button_event_ok[attr - 1] = now + Gconfig.button_debounce; button_event_ok[attr - 1] = now + Gconfig.button_debounce;
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
if ((now - button_down_time[attr - 1]) <= Gconfig.click_time) if ((now - button_down_time[attr - 1]) <= Gconfig.click_time)
Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr); Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr);
posted = TRUE; posted = TRUE;
} }
else if (down & mask) else if (down & mask)
{ {
Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr);
button_down_time[attr - 1] = now; button_down_time[attr - 1] = now;
posted = TRUE; posted = TRUE;
} }
} }
last_bstate = st; last_bstate = st;
} }
@ -116,55 +116,54 @@ static BOOL poll_touchscreen(void)
Log(LERROR, "Unexpected end of file reading from touchscreen device"); Log(LERROR, "Unexpected end of file reading from touchscreen device");
return FALSE; return FALSE;
} }
nev = nb / sizeof(struct input_event); nev = nb / sizeof(struct input_event);
xerrno = nev * sizeof(struct input_event); xerrno = nev * sizeof(struct input_event);
if (nb > xerrno) if (nb > xerrno)
Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno); Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno);
for (i=0; i<nev; i++) for (i=0; i<nev; i++)
{ {
switch (buffer[i].type) switch (buffer[i].type)
{ {
case EV_SYN: case EV_SYN:
if (buffer[i].code == SYN_REPORT) if (buffer[i].code == SYN_REPORT)
{ {
now = Time_since_start(); now = Time_since_start();
Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y);
if (touch_nextmsg == WM_TOUCHDOWN) if (touch_nextmsg == WM_TOUCHDOWN)
{ {
touch_down_x = touch_x; touch_down_x = touch_x;
touch_down_y = touch_y; touch_down_y = touch_y;
touch_down_time = now; touch_down_time = now;
} }
else if (touch_nextmsg == WM_TOUCHUP) else if (touch_nextmsg == WM_TOUCHUP)
{ {
if ( ((now - touch_down_time) <= Gconfig.click_time) if ( ((now - touch_down_time) <= Gconfig.click_time)
&& (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius)
&& (ABS((INT32)touch_y - (INT32)touch_down_y) <= 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); Mq_post2(Sys_Queue, 0, WM_TOUCHCLICK, touch_x, touch_y);
} }
touch_nextmsg = WM_TOUCHMOVE; touch_nextmsg = WM_TOUCHMOVE;
posted = TRUE; posted = TRUE;
} }
break; break;
case EV_ABS: case EV_ABS:
/* Note that the touchscreen driver assumes the screen is "vertical," so swap the x and y axes */ /* The screen driver thinks the screen is horizontal with origin at upper left and max at lower right. */
/* Also it thinks origin is lower left with up = +y */ if (buffer[i].code == ABS_X)
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)
else if (buffer[i].code == ABS_Y) touch_y = buffer[i].value;
touch_x = buffer[i].value; break;
break;
case EV_KEY: case EV_KEY:
if (buffer[i].code == BTN_TOUCH) if (buffer[i].code == BTN_TOUCH)
touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP); touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
break; break;
default: default:
break; break;
} }
} }
return posted; return posted;
@ -173,23 +172,23 @@ static BOOL poll_touchscreen(void)
static void *input_thread(void *arg) static void *input_thread(void *arg)
{ {
BOOL gotinput; BOOL gotinput;
/* clear all state at startup */ /* clear all state at startup */
last_bstate = 0; last_bstate = 0;
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP)); memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
touch_x = touch_y = 0; touch_x = touch_y = 0;
touch_nextmsg = WM_TOUCHMOVE; touch_nextmsg = WM_TOUCHMOVE;
while (running) while (running)
{ {
gotinput = poll_buttons(); gotinput = poll_buttons();
gotinput = poll_touchscreen() || gotinput; gotinput = poll_touchscreen() || gotinput;
if (gotinput) if (gotinput)
{ {
pthread_mutex_lock(&wait_mutex); pthread_mutex_lock(&wait_mutex);
pthread_cond_signal(&wait_cond); pthread_cond_signal(&wait_cond);
pthread_mutex_unlock(&wait_mutex); pthread_mutex_unlock(&wait_mutex);
} }
} }
return NULL; return NULL;
} }
@ -208,7 +207,7 @@ HRESULT Sys_enable_input(void)
{ {
HRESULT rc = S_OK; HRESULT rc = S_OK;
int threadrc; int threadrc;
Sys_Queue = Mq_alloc(Gconfig.sys_mq_length); Sys_Queue = Mq_alloc(Gconfig.sys_mq_length);
if (!Sys_Queue) if (!Sys_Queue)
{ {
@ -223,22 +222,22 @@ HRESULT Sys_enable_input(void)
Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc); Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc);
goto error_0; goto error_0;
} }
running = 1; running = 1;
threadrc = pthread_create(&ithread, NULL, input_thread, NULL); threadrc = pthread_create(&ithread, NULL, input_thread, NULL);
if (threadrc != 0) if (threadrc != 0)
{ {
rc = SCODE_FROM_ERRNO(threadrc); rc = SCODE_FROM_ERRNO(threadrc);
Log(LFATAL, "Unable to start system input thread (%08X).", rc); Log(LFATAL, "Unable to start system input thread (%08X).", rc);
goto error_1; goto error_1;
} }
rc = Config_exitfunc(do_disable_input); rc = Config_exitfunc(do_disable_input);
if (FAILED(rc)) if (FAILED(rc))
do_disable_input(); do_disable_input();
return rc; return rc;
error_1: error_1:
close(ts_fd); close(ts_fd);
ts_fd = -1; ts_fd = -1;
error_0: error_0:
@ -250,6 +249,6 @@ void Sys_wait_for_input(void)
{ {
pthread_mutex_lock(&wait_mutex); pthread_mutex_lock(&wait_mutex);
while (Mq_is_empty(Sys_Queue)) while (Mq_is_empty(Sys_Queue))
pthread_cond_wait(&wait_cond, &wait_mutex); pthread_cond_wait(&wait_cond, &wait_mutex);
pthread_mutex_unlock(&wait_mutex); pthread_mutex_unlock(&wait_mutex);
} }