project for a (works on my devices) demo
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
*.o
|
||||
*.exe
|
||||
*.so
|
||||
*.so.*
|
||||
|
||||
# the order is important, an ignore definition overrides the preceding NOT_ignore
|
||||
wayland_objects/**
|
||||
!wayland_objects/Makefile
|
||||
12
AARCH64_BUILD/variables.mk
Normal file
12
AARCH64_BUILD/variables.mk
Normal file
@@ -0,0 +1,12 @@
|
||||
export COMPILER=aarch64-buildroot-linux-gnu-gcc
|
||||
|
||||
export BD=${PWD}AARCH64_BUILD/
|
||||
|
||||
# headers are good even if from ARM
|
||||
|
||||
# libraries must point to the right one
|
||||
|
||||
RESOURCES_LOC=${PWD}../../resources/
|
||||
export WAYLAND_LIBRARIES=${RESOURCES_LOC}libraries/
|
||||
export EGL_LIBRARIES=${RESOURCES_LOC}libraries/
|
||||
export MY_INPUT_LIBRARY=${PWD}../my_device_handler/AARCH64_BUILD
|
||||
7
BUGS
Normal file
7
BUGS
Normal file
@@ -0,0 +1,7 @@
|
||||
from glut_timers.c
|
||||
void timers_remove
|
||||
|
||||
null set at the end
|
||||
/* i added this and now works. should not need it, smells like bigger bug */
|
||||
toRemove->next = NULL;
|
||||
that line should not be needed...
|
||||
10
IA64_BUILD/variables.mk
Normal file
10
IA64_BUILD/variables.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
export COMPILER=gcc
|
||||
|
||||
export BD=${PWD}IA64_BUILD/
|
||||
|
||||
# headers are good even if from ARM
|
||||
|
||||
# libraries must point to the right one
|
||||
export WAYLAND_LIBRARIES=/usr/lib/x86_64-linux-gnu/
|
||||
export EGL_LIBRARIES=/usr/lib/x86_64-linux-gnu/
|
||||
export MY_INPUT_LIBRARY=${PWD}../my_device_handler/IA64_BUILD
|
||||
7
LOAD_TO_RG552.sh
Executable file
7
LOAD_TO_RG552.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
WAYROOT=/home/beno/Desktop/BATO/WAYLAND/
|
||||
|
||||
ssh RG552 -o RemoteCommand="rm -rf /DEMO_3/"
|
||||
scp -r ${WAYROOT}demo_3_GLUT_remake/ RG552:/DEMO_3
|
||||
scp ${WAYROOT}demo_6_raw_input_lib/libmydevicehandler.so.0 RG552:/usr/lib/libmydevicehandler.so
|
||||
scp ${WAYROOT}demo_3_GLUT_remake/glut_mine/libmyGLUT.so.0 RG552:/usr/lib/libmyGLUT.so
|
||||
ssh RG552 -o RemoteCommand="ldconfig /usr/lib/"
|
||||
139
Makefile
Normal file
139
Makefile
Normal file
@@ -0,0 +1,139 @@
|
||||
include external.mk
|
||||
include ${ARCH}_BUILD/variables.mk
|
||||
|
||||
GENERIC_TARGET_DEMO=demo.exe #will create a demo for testing the functionalities implemented by the lib
|
||||
GENERIC_TARGET_LIB=libmyGLUT.so.0 #will create a shared lib
|
||||
|
||||
FLAVORED_TARGET_DEMO=${BD}${GENERIC_TARGET_DEMO}
|
||||
FLAVORED_TARGET_LIB=${BD}${GENERIC_TARGET_LIB}
|
||||
|
||||
|
||||
LIB_OBJECTS=${BD}glut.o ${BD}glut_extensions.o ${BD}glut_timers.o ${BD}glut_input.o ${BD}glut_graphics.o ${BD}glut_backend.o ${BD}backend_resources/xdg-shell.o \
|
||||
${BD}input/input_events.o ${BD}input/touch/touch_data.o ${BD}input/touch/touch_controller_L1_builder.o \
|
||||
${BD}input/touch/touch_controller_L2.o ${BD}input/touch/touch_controller_L3.o ${BD}input/touch/touch_controller_L3_deltas_compute.o
|
||||
|
||||
OBJECTS=${BD}demo.o ${LIB_OBJECTS}
|
||||
|
||||
all:
|
||||
make ${GENERIC_TARGET_DEMO}
|
||||
make ${GENERIC_TARGET_LIB}
|
||||
|
||||
${GENERIC_TARGET_DEMO}:
|
||||
make ${FLAVORED_TARGET_DEMO}
|
||||
|
||||
${GENERIC_TARGET_LIB}:
|
||||
make ${FLAVORED_TARGET_LIB}
|
||||
|
||||
|
||||
${FLAVORED_TARGET_DEMO} : ${OBJECTS}
|
||||
${COMPILER} \
|
||||
-Wl,-unresolved-symbols=ignore-in-shared-libs \
|
||||
-o ${FLAVORED_TARGET_DEMO} \
|
||||
${OBJECTS} \
|
||||
-L${MY_INPUT_LIBRARY} -L${WAYLAND_LIBRARIES} -L${EGL_LIBRARIES} \
|
||||
${LINKS_0} ${LINKS_1}
|
||||
|
||||
|
||||
|
||||
# links as last argument !!!
|
||||
${FLAVORED_TARGET_LIB} : ${LIB_OBJECTS}
|
||||
${COMPILER} \
|
||||
-fPIC \
|
||||
-shared \
|
||||
-Wl,-soname,${GENERIC_TARGET_LIB} \
|
||||
-Wl,-unresolved-symbols=ignore-in-shared-libs \
|
||||
-o ${FLAVORED_TARGET_LIB} \
|
||||
${LIB_OBJECTS} \
|
||||
-L${MY_INPUT_LIBRARY} -L${WAYLAND_LIBRARIES} -L${EGL_LIBRARIES} \
|
||||
${LINKS_0} ${LINKS_1}
|
||||
|
||||
${BD}demo.o : ${SD}demo.c ${HD}glut.h
|
||||
${COMPILER} \
|
||||
-o ${BD}demo.o \
|
||||
-c ${CFLAGS} ${SD}demo.c
|
||||
|
||||
${BD}glut.o : ${SD}glut.c ${HD}glut.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}glut.o \
|
||||
-c ${CFLAGS} ${SD}glut.c
|
||||
|
||||
${BD}glut_extensions.o : ${SD}glut_extensions.c ${HD}glut_extensions.h ${HD}input/touch/touch_data.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}glut_extensions.o \
|
||||
-c ${CFLAGS} ${SD}glut_extensions.c
|
||||
|
||||
${BD}glut_timers.o : ${SD}glut_timers.c ${HD}glut_timers.h
|
||||
${COMPILER} \
|
||||
-o ${BD}glut_timers.o \
|
||||
-c ${CFLAGS} ${EXTRA_COMPILATION_FLAGS} ${SD}glut_timers.c
|
||||
|
||||
${BD}glut_input.o : ${SD}glut_input.c ${HD}glut_input.h ${HD}input/input_events.h ${HD}input/touch/touch_controller_L2.h ${HD}input/touch/touch_controller_L3.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}glut_input.o \
|
||||
-c ${CFLAGS} ${SD}glut_input.c
|
||||
|
||||
${BD}glut_graphics.o : ${SD}glut_graphics.c ${HD}glut_graphics.h
|
||||
${COMPILER} \
|
||||
-o ${BD}glut_graphics.o \
|
||||
-c ${CFLAGS} ${SD}glut_graphics.c
|
||||
|
||||
${BD}glut_backend.o : ${SD}glut_backend.c ${HD}glut_backend.h ${HD}backend_resources/xdg-shell.h
|
||||
${COMPILER} \
|
||||
${I_EGL} \
|
||||
${I_WAYLAND} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}glut_backend.o \
|
||||
-c ${CFLAGS} ${SD}glut_backend.c
|
||||
|
||||
# there was something about the need to apply GLOBAL_COMPILE_CONF (disable stack-protection) to each unit?
|
||||
|
||||
${BD}backend_resources/xdg-shell.o : ${SD}backend_resources/xdg-shell.c ${HD}backend_resources/xdg-shell.h
|
||||
${COMPILER} \
|
||||
${I_WAYLAND} \
|
||||
-o ${BD}backend_resources/xdg-shell.o \
|
||||
-c ${CFLAGS} ${SD}backend_resources/xdg-shell.c
|
||||
|
||||
${BD}input/input_events.o : ${SD}input/input_events.c ${HD}input/input_events.h ${HD}input/touch/touch_controller_L1_builder.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/input_events.o \
|
||||
-c ${CFLAGS} ${SD}input/input_events.c
|
||||
|
||||
${BD}input/touch/touch_data.o : ${SD}input/touch/touch_data.c ${HD}input/touch/touch_data.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/touch/touch_data.o \
|
||||
-c ${CFLAGS} ${SD}input/touch/touch_data.c
|
||||
|
||||
${BD}input/touch/touch_controller_L1_builder.o : ${SD}input/touch/touch_controller_L1_builder.c ${HD}input/touch/touch_controller_L1_builder.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/touch/touch_controller_L1_builder.o \
|
||||
-c ${CFLAGS} ${SD}input/touch/touch_controller_L1_builder.c
|
||||
|
||||
${BD}input/touch/touch_controller_L2.o : ${SD}input/touch/touch_controller_L2.c ${HD}input/touch/touch_controller_L2.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/touch/touch_controller_L2.o \
|
||||
-c ${CFLAGS} ${SD}input/touch/touch_controller_L2.c
|
||||
|
||||
${BD}input/touch/touch_controller_L3.o : ${SD}input/touch/touch_controller_L3.c ${HD}input/touch/touch_controller_L3.h ${HD}input/touch/touch_controller_L3_deltas_compute.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/touch/touch_controller_L3.o \
|
||||
-c ${CFLAGS} ${SD}input/touch/touch_controller_L3.c
|
||||
|
||||
${BD}input/touch/touch_controller_L3_deltas_compute.o : ${SD}input/touch/touch_controller_L3_deltas_compute.c ${HD}input/touch/touch_controller_L3_deltas_compute.h
|
||||
${COMPILER} \
|
||||
${I_MY_INPUT} \
|
||||
-o ${BD}input/touch/touch_controller_L3_deltas_compute.o \
|
||||
-c ${CFLAGS} ${SD}input/touch/touch_controller_L3_deltas_compute.c
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
-rm ${FLAVORED_TARGET_DEMO} ${FLAVORED_TARGET_LIB} ${OBJECTS} *~ core
|
||||
83
README.md
83
README.md
@@ -1,71 +1,26 @@
|
||||
# my_glut
|
||||
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
## Add your files
|
||||
|
||||
* [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
* [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin http://localhost/root/my_glut.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
* [Set up project integrations](http://localhost/root/my_glut/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
* [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
* [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
* [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
* [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
* [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
|
||||
|
||||
## Test and Deploy
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
* [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
|
||||
* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
* [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
|
||||
***
|
||||
|
||||
# Editing this README
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
|
||||
## Suggestions for a good README
|
||||
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
A modern reimplementation for ARM linux handhelds of GLUT.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
GLUT is a graphical application library which provides an easy way of creating a window, intercepting input from it and drawing with OpenGL APIs.
|
||||
This implementation is aimed at linux systems which use a Wayland graphical system and extends the mousePointer events for touchscreen/multipointer support
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
***
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
Depends upon
|
||||
libmydevicehandler (my_device_handler)
|
||||
libevdev
|
||||
libwayland
|
||||
libEGL
|
||||
libwayland-egl
|
||||
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
@@ -77,17 +32,21 @@ Tell people where they can go to for help. It can be any combination of an issue
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
Fully open to contributions.
|
||||
What requirements?
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
Luca Benini [beno]
|
||||
```
|
||||
your name here
|
||||
```
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
MA CHE NE SAPPIAMO ANCORA
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||
se sei stanco, scrivilo in cima che qualcuno raccoglie il testimone
|
||||
|
||||
46
demo/Makefile
Normal file
46
demo/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
include ../external.mk
|
||||
|
||||
TARGET=main.exe
|
||||
|
||||
OBJECTS=main.o
|
||||
|
||||
FULL_BUILD_OBJECTS=${OBJECTS}
|
||||
|
||||
|
||||
GLUT_D=${PWD}
|
||||
|
||||
LINKS=-lGLESv2 -lmyGLUT
|
||||
|
||||
# same as the GL_STUFF MAKEFILE
|
||||
CFLAGS=-ansi -Wpedantic -Winline -Werror -std=c11
|
||||
|
||||
all :
|
||||
make -C ${GLUT_D}
|
||||
make ${TARGET}
|
||||
|
||||
|
||||
# -L GLUT_D MUST GO AFTER THE L_SHLIBS, OTHERWISE ASSUMES THAT THE myGLUT DEPENDENCIES ARE SIMPLY UNMET
|
||||
# removed the space between -L and GLUT_D
|
||||
${TARGET} : ${OBJECTS}
|
||||
${COMPILER} \
|
||||
-o ${TARGET} \
|
||||
${FULL_BUILD_OBJECTS} \
|
||||
-Wl,-unresolved-symbols=ignore-in-shared-libs \
|
||||
${L_SHLIBS} \
|
||||
-L${GLUT_D} \
|
||||
${LINKS}
|
||||
|
||||
|
||||
# -I ./ è una porcata clamorosa
|
||||
main.o : main.c ${GLUT_D}glut.h ${GLUT_D}glut_extensions.h
|
||||
${COMPILER} \
|
||||
${I_MY_GLUT} \
|
||||
${I_GRAPHICS} \
|
||||
-c ${CFLAGS} main.c \
|
||||
${GLOBAL_COMPILE_CONF}
|
||||
|
||||
.PHONY: clean debug
|
||||
|
||||
clean:
|
||||
make clean -C ${GLUT_D}
|
||||
-rm ${TARGET} ${OBJECTS} *~ core
|
||||
101
demo/main.c
Executable file
101
demo/main.c
Executable file
@@ -0,0 +1,101 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <glut.h>
|
||||
#include <glut_extensions.h>
|
||||
|
||||
const int TARGET_FPS = 15;
|
||||
static int ONE_TICK_MS = 1000 / TARGET_FPS;
|
||||
|
||||
float viewSize = 2.0f;
|
||||
float aspect_ratio;
|
||||
int steps = 60;
|
||||
|
||||
/* don't want to implement */
|
||||
/* also removed
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
*/
|
||||
GLuint GLUT_COMPATIBILITY_PROFILE = 0 ;
|
||||
GLuint GLUT_SINGLE = 0 ;
|
||||
GLuint GLUT_RGBA = 0 ;
|
||||
const GLuint GLUT_SCREEN_WIDTH = 0;
|
||||
const GLuint GLUT_SCREEN_HEIGHT = 1;
|
||||
|
||||
void glutInitContextVersion( int maj, int min){}
|
||||
void glutInitContextProfile( GLuint profile){}
|
||||
void glutInitDisplayMode( GLuint OR_ed_FLAGS){}
|
||||
|
||||
int glutGet(GLuint dimension){
|
||||
switch( dimension) {
|
||||
case 0 :
|
||||
return 1920;
|
||||
break;
|
||||
case 1 :
|
||||
return 1152;
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//funky stuff ahead
|
||||
void renderLoop() {
|
||||
|
||||
glClearColor( 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
void timer(int value) {
|
||||
printf("crashes here\n");
|
||||
uint8_t touch_count;
|
||||
touch_event **touch_buffer;
|
||||
glutGetTouchProxy().get_tracked_events( &touch_buffer, &touch_count);
|
||||
printf("%d touch_events\n", touch_count);
|
||||
if( touch_count)
|
||||
free_touch_events_array( touch_buffer, touch_count);
|
||||
|
||||
/*would have handled animations*/
|
||||
glutTimerFunc(ONE_TICK_MS, timer, 0);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void keypressed(unsigned char key, int x, int y) {
|
||||
printf("pressed key %d\n", key);
|
||||
}
|
||||
|
||||
void mousemoved(int x, int y) {
|
||||
//camera.mouseMotion(x, y);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
printf("i'm alive!\n");
|
||||
glutInit(&argc, argv);
|
||||
glutInitContextVersion(4, 0);
|
||||
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
|
||||
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
|
||||
|
||||
int scrWidth = glutGet(GLUT_SCREEN_WIDTH) * 5 / 6;
|
||||
int scrHeight = glutGet(GLUT_SCREEN_HEIGHT) * 5 / 6;
|
||||
//scrWidth = 640;
|
||||
//scrHeight = 480;
|
||||
aspect_ratio = ( (float) scrWidth) / scrHeight;
|
||||
glutInitWindowSize( scrWidth , scrHeight );
|
||||
glutInitWindowPosition( 0, 0);
|
||||
glutCreateWindow("TriDi");
|
||||
|
||||
glutTimerFunc(ONE_TICK_MS, timer, 0);
|
||||
glutDisplayFunc(renderLoop);
|
||||
glutKeyboardFunc(keypressed);
|
||||
glutPassiveMotionFunc(mousemoved);
|
||||
|
||||
/*check what MESA has to offer*/
|
||||
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
|
||||
printf("%s\n", extensions);
|
||||
|
||||
glutMainLoop();
|
||||
}
|
||||
35
external.mk
Normal file
35
external.mk
Normal file
@@ -0,0 +1,35 @@
|
||||
export GLOBAL_COMPILE_CONF=-fno-stack-protector
|
||||
|
||||
export PWD=/here/folder/projects/my_glut/
|
||||
|
||||
|
||||
export CFLAGS=-ansi -Wpedantic -Winline -Werror -std=c99 -fPIC ${GLOBAL_COMPILE_CONF} # c11
|
||||
|
||||
LINKS_0=-lEGL -lwayland-client -lGLESv2 -lwayland-egl -lmydevicehandler -lm # direct dependencies
|
||||
#LINKS_1=-lwayland-server -lgbm -lglapi -lexpat -ldrm -lffi -lc # secondary dependencies
|
||||
|
||||
|
||||
# DIRECTORIES
|
||||
export SD=sources/
|
||||
export HD=headers/
|
||||
|
||||
export RESOURCES_LOC=${PWD}../../resources/
|
||||
|
||||
# includes EGL GLES2 (KHR needed by both)
|
||||
export GRAPHICS=${RESOURCES_LOC}headers/
|
||||
|
||||
export GLM_HEADERS=${PWD}../../resources/sources/glm/
|
||||
|
||||
|
||||
WAYLAND_STUFF=${RESOURCES_LOC}sources/wayland-1.22.0/
|
||||
export WAYLAND_HEADERS=${WAYLAND_STUFF}src/
|
||||
export WAYLAND_PROTOCOL_HEADERS=${WAYLAND_STUFF}build/src/
|
||||
export WAYLAND_EGL_HEADERS=${WAYLAND_STUFF}egl/
|
||||
|
||||
|
||||
export MY_INPUT_HEADERS=${PWD}../my_device_handler/
|
||||
|
||||
export I_EGL=-I ${GRAPHICS}
|
||||
export I_WAYLAND=-I ${WAYLAND_HEADERS} -I ${WAYLAND_PROTOCOL_HEADERS} -I ${WAYLAND_EGL_HEADERS}
|
||||
export I_CGI_MATH=-I ${GLM_HEADERS}
|
||||
export I_MY_INPUT=-I ${MY_INPUT_HEADERS}
|
||||
2280
headers/backend_resources/xdg-shell.h
Normal file
2280
headers/backend_resources/xdg-shell.h
Normal file
File diff suppressed because it is too large
Load Diff
45
headers/glut.h
Normal file
45
headers/glut.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
/* creates a window with a bound GL context */
|
||||
int glutCreateWindow(const char *title);
|
||||
|
||||
/* invoked after a glutPostRedisplay */
|
||||
void glutDisplayFunc( void (*callback)(void));
|
||||
|
||||
void glutInit( char **devPaths, int count); /*initializes a */
|
||||
|
||||
void glutInitWindowPosition( int x, int y);
|
||||
void glutInitWindowSize( int width, int height );
|
||||
|
||||
|
||||
/* removed bc.
|
||||
from the school projects see
|
||||
/CGI/SHADING/packages/nupengl.core.0.1.0.1/build/native/include/GL
|
||||
|
||||
void glutInitContextVersion(4, 0);
|
||||
void glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
|
||||
void glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
|
||||
*/
|
||||
|
||||
|
||||
/* invokes CB after each keypress, passing keycode and mouse cords (buffered) */
|
||||
void glutKeyboardFunc( void ( *callback) (unsigned char key, int x, int y));
|
||||
|
||||
/*starts any timer and then loops waiting for postRedisplay() */
|
||||
void glutMainLoop();
|
||||
|
||||
/* passes to CB the xy coord relative to the screen */
|
||||
void glutPassiveMotionFunc( void ( *callback) (int x, int y) );
|
||||
|
||||
/* issue a call to glutDisplayCB glutKeyboardFunc glutPassiveMotionFunc */
|
||||
void glutPostRedisplay();
|
||||
|
||||
//glutSetCursor(GLUT_CURSOR_NONE);
|
||||
|
||||
void glutSwapBuffers();
|
||||
|
||||
/* waits TIME and then calls CB passing VAL as argument */
|
||||
void glutTimerFunc( int time, void ( *callback)(int), int value);
|
||||
|
||||
/* forces mouse position to SCR_X SCR_Y */
|
||||
void glutWarpPointer( int x, int y);
|
||||
9
headers/glut_backend.h
Normal file
9
headers/glut_backend.h
Normal file
@@ -0,0 +1,9 @@
|
||||
void init_implementation();
|
||||
|
||||
void init_window_size_implementation( int width, int height);
|
||||
|
||||
int create_window_implementation( const char *title);
|
||||
|
||||
void sleep_implementation();
|
||||
|
||||
void swap_buffers_implementation();
|
||||
22
headers/glut_extensions.h
Normal file
22
headers/glut_extensions.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "input/touch/touch_data.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t ( *get_count) ( void);
|
||||
void ( *get_tracked_events) ( touch_event ***store, uint8_t *count);
|
||||
touch_coordinates* ( *getAABB) ( touch_event **events, uint8_t count);
|
||||
float ( *get_width) ( touch_event **events, uint8_t count);
|
||||
float ( *get_angle) ( touch_event **events, uint8_t count);
|
||||
touch_coordinates* ( *get_midpoint) ( touch_event **events, uint8_t count);
|
||||
void ( *get_position_deltas) (
|
||||
touch_event **previous, uint8_t previous_count,
|
||||
touch_event **current, uint8_t current_count,
|
||||
touch_coordinates **deltas, uint8_t *count
|
||||
);
|
||||
float ( *get_angle_delta) ( float previous_angle, float current_angle);
|
||||
touch_coordinates* ( *get_midpoint_delta) ( touch_coordinates previous, touch_coordinates current);
|
||||
} touch_data_proxy;
|
||||
|
||||
touch_data_proxy glutGetTouchProxy();
|
||||
5
headers/glut_graphics.h
Normal file
5
headers/glut_graphics.h
Normal file
@@ -0,0 +1,5 @@
|
||||
void assignRedrawCallback( void ( *callback) ( void));
|
||||
|
||||
void issueRedraw();
|
||||
|
||||
void consume_redraws();
|
||||
15
headers/glut_input.h
Normal file
15
headers/glut_input.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <my_device_handler.h>
|
||||
|
||||
void warp_pointer_implementation( int x, int y);
|
||||
|
||||
void assignKeyboardCallback( void ( *callback) (unsigned char key, int x, int y));
|
||||
|
||||
void assignMouseMotionCallback( void ( *callback) (int x, int y));
|
||||
|
||||
void process_inputs();
|
||||
|
||||
static void process_key_events();
|
||||
|
||||
static void process_cursor_events();
|
||||
16
headers/glut_timers.h
Normal file
16
headers/glut_timers.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
/* list of timers, no way to identify them, so no prunability outside of their exhaustion */
|
||||
typedef struct timer_list_entry_t {
|
||||
int remaining_ms;
|
||||
void (*callback) (int);
|
||||
struct timer_list_entry_t* next;
|
||||
} timer_list_entry ;
|
||||
|
||||
void timers_add( timer_list_entry *toAdd);
|
||||
|
||||
void decrease_timers();
|
||||
|
||||
int timers_isEmpty();
|
||||
|
||||
int timers_isUpdating();
|
||||
49
headers/input/input_events.h
Normal file
49
headers/input/input_events.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <events.h> /* from mydevicehandler */
|
||||
|
||||
/* should include it in the input library instead... */
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "touch/touch_controller_L1_builder.h"
|
||||
|
||||
extern unsigned char buffered_keys[KEY_CNT];
|
||||
|
||||
/* DELTAS
|
||||
yes, typedef can also be used like this
|
||||
|
||||
typedef unsigned char buffered_keys_transition[KEY_CNT];
|
||||
*/
|
||||
|
||||
void dispatch_input_event();
|
||||
|
||||
static void dispatch_input_absolute_event( device_event event);
|
||||
|
||||
static void dispatch_input_key_event( device_event event);
|
||||
|
||||
static void dispatch_regular_absolute_event( device_event event);
|
||||
|
||||
/* subtype of input_absolute_event */
|
||||
static void dispatch_multitouch_event( device_event event);
|
||||
|
||||
|
||||
|
||||
/* common keyboard codes from 0 up to KEY_MACRO, before KEY_MUTE */
|
||||
static void dispatch_keyboard_keys( device_event event);
|
||||
|
||||
/* interesting keys from KEY_MIN_INTERESTING = KEY_MUTE up to BTN_DEAD, before BTN_GAMEPAD */
|
||||
static void dispatch_interesting_keys_1( device_event event);
|
||||
|
||||
/* joypad keys, from BTN_GAMEPAD up to BTN_THUMBR, gap of one before BTN_DIGI */
|
||||
static void dispatch_interesting_keys_2( device_event event);
|
||||
|
||||
/* interesting keys, from BTN_DIGI up to the MAX */
|
||||
static void dispatch_interesting_keys_3( device_event event);
|
||||
|
||||
/* reserving the NULL character code for unsupported keys
|
||||
maps from linux input.h key codes to ascii
|
||||
*/
|
||||
char get_ascii_code( unsigned short linux_code);
|
||||
|
||||
/* shitty hack waiting for the use of hashmaps */
|
||||
unsigned short remap_joypad_to_keyboard( unsigned short linux_key);
|
||||
20
headers/input/touch/touch_controller_L1_builder.h
Normal file
20
headers/input/touch/touch_controller_L1_builder.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "touch_data.h"
|
||||
|
||||
/* yes int instead of uint */
|
||||
void TC_L1_builder_set_tracking_id( int64_t tracking_id);
|
||||
|
||||
void TC_L1_builder_set_position_x( uint64_t x_coord);
|
||||
|
||||
void TC_L1_builder_set_position_y( uint64_t y_coord);
|
||||
|
||||
void TC_L1_builder_set_major_axis( uint64_t width);
|
||||
|
||||
void TC_L1_builder_set_approaching_major_axis( uint64_t width);
|
||||
|
||||
void TC_L1_builder_set_slot_number( uint64_t number);
|
||||
|
||||
void TC_L1_builder_copy_tracked_events( touch_event ***store, uint8_t *count);
|
||||
|
||||
void TC_L1_builder_destroy_copy( touch_event **store, uint8_t count);
|
||||
9
headers/input/touch/touch_controller_L2.h
Normal file
9
headers/input/touch/touch_controller_L2.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "touch_data.h"
|
||||
|
||||
touch_coordinates* TC_L2_getAABB( touch_event **events, uint8_t count);
|
||||
|
||||
float TC_L2_get_width( touch_event **events, uint8_t count);
|
||||
|
||||
float TC_L2_get_angle( touch_event **events, uint8_t count);
|
||||
|
||||
touch_coordinates* TC_L2_get_midpoint( touch_event **events, uint8_t count);
|
||||
13
headers/input/touch/touch_controller_L3.h
Normal file
13
headers/input/touch/touch_controller_L3.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "touch_controller_L2.h"
|
||||
|
||||
void TC_L3_get_position_deltas(
|
||||
touch_event **previous, uint8_t previous_count,
|
||||
touch_event **current, uint8_t current_count,
|
||||
touch_coordinates **deltas, uint8_t *count
|
||||
);
|
||||
|
||||
float TC_L3_get_angle_delta( float previous_angle, float current_angle);
|
||||
|
||||
touch_coordinates* TC_L3_get_midpoint_delta( touch_coordinates previous, touch_coordinates current);
|
||||
22
headers/input/touch/touch_controller_L3_deltas_compute.h
Normal file
22
headers/input/touch/touch_controller_L3_deltas_compute.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t state; /* entered unchanged exited */
|
||||
uint8_t old_index;
|
||||
uint8_t new_index;
|
||||
uint64_t tracking_id;
|
||||
} tracked_delta;
|
||||
|
||||
/* could also resort to TRANSIENT / PERSISTENT */
|
||||
static const uint8_t TRACKED_DELTA_ENTERED = 0;
|
||||
static const uint8_t TRACKED_DELTA_UNCHANGED = 1;
|
||||
static const uint8_t TRACKED_DELTA_EXITED = 2;
|
||||
|
||||
|
||||
void touch_events_sorted_ids_deltas(
|
||||
tracked_delta **endbuffer, uint16_t *endcount,
|
||||
uint64_t *previous_ids, uint8_t previous_count,
|
||||
uint64_t *current_ids, uint8_t current_count
|
||||
);
|
||||
30
headers/input/touch/touch_data.h
Normal file
30
headers/input/touch/touch_data.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
int64_t x; /* touch horizontal center */
|
||||
int64_t y; /* touch vertical center */
|
||||
} touch_coordinates;
|
||||
|
||||
/* using ultrawide ints (narrowing later) */
|
||||
typedef struct {
|
||||
uint64_t slot_number;
|
||||
uint64_t tracking_id; /* this increases with each new touch */
|
||||
touch_coordinates position;
|
||||
/* ignoring ABS_MT_TOUCH_MAJOR
|
||||
and ABS_MT_WIDTH_MAJOR
|
||||
*/
|
||||
} touch_event;
|
||||
|
||||
touch_event* touch_event_new();
|
||||
|
||||
void touch_event_copy( touch_event *dst, touch_event *src);
|
||||
|
||||
touch_coordinates* new_touch_coordinates_buffer( uint8_t count);
|
||||
|
||||
void free_touch_coordinates_buffer( touch_coordinates* buffer);
|
||||
|
||||
void touch_events_array_copy( touch_event ***dst, touch_event **src, uint8_t count);
|
||||
|
||||
void free_touch_events_array( touch_event **buffer, uint8_t count);
|
||||
21
headers/input/touch/two_fingers_simultaneous.event
Normal file
21
headers/input/touch/two_fingers_simultaneous.event
Normal file
@@ -0,0 +1,21 @@
|
||||
ABS_MT_TRACKING_ID [UNIQUE ID OF INITIATED CONTACT] 100
|
||||
ABS_MT_POSITION_X [CENTER X TOUCH POSITION] 288
|
||||
ABS_MT_POSITION_Y [CENTER Y TOUCH POSITION] 1028
|
||||
ABS_MT_TOUCH_MAJOR [MAJOR AXIS OF TOUCH ELLIPSE] 40
|
||||
ABS_MT_WIDTH_MAJOR [MINOR AXIS OF APPROACHING ELLIPSE] 40
|
||||
|
||||
ABS_MT_SLOT [MULTITOUCH SLOT MODIFIED] 1
|
||||
ABS_MT_TRACKING_ID [UNIQUE ID OF INITIATED CONTACT] 101
|
||||
ABS_MT_POSITION_X [CENTER X TOUCH POSITION] 866
|
||||
ABS_MT_POSITION_Y [CENTER Y TOUCH POSITION] 660
|
||||
ABS_MT_TOUCH_MAJOR [MAJOR AXIS OF TOUCH ELLIPSE] 49
|
||||
ABS_MT_WIDTH_MAJOR [MINOR AXIS OF APPROACHING ELLIPSE] 49
|
||||
TOUCH EVENT BEGIN
|
||||
separator for 0 : 0
|
||||
|
||||
ABS_MT_SLOT [MULTITOUCH SLOT MODIFIED] 0
|
||||
ABS_MT_TRACKING_ID [UNIQUE ID OF INITIATED CONTACT] -1
|
||||
ABS_MT_SLOT [MULTITOUCH SLOT MODIFIED] 1
|
||||
ABS_MT_TRACKING_ID [UNIQUE ID OF INITIATED CONTACT] -1
|
||||
TOUCH EVENT END
|
||||
separator for 0 : 0
|
||||
183
sources/backend_resources/xdg-shell.c
Normal file
183
sources/backend_resources/xdg-shell.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 5,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 5,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 5,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 5,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 5,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
||||
36
sources/demos/demo_headless.c
Normal file
36
sources/demos/demo_headless.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include "../headers/glut.h"
|
||||
|
||||
int frame_ms=16;
|
||||
int one_s=1000;
|
||||
int five_s=5000;
|
||||
|
||||
void printSomething( int value){
|
||||
printf("a frame\n");
|
||||
glutTimerFunc(frame_ms, printSomething, 0);
|
||||
}
|
||||
|
||||
void printSecond( int value){
|
||||
printf("a second\n");
|
||||
}
|
||||
|
||||
void printFiveSecond( int value){
|
||||
printf("five seconds\n");
|
||||
}
|
||||
|
||||
int main(){
|
||||
char *devPaths[2] = {
|
||||
"/dev/input/event4",
|
||||
"/dev/input/event5"
|
||||
};
|
||||
|
||||
glutInit( devPaths, 2);
|
||||
|
||||
glutTimerFunc(frame_ms, printSomething, 0);
|
||||
glutTimerFunc(one_s, printSecond, 0);
|
||||
glutTimerFunc(five_s, printFiveSecond, 0);
|
||||
|
||||
glutMainLoop();
|
||||
/*
|
||||
*/
|
||||
}
|
||||
86
sources/glut.c
Normal file
86
sources/glut.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h> /*printf for the main*/
|
||||
#include <stdlib.h>
|
||||
#include "../headers/glut.h"
|
||||
#include "../headers/glut_timers.h"
|
||||
#include "../headers/glut_graphics.h"
|
||||
#include "../headers/glut_input.h"
|
||||
|
||||
#include "../headers/glut_backend.h"
|
||||
|
||||
int terminated=0;
|
||||
|
||||
/* sta porcata per cappare la lettura dell'input a 60FPS */
|
||||
void input_timer( int delayms){
|
||||
process_inputs();
|
||||
glutTimerFunc( 17, input_timer, 0);
|
||||
}
|
||||
|
||||
|
||||
int glutCreateWindow( const char *title){
|
||||
return create_window_implementation(title);
|
||||
}
|
||||
|
||||
/*all the init functions collassed here*/
|
||||
void glutInit( char **devPaths, int count){
|
||||
init_implementation( devPaths, count);
|
||||
}
|
||||
|
||||
void glutInitWindowPosition( int x, int y){}
|
||||
|
||||
void glutInitWindowSize( int width, int height ){
|
||||
init_window_size_implementation( width, height);
|
||||
}
|
||||
|
||||
void glutDisplayFunc( void ( *callback) ( void)){
|
||||
assignRedrawCallback( callback);
|
||||
}
|
||||
|
||||
void glutKeyboardFunc( void ( *callback) ( unsigned char key, int x, int y)){
|
||||
assignKeyboardCallback( callback);
|
||||
}
|
||||
|
||||
void glutMainLoop(){
|
||||
int cappedTimer = 0;
|
||||
glutPostRedisplay();
|
||||
/*
|
||||
SHIEET
|
||||
*/
|
||||
glutTimerFunc( 17,input_timer, 0);
|
||||
|
||||
while( ! ( terminated || timers_isEmpty())){
|
||||
cappedTimer = ( cappedTimer + 1) % 17;
|
||||
if( ! cappedTimer){
|
||||
/*
|
||||
process_inputs();
|
||||
*/
|
||||
}
|
||||
decrease_timers();
|
||||
consume_redraws(); /* the drawing potentially goes at 1000FPS, capped internally at 60 */
|
||||
sleep_implementation();
|
||||
}
|
||||
}
|
||||
|
||||
void glutPassiveMotionFunc( void ( *callback) (int x, int y) ){
|
||||
assignMouseMotionCallback(callback);
|
||||
}
|
||||
|
||||
void glutPostRedisplay(){
|
||||
issueRedraw();
|
||||
}
|
||||
|
||||
void glutSwapBuffers(){
|
||||
swap_buffers_implementation();
|
||||
}
|
||||
|
||||
void glutTimerFunc(int ms, void ( *callback)(int), int value){
|
||||
timer_list_entry* toAdd = malloc( sizeof( timer_list_entry));
|
||||
toAdd->next = NULL;
|
||||
toAdd->remaining_ms = ms;
|
||||
toAdd->callback = callback;
|
||||
timers_add( toAdd);
|
||||
}
|
||||
|
||||
void glutWarpPointer(int x, int y){
|
||||
/* this one in glut_input */
|
||||
warp_pointer_implementation(x, y);
|
||||
}
|
||||
300
sources/glut_backend.c
Normal file
300
sources/glut_backend.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/* for nanosleep */
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
|
||||
#include <time.h> /*nanosleep*/
|
||||
#include <stdlib.h> /*malloc*/
|
||||
#include <stdio.h> /*fprintf*/
|
||||
#include <string.h>
|
||||
|
||||
#include <EGL/egl.h> /*graphic context*/
|
||||
|
||||
#include <wayland-egl.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "../headers/backend_resources/xdg-shell.h"
|
||||
|
||||
#include "../headers/glut_backend.h"
|
||||
|
||||
#include <my_device_handler.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct client_state {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
/**/
|
||||
struct wl_egl_window *egl_window;
|
||||
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
EGLContext egl_context;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
uint8_t running;
|
||||
};
|
||||
|
||||
|
||||
static struct client_state state;
|
||||
|
||||
|
||||
|
||||
static void global_registry(void *data, struct wl_registry *wl_registry,
|
||||
uint32_t name, const char *interface, uint32_t version) {
|
||||
struct client_state *state = data;
|
||||
|
||||
if(!strcmp(interface, wl_compositor_interface.name)) {
|
||||
state->compositor = wl_registry_bind(wl_registry, name,
|
||||
&wl_compositor_interface, version);
|
||||
} else if(!strcmp(interface, xdg_wm_base_interface.name)) {
|
||||
state->xdg_wm_base = wl_registry_bind(wl_registry, name,
|
||||
&xdg_wm_base_interface, version);
|
||||
}
|
||||
}
|
||||
|
||||
static void global_remove(void *data, struct wl_registry *wl_registry,
|
||||
uint32_t name) {
|
||||
(void) data;
|
||||
(void) wl_registry;
|
||||
(void) name;
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
global_registry,
|
||||
global_remove
|
||||
};
|
||||
|
||||
static void wm_ping(void *data, struct xdg_wm_base *xdg_wm_base,
|
||||
uint32_t serial) {
|
||||
(void) data;
|
||||
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener wm_base_listener = {
|
||||
wm_ping
|
||||
};
|
||||
|
||||
static void surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t serial) {
|
||||
(void) data;
|
||||
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener surface_listener = {
|
||||
surface_configure
|
||||
};
|
||||
|
||||
/******************************/
|
||||
/********XDG Toplevel**********/
|
||||
/******************************/
|
||||
|
||||
static void toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||
int32_t width, int32_t height, struct wl_array *states) {
|
||||
struct client_state *state = data;
|
||||
(void) xdg_toplevel;
|
||||
(void) states;
|
||||
|
||||
if(!width && !height) return;
|
||||
|
||||
if(state->width != width || state->height != height) {
|
||||
state->width = width;
|
||||
state->height = height;
|
||||
|
||||
wl_egl_window_resize(state->egl_window, width, height, 0, 0);
|
||||
wl_surface_commit(state->surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) {
|
||||
(void) xdg_toplevel;
|
||||
|
||||
struct client_state *state = data;
|
||||
|
||||
state->running = 0;
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_listener toplevel_listener = {
|
||||
toplevel_configure,
|
||||
toplevel_close
|
||||
};
|
||||
|
||||
static void wayland_connect(struct client_state *state) {
|
||||
state->display = wl_display_connect(NULL);
|
||||
if(!state->display) {
|
||||
fprintf(stderr, "Couldn't connect to wayland display\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state->registry = wl_display_get_registry(state->display);
|
||||
wl_registry_add_listener(state->registry, ®istry_listener, state);
|
||||
wl_display_roundtrip(state->display);
|
||||
if(!state->compositor || !state->xdg_wm_base) {
|
||||
fprintf(stderr, "Couldn't find compositor or xdg shell\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
xdg_wm_base_add_listener(state->xdg_wm_base, &wm_base_listener, NULL);
|
||||
|
||||
state->surface = wl_compositor_create_surface(state->compositor);
|
||||
state->xdg_surface = xdg_wm_base_get_xdg_surface(state->xdg_wm_base,
|
||||
state->surface);
|
||||
xdg_surface_add_listener(state->xdg_surface, &surface_listener, NULL);
|
||||
state->xdg_toplevel = xdg_surface_get_toplevel(state->xdg_surface);
|
||||
xdg_toplevel_set_title(state->xdg_toplevel, "Hello World");
|
||||
xdg_toplevel_add_listener(state->xdg_toplevel, &toplevel_listener, state);
|
||||
wl_surface_commit(state->surface);
|
||||
}
|
||||
/**/
|
||||
static void egl_init(struct client_state *state) {
|
||||
EGLint major;
|
||||
EGLint minor;
|
||||
EGLint num_configs;
|
||||
/*
|
||||
replaced EGL_OPENGL_BIT with EGL_OPENGL_ES2_BIT
|
||||
*/
|
||||
EGLint attribs[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
state->egl_window = wl_egl_window_create(state->surface, state->width,
|
||||
state->height);
|
||||
|
||||
state->egl_display = eglGetDisplay((EGLNativeDisplayType) state->display);
|
||||
if(state->display == EGL_NO_DISPLAY) {
|
||||
fprintf(stderr, "Couldn't get EGL display\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) {
|
||||
fprintf(stderr, "Couldnt initialize EGL\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(eglChooseConfig(state->egl_display, attribs, &state->egl_config, 1,
|
||||
&num_configs) != EGL_TRUE) {
|
||||
fprintf(stderr, "CouldnÄt find matching EGL config\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state->egl_surface = eglCreateWindowSurface(state->egl_display,
|
||||
state->egl_config,
|
||||
(EGLNativeWindowType) state->egl_window, NULL);
|
||||
if(state->egl_surface == EGL_NO_SURFACE) {
|
||||
fprintf(stderr, "Couldn't create EGL surface\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* added from
|
||||
https://stackoverflow.com/questions/25843368/glgetstringgl-version-returns-opengl-es-cm-1-1-but-my-phone-supports-opengl
|
||||
*/
|
||||
const EGLint context_attrib_list[] = {
|
||||
// request a context using Open GL ES 2.0
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
/*thanks to the dudes of stackoverflow for explaining how the attrib_list works*/
|
||||
state->egl_context = eglCreateContext(state->egl_display, state->egl_config,
|
||||
EGL_NO_CONTEXT, context_attrib_list);
|
||||
if(state->egl_context == EGL_NO_CONTEXT) {
|
||||
fprintf(stderr, "Couldn't create EGL context\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(!eglMakeCurrent(state->egl_display, state->egl_surface,
|
||||
state->egl_surface, state->egl_context)) {
|
||||
fprintf(stderr, "Couldn't make EGL context current\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* refer to demo_2_egl */
|
||||
void init_implementation( char **paths, int count){
|
||||
device_handler_init();
|
||||
for( int i = 0; i < count; i++){
|
||||
device_handler_add(paths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int create_window_implementation( const char *title){
|
||||
state.running = 1;
|
||||
|
||||
wayland_connect(&state);
|
||||
/*
|
||||
*/
|
||||
egl_init(&state);
|
||||
}
|
||||
|
||||
void init_window_size_implementation( int width, int height){
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
}
|
||||
|
||||
|
||||
/* BAD implementation : perpetual malloc and free */
|
||||
void sleep_implementation(){
|
||||
/* the second field should be the remainder, in case of premature ending */
|
||||
struct timespec *millisecond = malloc( sizeof( struct timespec));
|
||||
millisecond->tv_sec=0;
|
||||
millisecond->tv_nsec=1e6;
|
||||
nanosleep( millisecond, NULL); /*won't compensate any delay due to the loop body*/
|
||||
free(millisecond);
|
||||
}
|
||||
|
||||
void swap_buffers_implementation(){
|
||||
/* should not be here (glued) */
|
||||
wl_display_dispatch_pending(state.display);
|
||||
eglSwapBuffers( state.egl_display, state.egl_surface);
|
||||
}
|
||||
25
sources/glut_extensions.c
Normal file
25
sources/glut_extensions.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../headers/glut_extensions.h"
|
||||
#include "../headers/input/touch/touch_controller_L1_builder.h"
|
||||
#include "../headers/input/touch/touch_controller_L2.h"
|
||||
#include "../headers/input/touch/touch_controller_L3.h"
|
||||
|
||||
|
||||
uint8_t get_count_fallback() { return 0; }
|
||||
|
||||
static const touch_data_proxy touch_proxy = {
|
||||
.get_count = get_count_fallback,
|
||||
.get_tracked_events = TC_L1_builder_copy_tracked_events,
|
||||
.getAABB = TC_L2_getAABB,
|
||||
.get_width = TC_L2_get_width,
|
||||
.get_angle = TC_L2_get_angle,
|
||||
.get_midpoint = TC_L2_get_midpoint,
|
||||
.get_position_deltas = TC_L3_get_position_deltas,
|
||||
.get_angle_delta = TC_L3_get_angle_delta,
|
||||
.get_midpoint_delta = TC_L3_get_midpoint_delta
|
||||
};
|
||||
|
||||
touch_data_proxy glutGetTouchProxy(){
|
||||
return touch_proxy;
|
||||
}
|
||||
53
sources/glut_graphics.c
Normal file
53
sources/glut_graphics.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#include "../headers/glut_graphics.h"
|
||||
|
||||
/* each request simply sets a flag to be consumed by the main loop, (no need for more than one redraw per cycle) */
|
||||
int must_redraw = 0;
|
||||
const int REDRAW_TIMER_INIT = 16;
|
||||
int redraw_timer = 0;
|
||||
|
||||
void (*redraw_callback) (void) = NULL;
|
||||
|
||||
void assignRedrawCallback( void ( *callback) ( void)){
|
||||
if( NULL != redraw_callback){
|
||||
return;
|
||||
}
|
||||
|
||||
redraw_callback = callback;
|
||||
}
|
||||
|
||||
void issueRedraw(){
|
||||
must_redraw = 1;
|
||||
}
|
||||
|
||||
void consume_redraws(){
|
||||
/* ensuring a minimum interval of 1/FPS secs between redraws
|
||||
if the timer
|
||||
*/
|
||||
redraw_timer--;
|
||||
if( redraw_timer < 0){
|
||||
redraw_timer = 0;
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
|
||||
if( 0 == must_redraw){
|
||||
return;
|
||||
}
|
||||
|
||||
must_redraw = 0;
|
||||
|
||||
/* what to do if the redraw callback is not set?
|
||||
is not necessarily an error
|
||||
*/
|
||||
if( NULL == redraw_callback){
|
||||
return;
|
||||
}
|
||||
|
||||
redraw_timer = REDRAW_TIMER_INIT;
|
||||
/* here the drawing implementation */
|
||||
|
||||
redraw_callback();
|
||||
}
|
||||
128
sources/glut_input.c
Normal file
128
sources/glut_input.c
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <stddef.h>
|
||||
#include "../headers/glut_input.h"
|
||||
#include "../headers/input/input_events.h"
|
||||
|
||||
#include <stdio.h> /* a single printf */
|
||||
|
||||
void ( *keyboard_callback) ( unsigned char key, int x, int y) = NULL;
|
||||
void ( *mouse_motion_callback) ( int x, int y) = NULL;
|
||||
|
||||
void warp_pointer_implementation( int x, int y){}
|
||||
|
||||
void assignKeyboardCallback( void ( *callback) (unsigned char key, int x, int y)){
|
||||
if(keyboard_callback != NULL){
|
||||
return;
|
||||
}
|
||||
keyboard_callback = callback;
|
||||
}
|
||||
|
||||
void assignMouseMotionCallback( void ( *callback) (int x, int y)){
|
||||
if(mouse_motion_callback != NULL){
|
||||
return;
|
||||
}
|
||||
mouse_motion_callback = callback;
|
||||
}
|
||||
|
||||
void process_inputs(){
|
||||
int count, index;
|
||||
device_event *events, current;
|
||||
|
||||
count = device_handler_poll_events(&events);
|
||||
|
||||
if( count){
|
||||
printf("glut will dispatch %d events\n", count);
|
||||
}
|
||||
for( index = 0; index < count; index++){
|
||||
current = events[index];
|
||||
dispatch_input_event(current);
|
||||
}
|
||||
|
||||
device_handler_destroy_events(events);
|
||||
process_key_events();
|
||||
process_cursor_events();
|
||||
}
|
||||
|
||||
static void process_cursor_events(){
|
||||
}
|
||||
|
||||
static void process_key_events(){
|
||||
int index, remapped_index;
|
||||
char key_ascii_code;
|
||||
|
||||
for( index = 0; index < KEY_CNT; index++){
|
||||
if( buffered_keys[index]){
|
||||
remapped_index = index;
|
||||
/*
|
||||
printf("this key counts as pressed! %x\n", index);
|
||||
*/
|
||||
/* could add here the selection between classic GLUT and custom keymap */
|
||||
/* for now bad case MAPPING */
|
||||
if(
|
||||
( remapped_index >= BTN_GAMEPAD && remapped_index <= BTN_THUMBR)
|
||||
||
|
||||
( remapped_index >= BTN_DPAD_UP && remapped_index <= BTN_DPAD_RIGHT)
|
||||
){
|
||||
printf("should remap\n");
|
||||
remapped_index = remap_joypad_to_keyboard( remapped_index);
|
||||
}
|
||||
|
||||
key_ascii_code = get_ascii_code(remapped_index);
|
||||
|
||||
/*
|
||||
printf("going to keyCB %d\n", key_ascii_code);
|
||||
*/
|
||||
|
||||
/* NULL character would be zero */
|
||||
if( 0 < key_ascii_code){
|
||||
keyboard_callback( key_ascii_code, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short remap_joypad_to_keyboard( unsigned short linux_key){
|
||||
switch( linux_key){
|
||||
case BTN_DPAD_DOWN:
|
||||
/* return KEY_DOWN; */
|
||||
return KEY_S;
|
||||
case BTN_DPAD_UP:
|
||||
/* return KEY_UP; */
|
||||
return KEY_W;
|
||||
case BTN_DPAD_LEFT:
|
||||
return KEY_A;
|
||||
/* return KEY_LEFT; */
|
||||
case BTN_DPAD_RIGHT:
|
||||
return KEY_D;
|
||||
/* return KEY_RIGHT; */
|
||||
|
||||
case BTN_NORTH:
|
||||
return KEY_0;
|
||||
case BTN_WEST:
|
||||
return KEY_1;
|
||||
case BTN_SOUTH:
|
||||
return KEY_2;
|
||||
case BTN_EAST:
|
||||
return KEY_3;
|
||||
|
||||
case BTN_TL:
|
||||
return KEY_4;
|
||||
case BTN_TL2:
|
||||
return KEY_5;
|
||||
case BTN_TR2:
|
||||
return KEY_6;
|
||||
case BTN_TR:
|
||||
return KEY_7;
|
||||
|
||||
case BTN_START:
|
||||
return KEY_SPACE;
|
||||
case BTN_SELECT:
|
||||
return KEY_ESC;
|
||||
/*
|
||||
case BTN_THUMBL:
|
||||
case BTN_THUMBR:
|
||||
*/
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
170
sources/glut_timers.c
Normal file
170
sources/glut_timers.c
Normal file
@@ -0,0 +1,170 @@
|
||||
#include <stdlib.h>
|
||||
#include "../headers/glut_timers.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int is_updating_time=0;
|
||||
|
||||
static timer_list_entry *timers_first = NULL;
|
||||
static timer_list_entry *timers_last = NULL;
|
||||
|
||||
static timer_list_entry *unissued_timers_first = NULL;
|
||||
static timer_list_entry *unissued_timers_last = NULL;
|
||||
|
||||
/*CODE duplication*/
|
||||
void timers_add_to_unissued(timer_list_entry *toAdd){
|
||||
//printf("timers add to unissued begin\n");
|
||||
if(unissued_timers_last != NULL){
|
||||
unissued_timers_last->next = toAdd;
|
||||
}
|
||||
else{
|
||||
if(NULL == unissued_timers_first){
|
||||
unissued_timers_first=toAdd;
|
||||
}
|
||||
}
|
||||
unissued_timers_last = toAdd;
|
||||
//printf("timers add to unissued end\n");
|
||||
}
|
||||
|
||||
void timers_add(timer_list_entry *toAdd){
|
||||
//printf("timers add begin\n");
|
||||
if(is_updating_time){
|
||||
timers_add_to_unissued( toAdd);
|
||||
return;
|
||||
}
|
||||
|
||||
if(timers_last != NULL){
|
||||
timers_last->next = toAdd;
|
||||
}
|
||||
else{
|
||||
if(NULL == timers_first){
|
||||
timers_first=toAdd;
|
||||
}
|
||||
}
|
||||
timers_last = toAdd;
|
||||
//printf("timers add end\n");
|
||||
}
|
||||
|
||||
/**
|
||||
FULL OF PRINT STATEMENTS DUE TO A BUG MYSTERIOUSLY FIXED, see decrease_timers()
|
||||
*/
|
||||
/* unsafe, not checking the validity of the previous, toRemove precondition */
|
||||
void timers_remove(
|
||||
timer_list_entry *previous,
|
||||
timer_list_entry *toRemove
|
||||
){
|
||||
/*
|
||||
printf("timers remove\n");
|
||||
printf("timers remove previous is %p\n", (void*) previous);
|
||||
printf("timers remove toRemove is %p\n", (void*) toRemove);
|
||||
|
||||
if(NULL != previous){
|
||||
printf("timers remove previous->next is %p\n", (void*) previous->next);
|
||||
if(previous->next != toRemove){
|
||||
printf("timers remove previous->next is not the same as toRemove\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
printf("previous counts as NULL\n");
|
||||
}
|
||||
if(toRemove->next == NULL){
|
||||
printf("timers remove toRemove->next is NULL\n");
|
||||
}
|
||||
else{
|
||||
printf("timers remove toRemove->next is %p\n", (void*) toRemove->next);
|
||||
}
|
||||
*/
|
||||
if( toRemove == timers_first){
|
||||
// printf("timers remove toremove is the first\n");
|
||||
timers_first = timers_first->next;
|
||||
if(NULL == timers_first){
|
||||
timers_last = NULL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// printf("timers remove toremove is not the first\n");
|
||||
previous->next = toRemove->next;
|
||||
/* could move elsewhere, timer_last is an auxiliary variable */
|
||||
if( NULL == previous->next){
|
||||
timers_last = previous;
|
||||
}
|
||||
// printf("timers remove previous->next is now %p\n", (void*) previous->next);
|
||||
}
|
||||
/* i added this and now works. should not need it, smells like bigger bug */
|
||||
toRemove->next = NULL;
|
||||
// printf("timers remove end\n");
|
||||
}
|
||||
|
||||
void append_unissued_timers(){
|
||||
if( NULL == unissued_timers_first){
|
||||
return;
|
||||
}
|
||||
timers_add(unissued_timers_first);
|
||||
timers_last=unissued_timers_last;
|
||||
unissued_timers_first = NULL;
|
||||
unissued_timers_last = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
FULL OF PRINT STATEMENTS DUE TO A BUG MYSTERIOUSLY FIXED
|
||||
*/
|
||||
void decrease_timers(){
|
||||
timer_list_entry *current, *previous;
|
||||
previous = NULL;
|
||||
|
||||
int count = 0; /*DEBUG ONLY*/
|
||||
current = timers_first;
|
||||
|
||||
is_updating_time=1;
|
||||
|
||||
//printf("decrease timers begin\n");
|
||||
|
||||
while( current != NULL){
|
||||
/*
|
||||
printf("decreasing timer\n");
|
||||
printf("timer addr would be %p\n", (void*) current);
|
||||
*/
|
||||
current->remaining_ms--;
|
||||
//printf("decreased timer\n");
|
||||
if( 0 >= current->remaining_ms){
|
||||
//printf("will crash on removal?\n");
|
||||
timers_remove( previous, current);
|
||||
//printf("removed timer\nbreak on callback?\n");
|
||||
current->callback(0); /*should receive an int (i guess the runover time)*/
|
||||
//printf("callback done\nbreak on free?\n");
|
||||
free( current);
|
||||
//printf("was not the free\n");
|
||||
/* would make a removal from head inconsistent */
|
||||
if(previous != NULL){
|
||||
//printf("previous is not null during the looping, sliding\n");
|
||||
current=previous;
|
||||
}
|
||||
}
|
||||
/*
|
||||
printf("updating cursors\n");
|
||||
printf("previous is %p\n", (void*) previous);
|
||||
printf("current is %p\n", (void*) current);
|
||||
*/
|
||||
previous = current;
|
||||
current = current->next;
|
||||
/*
|
||||
printf("updated cursors\n");
|
||||
printf("previous is %p\n", (void*) previous);
|
||||
printf("current is %p\n", (void*) current);
|
||||
*/
|
||||
count++;
|
||||
// printf("wasn't even the counter\n");
|
||||
}
|
||||
// printf("out of the timers loop\n");
|
||||
/*
|
||||
printf("processed %d timers\n", count);
|
||||
*/
|
||||
is_updating_time=0;
|
||||
append_unissued_timers();
|
||||
// printf("reached the end of decrease timers\n");
|
||||
}
|
||||
|
||||
int timers_isEmpty(){
|
||||
return ( NULL == timers_first); /*could also check timer_last but it is an auxiliary variable */
|
||||
}
|
||||
303
sources/input/input_events.c
Normal file
303
sources/input/input_events.c
Normal file
@@ -0,0 +1,303 @@
|
||||
#include "../../headers/input/input_events.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* capturing all the keys known by linux */
|
||||
unsigned char buffered_keys[KEY_CNT];
|
||||
|
||||
/*
|
||||
glut exposes
|
||||
keypress
|
||||
until a key is pressed, will keep invoking the keypress callback
|
||||
mousemoved
|
||||
absolute x and y of the mouse
|
||||
*/
|
||||
|
||||
void dispatch_input_event( device_event event){
|
||||
switch( event.type){
|
||||
case EV_SYN:
|
||||
//printf("separator for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_KEY:
|
||||
dispatch_input_key_event( event);
|
||||
break;
|
||||
case EV_REL:
|
||||
//printf("delta event %d : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_ABS:
|
||||
dispatch_input_absolute_event( event);
|
||||
break;
|
||||
case EV_MSC:
|
||||
//printf("miscellaneous event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_SW:
|
||||
//printf("binary switch event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_LED:
|
||||
//printf("led toggle event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_SND:
|
||||
//printf("sound event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_REP:
|
||||
//printf("autorepeating event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_FF:
|
||||
//printf("force-feedback event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_PWR:
|
||||
//printf("power toggle event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
case EV_FF_STATUS:
|
||||
//printf("force-feedback status event for %u : %d\n", event.code, event.value);
|
||||
break;
|
||||
default:
|
||||
printf("unknown event for %u : %d\n", event.code, event.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dispatch_input_key_event( device_event event){
|
||||
/* goes from KEY_RESERVED = 0 to KEY_MAX = 0x2ff */
|
||||
|
||||
printf("this is dispatch_input_key_event\n");
|
||||
|
||||
/* common keyboard codes from 0 up to KEY_MACRO, before KEY_MUTE */
|
||||
if( event.code < KEY_MUTE){
|
||||
dispatch_keyboard_keys( event);
|
||||
}
|
||||
/* INTERESTING KEYS BEGIN */
|
||||
/* interesting keys from KEY_MIN_INTERESTING = KEY_MUTE up to BTN_DEAD, before BTN_GAMEPAD */
|
||||
else if( event.code >= KEY_MUTE && event.code <= BTN_DEAD){
|
||||
dispatch_interesting_keys_1( event);
|
||||
}
|
||||
/* NO GAP */
|
||||
/* joypad keys, from BTN_GAMEPAD up to BTN_THUMBR, gap of one before BTN_DIGI */
|
||||
else if( event.code >= BTN_GAMEPAD && event.code <= BTN_THUMBR){
|
||||
dispatch_interesting_keys_2( event);
|
||||
}
|
||||
/* GAP OF ONE between this and the previous.. */
|
||||
/* ignored keys */
|
||||
/* interesting keys, from BTN_DIGI up to the MAX */
|
||||
else if( event.code >= BTN_DIGI && event.code <= KEY_MAX){
|
||||
dispatch_interesting_keys_3( event);
|
||||
}
|
||||
else{
|
||||
printf("UNKNOWN KEY EVENT CODE %d with value %d\n", event.code, event.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dispatch_input_absolute_event( device_event event){
|
||||
if(event.code < ABS_RESERVED){
|
||||
dispatch_regular_absolute_event( event);
|
||||
}
|
||||
/* a gap for ABS_RESERVED */
|
||||
else if( event.code >= ABS_MT_SLOT && event.code <= ABS_MT_TOOL_Y){
|
||||
dispatch_multitouch_event( event);
|
||||
}
|
||||
else{
|
||||
printf("UNKNOWN ABSOLUTE EVENT CODE %d with value %d\n", event.code, event.value);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_regular_absolute_event( device_event event){
|
||||
switch( event.code){
|
||||
case ABS_X:
|
||||
//cursor_x = event.value;
|
||||
//printf("WARN !!! ABS_X untracked %d\n", event.value);
|
||||
break;
|
||||
case ABS_Y:
|
||||
//cursor_y = event.value;
|
||||
//printf("WARN !!! ABS_Y untracked %d\n", event.value);
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN REGULAR ABSOLUTE EVENT CODE %d with value %d\n", event.code, event.value);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_multitouch_event( device_event event){
|
||||
switch( event.code){
|
||||
case ABS_MT_SLOT: /* MT slot being modified */
|
||||
//printf("ABS_MT_SLOT [MULTITOUCH SLOT MODIFIED] %d\n", event.value);
|
||||
TC_L1_builder_set_slot_number( event.value);
|
||||
break;
|
||||
case ABS_MT_TOUCH_MAJOR: /* Major axis of touching ellipse */
|
||||
// printf("ABS_MT_TOUCH_MAJOR [MAJOR AXIS OF TOUCH ELLIPSE] %d\n", event.value);
|
||||
TC_L1_builder_set_major_axis( event.value);
|
||||
break;
|
||||
case ABS_MT_TOUCH_MINOR: /* Minor axis (omit if circular) */
|
||||
// printf("ABS_MT_TOUCH_MINOR [MINOR AXIS OF TOUCH ELLIPSE] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_WIDTH_MAJOR: /* Major axis of approaching ellipse */
|
||||
// printf("ABS_MT_WIDTH_MAJOR [MAJOR AXIS OF APPROACHING ELLIPSE] %d\n", event.value);
|
||||
TC_L1_builder_set_approaching_major_axis( event.value);
|
||||
break;
|
||||
case ABS_MT_WIDTH_MINOR: /* Minor axis (omit if circular) */
|
||||
// printf("ABS_MT_WIDTH_MINOR [MINOR AXIS OF APPROACHING ELLIPSE] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_ORIENTATION: /* Ellipse orientation */
|
||||
// printf("ABS_MT_ORIENTATION [ELLIPSE ORIENTATION] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_POSITION_X: /* Center X touch position */
|
||||
// printf("ABS_MT_POSITION_X [CENTER X TOUCH POSITION] %d\n", event.value);
|
||||
TC_L1_builder_set_position_x( event.value);
|
||||
break;
|
||||
case ABS_MT_POSITION_Y: /* Center Y touch position */
|
||||
//printf("ABS_MT_POSITION_Y [CENTER Y TOUCH POSITION] %d\n", event.value);
|
||||
TC_L1_builder_set_position_y( event.value);
|
||||
break;
|
||||
case ABS_MT_TOOL_TYPE: /* Type of touching device */
|
||||
// printf("ABS_MT_TOOL_TYPE [TYPE OF TOUCHING DEVICE] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_BLOB_ID: /* Group a set of packets as a blob */
|
||||
// printf("ABS_MT_BLOB_ID [GROUP A SET OF PACKETS AS A BLOB] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_TRACKING_ID: /* Unique ID of initiated contact */
|
||||
//printf("ABS_MT_TRACKING_ID [UNIQUE ID OF INITIATED CONTACT] %d\n", event.value);
|
||||
TC_L1_builder_set_tracking_id( event.value);
|
||||
break;
|
||||
case ABS_MT_PRESSURE: /* Pressure on contact area */
|
||||
// printf("ABS_MT_PRESSURE [PRESSURE ON CONTACT AREA] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_DISTANCE: /* Contact hover distance */
|
||||
// printf("ABS_MT_DISTANCE [CONTACT HOVER DISTANCE] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_TOOL_X: /* Center X tool position */
|
||||
// printf("ABS_MT_TOOL_X [CENTER X TOOL POSITION] %d\n", event.value);
|
||||
break;
|
||||
case ABS_MT_TOOL_Y: /* Center Y tool position */
|
||||
// printf("ABS_MT_TOOL_Y [CENTER Y TOOL POSITION] %d\n", event.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* common keyboard codes from 0 up to KEY_MACRO, before KEY_MUTE */
|
||||
void dispatch_keyboard_keys( device_event event){
|
||||
printf("IGNORED KEY EVENT CODE %d with value %d [KEYBOARD GROUP]\n", event.code, event.value);
|
||||
}
|
||||
|
||||
/* interesting keys from KEY_MIN_INTERESTING = KEY_MUTE up to BTN_DEAD, before BTN_GAMEPAD */
|
||||
void dispatch_interesting_keys_1( device_event event){
|
||||
printf("UNKNOWN KEY EVENT CODE %d with value %d [INTERESTING GROUP]\n", event.code, event.value);
|
||||
}
|
||||
|
||||
/* joypad keys, from BTN_GAMEPAD up to BTN_THUMBR, gap of one before BTN_DIGI */
|
||||
void dispatch_interesting_keys_2( device_event event){
|
||||
|
||||
/* NO OFFSET NEEDED, THEY START FROM 0 */
|
||||
|
||||
/* could also store the transitions
|
||||
unsigned char buffered_keys_transition[KEY_CNT];
|
||||
*/
|
||||
printf("interesting key [JOYPAD] %x %x\n", event.code, event.value);
|
||||
buffered_keys[event.code] = (char) event.value; /* they only have 3 states : press, released, retriggered */
|
||||
}
|
||||
|
||||
|
||||
/* interesting keys, from BTN_DIGI up to the MAX */
|
||||
void dispatch_interesting_keys_3( device_event event){
|
||||
if( event.code == BTN_TOUCH){
|
||||
printf("TOUCH EVENT %s\n", (event.value) ? "BEGIN" : "END");
|
||||
}
|
||||
else{
|
||||
printf("UNKNOWN KEY EVENT CODE %d with value %d [INTERESTING GROUP]\n", event.code, event.value);
|
||||
buffered_keys[event.code] = (char) event.value; /* they only have 3 states : press, released, retriggered */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* reserving the NULL character code for unsupported keys
|
||||
maps from linux input.h key codes to ascii
|
||||
*/
|
||||
/*
|
||||
UPPERCASE REQUIRES QUERYING THE STATE OF THE SHIFT KEY
|
||||
*/
|
||||
char get_ascii_code( unsigned short linux_code){
|
||||
/* yanderedev would be proud of me... :'( */
|
||||
switch( linux_code){
|
||||
case KEY_DELETE:
|
||||
return 0x18; /* refer to ascii CANCEL (non printable) instead of DELETE (printable)*/
|
||||
case KEY_ESC:
|
||||
return 0x1b;
|
||||
/* KEY_1 is 0x2 KEY_9 is 0xA KEY_0 is 0xB */
|
||||
/* ASCII 0 is 0x30 ASCII 9 is 0x39 */
|
||||
case KEY_1:
|
||||
case KEY_2:
|
||||
case KEY_3:
|
||||
case KEY_4:
|
||||
case KEY_5:
|
||||
case KEY_6:
|
||||
case KEY_7:
|
||||
case KEY_8:
|
||||
case KEY_9:
|
||||
/* ASCII 1 - (lin_1 - lin_code) */
|
||||
return ( 0x31 + ( 0x2 - linux_code));
|
||||
case KEY_0:
|
||||
return 0x30;
|
||||
|
||||
case KEY_BACKSPACE:
|
||||
return 0x8;
|
||||
case KEY_TAB:
|
||||
return 0x9;
|
||||
case KEY_SPACE:
|
||||
return 0x20;
|
||||
|
||||
case KEY_A:
|
||||
return 0x41;
|
||||
case KEY_B:
|
||||
return 0x42;
|
||||
case KEY_C:
|
||||
return 0x43;
|
||||
case KEY_D:
|
||||
return 0x44;
|
||||
case KEY_E:
|
||||
return 0x45;
|
||||
case KEY_F:
|
||||
return 0x46;
|
||||
case KEY_G:
|
||||
return 0x47;
|
||||
case KEY_H:
|
||||
return 0x48;
|
||||
case KEY_I:
|
||||
return 0x49;
|
||||
case KEY_J:
|
||||
return 0x4a;
|
||||
case KEY_K:
|
||||
return 0x4b;
|
||||
case KEY_L:
|
||||
return 0x4c;
|
||||
case KEY_M:
|
||||
return 0x4d;
|
||||
case KEY_N:
|
||||
return 0x4e;
|
||||
case KEY_O:
|
||||
return 0x4f;
|
||||
case KEY_P:
|
||||
return 0x50;
|
||||
case KEY_Q:
|
||||
return 0x51;
|
||||
case KEY_R:
|
||||
return 0x52;
|
||||
case KEY_S:
|
||||
return 0x53;
|
||||
case KEY_T:
|
||||
return 0x54;
|
||||
case KEY_U:
|
||||
return 0x55;
|
||||
case KEY_V:
|
||||
return 0x56;
|
||||
case KEY_W:
|
||||
return 0x57;
|
||||
case KEY_X:
|
||||
return 0x58;
|
||||
case KEY_Y:
|
||||
return 0x59;
|
||||
case KEY_Z:
|
||||
return 0x5a;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
162
sources/input/touch/touch_controller_L1_builder.c
Normal file
162
sources/input/touch/touch_controller_L1_builder.c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "../../../headers/input/touch/touch_controller_L1_builder.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* otherwise
|
||||
error: variably modified ‘tracked’ at file scope
|
||||
even if tracked_size gets declared as const
|
||||
*/
|
||||
#define tracked_size 255
|
||||
/* could hold 256 using tracked_size + 1 but don't want to mess the copy tracked loop */
|
||||
static touch_event *tracked[ tracked_size] = { NULL };
|
||||
static uint8_t tracked_count = 0;
|
||||
|
||||
static touch_event *last_event = NULL;
|
||||
static touch_event *current_event = NULL;
|
||||
|
||||
|
||||
touch_event* tracked_find( uint64_t slot_number){
|
||||
return tracked[slot_number];
|
||||
}
|
||||
|
||||
void tracked_remove( touch_event *toremove){
|
||||
tracked[toremove->slot_number] = NULL;
|
||||
tracked_count--;
|
||||
}
|
||||
|
||||
void tracked_add( touch_event *toadd){
|
||||
tracked[toadd->slot_number] = toadd;
|
||||
tracked_count++;
|
||||
}
|
||||
|
||||
uint8_t tracked_get_first_free_slot_number(){
|
||||
int first_free_slot_number = 0;
|
||||
while(
|
||||
tracked[first_free_slot_number]
|
||||
&&
|
||||
! ( tracked_size == first_free_slot_number)
|
||||
){
|
||||
first_free_slot_number++;
|
||||
}
|
||||
if( tracked_size == first_free_slot_number){
|
||||
fprintf( stderr, "no more slot_numbers for tracked touches\n");
|
||||
exit(1);
|
||||
}
|
||||
return first_free_slot_number;
|
||||
}
|
||||
|
||||
/* yes int instead of uint */
|
||||
/**
|
||||
SCHIFO : il primo tocco non ha mai ABS_MT_SLOT
|
||||
ma parte direttamente da ABS_MT_TRACKING_ID
|
||||
|
||||
QUINDI se viene settato senza ABS_MT_SLOT
|
||||
|
||||
|
||||
*/
|
||||
void TC_L1_builder_set_tracking_id( int64_t tracking_id){
|
||||
/*
|
||||
fix brutta
|
||||
*/
|
||||
if( ! current_event){
|
||||
if( last_event){
|
||||
printf("current was unset : setting as the last, which had slot number %ld\n", last_event->slot_number);
|
||||
current_event = last_event;
|
||||
}
|
||||
else{
|
||||
printf("current was unset : setting as NEW\n");
|
||||
TC_L1_builder_set_slot_number( tracked_get_first_free_slot_number());
|
||||
}
|
||||
}
|
||||
|
||||
/* unsigned aghhh */
|
||||
if( -1u == tracking_id){
|
||||
printf("REMOVE\n");
|
||||
tracked_remove( current_event);
|
||||
free( current_event);
|
||||
current_event = NULL;
|
||||
}
|
||||
else{
|
||||
current_event->tracking_id = tracking_id;
|
||||
}
|
||||
}
|
||||
|
||||
void TC_L1_builder_set_position_x( uint64_t x_coord){
|
||||
current_event->position.x = x_coord;
|
||||
}
|
||||
|
||||
void TC_L1_builder_set_position_y( uint64_t y_coord){
|
||||
current_event->position.y = y_coord;
|
||||
}
|
||||
|
||||
void TC_L1_builder_set_major_axis( uint64_t width){
|
||||
|
||||
}
|
||||
|
||||
void TC_L1_builder_set_approaching_major_axis( uint64_t width){
|
||||
|
||||
}
|
||||
|
||||
void TC_L1_builder_set_slot_number( uint64_t number){
|
||||
touch_event* target = tracked_find( number);
|
||||
if( ! target){
|
||||
printf("FETCHING DID NOT SUCCEED, allocating\n");
|
||||
target = malloc( sizeof( touch_event));
|
||||
target->slot_number = number;
|
||||
tracked_add( target);
|
||||
}
|
||||
else{
|
||||
printf("FETCHING SUCCEEDED\n");
|
||||
target->slot_number = number;
|
||||
}
|
||||
last_event = current_event;
|
||||
current_event = target;
|
||||
}
|
||||
|
||||
void TC_L1_builder_copy_tracked_events( touch_event ***store, uint8_t *count){
|
||||
//printf("TC_L1_builder_copy_tracked_events begins with %p, %d\n", (void*) *store, *count);
|
||||
|
||||
if( ! tracked_count){
|
||||
//printf("TC_L1_b_c_t_e has nothing to copy");
|
||||
*store = NULL;
|
||||
*count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("tracked\n");
|
||||
//for( uint8_t i = 0; i < tracked_count; i++){
|
||||
// printf( "%ld\n", tracked[i]->tracking_id);
|
||||
//}
|
||||
|
||||
*store = malloc( tracked_count * sizeof( touch_event* ));
|
||||
touch_event *clone;
|
||||
touch_event *current;
|
||||
int index = 0;
|
||||
|
||||
for( int i = 0; i < tracked_size; i++){
|
||||
current = tracked[i];
|
||||
if( current){
|
||||
clone = malloc( sizeof( touch_event));
|
||||
touch_event_copy( clone, current);
|
||||
(*store)[index++] = clone;
|
||||
}
|
||||
}
|
||||
*count = index;
|
||||
|
||||
//printf("copied\n");
|
||||
//for( uint8_t i = 0; i < *count; i++){
|
||||
// printf( "%ld\n", (*store)[i]->tracking_id);
|
||||
//}
|
||||
|
||||
//printf("TC_L1_builder_copy_tracked_events ends with %p, %d\n", (void*) *store, *count);
|
||||
}
|
||||
|
||||
void TC_L1_builder_destroy_copy( touch_event **store, uint8_t count){
|
||||
for( int i = 0; i < count; i++){
|
||||
free(store[i]);
|
||||
}
|
||||
if( count){
|
||||
free( store);
|
||||
}
|
||||
}
|
||||
81
sources/input/touch/touch_controller_L2.c
Normal file
81
sources/input/touch/touch_controller_L2.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "../../../headers/input/touch/touch_controller_L2.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* ...but the compiler throws an error, so math.h does not really define it */
|
||||
/* aarch64-linux-gnu/include/math.h already defines it */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
touch_coordinates* TC_L2_getAABB( touch_event **events, uint8_t count){
|
||||
touch_coordinates* AABB = malloc( 2 * sizeof(touch_coordinates));
|
||||
uint8_t minX = UINT8_MAX;
|
||||
uint8_t maxX = 0;
|
||||
uint8_t minY = UINT8_MAX;
|
||||
uint8_t maxY = 0;
|
||||
|
||||
touch_event *current;
|
||||
for( uint8_t i = 0; i < count; i++){
|
||||
current = events[i];
|
||||
if( minX > current->position.x)
|
||||
minX = current->position.x;
|
||||
|
||||
if( maxX < current->position.x)
|
||||
maxX = current->position.x;
|
||||
|
||||
if( minY > current->position.y)
|
||||
minY = current->position.y;
|
||||
|
||||
if( maxY < current->position.y)
|
||||
maxY = current->position.y;
|
||||
}
|
||||
|
||||
AABB[0].x = minX;
|
||||
AABB[0].y = minY;
|
||||
AABB[1].x = maxX;
|
||||
AABB[1].y = maxY;
|
||||
return AABB;
|
||||
}
|
||||
|
||||
float TC_L2_get_width( touch_event **events, uint8_t count){
|
||||
touch_coordinates* AABB = TC_L2_getAABB( events, count);
|
||||
|
||||
uint16_t dx = AABB[0].x - AABB[1].x;
|
||||
uint16_t dy = AABB[0].y - AABB[1].y;
|
||||
float width = sqrtf( powf( dx, 2) + powf( dy, 2));
|
||||
|
||||
free( AABB);
|
||||
return width;
|
||||
}
|
||||
|
||||
float TC_L2_get_angle( touch_event **events, uint8_t count){
|
||||
touch_coordinates* AABB = TC_L2_getAABB( events, count);
|
||||
|
||||
uint16_t dx = AABB[0].x - AABB[1].x;
|
||||
uint16_t dy = AABB[0].y - AABB[1].y;
|
||||
|
||||
free( AABB);
|
||||
return atan2f(dx, dy) * 180 / M_PI;
|
||||
|
||||
}
|
||||
|
||||
touch_coordinates* TC_L2_get_midpoint( touch_event **events, uint8_t count){
|
||||
uint32_t sum_x;
|
||||
uint32_t sum_y;
|
||||
|
||||
if( !count){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( uint8_t i = 0; i < count; i++){
|
||||
sum_x += events[i]->position.x;
|
||||
sum_y += events[i]->position.y;
|
||||
}
|
||||
|
||||
touch_coordinates *mid = malloc( sizeof( touch_coordinates));
|
||||
mid->x = sum_x / count;
|
||||
mid->y = sum_y / count;
|
||||
|
||||
return mid;
|
||||
}
|
||||
145
sources/input/touch/touch_controller_L3.c
Normal file
145
sources/input/touch/touch_controller_L3.c
Normal file
@@ -0,0 +1,145 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
|
||||
/* a single printf */
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../headers/input/touch/touch_controller_L2.h"
|
||||
#include "../../../headers/input/touch/touch_controller_L3.h"
|
||||
#include "../../../headers/input/touch/touch_controller_L3_deltas_compute.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
WHAT POINTER IS THE THIRD???
|
||||
|
||||
*/
|
||||
static int cmp_uint64(const void *p1, const void *p2)
|
||||
{
|
||||
uint64_t a = *(const uint64_t*) p1;
|
||||
uint64_t b = *(const uint64_t*) p2;
|
||||
//printf("comparison between %ld and %ld\n", a, b);
|
||||
if( a < b ){
|
||||
return 1;
|
||||
}
|
||||
else if( a > b){
|
||||
return -1;
|
||||
}
|
||||
else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* returns the sorted tracking_ids of a touch_coordinates array */
|
||||
void touch_events_to_sorted_ids( uint64_t **sortedIds, touch_event **full, uint8_t full_count){
|
||||
//printf("sorting an array of ids long %d\n", full_count);
|
||||
*sortedIds = malloc( full_count * sizeof( uint64_t));
|
||||
//printf("populate\n");
|
||||
for( uint8_t i = 0; i < full_count; i++){
|
||||
// could crash here...
|
||||
( *sortedIds)[i] = full[i]->tracking_id;
|
||||
}
|
||||
//printf("begin of actual sorting\n");
|
||||
/* this NULL arg could bite */
|
||||
/* qsort_r */
|
||||
qsort( sortedIds, full_count, sizeof( uint64_t), cmp_uint64);
|
||||
}
|
||||
|
||||
void TC_L3_get_position_deltas(
|
||||
touch_event **previous, uint8_t previous_count,
|
||||
touch_event **current, uint8_t current_count,
|
||||
touch_coordinates **deltas, uint8_t *count
|
||||
){
|
||||
if( previous && current){
|
||||
uint64_t *sorted_previous_ids = NULL;
|
||||
uint64_t *sorted_current_ids = NULL;
|
||||
tracked_delta *id_deltas;
|
||||
/* the number of total id_deltas, being a sum of sets, can be greater than the single sorted_ids list
|
||||
but the output count, being their intersections, cannot
|
||||
*/
|
||||
uint16_t id_deltas_count;
|
||||
|
||||
printf("mannaggia all'abaco mostrami sti id\n");
|
||||
printf("previous\n");
|
||||
for( uint8_t i = 0; i < previous_count; i++){
|
||||
printf( "%ld\n", previous[i]->tracking_id);
|
||||
}
|
||||
|
||||
printf("current\n");
|
||||
for( uint8_t i = 0; i < current_count; i++){
|
||||
printf( "%ld\n", current[i]->tracking_id);
|
||||
}
|
||||
|
||||
printf("sort ids 1\n");
|
||||
|
||||
touch_events_to_sorted_ids( &sorted_previous_ids, previous, previous_count);
|
||||
|
||||
printf("sort ids 2\n");
|
||||
|
||||
touch_events_to_sorted_ids( &sorted_current_ids, current, current_count);
|
||||
|
||||
printf("sorted ids\n");
|
||||
|
||||
printf("get id_deltas\n");
|
||||
touch_events_sorted_ids_deltas(
|
||||
&id_deltas, &id_deltas_count,
|
||||
sorted_previous_ids, previous_count,
|
||||
sorted_current_ids, current_count
|
||||
);
|
||||
printf("got id_deltas\n");
|
||||
|
||||
free( sorted_previous_ids);
|
||||
free( sorted_current_ids);
|
||||
|
||||
uint8_t endcount = 0;
|
||||
|
||||
for( uint16_t i = 0; i < id_deltas_count; i++){
|
||||
if( TRACKED_DELTA_UNCHANGED == id_deltas[i].state){
|
||||
endcount++;
|
||||
}
|
||||
}
|
||||
|
||||
*count = endcount;
|
||||
|
||||
*deltas = new_touch_coordinates_buffer( endcount);
|
||||
|
||||
for( uint16_t i = 0; i < id_deltas_count; i++){
|
||||
tracked_delta current_id_delta = id_deltas[i];
|
||||
if( TRACKED_DELTA_UNCHANGED == current_id_delta.state){
|
||||
touch_event *prev_evt = previous[ current_id_delta.old_index];
|
||||
touch_event *next_evt = current[ current_id_delta.new_index];
|
||||
deltas[i]->x = next_evt->position.x - prev_evt->position.x;
|
||||
deltas[i]->y = next_evt->position.y - prev_evt->position.y;
|
||||
}
|
||||
}
|
||||
free( id_deltas);
|
||||
}
|
||||
else{
|
||||
printf( "previous or current are empty!\n");
|
||||
*deltas = NULL;
|
||||
*count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float TC_L3_get_angle_delta( float previous_angle, float current_angle){
|
||||
float dAngle = 0;
|
||||
dAngle = current_angle - previous_angle;
|
||||
if( dAngle > 180){
|
||||
dAngle -= 360;
|
||||
}
|
||||
else if( dAngle < -180){
|
||||
dAngle += 360;
|
||||
}
|
||||
return dAngle;
|
||||
}
|
||||
|
||||
touch_coordinates* TC_L3_get_midpoint_delta( touch_coordinates previous, touch_coordinates current){
|
||||
touch_coordinates* delta = malloc( sizeof( touch_coordinates));
|
||||
|
||||
delta->x = current.x - previous.x;
|
||||
delta->y = current.y - previous.y;
|
||||
|
||||
return delta;
|
||||
}
|
||||
110
sources/input/touch/touch_controller_L3_deltas_compute.c
Normal file
110
sources/input/touch/touch_controller_L3_deltas_compute.c
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "../../../headers/input/touch/touch_controller_L3_deltas_compute.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void delta_store(
|
||||
tracked_delta *delta, uint8_t state_flag, uint8_t cursor, uint64_t *ids_buffer
|
||||
){
|
||||
(*delta).state = state_flag;
|
||||
(*delta).tracking_id = ids_buffer[cursor];
|
||||
}
|
||||
|
||||
void increase_and_flag(
|
||||
uint8_t *cursor, uint8_t buffer_length, uint8_t *buffer_completed
|
||||
){
|
||||
(*cursor)++;
|
||||
|
||||
if( (*cursor) >= buffer_length){
|
||||
*buffer_completed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* a lot of params since sizeof(arr) does not work with heap arrays */
|
||||
/* takes two sorted arrays of ids : previous and current
|
||||
returns an array of tracked_delta(s)
|
||||
*/
|
||||
void touch_events_sorted_ids_deltas(
|
||||
tracked_delta **endbuffer, uint16_t *endcount,
|
||||
uint64_t *previous_ids, uint8_t previous_count,
|
||||
uint64_t *current_ids, uint8_t current_count
|
||||
){
|
||||
uint16_t accumulatedCounter = 0;
|
||||
|
||||
uint8_t previous_completed = 0;
|
||||
uint8_t current_completed = 0;
|
||||
|
||||
uint8_t previous_cursor = 0;
|
||||
uint8_t current_cursor = 0;
|
||||
|
||||
//until at least one of the lists has not been fully traversed, checks must be done to avoid collisions
|
||||
while( ! previous_completed && ! current_completed){
|
||||
|
||||
accumulatedCounter++;
|
||||
|
||||
if( previous_ids[previous_cursor] < current_ids[current_cursor]){
|
||||
increase_and_flag( &previous_cursor, previous_count, &previous_completed);
|
||||
}
|
||||
else if( previous_ids[previous_cursor] == current_ids[current_cursor]){
|
||||
increase_and_flag( &previous_cursor, previous_count, &previous_completed);
|
||||
increase_and_flag( ¤t_cursor, current_count, ¤t_completed);
|
||||
}
|
||||
else{
|
||||
increase_and_flag( ¤t_cursor, current_count, ¤t_completed);
|
||||
}
|
||||
}
|
||||
|
||||
accumulatedCounter += ( previous_count - previous_cursor);
|
||||
accumulatedCounter += ( current_count - current_cursor);
|
||||
|
||||
*endcount = accumulatedCounter;
|
||||
|
||||
*endbuffer = malloc( *endcount * sizeof( tracked_delta));
|
||||
|
||||
/* since the scan has already been done once, previous_completed and current_completed could be substituted by a counter_threshold variable... */
|
||||
accumulatedCounter = (uint16_t) -1u;
|
||||
|
||||
previous_completed = 0;
|
||||
current_completed = 0;
|
||||
|
||||
previous_cursor = 0;
|
||||
current_cursor = 0;
|
||||
|
||||
while( ! previous_completed && ! current_completed){
|
||||
|
||||
accumulatedCounter++;
|
||||
|
||||
if( previous_ids[previous_cursor] < current_ids[current_cursor]){
|
||||
endbuffer[accumulatedCounter]->old_index = previous_cursor;
|
||||
delta_store( endbuffer[accumulatedCounter], TRACKED_DELTA_EXITED, previous_cursor, previous_ids);
|
||||
increase_and_flag( &previous_cursor, previous_count, &previous_completed);
|
||||
}
|
||||
else if( previous_ids[previous_cursor] == current_ids[current_cursor]){
|
||||
endbuffer[accumulatedCounter]->old_index = previous_cursor;
|
||||
endbuffer[accumulatedCounter]->new_index = current_cursor;
|
||||
// both the combinations of cursor and ids_buffer will work
|
||||
delta_store( endbuffer[accumulatedCounter], TRACKED_DELTA_UNCHANGED, previous_cursor, previous_ids);
|
||||
increase_and_flag( &previous_cursor, previous_count, &previous_completed);
|
||||
increase_and_flag( ¤t_cursor, current_count, ¤t_completed);
|
||||
}
|
||||
else{
|
||||
endbuffer[accumulatedCounter]->new_index = current_cursor;
|
||||
delta_store( endbuffer[accumulatedCounter], TRACKED_DELTA_ENTERED, current_cursor, current_ids );
|
||||
increase_and_flag( ¤t_cursor, current_count, ¤t_completed);
|
||||
}
|
||||
}
|
||||
|
||||
while( ! previous_completed){
|
||||
accumulatedCounter++;
|
||||
endbuffer[accumulatedCounter]->old_index = previous_cursor;
|
||||
delta_store( endbuffer[accumulatedCounter], TRACKED_DELTA_EXITED, previous_cursor, previous_ids);
|
||||
increase_and_flag( &previous_cursor, previous_count, &previous_completed);
|
||||
}
|
||||
|
||||
while( ! current_completed){
|
||||
accumulatedCounter++;
|
||||
endbuffer[accumulatedCounter]->new_index = current_cursor;
|
||||
delta_store( endbuffer[accumulatedCounter], TRACKED_DELTA_ENTERED, current_cursor, current_ids );
|
||||
increase_and_flag( ¤t_cursor, current_count, ¤t_completed);
|
||||
}
|
||||
}
|
||||
73
sources/input/touch/touch_data.c
Normal file
73
sources/input/touch/touch_data.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../headers/input/touch/touch_data.h"
|
||||
|
||||
touch_event* touch_event_new(){
|
||||
touch_event* te = malloc( sizeof( touch_event));
|
||||
te->slot_number = 0;
|
||||
te->tracking_id = 0;
|
||||
te->position.x = 0;
|
||||
te->position.y = 0;
|
||||
return te;
|
||||
}
|
||||
|
||||
/* could use memcpy...*/
|
||||
void touch_event_copy( touch_event *dst, touch_event *src){
|
||||
dst->slot_number = src->slot_number;
|
||||
dst->tracking_id = src->tracking_id;
|
||||
dst->position.x = src->position.x;
|
||||
dst->position.y = src->position.y;
|
||||
}
|
||||
|
||||
touch_coordinates* new_touch_coordinates_buffer( uint8_t count){
|
||||
if( ! count){
|
||||
return NULL;
|
||||
}
|
||||
touch_coordinates* buffer = malloc( count * sizeof( touch_coordinates));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void free_touch_coordinates_buffer( touch_coordinates* buffer){
|
||||
if( buffer){
|
||||
free( buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void print_touch_event( touch_event *event){
|
||||
printf("touch_event info : %p\n", (void*) event);
|
||||
printf("slot_number : %ld\n", event->slot_number);
|
||||
printf("tracking_id : %ld\n", event->tracking_id);
|
||||
printf("position_x : %ld\n", event->position.x);
|
||||
printf("position_y : %ld\n", event->position.y);
|
||||
printf("touch_event info end\n");
|
||||
}
|
||||
|
||||
void touch_events_array_copy( touch_event ***dst, touch_event **src, uint8_t count){
|
||||
//printf("begin copy\n");
|
||||
if( ! count){
|
||||
//printf("nothing to copy\n");
|
||||
*dst = NULL;
|
||||
return;
|
||||
}
|
||||
*dst = malloc( count * sizeof( touch_event*));
|
||||
//printf("will copy %d items, into %p, taken from %p\n", count, ( void*) (*dst), ( void*) src);
|
||||
for( uint8_t i ; i < count; i++){
|
||||
//print_touch_event( src[i]);
|
||||
( *dst)[i] = touch_event_new();
|
||||
|
||||
//print_touch_event( ( *dst)[i]);
|
||||
|
||||
touch_event_copy( ( *dst)[i], src[i]);
|
||||
//print_touch_event( ( *dst)[i]);
|
||||
}
|
||||
//printf("end copy\n");
|
||||
}
|
||||
|
||||
void free_touch_events_array( touch_event **buffer, uint8_t count){
|
||||
for( uint8_t i; i < count; i++){
|
||||
free( buffer[i]);
|
||||
}
|
||||
free( buffer);
|
||||
}
|
||||
Reference in New Issue
Block a user