Merge branch 'release-0.1' - Release 0.1

This commit is contained in:
Amy Bowersox 2019-12-12 13:59:42 -07:00
commit 0ef989579a
68 changed files with 5879 additions and 2 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*~
*.o
src/upiwin
src/splash.bin
buildutils/mksplash

57
CODE-OF-CONDUCT.md Executable file
View File

@ -0,0 +1,57 @@
# The Erbosoft Project Code of Conduct
## (Revised December 2019)
For the purposes of this project, the Owner is Amy G. Bowersox/Erbosoft Metaverse Design Solutions.
1. *The Owner owns this project.* Not you. The Owner's decisions about any aspect of the project
are *final.*
2. This Code of Conduct contains harsh language. Tough shit. Suck it up, Buttercup.
3. Anyone who is an *asshole* is **banned** *from this project.* **Permanently.**
4. This project has certain objectives. Anything outside of those objectives is *irrelevant,*
unless and until the *Owner* changes the objectives. Not you. In particular, if youre a Social
Justice Warrior trying to join this project to spread your *bullshit,* you are *automatically
declared an asshole.* And youre *gone.*
5. The Owner reserves the right to change this Code of Conduct as they see fit. If, however, you try
to force the Owner to change it in ways that are *offensive to them,* or that try to advance
“social justice” ideals in any way, shape, or form, youre an *asshole.* And youre *gone.*
6. In particular, this project explicitly *rejects* the “Open Code of Conduct” by the TODO Group,
the “Contributor Code of Merit” by Coraline Ada Ehmke, the “Citizen Code of Conduct” by
Stumptown Syndicate, and any similar “codes of conduct” that may be promulgated. Anyone complaining
about this is an *asshole,* because *who the fuck are you* to tell *the Owner* how *they* should
run *their* goddamn project? And youre *gone.*
7. The *one and only* criterion that will be used to determine whether a contribution to this project
will be accepted is *the quality of the contribution and how well it solves the problem it was
contributed to solve.* **Period.** (“Contribution” may include code, documentation, testing, or fundraising.)
8. The *one and only* criterion that will be used to judge your worth in relation to this project is
*the quality of your contributions (as defined above) to this project.* **Period.**
9. The Owner hereby does not give *one milli-micro-nano-fraction of a* **fuck** what race you are,
what gender you are or identify as, who you want to sleep with, how old you are, what your height or
weight is, what if anything may be different about your body or brain, what language you speak,
what country youre 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.
10. If your contribution is not accepted, and you start *whining* about how its “actually” because youre
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.*
11. Only those people who have contributed a sufficient quantity of good work to the project,
*as determined in the Owner's sole discretion,* will be allowed to assume any board position,
administrative position, or management-related role. And, any position that the Owner gives, they can
also *take away,* for any reason. Anyone who complains about this is an *asshole.* And theyre *gone.*
12. You will do your own work. If you try to pass off the work of others as your own, youre a
fucking *plagiarist,* and also an *asshole.* And youre *gone.*
13. If theres a discussion that cannot be resolved within the scope of the project,
*take that shit somewhere else.* The Owner does not want your bullshit here. If you continue to spread
your bullshit here, youre an *asshole.* And youre *gone.*
14. As noted above, the Owner's decisions about any aspect of the project are *final.* Anyone
*pissing the Owner off* by getting all up in their face about said decisions is an *asshole.*
And theyre *gone.*
15. Any advisory boards, committees, etc., having to do with this project will answer to *the Owner.*
The Owner reserves the right to disband any such whenever the hell they feel like it. As always, anyone
complaining about this is an *asshole.* And theyre *gone.*
16. Anyone who does not approve of the objectives, direction, or attitude of this project is
free to *get the fuck out* at any time. Bye Felicia!
Acknowlegements:
- [Why Hackers Must Eject the SJWs](http://esr.ibiblio.org/?p=6918), Eric S. Raymond
- [OSS Code of Merit](http://voxday.blogspot.com/2016/01/code-of-merit.html), Vox Day
- [A contribution policy for open source that works](https://medium.com/@jmaynard/a-contribution-policy-for-open-source-that-works-bfc4600c9d83#.dslxcx1fc), Jay Maynard
- [The Code of Merit](https://github.com/rosarior/Code-of-Merit/blob/master/CODE_OF_MERIT.md), Roberto Rosario

336
LICENSE.md Executable file
View File

@ -0,0 +1,336 @@
GNU General Public License
==========================
_Version 2, June 1991_
_Copyright © 1989, 1991 Free Software Foundation, Inc.,_
_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
### Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: **(1)** copyright the software, and
**(2)** offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
**0.** This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The “Program”, below,
refers to any such program or work, and a “work based on the Program”
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term “modification”.) Each licensee is addressed as “you”.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
**1.** You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
**2.** You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
* **a)** You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
* **b)** You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
* **c)** If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
**3.** You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
* **a)** Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
* **b)** Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
* **c)** Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
**4.** You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
**5.** You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
**6.** Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
**7.** If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
**8.** If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
**9.** The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and “any
later version”, you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
**10.** If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
### NO WARRANTY
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
### How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the “copyright” line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w` and `show c` should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w` and `show c`; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a “copyright disclaimer” for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
all:
make -C buildutils all
make -C src all
clean:
make -C buildutils clean
make -C src clean

View File

@ -1,4 +1,17 @@
# UPIWIN - Micro Pi Windows Kernel
Requirements:
- Raspberry Pi 3 with PiTFT touchscreen
*Release 0.1 - December 12, 2019*
This project involves the development of a framework for running self-contained applications in Python
on a Raspberry Pi with LCD graphical output and touchscreen input. The ultimate goal is to produce a
framework which is flexible enough to serve any number of “appliance” needs, by using different Python
scripts over the same native-code substrate, deployed on an inexpensive embedded platform.
## Hardware requirements
- Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423)
## Acknowledgements
A good portion of this code was written during the VMware Carbon Black Hackathon 3.3, December 6-13 2019.
Grateful acknowledgement is provided to VMware Carbon Black for the time to accomplish this coding.

24
buildutils/Makefile Normal file
View File

@ -0,0 +1,24 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
all: mkgfx
mkgfx: mkgfx.c
gcc -o mkgfx -O -Wall -I/usr/include/libpng mkgfx.c -lpng16 -lz
clean:
rm -f *.o mkgfx

319
buildutils/mkgfx.c Normal file
View File

@ -0,0 +1,319 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <png.h>
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#ifndef png_jmpbuf
#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_uint_32 width, height;
int bit_depth, color_type;
uch *image_data = NULL;
/* returns 0 on success, -1 on error */
int readpng_init(const char *fname, FILE *infile, ulg *pWidth, ulg *pHeight)
{
uch sig[8];
fread(sig, 1, 8, infile);
if (!png_check_sig(sig, 8))
{
fprintf(stderr, "%s: invalid PNG file signature\n", fname);
return -1;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fprintf(stderr, "%s: out of memory\n", fname);
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fprintf(stderr, "%s: out of memory\n", fname);
return -1;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fprintf(stderr, "%s: bad header in PNG image\n", fname);
return -1;
}
png_init_io(png_ptr, infile);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
*pWidth = width;
*pHeight = height;
return 0;
}
/* returns -1 on error, 0 otherwise (out vars not touched if we can't find background */
int readpng_get_bgcolor(const char *fname, uch *red, uch *green, uch *blue)
{
png_color_16p pBackground;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fprintf(stderr, "%s: unspecified error in background reading\n", fname);
return -1;
}
if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
return 0;
png_get_bKGD(png_ptr, info_ptr, &pBackground);
if (bit_depth == 16)
{
*red = pBackground->red >> 8;
*green = pBackground->green >> 8;
*blue = pBackground->blue >> 8;
}
else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
if (bit_depth == 1)
*red = *green = *blue = pBackground->gray ? 255 : 0;
else if (bit_depth == 2)
*red = *green = *blue = (255/3) * pBackground->gray;
else /* bit_depth == 4 */
*red = *green = *blue = (255/15) * pBackground->gray;
}
else
{
*red = (uch)pBackground->red;
*green = (uch)pBackground->green;
*blue = (uch)pBackground->blue;
}
return 0;
}
/* display_exponent == LUT_exponent * CRT_exponent */
uch *readpng_get_image(const char *fname, double display_exponent, int *pChannels, ulg *pRowbytes)
{
double gamma;
png_uint_32 i, rowbytes;
png_bytepp row_pointers = NULL;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fprintf(stderr, "%s: unspecified error in image data reading\n", fname);
return NULL;
}
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand(png_ptr);
if (bit_depth == 16)
png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
png_set_gamma(png_ptr, display_exponent, gamma);
png_read_update_info(png_ptr, info_ptr);
*pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
*pChannels = (int)png_get_channels(png_ptr, info_ptr);
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fprintf(stderr, "%s: could not allocate image buffer\n", fname);
return NULL;
}
if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
free(image_data);
image_data = NULL;
fprintf(stderr, "%s: could not allocate image row buffer\n", fname);
return NULL;
}
fprintf(stderr, "image %s: chans=%d rowbytes=%u height=%u\n", fname, *pChannels,
rowbytes, height);
for (i = 0; i < height; ++i)
row_pointers[i] = image_data + i * rowbytes;
png_read_image(png_ptr, row_pointers);
free(row_pointers);
row_pointers = NULL;
png_read_end(png_ptr, NULL);
return image_data;
}
void readpng_cleanup(int free_image_data)
{
if (free_image_data && image_data)
{
free(image_data);
image_data = NULL;
}
if (png_ptr && info_ptr)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
png_ptr = NULL;
info_ptr = NULL;
}
}
int do_convert(const char *infilename, const char *outfilename)
{
ulg image_width, image_height, image_rowbytes, row, i;
FILE *fpin;
uch *image_data, *src;
uint16_t bred = 0, bgreen = 0, bblue = 0, buf = 0;
int image_channels, fdout;
uch bg_red=0, bg_green=0, bg_blue=0, br, bg, bb, ba;
double display_exponent = 2.2; /* a guesstimate */
if (!(fpin = fopen(infilename, "rb")))
{
fprintf(stderr, "%s: could not open file\n", infilename);
return -1;
}
if (readpng_init(infilename, fpin, &image_width, &image_height))
{
readpng_cleanup(1);
fclose(fpin);
return -1;
}
if (readpng_get_bgcolor(infilename, &bg_red, &bg_green, &bg_blue))
{
readpng_cleanup(1);
fclose(fpin);
return -1;
}
image_data = readpng_get_image(infilename, display_exponent, &image_channels, &image_rowbytes);
readpng_cleanup(0);
fclose(fpin);
if (!image_data)
return -1;
if ((fdout = creat(outfilename, S_IREAD|S_IWRITE)) < 0)
{
free(image_data);
fprintf(stderr, "%s: could not open file\n", outfilename);
return -1;
}
for (row = 0; row < image_height; ++row)
{
src = image_data + (row * image_rowbytes);
for (i = image_width; i > 0; --i)
{
if (image_channels == 3)
{
bred = *src++;
bgreen = *src++;
bblue = *src++;
}
else if (image_channels == 4)
{
br = *src++;
bg = *src++;
bb = *src++;
ba = *src++;
if (ba == 255)
{
bred = br;
bgreen = bg;
bblue = bb;
}
else if (ba == 0)
{
bred = bg_red;
bgreen = bg_green;
bblue = bg_blue;
}
else
{
png_composite(bred, br, ba, bg_red);
png_composite(bgreen, bg, ba, bg_green);
png_composite(bblue, bb, ba, bg_blue);
}
}
bred = (bred >> 3) & 0x1F;
bgreen = (bgreen >> 2) & 0x3F;
bblue = (bblue >> 3) & 0x1F;
buf = (bred << 11) | (bgreen << 5) | bblue;
if (write(fdout, &buf, sizeof(uint16_t)) < 0)
{
close(fdout);
free(image_data);
fprintf(stderr, "%s: error writing image data\n", outfilename);
return -1;
}
}
}
close(fdout);
free(image_data);
return 0;
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
fprintf(stderr, "usage: mksplash inputfile outputfile\n");
return EXIT_FAILURE;
}
if (do_convert(argv[1], argv[2]))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

19
docs/templates/license_header.c vendored Executable file
View File

@ -0,0 +1,19 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/

17
docs/templates/license_header.mk vendored Executable file
View File

@ -0,0 +1,17 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------

17
docs/templates/license_header.py vendored Executable file
View File

@ -0,0 +1,17 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------

BIN
resources/i_clear.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
resources/i_fillrect.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

BIN
resources/i_freehand.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

BIN
resources/i_line.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

BIN
resources/i_rect.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

BIN
resources/i_undo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
resources/splash-vmwcblk.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

293
scripts/demo1.py Executable file
View File

