Merge branch 'release-0.1' - Release 0.1
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
*~
|
||||
*.o
|
||||
src/upiwin
|
||||
src/splash.bin
|
||||
buildutils/mksplash
|
57
CODE-OF-CONDUCT.md
Executable 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 you’re a Social
|
||||
Justice Warrior trying to join this project to spread your *bullshit,* you are *automatically
|
||||
declared an asshole.* And you’re *gone.*
|
||||
5. The Owner reserves the right to change this Code of Conduct as they see fit. If, however, you try
|
||||
to force the Owner to change it in ways that are *offensive to them,* or that try to advance
|
||||
“social justice” ideals in any way, shape, or form, you’re an *asshole.* And you’re *gone.*
|
||||
6. In particular, this project explicitly *rejects* the “Open Code of Conduct” by the TODO Group,
|
||||
the “Contributor Code of Merit” by Coraline Ada Ehmke, the “Citizen Code of Conduct” by
|
||||
Stumptown Syndicate, and any similar “codes of conduct” that may be promulgated. Anyone complaining
|
||||
about this is an *asshole,* because *who the fuck are you* to tell *the Owner* how *they* should
|
||||
run *their* goddamn project? And you’re *gone.*
|
||||
7. The *one and only* criterion that will be used to determine whether a contribution to this project
|
||||
will be accepted is *the quality of the contribution and how well it solves the problem it was
|
||||
contributed to solve.* **Period.** (“Contribution” may include code, documentation, testing, or fundraising.)
|
||||
8. The *one and only* criterion that will be used to judge your worth in relation to this project is
|
||||
*the quality of your contributions (as defined above) to this project.* **Period.**
|
||||
9. The Owner hereby does not give *one milli-micro-nano-fraction of a* **fuck** what race you are,
|
||||
what gender you are or identify as, who you want to sleep with, how old you are, what your height or
|
||||
weight is, what if anything may be different about your body or brain, what language you speak,
|
||||
what country you’re from, what God you pray to, where you work, how much money you have,
|
||||
et fucking cetera. Is your contribution any *good?* That’s all that matters.
|
||||
10. If your contribution is not accepted, and you start *whining* about how it’s “actually” because you’re
|
||||
of some-or-other gender/race/religion/nationality/whatthefuckever, you are attempting to have the deck
|
||||
stacked in your favor because you’re “special.” That makes you an *asshole.* And you’re *gone.*
|
||||
11. Only those people who have contributed a sufficient quantity of good work to the project,
|
||||
*as determined in the Owner's sole discretion,* will be allowed to assume any board position,
|
||||
administrative position, or management-related role. And, any position that the Owner gives, they can
|
||||
also *take away,* for any reason. Anyone who complains about this is an *asshole.* And they’re *gone.*
|
||||
12. You will do your own work. If you try to pass off the work of others as your own, you’re a
|
||||
fucking *plagiarist,* and also an *asshole.* And you’re *gone.*
|
||||
13. If there’s a discussion that cannot be resolved within the scope of the project,
|
||||
*take that shit somewhere else.* The Owner does not want your bullshit here. If you continue to spread
|
||||
your bullshit here, you’re an *asshole.* And you’re *gone.*
|
||||
14. As noted above, the Owner's decisions about any aspect of the project are *final.* Anyone
|
||||
*pissing the Owner off* by getting all up in their face about said decisions is an *asshole.*
|
||||
And they’re *gone.*
|
||||
15. Any advisory boards, committees, etc., having to do with this project will answer to *the Owner.*
|
||||
The Owner reserves the right to disband any such whenever the hell they feel like it. As always, anyone
|
||||
complaining about this is an *asshole.* And they’re *gone.*
|
||||
16. Anyone who does not approve of the objectives, direction, or attitude of this project is
|
||||
free to *get the fuck out* at any time. Bye Felicia!
|
||||
|
||||
Acknowlegements:
|
||||
- [Why Hackers Must Eject the SJWs](http://esr.ibiblio.org/?p=6918), Eric S. Raymond
|
||||
- [OSS Code of Merit](http://voxday.blogspot.com/2016/01/code-of-merit.html), Vox Day
|
||||
- [A contribution policy for open source that works](https://medium.com/@jmaynard/a-contribution-policy-for-open-source-that-works-bfc4600c9d83#.dslxcx1fc), Jay Maynard
|
||||
- [The Code of Merit](https://github.com/rosarior/Code-of-Merit/blob/master/CODE_OF_MERIT.md), Roberto Rosario
|
336
LICENSE.md
Executable 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
|
@ -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
|
17
README.md
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
After Width: | Height: | Size: 3.8 KiB |
BIN
resources/i_fillrect.png
Executable file
After Width: | Height: | Size: 672 B |
BIN
resources/i_freehand.png
Executable file
After Width: | Height: | Size: 813 B |
BIN
resources/i_line.png
Executable file
After Width: | Height: | Size: 783 B |
BIN
resources/i_rect.png
Executable file
After Width: | Height: | Size: 666 B |
BIN
resources/i_undo.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
resources/splash-erbosoft.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
resources/splash-vmwcblk.png
Executable file
After Width: | Height: | Size: 7.9 KiB |
293
scripts/demo1.py
Executable 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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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 */
|