project for a (works on my devices) demo
This commit is contained in:
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