@ -0,0 +1,293 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
# Demo script that implements a simple drawing program
import upiwin
# Save off some color values.
BLACK = upiwin.rgb(0, 0, 0)
WHITE = upiwin.rgb(255, 255, 255)
LTGRAY = upiwin.rgb(204, 204, 204)
RED = upiwin.rgb(255, 0, 0)
GREEN = upiwin.rgb(0, 255, 0)
BLUE = upiwin.rgb(0, 0, 255)
CYAN = upiwin.rgb(0, 255, 255)
MAGENTA = upiwin.rgb(255, 0, 255)
YELLOW = upiwin.rgb(255, 255, 0)
# Get the stock bitmaps.
bmp_freehand = upiwin.Bitmap(stock='freehand')
bmp_line = upiwin.Bitmap(stock='line')
bmp_rect = upiwin.Bitmap(stock='rect')
bmp_fillrect = upiwin.Bitmap(stock='fillrect')
bmp_undo = upiwin.Bitmap(stock='undo')
bmp_clear = upiwin.Bitmap(stock='clear')
hdc = upiwin.DevCtxt(type='screen')
hdc_bits = upiwin.DevCtxt(type='memory')
# divide the screen into "drawing" and "command" areas
screen_rect = hdc.get_clip_rect()
drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect[3])
command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3])
# further divide up the "command" area
tool_select_rect = (command_rect[0], command_rect[1], command_rect[2], 60)
color_select_rect = (command_rect[0], 60, command_rect[2], 120)
undo_rect = (command_rect[0], 120, command_rect[2], 180)
clear_rect = (command_rect[0], 180, command_rect[2], command_rect[3])
def point_in_rect(rect, x, y):
return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3])
# --- Backlight control ---
backlight_level_list = [1023, 768, 512, 256]
current_backlight = 0
def do_backlight():
upiwin.set_backlight_level(backlight_level_list[current_backlight])
def select_next_backlight():
global current_backlight
current_backlight += 1
if current_backlight == len(backlight_level_list):
current_backlight = 0
do_backlight()
# --- Color selections ---
color_list = [WHITE, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW]
current_color = 0
def draw_current_color():
hdc.text_color = color_list[current_color]
hdc.rop2 = upiwin.R2_COPYPEN
hdc.solid_rectangle(color_select_rect[0] + 6, color_select_rect[1] + 6, color_select_rect[0] + 54, color_select_rect[1] + 54)
def select_next_color():
global current_color
current_color += 1
if current_color == len(color_list):
current_color = 0
draw_current_color()
# --- Object drawing ---
def draw_freehand(color, data):
hdc.text_color = color
hdc.rop2 = upiwin.R2_COPYPEN
hdc.move_to(data[0][0], data[0][1])
for pt in data[1:]:
hdc.line_to(pt[0], pt[1])
def draw_line(color, data):
hdc.text_color = color
hdc.rop2 = upiwin.R2_COPYPEN
hdc.move_to(data[0][0], data[0][1])
hdc.line_to(data[1][0], data[1][1])
def draw_rectangle(color, data):
hdc.text_color = color
hdc.rop2 = upiwin.R2_COPYPEN
hdc.rectangle(data[0], data[1], data[2], data[3])
def draw_filled_rectangle(color, data):
hdc.text_color = color
hdc.rop2 = upiwin.R2_COPYPEN
hdc.solid_rectangle(data[0], data[1], data[2], data[3])
def draw_object(obj):
obj['draw'](obj['color'], obj['data'])
# --- Master object list ---
objects_drawn = []
def repaint():
global drawing_rect, objects_drawn
hdc.text_color = BLACK
hdc.rop2 = upiwin.R2_COPYPEN
hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3])
for obj in objects_drawn:
draw_object(obj)
def undo_last():
global objects_drawn
if len(objects_drawn) > 0:
last = len(objects_drawn) - 1
del objects_drawn[last]
repaint()
def clear_all():
global objects_drawn
if len(objects_drawn) > 0:
objects_drawn.clear()
repaint()
# --- Graphic feedback --
origin_x = 0
origin_y = 0
current_x = 0
current_y = 0
freehand_points = []
def freehand_draw(x, y, down, up):
global current_x, current_y, freehand_points
if down:
freehand_points = []
else:
hdc.text_color = color_list[current_color]
hdc.rop2 = upiwin.R2_COPYPEN
hdc.move_to(current_x, current_y)
hdc.line_to(x, y)
current_x = x
current_y = y
freehand_points += [(x, y)]
def rubberband_rectangle(x, y, down, up):
global current_x, current_y
hdc.text_color = LTGRAY
hdc.rop2 = upiwin.R2_XORPEN
if not down:
hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y))
current_x = x
current_y = y
if not up:
hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y))
def rubberband_line(x, y, down, up):
global current_x, current_y
hdc.text_color = LTGRAY
hdc.rop2 = upiwin.R2_XORPEN
if not down:
hdc.move_to(origin_x, origin_y)
hdc.line_to(current_x, current_y)
current_x = x
current_y = y
if not up:
hdc.move_to(origin_x, origin_y)
hdc.line_to(current_x, current_y)
# --- Tool definitions ---
def save_freehand():
return { 'draw': draw_freehand, 'color': color_list[current_color], 'data': freehand_points }
def save_line():
return { 'draw': draw_line, 'color': color_list[current_color], 'data': [(origin_x, origin_y), (current_x, current_y)] }
def save_rectangle():
return { 'draw': draw_rectangle, 'color': color_list[current_color],
'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) }
def save_filled_rectangle():
return { 'draw': draw_filled_rectangle, 'color': color_list[current_color],
'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) }
tool_list = [
{ 'icon': bmp_freehand, 'feedback': freehand_draw, 'save': save_freehand, 'dodraw': False },
{ 'icon': bmp_line, 'feedback': rubberband_line, 'save': save_line, 'dodraw': True },
{ 'icon': bmp_rect, 'feedback': rubberband_rectangle, 'save': save_rectangle, 'dodraw': True },
{ 'icon': bmp_fillrect, 'feedback': rubberband_rectangle, 'save': save_filled_rectangle, 'dodraw': True }
]
current_tool = 0
def draw_current_tool():
hdc_bits.select_object(tool_list[current_tool]['icon'])
hdc.bitblt(tool_select_rect[0] + 6, tool_select_rect[1] + 6, tool_select_rect[0] + 54, tool_select_rect[1] + 54, hdc_bits, 0, 0, 0)
def select_next_tool():
global current_tool
current_tool += 1
if current_tool == len(tool_list):
current_tool = 0
draw_current_tool()
# --- Message handlers ---
def on_touchdown(x, y):
global origin_x, origin_y
if point_in_rect(drawing_rect, x, y):
origin_x = x
origin_y = y
tool_list[current_tool]['feedback'](x, y, True, False)
def on_touchmove(x, y):
if point_in_rect(drawing_rect, x, y):
tool_list[current_tool]['feedback'](x, y, False, False)
def on_touchup(x, y):
global objects_drawn
if point_in_rect(drawing_rect, x, y):
tool_list[current_tool]['feedback'](x, y, False, True)
object = tool_list[current_tool]['save']()
if tool_list[current_tool]['dodraw']:
draw_object(object)
objects_drawn += [object]
def on_touchclick(x, y):
if point_in_rect(tool_select_rect, x, y):
select_next_tool()
elif point_in_rect(color_select_rect, x, y):
select_next_color()
elif point_in_rect(undo_rect, x, y):
undo_last()
elif point_in_rect(clear_rect, x, y):
clear_all()
def on_button_click(button):
if button == 1: # Button 1 = Set backlight level
select_next_backlight()
if button == 4: # Button 4 = Exit app
upiwin.post_quit_message(0)
# --- Initialize and start message loop ---
do_backlight()
# Draw the basic layout.
hdc.text_color = LTGRAY
hdc.rop2 = upiwin.R2_COPYPEN
hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3])
hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3])
hdc.rectangle(undo_rect[0], undo_rect[1], undo_rect[2], undo_rect[3])
hdc.rectangle(clear_rect[0], clear_rect[1], clear_rect[2], clear_rect[3])
draw_current_tool()
draw_current_color()
hdc_bits.select_object(bmp_undo)
hdc.bitblt(undo_rect[0] + 6, undo_rect[1] + 6, undo_rect[0] + 54, undo_rect[1] + 54, hdc_bits, 0, 0, 0)
hdc_bits.select_object(bmp_clear)
hdc.bitblt(clear_rect[0] + 6, clear_rect[1] + 6, clear_rect[0] + 54, clear_rect[1] + 54, hdc_bits, 0, 0, 0)
# Main message loop
msg = {}
while upiwin.get_message(msg):
if msg['message'] == upiwin.WM_TOUCHDOWN:
on_touchdown(msg['attrs'][0], msg['attrs'][1])
if msg['message'] == upiwin.WM_TOUCHMOVE:
on_touchmove(msg['attrs'][0], msg['attrs'][1])
if msg['message'] == upiwin.WM_TOUCHUP:
on_touchup(msg['attrs'][0], msg['attrs'][1])
if msg['message'] == upiwin.WM_TOUCHCLICK:
on_touchclick(msg['attrs'][0], msg['attrs'][1])
elif msg['message'] == upiwin.WM_HWBUTTONCLICK:
on_button_click(msg['attrs'][0])

52
scripts/test_clipping.py Executable file
View File

@ -0,0 +1,52 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
# Test of line clipping
import upiwin
hdc = upiwin.DevCtxt(type='screen')
hdc.text_color = 0xFFFFFF # white
hdc.rectangle(99, 99, 200, 200)
clip = hdc.get_clip_rect()
hdc.set_clip_rect(100, 100, 200, 200)
hdc.text_color = 0x0000FF # red
hdc.move_to(50, 200)
hdc.line_to(200, 50)
hdc.text_color = 0x00FF00 # green
hdc.move_to(250, 200)
hdc.line_to(100, 50)
hdc.text_color = 0xFF0000 # blue
hdc.move_to(50, 100)
hdc.line_to(200, 250)
hdc.text_color = 0x00FFFF # yellow
hdc.move_to(250, 100)
hdc.line_to(100, 250)
hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3])
msg = {}
while upiwin.get_message(msg):
if msg['message'] == upiwin.WM_HWBUTTONUP:
bn = msg['attrs'][0]
if bn == 4:
print("Quitting the application.")
upiwin.post_quit_message(0)

64
scripts/tmp_main.py Normal file
View File

@ -0,0 +1,64 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
# Initial test script
import upiwin
import upiwin_tmp
def log_touch(event, x, y):
print("Touch {0} at ({1}, {2})".format(event, x, y))
upiwin_tmp.filled_rectangle(10, 10, 50, 50, upiwin_tmp.FBPRIMCLR_RED, False)
upiwin_tmp.filled_rectangle(60, 10, 100, 50, upiwin_tmp.FBPRIMCLR_GREEN, False)
upiwin_tmp.filled_rectangle(110, 10, 150, 50, upiwin_tmp.FBPRIMCLR_BLUE, False)
upiwin_tmp.filled_rectangle(10, 60, 50, 100, upiwin_tmp.FBPRIMCLR_CYAN, False)
upiwin_tmp.filled_rectangle(60, 60, 100, 100, upiwin_tmp.FBPRIMCLR_MAGENTA, False)
upiwin_tmp.filled_rectangle(110, 60, 150, 100, upiwin_tmp.FBPRIMCLR_YELLOW, False)
upiwin_tmp.rectangle(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False)
upiwin_tmp.line(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False)
upiwin_tmp.line(10, 150, 150, 110, upiwin_tmp.FBPRIMCLR_WHITE, False)
upiwin_tmp.line(0, 180, 319, 180, upiwin_tmp.FBPRIMCLR_RED, False);
upiwin_tmp.line(0, 196, 319, 196, upiwin_tmp.FBPRIMCLR_RED, False);
upiwin_tmp.textout(10, 180, 'Amy was here!!!')
msg = {}
while upiwin.get_message(msg):
if msg['message'] == upiwin.WM_HWBUTTONDOWN:
print("Button {0} was pressed.".format(msg['attrs'][0]))
elif msg['message'] == upiwin.WM_HWBUTTONUP:
print("Button {0} was released.".format(msg['attrs'][0]))
elif msg['message'] == upiwin.WM_HWBUTTONCLICK:
print("Button {0} was clicked.".format(msg['attrs'][0]))
bn = msg['attrs'][0]
if bn == 1:
print("Backlight ON.")
upiwin.set_backlight(True)
elif bn == 2:
print("Backlight OFF.")
upiwin.set_backlight(False)
elif bn == 4:
print("Quitting the application.")
upiwin.post_quit_message(0)
elif msg['message'] == upiwin.WM_TOUCHDOWN:
log_touch('DOWN', msg['attrs'][0], msg['attrs'][1])
elif msg['message'] == upiwin.WM_TOUCHMOVE:
log_touch('MOVE', msg['attrs'][0], msg['attrs'][1])
elif msg['message'] == upiwin.WM_TOUCHUP:
log_touch('UP', msg['attrs'][0], msg['attrs'][1])
elif msg['message'] == upiwin.WM_TOUCHCLICK:
log_touch('CLICK', msg['attrs'][0], msg['attrs'][1])

66
src/Makefile Normal file
View File

@ -0,0 +1,66 @@
# UPIWIN - Micro Pi Windowing Framework Kernel
# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# ------------------------------------------------------------------------
BUILDUTILS=../buildutils
RESOURCES=../resources
SPLASHSCREEN=splash-vmwcblk.png
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \
ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \
bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \
i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.o splash.o
LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm
CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \
-Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT
LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \
-Wl,-Bsymbolic-functions
all: upiwin
upiwin: $(OBJS)
gcc -o upiwin $(LDFLAGS) $(OBJS) $(LIBS)
.c.o:
gcc -c $(CFLAGS) $<
%.o: %.bin
objcopy -I binary -O elf32-littlearm -B arm --rename-section \
.data=.rodata,alloc,load,readonly,data,contents $< $@
splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/$(SPLASHSCREEN) splash.bin
i_freehand.bin: $(RESOURCES)/i_freehand.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_freehand.png i_freehand.bin
i_line.bin: $(RESOURCES)/i_line.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_line.png i_line.bin
i_rect.bin: $(RESOURCES)/i_rect.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_rect.png i_rect.bin
i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin
i_undo.bin: $(RESOURCES)/i_undo.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png i_undo.bin
i_clear.bin: $(RESOURCES)/i_clear.png $(BUILDUTILS)/mkgfx
$(BUILDUTILS)/mkgfx $(RESOURCES)/i_clear.png i_clear.bin
clean:
rm -f upiwin *.o splash.bin *~

44
src/bitmap.c Executable file
View File

@ -0,0 +1,44 @@
/*
* 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 "bitmap.h"
PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits)
{
PBITMAP rc;
UINT32 tot_size = sizeof(BITMAP) + (width * height * sizeof(UINT16));
rc = (PBITMAP)malloc(tot_size);
if (!rc)
return NULL;
memset(rc, 0, tot_size);
_Go_init(&(rc->hdr), BMP_SIG_WORD, tot_size);
rc->width = width;
rc->height = height;
if (bits)
memcpy(rc->bits, bits, width * height * sizeof(UINT16));
return rc;
}
void BMP_Delete(PBITMAP pbmp)
{
Go_release(&(pbmp->hdr));
}

40
src/bitmap.h Executable 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 __BITMAP_H_INCLUDED
#define __BITMAP_H_INCLUDED
#include "wintype.h"
#include "gfxobj.h"
#define BMP_SIG_WORD 0x706D4221 /* !Bmp */
typedef struct tagBITMAP {
GFXOBJECT hdr;
INT32 width;
INT32 height;
UINT16 bits[0];
} BITMAP, *PBITMAP;
extern PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits);
extern void BMP_Delete(PBITMAP pbmp);
extern PBITMAP _BMP_GetStock(PCSTR name);
#endif /* __BITMAP_H_INCLUDED */

254
src/config.c Normal file
View File

@ -0,0 +1,254 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include "config.h"
#include "scode.h"
#include "log.h"
/* command line options for UPIWIN */
static const struct option long_options[] = {
{"framebuffer", required_argument, 0, 'F'},
{"help", no_argument, 0, 'h'},
{"touchscreen", required_argument, 0, 'T'},
{ NULL, 0, 0, 0 }
};
static const char *short_options = "F:hT:";
/* printed to stdout when upiwin is executed with -h/--help option */
static const char *helptext =
"UPIWIN - Micro Pi Windows server program\n\n"
"Usage: upiwin [options] scriptname [scriptargs]\n\n"
"Available options:\n"
" -F,--framebuffer [devname] - Specifies the framebuffer device name\n"
" -h,--help - Displays this help message.\n"
" -T,--touchscreen - Specifies the touchscreen device name\n"
"";
#define EXITFUNCBLOCK_FUNCCOUNT 64 /* number of exit functions per function block */
/* exit functions are stored in these data blocks */
typedef struct tagEXITFUNCBLOCK
{
struct tagEXITFUNCBLOCK *next; /* chained in single linked list */
int num_funcs; /* number of functions this block contains */
PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT]; /* pointers to functions */
} EXITFUNCBLOCK, *PEXITFUNCBLOCK;
/* The global configuration data */
GLOBAL_CONFIG Gconfig;
static PEXITFUNCBLOCK exitfuncs = NULL; /* pointer to head of exit function chain */
static void run_exit_funcs(void)
{
int i;
PEXITFUNCBLOCK p;
while (exitfuncs)
{
p = exitfuncs;
exitfuncs = p->next;
for (i = p->num_funcs - 1; i >= 0; i--)
{
/* execute functions in LIFO order */
ASSERT(p->funcs[i]);
(*(p->funcs[i]))();
}
free(p);
}
}
static void init_defaults(void)
{
memset(&Gconfig, 0, sizeof(GLOBAL_CONFIG));
Gconfig.framebuffer_device = "/dev/fb1";
Gconfig.touchscreen_device = "/dev/input/touchscreen";
Gconfig.python_loc = "/usr/bin/python3";
Gconfig.button_debounce = 100;
Gconfig.sys_mq_length = 64;
Gconfig.click_time = 500;
Gconfig.click_radius = 2;
}
static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
{
int c;
PSTR pstr;
PPCSTR pargs;
BOOL help = FALSE;
memset(parsed, 0, sizeof(GLOBAL_CONFIG));
for (;;)
{
c = getopt_long(argc, argv, short_options, long_options, NULL);
if (c==-1)
break;
switch (c)
{
case 'F': /* frame buffer device name */
pstr = strdup(optarg);
if (!pstr)
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
if (parsed->framebuffer_device)
free((PVOID)(parsed->framebuffer_device));
parsed->framebuffer_device = pstr;
break;
case 'h': /* show help */
help = TRUE;
break;
case 'T': /* touchscreen device name */
pstr = strdup(optarg);
if (!pstr)
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
if (parsed->touchscreen_device)
free((PVOID)(parsed->touchscreen_device));
parsed->touchscreen_device = pstr;
break;
default:
fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c);
return E_UNEXPECTED;
}
}
if (help)
{
fputs(helptext, stdout);
return S_FALSE;
}
if (optind < argc)
{
pstr = realpath(argv[optind], NULL); /* implicit strdup */
if (!pstr)
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
if (access(pstr, R_OK))
{
fprintf(stderr, "%s: script %s not found\n", argv[0], pstr);
return UPIWIN_E_INVALIDSCRIPT;
}
parsed->script_name = pstr;
if (++optind < argc)
{
parsed->script_arg_count = argc - optind;
pargs = (PPCSTR)malloc(sizeof(PCSTR) * parsed->script_arg_count);
if (!pargs)
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
for (c = 0; c < parsed->script_arg_count; c++)
{
pargs[c] = strdup(argv[optind++]);
if (!(pargs[c]))
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
}
parsed->script_args = pargs;
}
}
else
{
fprintf(stderr, "%s: no script specified\n", argv[0]);
return UPIWIN_E_NOSCRIPT;
}
return S_OK;
}
static void overlay_config(GLOBAL_CONFIG *p)
{
if (p->framebuffer_device)
Gconfig.framebuffer_device = p->framebuffer_device;
if (p->touchscreen_device)
Gconfig.touchscreen_device = p->touchscreen_device;
/* always overlay the script name and arguments */
Gconfig.script_name = p->script_name;
Gconfig.script_arg_count = p->script_arg_count;
Gconfig.script_args = p->script_args;
}
HRESULT Config_setup(int argc, char *argv[])
{
HRESULT hr;
GLOBAL_CONFIG from_commandline;
if (geteuid() != 0)
{
Log(LFATAL, "upiwin must be run with root privileges");
return E_ACCESSDENIED;
}
if (atexit(run_exit_funcs))
{
Log(LFATAL, "Unable to set up exit function mechanism");
return E_FAIL;
}
/* set defaults */
init_defaults();
/* evaluate command line */
hr = parse_cmdline(argc, argv, &from_commandline);
if (hr != S_OK)
return hr;
/* command line overrides everything */
overlay_config(&from_commandline);
return S_OK;
}
HRESULT Config_exitfunc(PEXITFUNC pfn)
{
PEXITFUNCBLOCK p;
if (!exitfuncs || (exitfuncs->num_funcs == EXITFUNCBLOCK_FUNCCOUNT))
{
p = (PEXITFUNCBLOCK)malloc(sizeof(EXITFUNCBLOCK));
if (!p)
{
Log(LERROR, "unable to allocate another exit function block");
return E_OUTOFMEMORY;
}
p->next = exitfuncs;
p->num_funcs = 0;
exitfuncs = p;
}
exitfuncs->funcs[exitfuncs->num_funcs++] = pfn;
return S_OK;
}

