Compare commits
11 Commits
master
...
758af85d84
| Author | SHA1 | Date | |
|---|---|---|---|
| 758af85d84 | |||
| 6b62d0e4f1 | |||
| 2cdc0a3dcc | |||
| 71e9a4ff4e | |||
| e15bd3ab90 | |||
| f436cf9200 | |||
| e536685f56 | |||
| d8c38cd08a | |||
| a0993bceca | |||
|
|
79a777b22d | ||
|
|
d9f5d7f282 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,7 @@
|
||||
*.o
|
||||
src/upiwin
|
||||
src/splash.bin
|
||||
src/i_*.bin
|
||||
buildutils/mksplash
|
||||
buildutils/mkgfx
|
||||
output/
|
||||
|
||||
40
CODE-OF-CONDUCT.md
Normal file → Executable file
40
CODE-OF-CONDUCT.md
Normal file → Executable file
@@ -1,8 +1,6 @@
|
||||
# The Erbosoft Project Code of Conduct
|
||||
## (Revised December 2019)
|
||||
|
||||
_This document may be redistributed freely in its unmodified form by anyone. The only part which may be freely modified is the designation of the Owner in the following sentence, which should be changed to reflect the ownership of the project this Code of Conduct is being applied to._
|
||||
|
||||
For the purposes of this project, the Owner is Amy G. Bowersox/Erbosoft Metaverse Design Solutions.
|
||||
|
||||
1. *The Owner owns this project.* Not you. The Owner's decisions about any aspect of the project
|
||||
@@ -10,45 +8,45 @@ are *final.*
|
||||
2. This Code of Conduct contains harsh language. Tough shit. Suck it up, Buttercup.
|
||||
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
|
||||
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.*
|
||||
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
|
||||
"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.*
|
||||
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.)
|
||||
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
|
||||
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.*
|
||||
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,
|
||||
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.*
|
||||
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.*
|
||||
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.*
|
||||
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!
|
||||
|
||||
|
||||
18
LICENSE.md
18
LICENSE.md
@@ -2,7 +2,7 @@ GNU General Public License
|
||||
==========================
|
||||
|
||||
_Version 2, June 1991_
|
||||
_Copyright © 1989, 1991 Free Software Foundation, Inc.,_
|
||||
_Copyright © 1989, 1991 Free Software Foundation, Inc.,_
|
||||
_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@@ -62,13 +62,13 @@ modification follow.
|
||||
|
||||
**0.** This License applies to any program or other work which contains
|
||||
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”
|
||||
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”.
|
||||
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
|
||||
@@ -237,8 +237,8 @@ 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
|
||||
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
|
||||
@@ -257,7 +257,7 @@ of promoting the sharing and reuse of software generally.
|
||||
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
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
|
||||
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
|
||||
@@ -285,7 +285,7 @@ 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.
|
||||
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>
|
||||
@@ -320,7 +320,7 @@ 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
|
||||
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
|
||||
|
||||
7
Makefile
7
Makefile
@@ -18,7 +18,14 @@
|
||||
all:
|
||||
make -C buildutils all
|
||||
make -C src all
|
||||
make output
|
||||
|
||||
output:
|
||||
mkdir -p output
|
||||
cp src/upiwin output
|
||||
cp scripts/*.py output
|
||||
|
||||
clean:
|
||||
-rm -rf output
|
||||
make -C buildutils clean
|
||||
make -C src clean
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
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
|
||||
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)
|
||||
- Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423). See
|
||||
[Building the Hardware to Run UPIWIN](docs/hardware-instructions.md) to assemble the hardware, and
|
||||
[Preparing the Operating System for UPIWIN](docs/os-instructions.md) for the system software.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -257,34 +257,34 @@ int do_convert(const char *infilename, const char *outfilename)
|
||||
{
|
||||
if (image_channels == 3)
|
||||
{
|
||||
bred = *src++;
|
||||
bgreen = *src++;
|
||||
bblue = *src++;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
@@ -292,10 +292,10 @@ int do_convert(const char *infilename, const char *outfilename)
|
||||
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);
|
||||
fprintf(stderr, "%s: error writing image data\n", outfilename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
docs/UPIWIN-report.odt
Executable file
BIN
docs/UPIWIN-report.odt
Executable file
Binary file not shown.
BIN
docs/complete.jpg
Normal file
BIN
docs/complete.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
37
docs/hardware-instructions.md
Normal file
37
docs/hardware-instructions.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Building the Hardware to Run UPIWIN
|
||||
|
||||
UPIWIN is designed for a hardware configuration with a miniature capacitive-touch touchscreen mounted on a
|
||||
Raspberry Pi computer, making for a compact assembly. This document describes how to assemble one.
|
||||
|
||||
## Parts List
|
||||
|
||||
- Raspberry Pi 3 Model B+ computer
|
||||
- PiTFT Plus 320x240 2.8" Capacitive Touch Touchscreen (Adafruit part number 2423)
|
||||
- Pi Model B+/Pi 2 Case Base - Clear (Adafruit part number 2253)
|
||||
- PiTFT Faceplate and Buttons (Adafruit part number 2807)
|
||||
- 2x Brass M2.5 Standoffs (Adafruit part number 2337)
|
||||
- Additional Raspberry Pi hardware (MicroSD card, power supply, keyboard and display connections)
|
||||
|
||||
## Assembly Instructions
|
||||
|
||||
1. On the back of the PiTFT, solder closed the jumper pads labeled "#18". This will allow the use of GPIO line 18 as
|
||||
a PWM backlight control.
|
||||
2. Attach two standoffs to the underside of the PiTFT (pointing in the same direction as the 40-pin connector), on the
|
||||
right side (the side with the pushbutton switches). Secure with the included nuts.
|
||||
3. Attach the PiTFT to the Raspberry Pi, pressing down hard to seat the 40-pin connector atop the Pi's GPIO pins.
|
||||
4. Seat the completed assembly inside the case base, lining up the holes for the USB and Ethernet ports on the left
|
||||
side. Press down to snap the latches into place.
|
||||
5. Holding the faceplate upside down, insert four plastic buttons into the four small rectangular slots. Invert the
|
||||
case assembly and snap it together with the faceplate, lining the buttons up with the pushbutton switches.
|
||||
6. Connect the Pi to keyboard, display, power, and network (if necessary). Insert the MicroSD card with the operating
|
||||
system installed, and boot as usual.
|
||||
|
||||
## Illustrations
|
||||
|
||||
### Completed subassembly
|
||||
|
||||

|
||||
|
||||
### Completed Assembly
|
||||
|
||||

|
||||
64
docs/os-instructions.md
Normal file
64
docs/os-instructions.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Preparing the Operating System for UPIWIN
|
||||
|
||||
The Raspberry Pi OS needs to be configured with the appropriate device tree support, software, and libraries to compile
|
||||
and run UPIWIN successfully. This document describes the process.
|
||||
|
||||
## Preparing the Operating System
|
||||
|
||||
1. Download an image of Raspberry Pi OS from
|
||||
[the Raspberry Pi Foundation](https://downloads.raspberrypi.org/raspios_armhf/images/). The most-recent version of
|
||||
Raspberry Pi OS that is known to work with the PiTFT is
|
||||
[the December 4, 2020 image](https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2020-12-04/).
|
||||
2. Unzip the `.zip` file for your image and write th included `.img` file to a fresh MicroSD card using one of the
|
||||
methods described on [this page](https://www.raspberrypi.org/documentation/computers/getting-started.html).
|
||||
3. Connect your UPIWIN-compatible Raspberry Pi (RPi 3B+ with PiTFT) to power, HDMI display, keyboard, and network
|
||||
(if necessary). Insert the freshly-written MicroSD card into the Pi.
|
||||
4. Turn on the Pi, boot into Raspberry Pi OS, and set it up. Make sure to get updates installed.
|
||||
|
||||
## Installing the PiTFT Drivers
|
||||
|
||||
1. In a terminal window, enter the command `sudo -i` to get a root command prompt.
|
||||
2. Enter the following commands:
|
||||
|
||||
pip3 install --upgrade adafruit-python-shell click
|
||||
git clone https://github.com/adafruit/Raspberry-Pi-Installer-Scripts.git
|
||||
cd Raspberry-Pi-Installer-Scripts
|
||||
python3 adafruit-pitft.py --display=28c --rotation=90
|
||||
|
||||
3. Answer "N" to the questions about the console appearing on the PiTFT display and mirroring HDMI to the PiTFT
|
||||
display.
|
||||
4. Reboot the Pi when prompted.
|
||||
|
||||
## Installing Libraries for UPIWIN
|
||||
|
||||
1. Use `sudo -i` to get a root command prompt.
|
||||
2. Execute the command to install packaged libraries:
|
||||
|
||||
apt install python3-dev libfreetype6-dev libpng-dev ttf-mscorefonts-installer
|
||||
|
||||
3. Execute the commands to install the BCM2835 library:
|
||||
|
||||
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz
|
||||
tar xzvf bcm2835-1.68.tar.gz
|
||||
cd bcm2835-1.68
|
||||
./configure
|
||||
make
|
||||
make check
|
||||
make install
|
||||
|
||||
4. Copy the Arial font to where the code expects to see it:
|
||||
|
||||
mkdir /usr/local/share/fonts/truetype
|
||||
cp /usr/share/fonts/truetype/msttcorefonts/arial.ttf /usr/local/share/fonts/truetype
|
||||
|
||||
## Building the Source
|
||||
|
||||
After cloning the repository for UPIWIN, enter the following commands:
|
||||
|
||||
cd upiwin
|
||||
make
|
||||
|
||||
The resulting executable and demo scripts will be placed into the `output` directory.
|
||||
|
||||
To execute, change to the `output` directory and enter the command `sudo ./upiwin` followed by the name of the script
|
||||
to be run. For example, `sudo ./upiwin demo1.py`.
|
||||
BIN
docs/subassembly.jpg
Normal file
BIN
docs/subassembly.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
12
src/Makefile
12
src/Makefile
@@ -17,12 +17,12 @@
|
||||
# ------------------------------------------------------------------------
|
||||
BUILDUTILS=../buildutils
|
||||
RESOURCES=../resources
|
||||
SPLASHSCREEN=splash-vmwcblk.png
|
||||
SPLASHSCREEN=splash-erbosoft.png
|
||||
|
||||
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \
|
||||
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
|
||||
i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.o splash.o sysresources.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
|
||||
@@ -37,6 +37,14 @@ upiwin: $(OBJS)
|
||||
.c.o:
|
||||
gcc -c $(CFLAGS) $<
|
||||
|
||||
sysresources.o: sysresources.zip
|
||||
objcopy -I binary -O elf32-littlearm -B arm --rename-section \
|
||||
.data=.rodata,alloc,load,readonly,data,contents sysresources.zip sysresources.o
|
||||
|
||||
sysresources.zip: splash.bin
|
||||
-rm sysresources.zip
|
||||
zip sysresources.zip splash.bin
|
||||
|
||||
%.o: %.bin
|
||||
objcopy -I binary -O elf32-littlearm -B arm --rename-section \
|
||||
.data=.rodata,alloc,load,readonly,data,contents $< $@
|
||||
|
||||
68
src/config.c
68
src/config.c
@@ -109,36 +109,36 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c);
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
if (help)
|
||||
@@ -167,17 +167,17 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
|
||||
pargs = (PPCSTR)malloc(sizeof(PCSTR) * parsed->script_arg_count);
|
||||
if (!pargs)
|
||||
{
|
||||
Log(LERROR, "Out of memory in parse_cmdline");
|
||||
return E_OUTOFMEMORY;
|
||||
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;
|
||||
}
|
||||
pargs[c] = strdup(argv[optind++]);
|
||||
if (!(pargs[c]))
|
||||
{
|
||||
Log(LERROR, "Out of memory in parse_cmdline");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
parsed->script_args = pargs;
|
||||
}
|
||||
@@ -210,8 +210,8 @@ HRESULT Config_setup(int argc, char *argv[])
|
||||
|
||||
if (geteuid() != 0)
|
||||
{
|
||||
Log(LFATAL, "upiwin must be run with root privileges");
|
||||
return E_ACCESSDENIED;
|
||||
Log(LFATAL, "upiwin must be run with root privileges");
|
||||
return E_ACCESSDENIED;
|
||||
}
|
||||
|
||||
if (atexit(run_exit_funcs))
|
||||
|
||||
196
src/dc_screen.c
196
src/dc_screen.c
@@ -41,42 +41,42 @@ inline static COLORREF COLORREF_from_native(UINT16 cr)
|
||||
return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800));
|
||||
}
|
||||
|
||||
static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen)
|
||||
inline static UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
case R2_MERGEPENNOT:
|
||||
return (~disp) | pen;
|
||||
case R2_MERGEPEN:
|
||||
return disp | pen;
|
||||
case R2_WHITE:
|
||||
return (UINT16)(-1);
|
||||
}
|
||||
return pen; /* last ditch default */
|
||||
}
|
||||
@@ -113,62 +113,62 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
|
||||
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;
|
||||
}
|
||||
}
|
||||
{
|
||||
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;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -184,12 +184,12 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32
|
||||
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;
|
||||
for (x = rect->left; x < rect->right; x++)
|
||||
{
|
||||
*p = apply_rop2(op, *p, pencolor);
|
||||
++p;
|
||||
}
|
||||
ps += priv->pix_per_row;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -219,17 +219,17 @@ static PDCTXT screen_create_compat(PVOID privdata)
|
||||
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;
|
||||
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));
|
||||
Go_release(&(pbmp->hdr));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32
|
||||
{
|
||||
memcpy(pd, ps, width * sizeof(UINT16));
|
||||
pd += dest->pix_per_row;
|
||||
ps += src->pix_per_row;
|
||||
ps += src->pix_per_row;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -292,11 +292,11 @@ PDCTXT DC_CreateScreenContext(void)
|
||||
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));
|
||||
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);
|
||||
|
||||
110
src/devctxt.c
110
src/devctxt.c
@@ -58,46 +58,46 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT
|
||||
for (;;)
|
||||
{
|
||||
if (++nloop == 20)
|
||||
{
|
||||
Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING");
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
@@ -137,7 +137,7 @@ void _DC_FinalizeCommon(PDCTXT pdctxt)
|
||||
COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color)
|
||||
{
|
||||
if (!G_coords_in_rect(&(pdctxt->cliprect), x, y))
|
||||
return (COLORREF)(-1);
|
||||
return (COLORREF)(-1);
|
||||
return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y)
|
||||
if (rc)
|
||||
{
|
||||
pdctxt->pos.x = x;
|
||||
pdctxt->pos.y = y;
|
||||
pdctxt->pos.y = y;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -227,22 +227,22 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj)
|
||||
if (pobj->sig == BMP_SIG_WORD)
|
||||
{
|
||||
if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY)
|
||||
{
|
||||
RECT rtmp;
|
||||
{
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "gfxobj.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
#define DCTXT_SIG_WORD 0x78744344 /* "DCtx */
|
||||
#define DCTXT_SIG_WORD 0x78744344 /* "DCtx" */
|
||||
|
||||
/* Raster operation codes */
|
||||
#define R2_BLACK 1
|
||||
|
||||
@@ -69,12 +69,12 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
if (stock)
|
||||
{
|
||||
self->pbmp = _BMP_GetStock(stock);
|
||||
if (!(self->pbmp))
|
||||
{
|
||||
PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock);
|
||||
return -1;
|
||||
}
|
||||
self->pbmp = _BMP_GetStock(stock);
|
||||
if (!(self->pbmp))
|
||||
{
|
||||
PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -83,8 +83,8 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
|
||||
self->pbmp = BMP_Create(width, height, NULL);
|
||||
if (!(self->pbmp))
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
|
||||
return -1;
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -114,12 +114,12 @@ PyTypeObject BitmapType = {
|
||||
HRESULT Epython_register_bitmap(PyObject *module)
|
||||
{
|
||||
if (PyType_Ready(&BitmapType) < 0)
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
Py_INCREF(&BitmapType);
|
||||
if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0)
|
||||
{
|
||||
Py_DECREF(&BitmapType);
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -132,19 +132,19 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp)
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -166,23 +166,23 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp
|
||||
if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context");
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
@@ -202,7 +202,7 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args)
|
||||
if (!obj)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "bad object selected");
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (PyObject_TypeCheck(obj, &BitmapType))
|
||||
return devctxt_select_bitmap(self, (BitmapObject *)obj);
|
||||
@@ -319,25 +319,25 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds)
|
||||
if (strcmp(type, "screen") == 0)
|
||||
{
|
||||
self->pdctxt = DC_CreateScreenContext();
|
||||
if (!(self->pdctxt))
|
||||
if (!(self->pdctxt))
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create screen context");
|
||||
return -1;
|
||||
}
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create screen context");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(type, "memory") == 0)
|
||||
{
|
||||
self->pdctxt = _DC_CreateScreenCompatibleContext();
|
||||
if (!(self->pdctxt))
|
||||
if (!(self->pdctxt))
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create memory context");
|
||||
return -1;
|
||||
}
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to create memory context");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type);
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ HRESULT Epython_register_devctxt(PyObject *module)
|
||||
if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0)
|
||||
{
|
||||
Py_DECREF(&DevCtxtType);
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -131,20 +131,20 @@ HRESULT Epython_run(void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
Log(LERROR, "out of memory running script %s", Gconfig.script_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -153,7 +153,7 @@ HRESULT Epython_run(void)
|
||||
}
|
||||
for (i = 0; i<(Gconfig.script_arg_count + 1); i++)
|
||||
if (args[i])
|
||||
PyMem_RawFree(args[i]);
|
||||
PyMem_RawFree(args[i]);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
|
||||
11
src/ep_msg.c
11
src/ep_msg.c
@@ -36,22 +36,22 @@ static HRESULT convert_msg(PyObject *target, PMSG source)
|
||||
if (!attr)
|
||||
return E_FAIL;
|
||||
if (PyDict_SetItemString(target, "target", attr))
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
attr = PyLong_FromUnsignedLong(source->message);
|
||||
if (!attr)
|
||||
return E_FAIL;
|
||||
if (PyDict_SetItemString(target, "message", attr))
|
||||
return E_FAIL;
|
||||
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;
|
||||
return E_FAIL;
|
||||
attr = PyLong_FromUnsignedLongLong(source->timestamp);
|
||||
if (!attr)
|
||||
return E_FAIL;
|
||||
if (PyDict_SetItemString(target, "timestamp", attr))
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ PyObject *Epython_get_message(PyObject *self, PyObject *args)
|
||||
if (FAILED(convert_msg(out, &msg)))
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "could not convert received message");
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
return PyBool_FromLong(msg.message != WM_QUIT);
|
||||
}
|
||||
@@ -87,4 +87,3 @@ PyObject *Epython_post_quit_message(PyObject *self, PyObject *args)
|
||||
Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,20 +101,20 @@ PyObject *Epython_init_upiwin_module(void)
|
||||
|
||||
if (FAILED(Epython_register_constants(module, UPIWINConstants)))
|
||||
{
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FAILED(Epython_register_bitmap(module)))
|
||||
{
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FAILED(Epython_register_devctxt(module)))
|
||||
{
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set up the module state */
|
||||
|
||||
@@ -123,11 +123,11 @@ PyObject *Epython_init_upiwin_tmp_module(void)
|
||||
module = PyModule_Create(&DefUPIWIN_tmp);
|
||||
if (module)
|
||||
{
|
||||
if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants)))
|
||||
{
|
||||
Py_DECREF(module);
|
||||
module = NULL;
|
||||
}
|
||||
if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants)))
|
||||
{
|
||||
Py_DECREF(module);
|
||||
module = NULL;
|
||||
}
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
@@ -70,24 +70,24 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table)
|
||||
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;
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -129,9 +129,9 @@ void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, B
|
||||
for (tmp = x1; tmp <= x2; tmp++)
|
||||
{
|
||||
if (xor)
|
||||
*p++ ^= color;
|
||||
*p++ ^= color;
|
||||
else
|
||||
*p++ = color;
|
||||
*p++ = color;
|
||||
}
|
||||
ps += Fb_Info->width;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size)
|
||||
void Go_unchain(PGFXOBJECT obj)
|
||||
{
|
||||
if (!(obj->next || obj->prev))
|
||||
return;
|
||||
return;
|
||||
if (obj->next)
|
||||
obj->next->prev = obj->prev;
|
||||
if (obj->prev)
|
||||
@@ -50,9 +50,9 @@ INT32 Go_release(PGFXOBJECT obj)
|
||||
int rc = --(obj->refcnt);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (obj->dtor)
|
||||
(*(obj->dtor))(obj);
|
||||
free(obj);
|
||||
if (obj->dtor)
|
||||
(*(obj->dtor))(obj);
|
||||
free(obj);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,6 @@ PBITMAP _BMP_GetStock(PCSTR name)
|
||||
|
||||
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 BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
107
src/sysinput.c
107
src/sysinput.c
@@ -74,22 +74,22 @@ static BOOL poll_buttons(void)
|
||||
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
|
||||
{
|
||||
if (now < button_event_ok[attr - 1])
|
||||
continue; /* this is a "contact bounce" event, don't bother */
|
||||
continue; /* this is a "contact bounce" event, don't bother */
|
||||
if (up & mask)
|
||||
{
|
||||
/* reset contact bounce timer - only seems to happen after button releases */
|
||||
button_event_ok[attr - 1] = now + Gconfig.button_debounce;
|
||||
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
|
||||
if ((now - button_down_time[attr - 1]) <= Gconfig.click_time)
|
||||
Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr);
|
||||
posted = TRUE;
|
||||
/* 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;
|
||||
}
|
||||
{
|
||||
Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr);
|
||||
button_down_time[attr - 1] = now;
|
||||
posted = TRUE;
|
||||
}
|
||||
}
|
||||
last_bstate = st;
|
||||
}
|
||||
@@ -127,44 +127,43 @@ static BOOL poll_touchscreen(void)
|
||||
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;
|
||||
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;
|
||||
/* The screen driver thinks the screen is horizontal with origin at upper left and max at lower right. */
|
||||
if (buffer[i].code == ABS_X)
|
||||
touch_x = buffer[i].value;
|
||||
else if (buffer[i].code == ABS_Y)
|
||||
touch_y = buffer[i].value;
|
||||
break;
|
||||
|
||||
case EV_KEY:
|
||||
if (buffer[i].code == BTN_TOUCH)
|
||||
touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
|
||||
break;
|
||||
if (buffer[i].code == BTN_TOUCH)
|
||||
touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return posted;
|
||||
@@ -182,14 +181,14 @@ static void *input_thread(void *arg)
|
||||
|
||||
while (running)
|
||||
{
|
||||
gotinput = poll_buttons();
|
||||
gotinput = poll_buttons();
|
||||
gotinput = poll_touchscreen() || gotinput;
|
||||
if (gotinput)
|
||||
{
|
||||
pthread_mutex_lock(&wait_mutex);
|
||||
pthread_cond_signal(&wait_cond);
|
||||
pthread_mutex_unlock(&wait_mutex);
|
||||
}
|
||||
if (gotinput)
|
||||
{
|
||||
pthread_mutex_lock(&wait_mutex);
|
||||
pthread_cond_signal(&wait_cond);
|
||||
pthread_mutex_unlock(&wait_mutex);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -230,12 +229,12 @@ HRESULT Sys_enable_input(void)
|
||||
{
|
||||
rc = SCODE_FROM_ERRNO(threadrc);
|
||||
Log(LFATAL, "Unable to start system input thread (%08X).", rc);
|
||||
goto error_1;
|
||||
goto error_1;
|
||||
}
|
||||
|
||||
rc = Config_exitfunc(do_disable_input);
|
||||
if (FAILED(rc))
|
||||
do_disable_input();
|
||||
do_disable_input();
|
||||
return rc;
|
||||
|
||||
error_1:
|
||||
@@ -250,6 +249,6 @@ 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_cond_wait(&wait_cond, &wait_mutex);
|
||||
pthread_mutex_unlock(&wait_mutex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user