46
src/config.h Normal file
View File

@ -0,0 +1,46 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __CONFIG_H_INCLUDED
#define __CONFIG_H_INCLUDED
#include "wintype.h"
typedef void (*PEXITFUNC)(void);
/* global configuration data for UPIWIN */
typedef struct tagGLOBAL_CONFIG {
PCSTR framebuffer_device; /* name of frame buffer device */
PCSTR touchscreen_device; /* name of touchscreen device */
PCSTR python_loc; /* location of the Python3 executable */
UINT32 button_debounce; /* minimum time between button up and next button down (ms) */
UINT32 sys_mq_length; /* length of system message queue */
UINT32 click_time; /* time between button/touch DOWN and UP to be considered a "click" (ms) */
UINT32 click_radius; /* maximum number of pixels a touch can "drift" to be considered a "click" */
PCSTR script_name; /* script name to be run */
INT32 script_arg_count; /* number of arguments to pass to the script */
PPCSTR script_args; /* arguments to pass to the script */
} GLOBAL_CONFIG;
extern GLOBAL_CONFIG Gconfig; /* one global configuration to rule them all */
extern HRESULT Config_setup(int argc, char *argv[]);
extern HRESULT Config_exitfunc(PEXITFUNC pfn);
#endif /* __CONFIG_H_INCLUDED */

309
src/dc_screen.c Executable file
View File

@ -0,0 +1,309 @@
/*
* 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 "log.h"
#include "fbinit.h"
#include "devctxt.h"
#include "dc_screen.h"
#include "bitmap.h"
inline static PUINT16 loc_from_coords(PSCREENPRIVDATA priv, INT32 x, INT32 y)
{
return priv->pdata + (y * priv->pix_per_row) + x;
}
inline static UINT16 native_from_COLORREF(COLORREF cr)
{
return (UINT16)(((cr << 8) & 0xF800) | ((cr >> 5) & 0x7E0) | ((cr >> 19) & 0x1F));
}
inline static COLORREF COLORREF_from_native(UINT16 cr)
{
UINT32 tmp = cr;
return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800));
}
static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen)
{
switch (op)
{
case R2_BLACK:
return 0;
case R2_NOTMERGEPEN:
return ~(disp | pen);
case R2_MASKNOTPEN:
return disp & (~pen);
case R2_NOTCOPYPEN:
return ~pen;
case R2_MASKPENNOT:
return (~disp) & pen;
case R2_NOT:
return ~disp;
case R2_XORPEN:
return disp ^ pen;
case R2_NOTMASKPEN:
return ~(disp & pen);
case R2_MASKPEN:
return disp & pen;
case R2_NOTXORPEN:
return ~(disp ^ pen);
case R2_NOP:
return disp;
case R2_MERGENOTPEN:
return disp | (~pen);
case R2_COPYPEN:
return pen;
case R2_MERGEPENNOT:
return (~disp) | pen;
case R2_MERGEPEN:
return disp | pen;
case R2_WHITE:
return (UINT16)(-1);
}
return pen; /* last ditch default */
}
static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op)
{
PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
UINT16 pencolor = native_from_COLORREF(color);
PUINT16 loc = loc_from_coords(priv, x, y);
UINT16 screen = *loc;
*loc = apply_rop2(op, screen, pencolor);
return COLORREF_from_native(screen);
}
static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op)
{
PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
UINT16 pencolor = native_from_COLORREF(color);
INT32 dx = x2 - x1;
INT32 dy = y2 - y1;
INT32 tmp;
PUINT16 loc;
ASSERT(x1 >= 0);
ASSERT(x1 < Fb_Info->width);
ASSERT(y1 >= 0);
ASSERT(y1 < Fb_Info->height);
ASSERT(x2 >= 0);
ASSERT(x2 < Fb_Info->width);
ASSERT(y2 >= 0);
ASSERT(y2 < Fb_Info->height);
/* uses Bresenham's line algorithm with 16-bit fixed-point arithmetic */
if (ABS(dx) < ABS(dy))
{
if (y1 > y2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
loc = loc_from_coords(priv, x1, y1);
tmp = x1;
x1 <<= 16;
dx = (dx << 16) / dy;
while (y1 <= y2)
{
*loc = apply_rop2(op, *loc, pencolor);
x1 += dx;
++y1;
loc += priv->pix_per_row;
if (tmp != (x1 >> 16))
{
loc += ((x1 >> 16) - tmp);
tmp = x1 >> 16;
}
}
}
else
{
if (x1 > x2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
loc = loc_from_coords(priv, x1, y1);
tmp = y1;
y1 <<= 16;
dy = dx ? (dy << 16) / dx : 0;
while (x1 <= x2)
{
*loc = apply_rop2(op, *loc, pencolor);
y1 += dy;
++x1;
++loc;
if (tmp != (y1 >> 16))
{
loc += (((y1 >> 16) - tmp) * priv->pix_per_row);
tmp = y1 >> 16;
}
}
}
return TRUE;
}
static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 op)
{
PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
UINT16 pencolor = native_from_COLORREF(color);
PUINT16 ps, p;
int y, x;
ps = loc_from_coords(priv, rect->left, rect->top);
for (y = rect->top; y < rect->bottom; y++)
{
p = ps;
for (x = rect->left; x < rect->right; x++)
{
*p = apply_rop2(op, *p, pencolor);
++p;
}
ps += priv->pix_per_row;
}
return TRUE;
}
static const DCFUNTABLE screen_funtable; /* forward declaration */
static void screen_context_destroy(PVOID obj);
static PDCTXT screen_create_compat(PVOID privdata)
{
PSCREENPRIVDATA priv_new;
PBITMAP pbmp;
PDCTXT rc;
pbmp = BMP_Create(1, 1, NULL);
if (!pbmp)
return NULL;
priv_new = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA));
if (!priv_new)
{
Go_release(&(pbmp->hdr));
return NULL;
}
priv_new->pix_per_row = pbmp->width;
priv_new->pdata = pbmp->bits;
rc = _DC_Allocate(&screen_funtable, priv_new);
if (rc)
{
rc->hdr.dtor = screen_context_destroy;
rc->flags = DCFLG_IS_MEMORY;
rc->baserect.left = rc->baserect.top = 0;
rc->baserect.right = pbmp->width;
rc->baserect.bottom = pbmp->height;
memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT));
rc->cur_bitmap = pbmp;
}
else
{
free(priv_new);
Go_release(&(pbmp->hdr));
}
return rc;
}
BOOL screen_new_bitmap(PVOID privdata, PBITMAP pbmp)
{
PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata;
priv->pix_per_row = pbmp->width;
priv->pdata = pbmp->bits;
return TRUE;
}
BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op)
{
PSCREENPRIVDATA dest = (PSCREENPRIVDATA)p_dest;
PSCREENPRIVDATA src = (PSCREENPRIVDATA)p_src;
PUINT16 pd, ps;
INT32 width, i;
pd = loc_from_coords(dest, r_dest->left, r_dest->top);
ps = loc_from_coords(src, r_src->left, r_src->top);
width = r_src->right - r_src->left;
for (i = r_src->top; i < r_src->bottom; ++i)
{
memcpy(pd, ps, width * sizeof(UINT16));
pd += dest->pix_per_row;
ps += src->pix_per_row;
}
return TRUE;
}
static const DCFUNTABLE screen_funtable = {
screen_set_pixel,
screen_line,
screen_solid_rect,
screen_create_compat,
screen_new_bitmap,
screen_bitblt
};
static void screen_context_destroy(PVOID obj)
{
PDCTXT pdctxt = (PDCTXT)obj;
_DC_FinalizeCommon(pdctxt);
free(pdctxt->privdata);
}
PDCTXT DC_CreateScreenContext(void)
{
PDCTXT rc;
PSCREENPRIVDATA priv;
priv = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA));
if (!priv)
return NULL;
priv->pix_per_row = Fb_Info->width;
priv->pdata = Fb_Ptr;
rc = _DC_Allocate(&screen_funtable, priv);
if (rc)
{
rc->hdr.dtor = screen_context_destroy;
rc->flags = DCFLG_IS_SCREEN;
rc->baserect.left = rc->baserect.top = 0;
rc->baserect.right = Fb_Info->width;
rc->baserect.bottom = Fb_Info->height;
memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT));
}
else
free(priv);
return rc;
}
PDCTXT _DC_CreateScreenCompatibleContext(void)
{
return screen_create_compat(NULL);
}

34
src/dc_screen.h Executable file
View File

@ -0,0 +1,34 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __DC_SCREEN_H_INCLUDED
#define __DC_SCREEN_H_INCLUDED
#include "wintype.h"
#include "gfxtype.h"
typedef struct tagSCREENPRIVDATA {
UINT32 pix_per_row;
UINT16 *pdata;
} SCREENPRIVDATA, *PSCREENPRIVDATA;
extern PDCTXT DC_CreateScreenContext(void);
extern PDCTXT _DC_CreateScreenCompatibleContext(void);
#endif /* __DC_SCREEN_H_INCLUDED */

263
src/devctxt.c Executable file
View File

@ -0,0 +1,263 @@
/*
* 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>
#include <stdlib.h>
#include "log.h"
#include "gfxtype.h"
#include "gfxobj.h"
#include "devctxt.h"
#include "bitmap.h"
#include "dc_screen.h"
inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
{
BYTE rc = 0;
if (y < ymin)
rc |= 0x8;
else if (y >= ymax)
rc |= 0x4;
if (x < xmin)
rc |= 0x1;
else if (x >= xmax)
rc |= 0x2;
return rc;
}
#define CPX 8 /* clipping precision in bits */
#define ONE (1 << CPX) /* constant for mathematics */
/* these macros keep the number of bits straight when doing fixed-point multiply & divide */
#define M(a, b) ((((a) * (b))) >> CPX)
#define D(a, b) (((a) << CPX) / (b))
static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
{
BYTE outcode1, outcode2;
INT32 tmp;
int nloop = 0;
/* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */
for (;;)
{
if (++nloop == 20)
{
Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING");
return FALSE;
}
outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax);
outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax);
if ((outcode1 & outcode2) != 0)
return FALSE; /* trivial rejection */
else if ((outcode1 == 0) && (outcode2 == 0))
break; /* trivial acceptance */
if (outcode1 == 0)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
outcode1 = outcode2; /* we don't reference outcode2 in the rest of the loop */
}
if (outcode1 & 0x8)
{
x1 += M(x2 - x1, D(ymin - y1, y2 - y1));
y1 = ymin;
}
else if (outcode1 & 0x4)
{
x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1));
y1 = ymax - ONE;
}
else if (outcode1 & 0x2)
{
y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1));
x1 = xmax - ONE;
}
else if (outcode1 & 0x1)
{
y1 += M(y2 - y1, D(xmin - x1, x2 - x1));
x1 = xmin;
}
}
output[0] = x1;
output[1] = y1;
output[2] = x2;
output[3] = y2;
return TRUE;
}
static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
{
INT32 buffer[4];
if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX,
pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX))
return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2);
return TRUE;
}
PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata)
{
PDCTXT rc = (PDCTXT)malloc(sizeof(DCTXT));
if (!rc)
return NULL;
memset(rc, 0, sizeof(DCTXT));
_Go_init(&(rc->hdr), DCTXT_SIG_WORD, sizeof(DCTXT));
rc->funcs = funcs;
rc->privdata = privdata;
rc->rop2 = R2_COPYPEN;
return rc;
}
void _DC_FinalizeCommon(PDCTXT pdctxt)
{
if (pdctxt->cur_bitmap)
Go_release(&(pdctxt->cur_bitmap->hdr));
}
COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color)
{
if (!G_coords_in_rect(&(pdctxt->cliprect), x, y))
return (COLORREF)(-1);
return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2);
}
BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y)
{
BOOL rc = internal_line(pdctxt, pdctxt->pos.x, pdctxt->pos.y, x, y);
if (rc)
{
pdctxt->pos.x = x;
pdctxt->pos.y = y;
}
return rc;
}
BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt)
{
if (oldpt)
memcpy(oldpt, &(pdctxt->pos), sizeof(POINT));
pdctxt->pos.x = x;
pdctxt->pos.y = y;
return TRUE;
}
BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom)
{
internal_line(pdctxt, left, top, right - 1, top);
internal_line(pdctxt, left, top + 1, left, bottom - 2);
internal_line(pdctxt, right - 1, top + 1, right - 1, bottom - 2);
internal_line(pdctxt, left, bottom - 1, right - 1, bottom - 1);
return TRUE;
}
BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom)
{
RECT rect, actual;
G_set_rect(&rect, left, top, right, bottom);
if (!G_rect_intersect(&actual, &rect, &(pdctxt->cliprect)))
return TRUE;
return (*(pdctxt->funcs->solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2);
}
UINT32 DC_GetROP2(PDCTXT pdctxt)
{
return pdctxt->rop2;
}
UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop)
{
UINT32 rc = pdctxt->rop2;
pdctxt->rop2 = rop;
return rc;
}
COLORREF DC_GetTextColor(PDCTXT pdctxt)
{
return pdctxt->color;
}
COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr)
{
COLORREF rc = pdctxt->color;
pdctxt->color = cr;
return rc;
}
BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect)
{
memcpy(prect, &(pdctxt->cliprect), sizeof(RECT));
return TRUE;
}
BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect)
{
memcpy(&(pdctxt->cliprect), prect, sizeof(RECT));
return TRUE;
}
PDCTXT DC_CreateCompatible(PDCTXT pdctxt)
{
if (pdctxt)
return (*(pdctxt->funcs->create_compat))(pdctxt->privdata);
return _DC_CreateScreenCompatibleContext();
}
PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj)
{
if (pobj->sig == BMP_SIG_WORD)
{
if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY)
{
RECT rtmp;
PBITMAP rbmp = pdctxt->cur_bitmap;
Go_addref(pobj);
if ((*(pdctxt->funcs->new_bitmap))(pdctxt->privdata, (PBITMAP)pobj))
{
pdctxt->cur_bitmap = (PBITMAP)pobj;
pdctxt->baserect.left = pdctxt->baserect.top = 0;
pdctxt->baserect.right = ((PBITMAP)pobj)->width;
pdctxt->baserect.bottom = ((PBITMAP)pobj)->height;
G_rect_intersect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect));
memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT));
return (PGFXOBJECT)rbmp;
}
Go_release(pobj);
}
}
return NULL;
}
BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop)
{
RECT destrect, actualdest, srcrect, actualsrc;
G_set_rect(&destrect, x, y, x + width, y + height);
if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect)))
return TRUE; /* no-op */
G_set_rect(&srcrect, x1, y1, x1 + (actualdest.right - actualdest.left), y1 + (actualdest.bottom - actualdest.top));
if (!G_rect_intersect(&actualsrc, &srcrect, &(source->baserect)))
return TRUE;
actualdest.right = actualdest.left + (actualsrc.right - actualsrc.left);
actualdest.bottom = actualdest.top + (actualsrc.bottom - actualsrc.top);
return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, source->privdata, &actualsrc, rop);
}

106
src/devctxt.h Executable file
View File

@ -0,0 +1,106 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __DEVCTXT_H_INCLUDED
#define __DEVCTXT_H_INCLUDED
#include "wintype.h"
#include "gfxtype.h"
#include "gfxobj.h"
#include "bitmap.h"
#define DCTXT_SIG_WORD 0x78744344 /* "DCtx */
/* Raster operation codes */
#define R2_BLACK 1
#define R2_NOTMERGEPEN 2
#define R2_MASKNOTPEN 3
#define R2_NOTCOPYPEN 4
#define R2_MASKPENNOT 5
#define R2_NOT 6
#define R2_XORPEN 7
#define R2_NOTMASKPEN 8
#define R2_MASKPEN 9
#define R2_NOTXORPEN 10
#define R2_NOP 11
#define R2_MERGENOTPEN 12
#define R2_COPYPEN 13
#define R2_MERGEPENNOT 14
#define R2_MERGEPEN 15
#define R2_WHITE 16
struct tagDCTXT; /* forward declaration */
typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op);
typedef BOOL (*DCtx_Line)(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op);
typedef BOOL (*DCtx_SolidRect)(PVOID privdata, PRECT rect, COLORREF color, INT32 op);
typedef struct tagDCTXT *(*DCtx_CreateCompat)(PVOID privdata);
typedef BOOL (*DCtx_NewBitmap)(PVOID privdata, PBITMAP pbmp);
typedef BOOL (*DCtx_BitBlt)(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op);
typedef struct tagDCFUNTABLE {
DCtx_SetPixel set_pixel; /* sets a single pixel on the display */
DCtx_Line line; /* draws a line on the display */
DCtx_SolidRect solid_rect; /* draws a solid rectangle on the display */
DCtx_CreateCompat create_compat; /* create a memory DC compatible with this one */
DCtx_NewBitmap new_bitmap; /* new bitmap selected notification */
DCtx_BitBlt bitblt; /* bit block transfer */
} DCFUNTABLE;
typedef const DCFUNTABLE *PDCFUNTABLE;
typedef struct tagDCTXT {
GFXOBJECT hdr; /* the header of all objects */
PDCFUNTABLE funcs; /* device context functions */
PVOID privdata; /* private data for the type of DC */
UINT32 flags; /* flags for the DC */
RECT baserect; /* base rectangle */
RECT cliprect; /* clipping rectangle */
POINT pos; /* current position */
UINT32 rop2; /* current raster operation */
COLORREF color; /* current drawing color (XXX replace with pens later) */
PBITMAP cur_bitmap; /* current selected bitmap */
} DCTXT, *PDCTXT;
#define DCFLG_TYPES 0x03
#define DCFLG_IS_SCREEN 0x00
#define DCFLG_IS_MEMORY 0x01
extern PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata);
extern void _DC_FinalizeCommon(PDCTXT pdctxt);
extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color);
extern BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y);
extern BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt);
extern BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom);
extern BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom);
extern UINT32 DC_GetROP2(PDCTXT pdctxt);
extern UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop);
extern COLORREF DC_GetTextColor(PDCTXT pdctxt);
extern COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr);
extern BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect);
extern BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect);
extern PDCTXT DC_CreateCompatible(PDCTXT pdctxt);
extern PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj);
extern BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop);
#define DC_addref(pdctxt) Go_addref(&(pdctxt->hdr))
#define DC_release(pdctxt) Go_release(&(pdctxt->hdr))
#endif /* __DEVCTXT_H_INCLUDED */

84
src/ep_backlight.c Normal file
View File

@ -0,0 +1,84 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "log.h"
#include "gpio.h"
#include "ep_upiwin.h"
#include "ep_init.h"
PyObject *Epython_get_backlight(PyObject *self, PyObject *args)
{
PUPIWIN_STATE pstate;
if (!PyArg_ParseTuple(args, ""))
return NULL;
pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module);
return PyBool_FromLong((long)(pstate->backlight_on));
}
PyObject *Epython_set_backlight(PyObject *self, PyObject *args)
{
PUPIWIN_STATE pstate;
int new_state;
if (!PyArg_ParseTuple(args, "p", &new_state))
return NULL;
pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module);
if (new_state && !(pstate->backlight_on))
Gpio_set_backlight(pstate->backlight_level);
else if (!new_state && pstate->backlight_on)
Gpio_set_backlight(0);
pstate->backlight_on = MAKEBOOL(new_state);
return PyLong_FromUnsignedLong(S_OK);
}
PyObject *Epython_get_backlight_level(PyObject *self, PyObject *args)
{
PUPIWIN_STATE pstate;
if (!PyArg_ParseTuple(args, ""))
return NULL;
pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module);
return PyLong_FromUnsignedLong(pstate->backlight_level);
}
PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args)
{
PUPIWIN_STATE pstate;
UINT32 new_level;
HRESULT hr = S_OK;
if (!PyArg_ParseTuple(args, "k", &new_level))
return NULL;
if (new_level <= GSB_BACKLIGHT_MAX)
{
pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module);
if (pstate->backlight_on)
Gpio_set_backlight(new_level);
pstate->backlight_level = new_level;
}
else
{
hr = E_INVALIDARG;
}
return PyLong_FromUnsignedLong(hr);
}

154
src/ep_bitmap.c Executable file
View File

@ -0,0 +1,154 @@
/*
* 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 "scode.h"
#include "log.h"
#include "gfxobj.h"
#include "bitmap.h"
#include "ep_types.h"
static PyMethodDef BitmapMethods[] = {
{NULL, NULL, 0, NULL}
};
static PyObject *bitmap_get_width(BitmapObject *self, void *closure)
{
if (!(self->pbmp))
{
PyErr_SetString(PyExc_RuntimeError, "bad bitmap object");
return NULL;
}
return PyLong_FromUnsignedLong(self->pbmp->width);
}
static PyObject *bitmap_get_height(BitmapObject *self, void *closure)
{
if (!(self->pbmp))
{
PyErr_SetString(PyExc_RuntimeError, "bad bitmap object");
return NULL;
}
return PyLong_FromUnsignedLong(self->pbmp->height);
}
static PyGetSetDef BitmapProperties[] = {
{"width", (getter)bitmap_get_width, NULL,
"Width of this bitmap", NULL},
{"height", (getter)bitmap_get_height, NULL,
"Height of this bitmap", NULL},
{NULL, NULL, NULL, NULL, NULL}
};
static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = { "stock", "width", "height", NULL };
const char *stock;
int width = 0, height = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height))
return -1;
if (stock)
{
self->pbmp = _BMP_GetStock(stock);
if (!(self->pbmp))
{
PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock);
return -1;
}
}
else
{
width = MAX(1, width);
height = MAX(1, height);
self->pbmp = BMP_Create(width, height, NULL);
if (!(self->pbmp))
{
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
return -1;
}
}
return 0;
}
static void bitmap_dealloc(BitmapObject *self)
{
if (self->pbmp)
BMP_Delete(self->pbmp);
Py_TYPE(self)->tp_free((PyObject *)self);
}
PyTypeObject BitmapType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "upiwin.Bitmap",
.tp_doc = "Bitmap object",
.tp_basicsize = sizeof(BitmapObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)bitmap_init,
.tp_dealloc = (destructor)bitmap_dealloc,
.tp_methods = BitmapMethods,
.tp_getset = BitmapProperties,
};
HRESULT Epython_register_bitmap(PyObject *module)
{
if (PyType_Ready(&BitmapType) < 0)
return E_FAIL;
Py_INCREF(&BitmapType);
if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0)
{
Py_DECREF(&BitmapType);
return E_FAIL;
}
return S_OK;
}
PyObject *Epython_wrap_bitmap(PBITMAP pbmp)
{
PyObject *rc = NULL, *args, *kwargs;
BitmapObject *pbitmapobj;
args = PyTuple_New(0);
if (args)
{
kwargs = PyDict_New();
if (kwargs)
{
rc = PyType_GenericNew(&BitmapType, args, kwargs);
if (rc)
{
pbitmapobj = (BitmapObject *)rc;
if (pbitmapobj->pbmp)
BMP_Delete(pbitmapobj->pbmp);
pbitmapobj->pbmp = pbmp;
}
Py_DECREF(kwargs);
}
Py_DECREF(args);
}
if (!rc)
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
return rc;
}

370
src/ep_devctxt.c Executable file
View File

@ -0,0 +1,370 @@
/*
* 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 "devctxt.h"
#include "dc_screen.h"
#include "ep_init.h"
#include "ep_types.h"
static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args)
{
INT32 x, y;
COLORREF color, rc;
if (!PyArg_ParseTuple(args, "iik", &x, &y, &color))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_SetPixel(self->pdctxt, x, y, color);
return PyLong_FromUnsignedLong(rc);
}
static PyObject *devctxt_line_to(DevCtxtObject *self, PyObject *args)
{
INT32 x, y;
BOOL rc;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_LineTo(self->pdctxt, x, y);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_move_to(DevCtxtObject *self, PyObject *args)
{
INT32 x, y;
BOOL rc;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_MoveTo(self->pdctxt, x, y, NULL);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args)
{
INT32 left, top, right, bottom;
BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_Rectangle(self->pdctxt, left, top, right, bottom);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_solid_rectangle(DevCtxtObject *self, PyObject *args)
{
INT32 left, top, right, bottom;
BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_SolidRectangle(self->pdctxt, left, top, right, bottom);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_bitblt(DevCtxtObject *self, PyObject *args)
{
INT32 x, y, width, height, x1, y1;
UINT32 rop;
DevCtxtObject *source;
BOOL rc;
if (!PyArg_ParseTuple(args, "iiiiO!iik", &x, &y, &width, &height, &DevCtxtType, &source, &x1, &y1, &rop))
return NULL;
if (!(self->pdctxt) || !(source->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_BitBlt(self->pdctxt, x, y, width, height, source->pdctxt, x1, y1, rop);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args)
{
RECT rect;
if (!PyArg_ParseTuple(args, ""))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
DC_GetClipRect(self->pdctxt, &rect);
return Py_BuildValue("(i,i,i,i)", rect.left, rect.top, rect.right, rect.bottom);
}
static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args)
{
RECT rect;
BOOL rc;
if (!PyArg_ParseTuple(args, "iiii", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)))
return NULL;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
rc = DC_SetClipRect(self->pdctxt, &rect);
return PyBool_FromLong(rc);
}
static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp)
{
BitmapObject *old_bitmap = NULL;
PBITMAP old_pbmp;
if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY)
{
PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context");
return NULL;
}
old_bitmap = self->selected_bitmap;
old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp));
if (!old_bitmap)
{
old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp);
if (!old_bitmap)
{
DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp);
return NULL;
}
else
{
Py_INCREF(old_bitmap);
self->selected_bitmap = old_bitmap;
}
}
ASSERT(old_bitmap);
ASSERT(self->selected_bitmap);
ASSERT(newbmp);
Py_DECREF(self->selected_bitmap);
self->selected_bitmap = newbmp;
Py_INCREF(self->selected_bitmap);
return (PyObject *)old_bitmap;
}
static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
if (!obj)
{
PyErr_SetString(PyExc_RuntimeError, "bad object selected");
return NULL;
}
if (PyObject_TypeCheck(obj, &BitmapType))
return devctxt_select_bitmap(self, (BitmapObject *)obj);
PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected");
return NULL;
}
static PyMethodDef DevCtxtMethods[] = {
{"set_pixel", (PyCFunction)devctxt_set_pixel, METH_VARARGS,
"Sets a single pixel on the display."},
{"line_to", (PyCFunction)devctxt_line_to, METH_VARARGS,
"Draws a line from the current position to the specified location."},
{"move_to", (PyCFunction)devctxt_move_to, METH_VARARGS,
"Draws a line from the current position to the specified location."},
{"rectangle", (PyCFunction)devctxt_rectangle, METH_VARARGS,
"Draws a rectangle."},
{"solid_rectangle", (PyCFunction)devctxt_solid_rectangle, METH_VARARGS,
"Draws a solid rectangle."},
{"bitblt", (PyCFunction)devctxt_bitblt, METH_VARARGS,
"Copy bits from one device context to another."},
{"select_object", (PyCFunction)devctxt_select_object, METH_VARARGS,
"Selects a graphic object into the device context."},
{"get_clip_rect", (PyCFunction)devctxt_get_clip_rect, METH_VARARGS,
"Returns the current clipping rectangle of the device context."},
{"set_clip_rect", (PyCFunction)devctxt_set_clip_rect, METH_VARARGS,
"Sets the current clipping rectangle of the device context."},
{NULL, NULL, 0, NULL}
};
static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure)
{
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
return PyLong_FromUnsignedLong(DC_GetROP2(self->pdctxt));
}
static int devctxt_set_rop2(DevCtxtObject *self, PyObject *value, void *closure)
{
UINT32 v;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return -1;
}
if (value == NULL)
{
PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
return -1;
}
v = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred())
return -1;
DC_SetROP2(self->pdctxt, v);
return 0;
}
static PyObject *devctxt_get_text_color(DevCtxtObject *self, void *closure)
{
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return NULL;
}
return PyLong_FromUnsignedLong(DC_GetTextColor(self->pdctxt));
}
static int devctxt_set_text_color(DevCtxtObject *self, PyObject *value, void *closure)
{
COLORREF v;
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "bad device context");
return -1;
}
if (value == NULL)
{
PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
return -1;
}
v = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred())
return -1;
DC_SetTextColor(self->pdctxt, v);
return 0;
}
static PyGetSetDef DevCtxtProperties[] = {
{"rop2", (getter)devctxt_get_rop2, (setter)devctxt_set_rop2,
"Current raster operation", NULL},
{"text_color", (getter)devctxt_get_text_color, (setter)devctxt_set_text_color,
"Current text color", NULL},
{NULL, NULL, NULL, NULL, NULL}
};
static void devctxt_dealloc(DevCtxtObject *self)
{
if (self->pdctxt)
DC_release(self->pdctxt);
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = { "type", NULL };
const char *type;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type))
return -1;
if (strcmp(type, "screen") == 0)
{
self->pdctxt = DC_CreateScreenContext();
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "unable to create screen context");
return -1;
}
}
else if (strcmp(type, "memory") == 0)
{
self->pdctxt = _DC_CreateScreenCompatibleContext();
if (!(self->pdctxt))
{
PyErr_SetString(PyExc_RuntimeError, "unable to create memory context");
return -1;
}
}
else
{
PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type);
return -1;
}
return 0;
}
PyTypeObject DevCtxtType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "upiwin.DevCtxt",
.tp_doc = "Device context object",
.tp_basicsize = sizeof(DevCtxtObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)devctxt_init,
.tp_dealloc = (destructor)devctxt_dealloc,
.tp_methods = DevCtxtMethods,
.tp_getset = DevCtxtProperties,
};
HRESULT Epython_register_devctxt(PyObject *module)
{
if (PyType_Ready(&DevCtxtType) < 0)
return E_FAIL;
Py_INCREF(&DevCtxtType);
if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0)
{
Py_DECREF(&DevCtxtType);
return E_FAIL;
}
return S_OK;
}

32
src/ep_graphics.c Executable file
View File

@ -0,0 +1,32 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
#include "gfxtype.h"
PyObject *Epython_rgb(PyObject *self, PyObject *args)
{
UINT32 r, g, b;
if (!PyArg_ParseTuple(args, "kkk", &r, &g, &b))
return NULL;
return PyLong_FromUnsignedLong(RGB(r, g, b));
}

165
src/ep_init.c Normal file
View File

@ -0,0 +1,165 @@
/*
* 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 <stdio.h>
#include <string.h>
#include <alloca.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "config.h"
#include "log.h"
#include "ep_init.h"
#include "ep_util.h"
static wchar_t *python_name = NULL; /* location of the Python executable */
PyObject *UPIWIN_module = NULL;
PyObject *UPIWIN_tmp_module = NULL;
/* used to link the two modules into Python's init table */
static struct _inittab upiwin_inittab[] = {
{ MOD_NAME_UPIWIN, Epython_init_upiwin_module },
{ MOD_NAME_UPIWIN_TMP, Epython_init_upiwin_tmp_module },
{ NULL, NULL }
};
static void epython_cleanup(void)
{
Py_DECREF(UPIWIN_tmp_module);
UPIWIN_tmp_module = NULL;
Py_DECREF(UPIWIN_module);
UPIWIN_module = NULL;
Py_FinalizeEx();
PyMem_RawFree(python_name);
python_name = NULL;
}
HRESULT Epython_setup(void)
{
HRESULT hr;
size_t size;
python_name = Py_DecodeLocale(Gconfig.python_loc, &size);
if (!python_name)
{
if (size==(size_t)(-1))
{
Log(LFATAL, "error allocating Python program location");
return E_OUTOFMEMORY;
}
else
{
Log(LFATAL, "internal error in Py_DecodeLocale");
return E_UNEXPECTED;
}
}
Py_SetProgramName(python_name);
if (PyImport_ExtendInittab(upiwin_inittab))
{
Log(LFATAL, "error allocating extended init table");
hr = E_OUTOFMEMORY;
goto error_0;
}
Py_Initialize();
/* Import the modules */
UPIWIN_module = PyImport_ImportModule(MOD_NAME_UPIWIN);
if (!UPIWIN_module)
{
Log(LFATAL, "error importing the upiwin module");
hr = Epython_trace_exception();
goto error_1;
}
UPIWIN_tmp_module = PyImport_ImportModule(MOD_NAME_UPIWIN_TMP);
if (!UPIWIN_tmp_module)
{
Log(LFATAL, "error importing the upiwin_tmp module");
hr = Epython_trace_exception();
goto error_2;
}
hr = Config_exitfunc(epython_cleanup);
if (FAILED(hr))
epython_cleanup();
return hr;
error_2:
Py_DECREF(UPIWIN_module);
UPIWIN_module = NULL;
error_1:
Py_FinalizeEx();
error_0:
PyMem_RawFree(python_name);
python_name = NULL;
return hr;
}
HRESULT Epython_run(void)
{
HRESULT hr = S_OK;
int i;
FILE *fp;
wchar_t **args;
Log(LINFO, "Ready to execute %s", Gconfig.script_name);
fp = fopen(Gconfig.script_name, "rb");
if (fp)
{
args = (wchar_t **)alloca((Gconfig.script_arg_count + 1) * sizeof(wchar_t *));
memset(args, 0, (Gconfig.script_arg_count + 1) * sizeof(wchar_t *));
args[0] = Py_DecodeLocale(Gconfig.script_name, NULL);
if (args[0])
{
for (i=0; i<Gconfig.script_arg_count; i++)
{
args[i + 1] = Py_DecodeLocale(Gconfig.script_args[i], NULL);
if (!(args[i + 1]))
{
hr = E_OUTOFMEMORY;
break;
}
}
if (SUCCEEDED(hr))
{
PySys_SetArgvEx(Gconfig.script_arg_count + 1, args, 1);
PyRun_SimpleFile(fp, Gconfig.script_name);
}
else
Log(LERROR, "out of memory running script %s", Gconfig.script_name);
}
else
{
Log(LERROR, "out of memory running script %s", Gconfig.script_name);
hr = E_OUTOFMEMORY;
}
for (i = 0; i<(Gconfig.script_arg_count + 1); i++)
if (args[i])
PyMem_RawFree(args[i]);
fclose(fp);
}
else
{
Log(LERROR, "Unable to open script file %s", Gconfig.script_name);
hr = E_ACCESSDENIED;
}
return hr;
}

42
src/ep_init.h Normal file
View File

@ -0,0 +1,42 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __EP_INIT_H_INCLUDED
#define __EP_INIT_H_INCLUDED
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
#define MOD_NAME_UPIWIN "upiwin"
#define MOD_NAME_UPIWIN_TMP "upiwin_tmp"
extern PyObject *UPIWIN_module;
extern PyObject *UPIWIN_tmp_module;
extern PyObject *Epython_init_upiwin_module(void);
extern PyObject *Epython_init_upiwin_tmp_module(void);
extern HRESULT Epython_register_devctxt(PyObject *module);
extern HRESULT Epython_register_bitmap(PyObject *module);
extern HRESULT Epython_setup(void);
extern HRESULT Epython_run(void);
#endif /* __EP_INIT_H_INCLUDED */

90
src/ep_msg.c Executable file
View File

@ -0,0 +1,90 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "log.h"
#include "msg_queue.h"
#include "sysinput.h"
#include "ep_upiwin.h"
#include "ep_init.h"
static HRESULT convert_msg(PyObject *target, PMSG source)
{
PyObject *attr;
ASSERT(PyDict_CheckExact(target));
PyDict_Clear(target);
attr = PyLong_FromUnsignedLong(source->target);
if (!attr)
return E_FAIL;
if (PyDict_SetItemString(target, "target", attr))
return E_FAIL;
attr = PyLong_FromUnsignedLong(source->message);
if (!attr)
return E_FAIL;
if (PyDict_SetItemString(target, "message", attr))
return E_FAIL;
attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]);
if (!attr)
return E_FAIL;
if (PyDict_SetItemString(target, "attrs", attr))
return E_FAIL;
attr = PyLong_FromUnsignedLongLong(source->timestamp);
if (!attr)
return E_FAIL;
if (PyDict_SetItemString(target, "timestamp", attr))
return E_FAIL;
return S_OK;
}
PyObject *Epython_get_message(PyObject *self, PyObject *args)
{
PyObject *out;
MSG msg;
if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out))
return NULL;
/* release the GIL to allow us to block waiting for input if necessary */
Py_BEGIN_ALLOW_THREADS
while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE))
Sys_wait_for_input();
Py_END_ALLOW_THREADS
if (FAILED(convert_msg(out, &msg)))
{
PyErr_SetString(PyExc_RuntimeError, "could not convert received message");
return NULL;
}
return PyBool_FromLong(msg.message != WM_QUIT);
}
PyObject *Epython_post_quit_message(PyObject *self, PyObject *args)
{
INT32 exitcode;
if (!PyArg_ParseTuple(args, "i", &exitcode))
return NULL;
Sys_Exit_Code = exitcode;
Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode);
Py_RETURN_NONE;
}

47
src/ep_types.h Executable file
View File

@ -0,0 +1,47 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __EP_TYPES_H_INCLUDED
#define __EP_TYPES_H_INCLUDED
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
#include "gfxtype.h"
#include "gfxobj.h"
#include "devctxt.h"
#include "bitmap.h"
typedef struct tagBitmapObject {
PyObject_HEAD
PBITMAP pbmp;
} BitmapObject;
typedef struct tagDevCtxtObject {
PyObject_HEAD
PDCTXT pdctxt;
BitmapObject *selected_bitmap;
} DevCtxtObject;
extern PyTypeObject DevCtxtType;
extern PyTypeObject BitmapType;
extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp);
#endif /* __EP_TYPES_H_INCLUDED */

126
src/ep_upiwin.c Normal file
View File

@ -0,0 +1,126 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "msg.h"
#include "gpio.h"
#include "ep_init.h"
#include "ep_upiwin.h"
#include "ep_util.h"
#include "devctxt.h"
static PyMethodDef UPIWINMethods[] = {
/* Backlight control functions */
{"get_backlight", Epython_get_backlight, METH_VARARGS,
"Returns the current status of the backlight (True=on, False=off)."},
{"set_backlight", Epython_set_backlight, METH_VARARGS,
"Sets the current status of the backlight (True=on, False=off). Returns a SCODE."},
{"get_backlight_level", Epython_get_backlight_level, METH_VARARGS,
"Returns the current intensity level of the backlight."},
{"set_backlight_level", Epython_set_backlight_level, METH_VARARGS,
"Sets the current intensity level of the backlight. Returns a SCODE."},
/* Message functions */
{"get_message", Epython_get_message, METH_VARARGS,
"Retrieves a message from the message queue, blocking if necessary."},
{"post_quit_message", Epython_post_quit_message, METH_VARARGS,
"Posts a WM_QUIT message to the message queue, with an exit code."},
/* Graphics functions */
{"rgb", Epython_rgb, METH_VARARGS,
"Creates a color value from separate red, green, and blue indexes."},
{NULL, NULL, 0, NULL}
};
static PyModuleDef DefUPIWIN = {
PyModuleDef_HEAD_INIT, /* standard garbage */
MOD_NAME_UPIWIN, /* module name */
NULL, /* no doc string */
sizeof(UPIWIN_STATE), /* per-module memory */
UPIWINMethods, /* method defs */
NULL, /* no slots for multi-phase init */
NULL, /* no traversal proc */
NULL, /* no clear function */
NULL /* no free function */
};
BEGIN_CONSTANT_TABLE(UPIWINConstants)
/* Message constants */
CONSTANT_INT_MACRO(WM_NULL)
CONSTANT_INT_MACRO(WM_QUIT)
CONSTANT_INT_MACRO(WM_HWBUTTONDOWN)
CONSTANT_INT_MACRO(WM_HWBUTTONUP)
CONSTANT_INT_MACRO(WM_HWBUTTONCLICK)
CONSTANT_INT_MACRO(WM_TOUCHDOWN)
CONSTANT_INT_MACRO(WM_TOUCHMOVE)
CONSTANT_INT_MACRO(WM_TOUCHUP)
CONSTANT_INT_MACRO(WM_TOUCHCLICK)
/* Raster op constants */
CONSTANT_INT_MACRO(R2_BLACK)
CONSTANT_INT_MACRO(R2_NOTMERGEPEN)
CONSTANT_INT_MACRO(R2_MASKNOTPEN)
CONSTANT_INT_MACRO(R2_NOTCOPYPEN)
CONSTANT_INT_MACRO(R2_MASKPENNOT)
CONSTANT_INT_MACRO(R2_NOT)
CONSTANT_INT_MACRO(R2_XORPEN)
CONSTANT_INT_MACRO(R2_NOTMASKPEN)
CONSTANT_INT_MACRO(R2_MASKPEN)
CONSTANT_INT_MACRO(R2_NOTXORPEN)
CONSTANT_INT_MACRO(R2_NOP)
CONSTANT_INT_MACRO(R2_MERGENOTPEN)
CONSTANT_INT_MACRO(R2_COPYPEN)
CONSTANT_INT_MACRO(R2_MERGEPENNOT)
CONSTANT_INT_MACRO(R2_MERGEPEN)
CONSTANT_INT_MACRO(R2_WHITE)
END_CONSTANT_TABLE
PyObject *Epython_init_upiwin_module(void)
{
PyObject *module;
PUPIWIN_STATE pstate;
module = PyModule_Create(&DefUPIWIN);
if (!module)
return NULL;
if (FAILED(Epython_register_constants(module, UPIWINConstants)))
{
Py_DECREF(module);
return NULL;
}
if (FAILED(Epython_register_bitmap(module)))
{
Py_DECREF(module);
return NULL;
}
if (FAILED(Epython_register_devctxt(module)))
{
Py_DECREF(module);
return NULL;
}
/* set up the module state */
pstate = (PUPIWIN_STATE)PyModule_GetState(module);
pstate->backlight_on = TRUE;
pstate->backlight_level = GSB_BACKLIGHT_DEFAULT;
return module;
}

47
src/ep_upiwin.h Normal file
View File

@ -0,0 +1,47 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __EP_UPIWIN_H_INCLUDED
#define __EP_UPIWIN_H_INCLUDED
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
typedef struct tagUPIWIN_STATE {
BOOL backlight_on;
UINT32 backlight_level;
} UPIWIN_STATE, *PUPIWIN_STATE;
/* method definitions go here */
/* ep_backlight.c */
extern PyObject *Epython_get_backlight(PyObject *self, PyObject *args);
extern PyObject *Epython_set_backlight(PyObject *self, PyObject *args);
extern PyObject *Epython_get_backlight_level(PyObject *self, PyObject *args);
extern PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args);
/* ep_msg.c */
extern PyObject *Epython_get_message(PyObject *self, PyObject *args);
extern PyObject *Epython_post_quit_message(PyObject *self, PyObject *args);
/* ep_graphics.c */
extern PyObject *Epython_rgb(PyObject *self, PyObject *args);
#endif /* __EP_UPIWIN_H_INCLUDED */

133
src/ep_upiwin_tmp.c Normal file
View File

@ -0,0 +1,133 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "fbprimitive.h"
#include "ep_init.h"
#include "ep_util.h"
static PyObject *do_setpixel(PyObject *self, PyObject *args)
{
INT32 x, y;
UINT16 color, oldcolor;
BOOL xor;
if (!PyArg_ParseTuple(args, "iiHi", &x, &y, &color, &xor))
return NULL;
oldcolor = Fb_setpixel(x, y, color, xor);
return PyLong_FromLong((long)oldcolor);
}
static PyObject *do_line(PyObject *self, PyObject *args)
{
INT32 x1, y1, x2, y2;
UINT16 color;
BOOL xor;
if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor))
return NULL;
Fb_line(x1, y1, x2, y2, color, xor);
Py_RETURN_NONE;
}
static PyObject *do_rectangle(PyObject *self, PyObject *args)
{
INT32 x1, y1, x2, y2;
UINT16 color;
BOOL xor;
if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor))
return NULL;
Fb_rectangle(x1, y1, x2, y2, color, xor);
Py_RETURN_NONE;
}
static PyObject *do_filled_rectangle(PyObject *self, PyObject *args)
{
INT32 x1, y1, x2, y2;
UINT16 color;
BOOL xor;
if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor))
return NULL;
Fb_filled_rectangle(x1, y1, x2, y2, color, xor);
Py_RETURN_NONE;
}
static PyObject *do_textout(PyObject *self, PyObject *args)
{
INT32 x, y;
PSTR text;
if (!PyArg_ParseTuple(args, "iis", &x, &y, &text))
return NULL;
Fb_textout(x, y, text);
Py_RETURN_NONE;
}
static PyMethodDef UPIWIN_tmpMethods[] = {
{"setpixel", do_setpixel, METH_VARARGS, "Set a single pixel on the display."},
{"line", do_line, METH_VARARGS, "Draw a line on the display."},
{"rectangle", do_rectangle, METH_VARARGS, "Draw a rectangle on the display."},
{"filled_rectangle", do_filled_rectangle, METH_VARARGS, "Draw a filled rectangle on the display."},
{"textout", do_textout, METH_VARARGS, "Draw text on the display."},
{NULL, NULL, 0, NULL}
};
static PyModuleDef DefUPIWIN_tmp = {
PyModuleDef_HEAD_INIT, /* standard garbage */
MOD_NAME_UPIWIN_TMP, /* module name */
NULL, /* no doc string */
-1, /* no per-module memory */
UPIWIN_tmpMethods, /* method defs */
NULL, /* no slots for multi-phase init */
NULL, /* no traversal proc */
NULL, /* no clear function */
NULL /* no free function */
};
BEGIN_CONSTANT_TABLE(UPIWIN_tmpConstants)
/* primitive color values */
CONSTANT_INT_MACRO(FBPRIMCLR_BLACK)
CONSTANT_INT_MACRO(FBPRIMCLR_RED)
CONSTANT_INT_MACRO(FBPRIMCLR_GREEN)
CONSTANT_INT_MACRO(FBPRIMCLR_BLUE)
CONSTANT_INT_MACRO(FBPRIMCLR_YELLOW)
CONSTANT_INT_MACRO(FBPRIMCLR_CYAN)
CONSTANT_INT_MACRO(FBPRIMCLR_MAGENTA)
CONSTANT_INT_MACRO(FBPRIMCLR_WHITE)
END_CONSTANT_TABLE
PyObject *Epython_init_upiwin_tmp_module(void)
{
PyObject *module;
module = PyModule_Create(&DefUPIWIN_tmp);
if (module)
{
if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants)))
{
Py_DECREF(module);
module = NULL;
}
}
return module;
}

94
src/ep_util.c Normal file
View File

@ -0,0 +1,94 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "ep_util.h"
#include "log.h"
void Epython_log_object(int level, const char *label, PyObject *object)
{
BOOL traced = FALSE;
PyObject *repr;
PCSTR pstr;
repr = PyObject_Repr(object);
if (repr)
{
ASSERT(PyUnicode_Check(repr));
pstr = PyUnicode_AsUTF8(repr);
Log(level, "object %s: %s", label, pstr);
traced = TRUE;
Py_DECREF(repr);
}
if (!traced)
Log(level, "object %s: could not be logged (memory error)", label);
}
HRESULT Epython_trace_exception(void)
{
HRESULT hr = E_FAIL;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
if (!type)
return S_OK;
Epython_log_object(LERROR, "exception type", type);
Epython_log_object(LERROR, "exception value", value);
Epython_log_object(LERROR, "exception traceback", value);
Py_DECREF(type);
Py_DECREF(value);
Py_DECREF(traceback);
return hr;
}
HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table)
{
HRESULT hr = S_OK;
int i = 0, rc;
while (const_table[i].name)
{
switch (const_table[i].regtype)
{
case 'i':
rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival);
break;
case 's':
rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval);
break;
default:
Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype);
return E_UNEXPECTED;
}
if (rc)
{
Log(LERROR, "Failed to register constant %s", const_table[i].name);
hr = E_FAIL;
break;
}
++i;
}
return hr;
}

49
src/ep_util.h Normal file
View File

@ -0,0 +1,49 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __EP_UTIL_H_INCLUDED
#define __EP_UTIL_H_INCLUDED
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "wintype.h"
typedef struct tagREGCONSTANT {
CHAR regtype;
PCSTR name;
union {
LONG ival;
PCSTR sval;
} value;
} REGCONSTANT, *PREGCONSTANT;
typedef const REGCONSTANT *PCREGCONSTANT;
extern void Epython_log_object(int level, const char *label, PyObject *object);
extern HRESULT Epython_trace_exception(void);
extern HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table);
#define BEGIN_CONSTANT_TABLE(name) static const REGCONSTANT name[] = {
#define CONSTANT_INT(name, value) { 'i', name, { .ival = value } },
#define CONSTANT_INT_MACRO(mac) CONSTANT_INT(#mac, mac)
#define CONSTANT_STRING(name, value) { 's', name, { .sval = value } },
#define CONSTANT_STRING_MACRO(mac) CONSTANT_STRING(#mac, mac)
#define END_CONSTANT_TABLE { 0, NULL, { .sval = NULL } } };
#endif /* __EP_UTIL_H_INCLUDED */

133
src/fbinit.c Normal file
View File

@ -0,0 +1,133 @@
/*
* 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 <stddef.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include "config.h"
#include "log.h"
#include "fbinit.h"
#include "scode.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 */
/* frame buffer information */
static FBINFO local_info;
PCFBINFO Fb_Info = &local_info;
UINT16 *Fb_Ptr = NULL; /* pointer to memory-mapped frame buffer */
inline static UINT16 makemask(unsigned offset, unsigned length)
{
return (UINT16)(((1 << length) - 1) << offset);
}
static void do_cleanup(void)
{
/* black out the display */
memset(Fb_Ptr, 0, local_info.screenbytes);
munmap((void *)Fb_Ptr, local_info.screenbytes);
Fb_Ptr = NULL;
close(fb_fd);
fb_fd = -1;
}
HRESULT Fb_setup(void)
{
HRESULT hr = S_OK;
struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var;
fb_fd = open(Gconfig.framebuffer_device, O_RDWR);
if (fb_fd == -1)
{
hr = ERRNO_AS_SCODE;
Log(LFATAL, "Unable to open framebuffer device %s (%08X)", Gconfig.framebuffer_device, hr);
return hr;
}
/* fixed info is needed to get the memory parameters for the display */
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed))
{
hr = ERRNO_AS_SCODE;
Log(LFATAL, "Could not get fixed screen info (%08X)", hr);
return hr;
}
local_info.linebytes = fixed.line_length;
local_info.screenbytes = fixed.smem_len;
/* variable info is used to get scren geometry and color info */
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
{
hr = ERRNO_AS_SCODE;
Log(LFATAL, "Could not get variable screen info (%08X)", hr);
return hr;
}
local_info.width = var.xres;
local_info.height = var.yres;
local_info.virtual_width = var.xres_virtual;
local_info.virtual_height = var.yres_virtual;
local_info.bpp = var.bits_per_pixel;
local_info.red_offset = var.red.offset;
local_info.red_length = var.red.length;
local_info.red_mask = makemask(var.red.offset, var.red.length);
local_info.green_offset = var.green.offset;
local_info.green_length = var.green.length;
local_info.green_mask = makemask(var.green.offset, var.green.length);
local_info.blue_offset = var.blue.offset;
local_info.blue_length = var.blue.length;
local_info.blue_mask = makemask(var.blue.offset, var.blue.length);
Fb_Ptr = (UINT16 *)mmap(0, fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
if ((int)Fb_Ptr == -1)
{
hr = ERRNO_AS_SCODE;
Log(LFATAL, "Unable to memmap framebuffer (%08X)", hr);
Fb_Ptr = NULL;
close(fb_fd);
fb_fd = -1;
return hr;
}
/* display the splash screen */
memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size));
hr = Config_exitfunc(do_cleanup);
if (FAILED(hr))
do_cleanup();
return hr;
}
void Fb_clear(void)
{
memset(Fb_Ptr, 0, local_info.screenbytes);
}

52
src/fbinit.h Normal file
View File

@ -0,0 +1,52 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __FBINIT_H_INCLUDED
#define __FBINIT_H_INCLUDED
#include "wintype.h"
/* info about the frame buffer */
typedef struct tagFBINFO {
UINT32 width; /* screen width */
UINT32 height; /* screen height */
UINT32 virtual_width; /* virtual screen width */
UINT32 virtual_height; /* virtual screen height */
UINT32 bpp; /* bits per pixel (16) */
UINT32 linebytes; /* number of bytes per line */
UINT32 screenbytes; /* number of bytes for the entire screen */
UINT16 red_offset; /* offset of "red" bits within pixel word (11) */
UINT16 red_length; /* number of "red" bits within pixel word (5) */
UINT16 red_mask; /* mask for the "red" bits in a pixel word */
UINT16 green_offset; /* offset of "green" bits within pixel word (5) */
UINT16 green_length; /* number of "green" bits within pixel word (6) */
UINT16 green_mask; /* mask for the "green" bits in a pixel word */
UINT16 blue_offset; /* offset of "blue" bits within pixel word (0) */
UINT16 blue_length; /* number of "blue" bits within pixel word (5) */
UINT16 blue_mask; /* mask for the "blue" bits in a pixel word */
} FBINFO;
typedef const FBINFO * const PCFBINFO;
extern PCFBINFO Fb_Info; /* pointer to screen information */
extern UINT16 *Fb_Ptr; /* pointer to memory-mapped screen buffer */
extern HRESULT Fb_setup(void);
extern void Fb_clear(void);
#endif /* __FBINIT_H_INCLUDED */

170
src/fbprimitive.c Normal file
View File

@ -0,0 +1,170 @@
/*
* 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>
#include <alloca.h>
#include "wintype.h"
#include "log.h"
#include "fbinit.h"
#include "fontengine.h"
#include "fbprimitive.h"
inline static PUINT16 loc_from_coords(INT32 x, INT32 y)
{
return Fb_Ptr + (y * Fb_Info->width) + x;
}
UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor)
{
UINT16 rc;
PUINT16 loc = loc_from_coords(x, y);
rc = *loc;
if (xor)
*loc ^= color;
else
*loc = color;
return rc;
}
void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
INT32 tmp;
INT32 dx = x2 - x1;
INT32 dy = y2 - y1;
/* uses Bresenham's line algorithm with fixed-point arithmetic */
if (ABS(dx) < ABS(dy))
{
if (y1 > y2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
x1 <<= 16;
dx = (dx << 16) / dy;
while (y1 <= y2)
{
Fb_setpixel(x1 >> 16, y1, color, xor);
x1 += dx;
y1++;
}
}
else
{
if (x1 > x2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
y1 <<= 16;
dy = dx ? (dy << 16) / dx : 0;
while (x1 <= x2)
{
Fb_setpixel(x1, y1 >> 16, color, xor);
y1 += dy;
x1++;
}
}
}
void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
Fb_line(x1, y1, x2, y1, color, xor);
Fb_line(x2, y1 + 1, x2, y2 - 1, color, xor);
Fb_line(x1, y2, x2, y2, color, xor);
Fb_line(x1, y1 + 1, x1, y2 - 1, color, xor);
}
void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
INT32 tmp;
PUINT16 ps, p;
if (x1 > x2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (y1 > y2)
{
tmp = y1;
y1 = y2;
y2 = tmp;
}
ps = loc_from_coords(x1, y1);
for (; y1 <= y2; y1++)
{
p = ps;
for (tmp = x1; tmp <= x2; tmp++)
{
if (xor)
*p++ ^= color;
else
*p++ = color;
}
ps += Fb_Info->width;
}
}
static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits)
{
INT32 i, j;
BYTE b;
PUINT16 dptr, lbuf;
if ((width == 0) && (height == 0))
return; /* must be drawing a space */
if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height))
return;
dptr = loc_from_coords(x, y);
lbuf = (PUINT16)alloca(width * sizeof(UINT16));
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
b = *gsbits++;
lbuf[j] = ((UINT16)(b >> 3) & 0x1F) << 11;
lbuf[j] |= ((UINT16)(b >> 2) & 0x3F) << 5;
lbuf[j] |= ((UINT16)(b >> 3) & 0x1F);
}
memcpy(dptr, lbuf, width * sizeof(UINT16));
dptr += Fb_Info->width;
}
}
void Fb_textout(INT32 x, INT32 y, PCSTR pstr)
{
FontEng_do_text_out(x, y, pstr, internal_textout);
}

41
src/fbprimitive.h Normal file
View File

@ -0,0 +1,41 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __FBPRIMITIVE_H_INCLUDED
#define __FBPRIMITIVE_H_INCLUDED
#include "wintype.h"
/* Some predefined "primitive" color values */
#define FBPRIMCLR_BLACK 0x0000
#define FBPRIMCLR_RED 0xF800
#define FBPRIMCLR_GREEN 0x07E0
#define FBPRIMCLR_BLUE 0x001F
#define FBPRIMCLR_YELLOW 0xFFE0
#define FBPRIMCLR_CYAN 0x07FF
#define FBPRIMCLR_MAGENTA 0xF81F
#define FBPRIMCLR_WHITE 0xFFFF
extern UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor);
extern void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_textout(INT32 x, INT32 y, PCSTR pstr);
#endif /* __FBPRIMITIVE_H_INCLUDED */

107
src/fontengine.c Normal file
View File

@ -0,0 +1,107 @@
/*
* 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 <ft2build.h>
#include FT_FREETYPE_H
#include "scode.h"
#include "config.h"
#include "log.h"
#include "fontengine.h"
static FT_Library library;
static FT_Face stdfont;
static void fonteng_cleanup(void)
{
FT_Done_Face(stdfont);
FT_Done_FreeType(library);
}
HRESULT FontEng_setup(void)
{
HRESULT hr = S_OK;
FT_Error err;
err = FT_Init_FreeType(&library);
if (err != 0)
{
Log(LFATAL, "Unable to initialize Freetype (%d)", err);
return E_FAIL;
}
err = FT_New_Face(library, "/usr/local/share/fonts/truetype/arial.ttf", 0, &stdfont);
if (err != 0)
{
Log(LFATAL, "Unable to load font (%d)", err);
hr = E_FAIL;
goto error_0;
}
err = FT_Set_Pixel_Sizes(stdfont, 0, 16);
if (err != 0)
{
Log(LFATAL, "Unable to set font size (%d)", err);
hr = E_FAIL;
goto error_1;
}
hr = Config_exitfunc(fonteng_cleanup);
if (FAILED(hr))
fonteng_cleanup();
return hr;
error_1:
FT_Done_Face(stdfont);
error_0:
FT_Done_FreeType(library);
return hr;
}
HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc)
{
HRESULT hr = S_OK;
FT_GlyphSlot slot = stdfont->glyph;
FT_UInt glyph_index;
FT_Error err;
y += (stdfont->size->metrics.ascender >> 6);
while (*pstr)
{
glyph_index = FT_Get_Char_Index(stdfont, *pstr);
err = FT_Load_Glyph(stdfont, glyph_index, FT_LOAD_DEFAULT);
if (err != 0)
{
hr = E_FAIL;
break;
}
err = FT_Render_Glyph(stdfont->glyph, FT_RENDER_MODE_NORMAL);
if (err != 0)
{
hr = E_FAIL;
break;
}
(*renderfunc)(x + slot->bitmap_left, y - slot->bitmap_top, slot->bitmap.width,
slot->bitmap.rows, slot->bitmap.buffer);
x += slot->advance.x >> 6;
y += slot->advance.y >> 6;
pstr++;
}
return hr;
}

30
src/fontengine.h Normal file
View File

@ -0,0 +1,30 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __FONTENGINE_H_INCLUDED
#define __FONTENGINE_H_INCLUDED
#include "wintype.h"
typedef void (*TEXTOUTFUNC)(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits);
extern HRESULT FontEng_setup(void);
extern HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc);
#endif /* __FONTENGINE_H_INCLUDED */

58
src/gfxobj.c Executable file
View File

@ -0,0 +1,58 @@
/*
* 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 "gfxobj.h"
void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size)
{
memset(obj, 0, sizeof(GFXOBJECT));
obj->sig = sig;
obj->size = size;
obj->refcnt = 1;
}
void Go_unchain(PGFXOBJECT obj)
{
if (!(obj->next || obj->prev))
return;
if (obj->next)
obj->next->prev = obj->prev;
if (obj->prev)
obj->prev->next = obj->next;
obj->prev = obj->next = NULL;
}
INT32 Go_addref(PGFXOBJECT obj)
{
return ++(obj->refcnt);
}
INT32 Go_release(PGFXOBJECT obj)
{
int rc = --(obj->refcnt);
if (rc == 0)
{
if (obj->dtor)
(*(obj->dtor))(obj);
free(obj);
}
return rc;
}

43
src/gfxobj.h Executable file
View File

@ -0,0 +1,43 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __GFXOBJ_H_INCLUDED
#define __GFXOBJ_H_INCLUDED
#include "wintype.h"
/* type definition for a graphics destructor */
typedef void (*GFX_DTOR)(PVOID obj);
/* A graphics object in memory always starts with this. */
typedef struct tagGFXOBJECT {
UINT32 sig; /* signature so we know what something is */
UINT32 size; /* size of total allocated memory in block */
INT32 refcnt; /* reference count */
GFX_DTOR dtor; /* destructor function called when we're no longer needed */
struct tagGFXOBJECT *next; /* support double linked lists of obejcts */
struct tagGFXOBJECT *prev;
} GFXOBJECT, *PGFXOBJECT;
extern void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size);
extern void Go_unchain(PGFXOBJECT obj);
extern INT32 Go_addref(PGFXOBJECT obj);
extern INT32 Go_release(PGFXOBJECT obj);
#endif /* __GFXOBJ_H_INCLUDED */

59
src/gfxtype.h Executable file
View File

@ -0,0 +1,59 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __GFXTYPE_H_INCLUDED
#define __GFXTYPE_H_INCLUDED
#include "wintype.h"
typedef struct tagPOINT {
INT32 x;
INT32 y;
} POINT, *PPOINT;
typedef struct tagRECT {
INT32 left;
INT32 top;
INT32 right;
INT32 bottom;
} RECT, *PRECT;
typedef const POINT *PCPOINT;
typedef const RECT *PCRECT;
typedef UINT32 COLORREF;
typedef PUINT32 PCOLORREF;
extern BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom);
extern BOOL G_set_rect_empty(PRECT rect);
extern BOOL G_inflate_rect(PRECT rect, int dx, int dy);
extern BOOL G_offset_rect(PRECT rect, int dx, int dy);
extern BOOL G_is_rect_empty(PCRECT rect);
extern BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y);
extern BOOL G_point_in_rect(PCRECT rect, PCPOINT pt);
extern BOOL G_rect_equal(PCRECT rect1, PCRECT rect2);
extern BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2);
extern BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2);
#define RGB(r, g, b) ((((UINT32)(r)) & 0xFF) | ((((UINT32)(g)) & 0xFF) << 8) | ((((UINT32)(b)) & 0xFF) << 16))
#define GetRValue(cr) ((UINT32)((cr) & 0xFF))
#define GetGValue(cr) ((UINT32)(((cr) >> 8) & 0xFF))
#define GetBValue(cr) ((UINT32)(((cr) >> 16) & 0xFF))
#endif /* __GFXTYPE_H_INCLUDED */

111
src/gpio.c Normal file
View File

@ -0,0 +1,111 @@
/*
* 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 <stdint.h>
#include <bcm2835.h>
#include "config.h"
#include "log.h"
#include "scode.h"
#include "gpio.h"
/* GPIO lines used by various peripheral devices */
#define GLINE_BUTTON1 17
#define GLINE_BUTTON2 22
#define GLINE_BUTTON3 23
#define GLINE_BUTTON4 27
#define GLINE_BACKLIGHT 18
#define PWM_BACKLIGHT 0 /* PWM channel used for backlight */
static void do_cleanup(void)
{
/* close down the backlight lines */
bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 0);
bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_INPT);
/* close down the button lines */
bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT);
if (!bcm2835_close())
Log(LWARN, "Closing BCM2835 library failed");
}
HRESULT Gpio_setup(void)
{
HRESULT hr;
if (!bcm2835_init())
{
Log(LFATAL, "Error initializing BCM2835 library");
return E_FAIL;
}
/* configure the buttons */
bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_UP);
bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_UP);
bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_UP);
bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_UP);
bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT);
/* configure the PWM for the backlight */
bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF);
bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_ALT5);
bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2);
bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 1);
bcm2835_pwm_set_range(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX + 1);
bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_DEFAULT);
hr = Config_exitfunc(do_cleanup);
if (FAILED(hr))
do_cleanup();
return hr;
}
UINT32 Gpio_read_buttons(void)
{
UINT32 rc = 0;
if (bcm2835_gpio_lev(GLINE_BUTTON1) == LOW)
rc |= GRB_STATE_BUTTON1;
if (bcm2835_gpio_lev(GLINE_BUTTON2) == LOW)
rc |= GRB_STATE_BUTTON2;
if (bcm2835_gpio_lev(GLINE_BUTTON3) == LOW)
rc |= GRB_STATE_BUTTON3;
if (bcm2835_gpio_lev(GLINE_BUTTON4) == LOW)
rc |= GRB_STATE_BUTTON4;
return rc;
}
void Gpio_set_backlight(UINT32 level)
{
if (level > GSB_BACKLIGHT_MAX)
level = GSB_BACKLIGHT_MAX;
bcm2835_pwm_set_data(PWM_BACKLIGHT, level);
}

41
src/gpio.h Normal file
View File

@ -0,0 +1,41 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __GPIO_H_INCLUDED
#define __GPIO_H_INCLUDED
#include "wintype.h"
#define GPIO_BUTTON_COUNT 4 /* number of GPIO buttons we have */
/* state flags for the GPIO buttons */
#define GRB_STATE_BUTTON1 (1 << 0)
#define GRB_STATE_BUTTON2 (1 << 1)
#define GRB_STATE_BUTTON3 (1 << 2)
#define GRB_STATE_BUTTON4 (1 << 3)
#define GSB_BACKLIGHT_MAX 1023 /* maximum level for backlight */
#define GSB_BACKLIGHT_DEFAULT GSB_BACKLIGHT_MAX
extern HRESULT Gpio_setup(void);
extern UINT32 Gpio_read_buttons(void);
extern void Gpio_set_backlight(UINT32 level);
#endif /* __GPIO_H_INCLUDED */

52
src/log.c Normal file
View File

@ -0,0 +1,52 @@
/*
* 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 <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include "log.h"
/* string equivalents to the severity values */
static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" };
static FILE *logfile = NULL; /* log file pointer */
void Log(int level, const char *format, ...)
{
va_list argp;
struct timeval tv;
struct tm tm;
char timestamp[32];
char buf[1024];
va_start(argp, format);
vsnprintf(buf, 1024, format, argp);
va_end(argp);
gettimeofday(&tv, NULL);
localtime_r(&(tv.tv_sec), &tm);
strftime(timestamp, 32, "%F %T", &tm);
fprintf(logfile ? logfile : stdout, "%s.%06ld %s %s\n", timestamp, tv.tv_usec, severities[level], buf);
}
void Log_assert_failed(const char *test, const char *file, int line)
{
Log(LERROR, "ASSERT FAILED: %s at %s:%d", test, file, line);
}

46
src/log.h Normal file
View File

@ -0,0 +1,46 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __LOG_H_INCLUDED
#define __LOG_H_INCLUDED
/* Logging level severities */
#define LFATAL 0 /* fatal error */
#define LERROR 1 /* error */
#define LWARN 2 /* warning */
#define LINFO 3 /* information */
#define LDEBUG 4 /* debugging */
extern void Log(int level, const char *format, ...);
extern void Log_assert_failed(const char *test, const char *file, int line);
/* Current file name definitions for assert macros */
#define THIS_FILE __FILE__
#define DECLARE_THIS_FILE() static const char THIS_FILE[] = __FILE__
/* Assert macros */
#ifdef DEBUG_ASSERT
#define ASSERT(x) ((x) ? (void)0 : Log_assert_failed(#x, THIS_FILE, __LINE__))
#define VERIFY(x) ASSERT(x)
#else
#define ASSERT(x) ((void)0)
#define VERIFY(x) ((void)(x))
#endif
#endif /* __LOG_H_INCLUDED */

63
src/main.c Normal file
View File

@ -0,0 +1,63 @@
/*
* 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 <unistd.h>
#include "scode.h"
#include "log.h"
#include "config.h"
#include "gpio.h"
#include "fbinit.h"
#include "fontengine.h"
#include "time_func.h"
#include "ep_init.h"
#include "sysinput.h"
int main(int argc, char *argv[])
{
HRESULT hr;
/* initialization sequence */
Time_init();
hr = Config_setup(argc, argv);
if (FAILED(hr))
return EXIT_FAILURE;
else if (hr != S_OK)
return EXIT_SUCCESS;
if (FAILED(Fb_setup()))
return EXIT_FAILURE;
if (FAILED(FontEng_setup()))
return EXIT_FAILURE;
if (FAILED(Gpio_setup()))
return EXIT_FAILURE;
if (FAILED(Epython_setup()))
return EXIT_FAILURE;
if (FAILED(Sys_enable_input()))
return EXIT_FAILURE;
Log(LINFO, "Pausing at startup.");
sleep(2); /* wait to show off splash screen */
Fb_clear();
if (FAILED(Epython_run()))
return EXIT_FAILURE;
Log(LINFO, "Script returned with exit code %d", Sys_Exit_Code);
return Sys_Exit_Code;
}

46
src/msg.h Normal file
View File

@ -0,0 +1,46 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __MSG_H_INCLUDED
#define __MSG_H_INCLUDED
#include "wintype.h"
#define MSG_ATTRCOUNT 2
typedef struct tagMSG {
HANDLE target;
UINT32 message;
UINT_PTR attrs[MSG_ATTRCOUNT];
TIMESTAMP timestamp;
} MSG, *PMSG;
#define WM_NULL 0x0000
#define WM_QUIT 0x0001
#define WM_HWBUTTONDOWN 0x0020
#define WM_HWBUTTONUP 0x0021
#define WM_HWBUTTONCLICK 0x0022
#define WM_TOUCHDOWN 0x0030
#define WM_TOUCHMOVE 0x0031
#define WM_TOUCHUP 0x0032
#define WM_TOUCHCLICK 0x0033
#endif /* __MSG_H_INCLUDED */

123
src/msg_queue.c Normal file
View File

@ -0,0 +1,123 @@
/*
* 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 <pthread.h>
#include "wintype.h"
#include "time_func.h"
#include "msg_queue.h"
PMSG_QUEUE Mq_alloc(UINT32 nentries)
{
int sz = sizeof(MSG_QUEUE) + (nentries * sizeof(MSG));
PMSG_QUEUE rc;
rc = (PMSG_QUEUE)malloc(sz);
if (!rc)
return NULL;
memset(rc, 0, sz);
rc->startbound = &(rc->messagestore[0]);
rc->endbound = rc->startbound + nentries;
rc->head = rc->tail = rc->startbound;
rc->nentries = nentries;
pthread_mutex_init(&(rc->mutex), NULL);
return rc;
}
void Mq_destroy(PMSG_QUEUE queue)
{
pthread_mutex_destroy(&(queue->mutex));
free(queue);
}
static void post_internal(PMSG_QUEUE queue, PMSG msg)
{
PMSG nexttail;
pthread_mutex_lock(&(queue->mutex));
nexttail = queue->tail + 1;
if (nexttail == queue->endbound)
nexttail = queue->startbound;
if (nexttail != queue->head)
{
memcpy(queue->tail, msg, sizeof(MSG));
queue->tail = nexttail;
}
/* else drop the message silently */
pthread_mutex_unlock(&(queue->mutex));
}
void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs)
{
MSG tmpmsg;
memset(&tmpmsg, 0, sizeof(MSG));
tmpmsg.target = target;
tmpmsg.message = message;
if (nattrs > MSG_ATTRCOUNT)
nattrs = MSG_ATTRCOUNT;
if (nattrs > 0)
memcpy(&(tmpmsg.attrs), attrs, sizeof(UINT_PTR) * nattrs);
tmpmsg.timestamp = Time_since_start();
post_internal(queue, &tmpmsg);
}
void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2)
{
MSG tmpmsg;
memset(&tmpmsg, 0, sizeof(MSG));
tmpmsg.target = target;
tmpmsg.message = message;
tmpmsg.attrs[0] = attr1;
tmpmsg.attrs[1] = attr2;
tmpmsg.timestamp = Time_since_start();
post_internal(queue, &tmpmsg);
}
BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags)
{
BOOL rc = FALSE;
PMSG nexthead;
pthread_mutex_lock(&(queue->mutex));
if (queue->head != queue->tail)
{
nexthead = queue->head + 1;
if (nexthead == queue->endbound)
nexthead = queue->startbound;
memcpy(msg, queue->head, sizeof(MSG));
if (flags & PEEK_REMOVE)
queue->head = nexthead;
rc = TRUE;
}
pthread_mutex_unlock(&(queue->mutex));
return rc;
}
BOOL Mq_is_empty(PMSG_QUEUE queue)
{
BOOL rc;
pthread_mutex_lock(&(queue->mutex));
rc = (queue->head == queue->tail);
pthread_mutex_unlock(&(queue->mutex));
return rc;
}

53
src/msg_queue.h Normal file
View File

@ -0,0 +1,53 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __MSG_QUEUE_H_INCLUDED
#define __MSG_QUEUE_H_INCLUDED
#include <pthread.h>
#include "wintype.h"
#include "msg.h"
/* internal structure of a message queue */
typedef struct tagMSG_QUEUE {
struct tagMSG_QUEUE *next; /* allow us to be in a singly-linked list */
PMSG startbound; /* start boundary for message buffer */
PMSG endbound; /* end boundary for message buffer */
PMSG head; /* head pointer of message queue */
PMSG tail; /* tail pointer of message queue */
UINT32 nentries; /* number of entries possible in message buffer */
pthread_mutex_t mutex; /* controls access to queue from multiple threads */
MSG messagestore[0]; /* message buffer */
} MSG_QUEUE, *PMSG_QUEUE;
/* flags to Mq_peek */
#define PEEK_REMOVE 0x0001 /* remove message if found */
#define PEEK_NOREMOVE 0x0000 /* do not remove message if found */
extern PMSG_QUEUE Mq_alloc(UINT32 nentries);
extern void Mq_destroy(PMSG_QUEUE queue);
extern void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs);
extern void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2);
extern BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags);
extern BOOL Mq_is_empty(PMSG_QUEUE queue);
#define Mq_post0(q, tgt, msg) Mq_post2(q, tgt, msg, 0, 0)
#define Mq_post1(q, tgt, msg, attr) Mq_post2(q, tgt, msg, attr, 0)
#endif /* __MSG_QUEUE_H_INCLUDED */

115
src/rect.c Executable file
View File

@ -0,0 +1,115 @@
/*
* 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>
#include "log.h"
#include "gfxtype.h"
BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom)
{
rect->left = left;
rect->top = top;
rect->right = right;
rect->bottom = bottom;
return TRUE;
}
BOOL G_set_rect_empty(PRECT rect)
{
memset(rect, 0, sizeof(RECT));
return TRUE;
}
BOOL G_inflate_rect(PRECT rect, int dx, int dy)
{
rect->left += dx;
rect->top += dy;
rect->right -= dx;
rect->bottom -= dy;
return TRUE;
}
BOOL G_offset_rect(PRECT rect, int dx, int dy)
{
rect->left += dx;
rect->top += dy;
rect->right += dx;
rect->bottom += dy;
return TRUE;
}
BOOL G_is_rect_empty(PCRECT rect)
{
return (rect->right <= rect->left) || (rect->bottom <= rect->top);
}
BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y)
{
return (rect->left <= x) && (x < rect->right) && (rect->top <= y) && (y < rect->bottom);
}
BOOL G_point_in_rect(PCRECT rect, PCPOINT pt)
{
return G_coords_in_rect(rect, pt->x, pt->y);
}
BOOL G_rect_equal(PCRECT rect1, PCRECT rect2)
{
return (memcmp(rect1, rect2, sizeof(RECT)) == 0);
}
BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2)
{
if (G_is_rect_empty(src1) || G_is_rect_empty(src2))
{
memset(dest, 0, sizeof(RECT));
return FALSE;
}
if ((src1->left >= src2->right) || (src2->left >= src1->right) || (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
{
memset(dest, 0, sizeof(RECT));
return FALSE;
}
dest->left = MAX(src1->left, src2->left);
dest->top = MAX(src1->top, src2->top);
dest->right = MIN(src1->right, src2->right);
dest->bottom = MIN(src1->bottom, src2->bottom);
ASSERT(dest->left <= dest->right);
ASSERT(dest->top <= dest->bottom);
return TRUE;
}
BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2)
{
if (G_is_rect_empty(src1))
{
memcpy(dest, src2, sizeof(RECT));
return !G_is_rect_empty(src2);
}
else if (G_is_rect_empty(src2))
{
memcpy(dest, src1, sizeof(RECT));
return TRUE;
}
dest->left = MIN(src1->left, src2->left);
dest->top = MIN(src1->top, src2->top);
dest->right = MAX(src1->right, src2->right);
dest->bottom = MAX(src1->bottom, src2->bottom);
return TRUE;
}

89
src/scode.h Normal file
View File

@ -0,0 +1,89 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __SCODE_H_INCLUDED
#define __SCODE_H_INCLUDED
#include "wintype.h"
/*-------------------------------------------------------------------
* Status codes are defined as follows:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |S| Facility | Code |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 9 8 7 6 5 4 3 2 1 0
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
*
* S = Severity: 0 = success, 1 = error
* Facility = Facility code
* Code = Specific error code
*-------------------------------------------------------------------
*/
/* Severity codes */
#define SEVERITY_SUCCESS 0x00000000
#define SEVERITY_ERROR 0x80000000
/* Facility codes - compatible with M$ */
#define FACILITY_NULL 0
#define FACILITY_RPC 1
#define FACILITY_STORAGE 3
#define FACILITY_ITF 4
#define FACILITY_UNIX 5
#define FACILITY_UPIWIN 6
#define SUCCEEDED(s) (((s) & SEVERITY_ERROR) == 0)
#define FAILED(s) (((s) & SEVERITY_ERROR) != 0)
#define SCODE_FACILITY(s) (((s) >> 16) & 0x7FFF)
#define SCODE_CODE(s) ((s) & 0xFFFF)
#define MAKE_SCODE(sev, fac, err) ((SCODE)((sev) | (((fac) & 0x7FFF) << 16) | ((err) & 0xFFFF)))
#define SCODE_FROM_ERRNO(x) MAKE_SCODE(SEVERITY_ERROR, FACILITY_UNIX, (x))
#define ERRNO_AS_SCODE SCODE_FROM_ERRNO(errno)
#define SCODE_CAST(x) ((SCODE)(x))
/* Basic success codes */
#define S_OK SCODE_CAST(0x00000000) /* OK return */
#define S_FALSE SCODE_CAST(0x00000001) /* "False" return */
/* Basic error codes */
#define E_NOTIMPL SCODE_CAST(0x80000001) /* not implemented */
#define E_OUTOFMEMORY SCODE_CAST(0x80000002) /* out of memory */
#define E_INVALIDARG SCODE_CAST(0x80000003) /* invalid argument */
#define E_NOINTERFACE SCODE_CAST(0x80000004) /* no such interface */
#define E_POINTER SCODE_CAST(0x80000005) /* invalid pointer */
#define E_HANDLE SCODE_CAST(0x80000006) /* invalid handle */
#define E_ABORT SCODE_CAST(0x80000007) /* aborted operation */
#define E_FAIL SCODE_CAST(0x80000008) /* unspecified failure */
#define E_ACCESSDENIED SCODE_CAST(0x80000009) /* access denied */
#define E_PENDING SCODE_CAST(0x8000000A) /* data not yet available */
#define E_BOUNDS SCODE_CAST(0x8000000B) /* access outside valid range */
#define E_CHANGED_STATE SCODE_CAST(0x8000000C) /* object changed state, result now invalid */
#define E_ILLEGAL_STATE_CHANGE SCODE_CAST(0x8000000D) /* illegal state change */
#define E_ILLEGAL_METHOD_CALL SCODE_CAST(0x8000000E) /* illegal method call */
#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */
/* UPIWIN-specific errorcodes */
#define UPIWIN_E_INVALIDSCRIPT SCODE_CAST(0x80060000) /* invalid script file */
#define UPIWIN_E_NOSCRIPT SCODE_CAST(0x80060001) /* no script specified */
#endif /* __SCODE_H_INCLUDED */

75
src/stockobj.c Executable file
View File

@ -0,0 +1,75 @@
/*
* 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 <stddef.h>
#include <string.h>
#include "wintype.h"
#include "bitmap.h"
/* references to the icon data */
extern uint8_t _binary_i_freehand_bin_start[];
extern uint8_t _binary_i_freehand_bin_end;
extern uint8_t _binary_i_freehand_bin_size;
extern uint8_t _binary_i_line_bin_start[];
extern uint8_t _binary_i_line_bin_end;
extern uint8_t _binary_i_line_bin_size;
extern uint8_t _binary_i_rect_bin_start[];
extern uint8_t _binary_i_rect_bin_end;
extern uint8_t _binary_i_rect_bin_size;
extern uint8_t _binary_i_fillrect_bin_start[];
extern uint8_t _binary_i_fillrect_bin_end;
extern uint8_t _binary_i_fillrect_bin_size;
extern uint8_t _binary_i_undo_bin_start[];
extern uint8_t _binary_i_undo_bin_end;
extern uint8_t _binary_i_undo_bin_size;
extern uint8_t _binary_i_clear_bin_start[];
extern uint8_t _binary_i_clear_bin_end;
extern uint8_t _binary_i_clear_bin_size;
typedef struct tagSTOCKBITMAPDESC {
PCSTR name;
INT32 width;
INT32 height;
const void *data;
} STOCKBITMAPDESC;
static const STOCKBITMAPDESC stock_bitmaps[] = {
{"freehand", 48, 48, _binary_i_freehand_bin_start },
{"line", 48, 48, _binary_i_line_bin_start },
{"rect", 48, 48, _binary_i_rect_bin_start },
{"fillrect", 48, 48, _binary_i_fillrect_bin_start },
{"undo", 48, 48, _binary_i_undo_bin_start },
{"clear", 48, 48, _binary_i_clear_bin_start },
{NULL, 0, 0, NULL }
};
PBITMAP _BMP_GetStock(PCSTR name)
{
INT32 i;
for (i = 0; stock_bitmaps[i].name; ++i)
if (strcmp(name, stock_bitmaps[i].name) == 0)
return BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data);
return NULL;
}

255
src/sysinput.c Normal file
View File

@ -0,0 +1,255 @@
/*
* 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 <stddef.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <linux/input.h>
#include "scode.h"
#include "config.h"
#include "log.h"
#include "msg_queue.h"
#include "gpio.h"
#include "fbinit.h"
#include "time_func.h"
#define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */
PMSG_QUEUE Sys_Queue = NULL; /* system message queue */
INT32 Sys_Exit_Code = -1; /* system exit code, set on WM_QUIT */
static int ts_fd = 0; /* file descriptor for touchscreen */
static pthread_t ithread; /* input thread handle */
static volatile sig_atomic_t running = 1; /* "running" flag for input thread */
static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER; /* mutex for waiting on input */
static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for waiting on input */
/* Local data for poll_buttons() */
static UINT32 last_bstate = 0; /* previous button state */
static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */
static TIMESTAMP button_down_time[GPIO_BUTTON_COUNT]; /* timestamps for click detection */
/* Local data for poll_touchscreen() */
static UINT_PTR touch_x = 0; /* X coordinate to send with next message */
static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */
static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */
static UINT_PTR touch_down_x, touch_down_y; /* location of the touch-down event for click detection */
static TIMESTAMP touch_down_time; /* timestamp for click detection */
static BOOL poll_buttons(void)
{
BOOL posted = FALSE;
UINT32 st, down, up, mask;
UINT_PTR attr;
TIMESTAMP now;
/* poll hardware buttons */
st = Gpio_read_buttons();
if (st != last_bstate)
{
now = Time_since_start();
up = last_bstate & ~st;
down = st & ~last_bstate;
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
{
if (now < button_event_ok[attr - 1])
continue; /* this is a "contact bounce" event, don't bother */
if (up & mask)
{
/* reset contact bounce timer - only seems to happen after button releases */
button_event_ok[attr - 1] = now + Gconfig.button_debounce;
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
if ((now - button_down_time[attr - 1]) <= Gconfig.click_time)
Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr);
posted = TRUE;
}
else if (down & mask)
{
Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr);
button_down_time[attr - 1] = now;
posted = TRUE;
}
}
last_bstate = st;
}
return posted;
}
static BOOL poll_touchscreen(void)
{
BOOL posted = FALSE;
int nb, nev, xerrno, i;
TIMESTAMP now;
struct input_event buffer[INPUT_EVENT_BATCH];
nb = read(ts_fd, buffer, INPUT_EVENT_BATCH * sizeof(struct input_event));
if (nb == -1)
{
xerrno = errno;
if ((xerrno != EAGAIN) && (xerrno != EWOULDBLOCK))
Log(LERROR, "Error reading from touchscreen device (%d)", xerrno);
return FALSE;
}
else if (nb == 0)
{
Log(LERROR, "Unexpected end of file reading from touchscreen device");
return FALSE;
}
nev = nb / sizeof(struct input_event);
xerrno = nev * sizeof(struct input_event);
if (nb > xerrno)
Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno);
for (i=0; i<nev; i++)
{
switch (buffer[i].type)
{
case EV_SYN:
if (buffer[i].code == SYN_REPORT)
{
now = Time_since_start();
Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y);
if (touch_nextmsg == WM_TOUCHDOWN)
{
touch_down_x = touch_x;
touch_down_y = touch_y;
touch_down_time = now;
}
else if (touch_nextmsg == WM_TOUCHUP)
{
if ( ((now - touch_down_time) <= Gconfig.click_time)
&& (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius)
&& (ABS((INT32)touch_y - (INT32)touch_down_y) <= Gconfig.click_radius))
Mq_post2(Sys_Queue, 0, WM_TOUCHCLICK, touch_x, touch_y);
}
touch_nextmsg = WM_TOUCHMOVE;
posted = TRUE;
}
break;
case EV_ABS:
/* Note that the touchscreen driver assumes the screen is "vertical," so swap the x and y axes */
/* Also it thinks origin is lower left with up = +y */
if (buffer[i].code == ABS_X)
touch_y = Fb_Info->height - buffer[i].value;
else if (buffer[i].code == ABS_Y)
touch_x = buffer[i].value;
break;
case EV_KEY:
if (buffer[i].code == BTN_TOUCH)
touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
break;
default:
break;
}
}
return posted;
}
static void *input_thread(void *arg)
{
BOOL gotinput;
/* clear all state at startup */
last_bstate = 0;
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
touch_x = touch_y = 0;
touch_nextmsg = WM_TOUCHMOVE;
while (running)
{
gotinput = poll_buttons();
gotinput = poll_touchscreen() || gotinput;
if (gotinput)
{
pthread_mutex_lock(&wait_mutex);
pthread_cond_signal(&wait_cond);
pthread_mutex_unlock(&wait_mutex);
}
}
return NULL;
}
static void do_disable_input(void)
{
running = 0;
pthread_join(ithread, NULL);
close(ts_fd);
ts_fd = -1;
Mq_destroy(Sys_Queue);
Sys_Queue = NULL;
}
HRESULT Sys_enable_input(void)
{
HRESULT rc = S_OK;
int threadrc;
Sys_Queue = Mq_alloc(Gconfig.sys_mq_length);
if (!Sys_Queue)
{
Log(LFATAL, "Unable to allocate system message queue.");
return E_OUTOFMEMORY;
}
ts_fd = open(Gconfig.touchscreen_device, O_RDONLY|O_NONBLOCK);
if (ts_fd < 0)
{
rc = ERRNO_AS_SCODE;
Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc);
goto error_0;
}
running = 1;
threadrc = pthread_create(&ithread, NULL, input_thread, NULL);
if (threadrc != 0)
{
rc = SCODE_FROM_ERRNO(threadrc);
Log(LFATAL, "Unable to start system input thread (%08X).", rc);
goto error_1;
}
rc = Config_exitfunc(do_disable_input);
if (FAILED(rc))
do_disable_input();
return rc;
error_1:
close(ts_fd);
ts_fd = -1;
error_0:
Mq_destroy(Sys_Queue);
return rc;
}
void Sys_wait_for_input(void)
{
pthread_mutex_lock(&wait_mutex);
while (Mq_is_empty(Sys_Queue))
pthread_cond_wait(&wait_cond, &wait_mutex);
pthread_mutex_unlock(&wait_mutex);
}

32
src/sysinput.h Normal file
View File

@ -0,0 +1,32 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __SYSINPUT_H_INCLUDED
#define __SYSINPUT_H_INCLUDED
#include "wintype.h"
#include "msg_queue.h"
extern PMSG_QUEUE Sys_Queue;
extern INT32 Sys_Exit_Code;
extern HRESULT Sys_enable_input(void);
extern void Sys_wait_for_input(void);
#endif /* __SYSINPUT_H_INCLUDED */

44
src/time_func.c Normal file
View File

@ -0,0 +1,44 @@
/*
* 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 <stddef.h>
#include <sys/time.h>
#include "time_func.h"
static TIMESTAMP start_timestamp = 0; /* time since epoch at start of run */
TIMESTAMP Time_since_epoch(void)
{
TIMESTAMP rc;
struct timeval tv;
gettimeofday(&tv, NULL);
rc = (tv.tv_sec * (TIMESTAMP)1000) + (tv.tv_usec / (TIMESTAMP)1000);
return rc;
}
TIMESTAMP Time_since_start(void)
{
return Time_since_epoch() - start_timestamp;
}
void Time_init(void)
{
start_timestamp = Time_since_epoch();
}

29
src/time_func.h Normal file
View File

@ -0,0 +1,29 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __TIMEFUNC_H_INCLUDED
#define __TIMEFUNC_H_INCLUDED
#include "wintype.h"
extern TIMESTAMP Time_since_epoch(void);
extern TIMESTAMP Time_since_start(void);
extern void Time_init(void);
#endif /* __TIMEFUNC_H_INCLUDED */

175
src/wintype.h Normal file
View File

@ -0,0 +1,175 @@
/*
* UPIWIN - Micro Pi Windowing Framework Kernel
* Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*-------------------------------------------------------------------------
*/
#ifndef __WINTYPE_H_INCLUDED
#define __WINTYPE_H_INCLUDED
#include <stdint.h>
/* Integral limit values */
/*#define INT16_MIN 0x8000 - defined in stdint.h */
/*#define INT16_MAX 0x7FFF - defined in stdint.h */
#define UINT16_MIN 0
/*#define UINT16_MAX 0xFFFF - defined in stdint.h*/
/*#define INT32_MIN 0x80000000 - defined in stdint.h*/
/*#define INT32_MAX 0x7FFFFFFF - defined in stdint.h*/
#define UINT32_MIN 0
/*#define UINT32_MAX 0xFFFFFFFF - defined in stdint.h*/
/*#define INT64_MIN 0x8000000000000000 - defined in stdint.h*/
/*#define INT64_MAX 0x7FFFFFFFFFFFFFFF - defined in stdint.h*/
#define UINT64_MIN 0
/*#define UINT64_MAX 0xFFFFFFFFFFFFFFFF - defined in stdint.h*/
#define INT_PTR_MIN INTPTR_MIN
#define INT_PTR_MAX INTPTR_MAX
#define UINT_PTR_MIN 0
#define UINT_PTR_MAX UINTPTR_MAX
#define DWORD_MIN UINT32_MIN
#define DWORD_MAX UINT32_MAX
/* Number of bits */
#define INT16_BITS 16
#define UINT16_BITS 16
#define INT32_BITS 32
#define UINT32_BITS 32
#define INT64_BITS 64
#define UINT64_BITS 64
#define LOG_PTRSIZE 2 /* log2(sizeof(void *)) */
#define LOG_INTSIZE 2 /* log2(sizeof(int)) */
#define LOG_UINTSIZE 2 /* log2(sizeof(UINT32)) */
#define LOG_INT64SIZE 3 /* log2(sizeof(long long)) */
#define PTRSIZE (1U << LOG_PTRSIZE)
#define PTR_MASK (PTRSIZE - 1)
#define PTR_CEILING(a) (((a) + PTR_MASK) & ~PTR_MASK)
/* Boolean values */
#define TRUE 1
#define FALSE 0
/* NULL value */
#ifndef NULL
#define NULL 0
#endif
/* Integral types */
typedef int16_t INT16;
typedef uint16_t UINT16;
typedef int32_t INT32;
typedef uint32_t UINT32;
typedef int64_t INT64;
typedef uint64_t UINT64;
typedef UINT16 WORD;
typedef UINT32 DWORD;
typedef UINT64 QWORD;
typedef INT32 LONG;
typedef UINT32 ULONG;
typedef INT64 LONG64;
typedef UINT64 ULONG64;
typedef INT32 INT;
typedef UINT32 UINT;
typedef INT64 LONGLONG;
typedef UINT64 ULONGLONG;
typedef intptr_t INT_PTR;
typedef uintptr_t UINT_PTR;
typedef UINT_PTR SIZE_T;
typedef INT_PTR SSIZE_T;
/* Base pointer types */
typedef INT16 *PINT16;
typedef UINT16 *PUINT16;
typedef INT32 *PINT32;
typedef UINT32 *PUINT32;
typedef INT64 *PINT64;
typedef UINT64 *PUINT64;
typedef SIZE_T *PSIZE_T;
typedef void *PVOID;
typedef const void *PCVOID;
typedef WORD *PWORD;
typedef DWORD *PDWORD;
typedef QWORD *PQWORD;
typedef LONGLONG *PLONGLONG;
typedef ULONGLONG *PULONGLONG;
/* Pointer-to-pointer types */
typedef PVOID *PPVOID;
/* Character types */
typedef char CHAR;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
typedef uint16_t WCHAR;
typedef CHAR *PCHAR;
typedef const CHAR *PCCHAR;
typedef UCHAR *PUCHAR;
typedef BYTE *PBYTE;
typedef const BYTE *PCBYTE;
typedef WCHAR *PWCHAR;
typedef const WCHAR *PCWCHAR;
typedef PCCHAR *PPCCHAR;
typedef CHAR *PSTR;
typedef const CHAR *PCSTR;
typedef WCHAR *PWSTR;
typedef const WCHAR *PCWSTR;
typedef PCSTR *PPCSTR;
/* Boolean type */
typedef int BOOL;
/* Handle type */
typedef UINT_PTR HANDLE;
typedef HANDLE *PHANDLE;
/* Status code/result types */
typedef UINT32 SCODE;
typedef SCODE *PSCODE;
typedef SCODE HRESULT;
typedef UINT64 TIMESTAMP;
#define MAKEBOOL(val) ((val) ? TRUE : FALSE)
#define OFFSETOF(struc, field) ((UINT_PTR)(&(((struc *)0)->field)))
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
#define ABS(v) ((v) < 0 ? -(v) : (v))
#define MAKEWORD(a, b) ((WORD)((((UINT_PTR)(a)) & 0xFF) | ((((UINT_PTR)(b)) & 0xFF) << 8)))
#define MAKELONG(a, b) ((LONG)((((UINT_PTR)(a)) & 0xFFFF) | ((((UINT_PTR)(b)) & 0xFFFF) << 16)))
#define MAKELONG64(a, b) ((LONG64)((((UINT64)(a)) & 0xFFFFFFFF) | ((((UINT64)(b)) & 0xFFFFFFFF) << 32)))
#define LODWORD(l) ((DWORD)(((UINT64)(l)) & 0xFFFFFFFF))
#define HIDWORD(l) ((DWORD)((((UINT64)(l)) >> 32) & 0xFFFFFFFF))
#define LOWORD(l) ((WORD)(((UINT_PTR)(l)) & 0xFFFF))
#define HIWORD(l) ((WORD)((((UINT_PTR)(l)) >> 16) & 0xFFFF))
#define LOBYTE(w) ((BYTE)(((UINT_PTR)(w)) & 0xFF))
#define HIBYTE(w) ((BYTE)((((UINT_PTR)(w)) >> 8) & 0xFF))
#endif /* __WINTYPE_H_INCLUDED */