Added rudimentary gesture engine and test in gtk frontend
svn path=/trunk/netsurf/; revision=2611
This commit is contained in:
parent
8fc65f1a64
commit
8a86b6b2b4
|
@ -34,6 +34,7 @@
|
||||||
#include "netsurf/desktop/options.h"
|
#include "netsurf/desktop/options.h"
|
||||||
#include "netsurf/desktop/selection.h"
|
#include "netsurf/desktop/selection.h"
|
||||||
#include "netsurf/desktop/textinput.h"
|
#include "netsurf/desktop/textinput.h"
|
||||||
|
#include "netsurf/desktop/gesture_core.h"
|
||||||
#include "netsurf/render/box.h"
|
#include "netsurf/render/box.h"
|
||||||
#include "netsurf/render/form.h"
|
#include "netsurf/render/form.h"
|
||||||
#include "netsurf/render/font.h"
|
#include "netsurf/render/font.h"
|
||||||
|
@ -114,7 +115,11 @@ void browser_window_create(const char *url, struct browser_window *clone,
|
||||||
bw->history = history_create();
|
bw->history = history_create();
|
||||||
else
|
else
|
||||||
bw->history = history_clone(clone->history);
|
bw->history = history_clone(clone->history);
|
||||||
bw->sel = selection_create(bw);
|
if (!clone)
|
||||||
|
bw->gesturer = NULL;
|
||||||
|
else
|
||||||
|
bw->gesturer = gesturer_clone(clone->gesturer);
|
||||||
|
bw->sel = selection_create(bw);
|
||||||
bw->throbbing = false;
|
bw->throbbing = false;
|
||||||
bw->caret_callback = NULL;
|
bw->caret_callback = NULL;
|
||||||
bw->paste_callback = NULL;
|
bw->paste_callback = NULL;
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct selection;
|
||||||
struct browser_window;
|
struct browser_window;
|
||||||
struct url_data;
|
struct url_data;
|
||||||
struct bitmap;
|
struct bitmap;
|
||||||
|
struct _gesturer_state;
|
||||||
|
|
||||||
|
|
||||||
typedef void (*browser_caret_callback)(struct browser_window *bw,
|
typedef void (*browser_caret_callback)(struct browser_window *bw,
|
||||||
|
@ -44,7 +45,10 @@ struct browser_window {
|
||||||
|
|
||||||
/** Window history structure. */
|
/** Window history structure. */
|
||||||
struct history *history;
|
struct history *history;
|
||||||
|
|
||||||
|
/** Gesturer for this browser window */
|
||||||
|
struct _gesturer_state *gesturer;
|
||||||
|
|
||||||
/** Selection state */
|
/** Selection state */
|
||||||
struct selection *sel;
|
struct selection *sel;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,342 @@
|
||||||
|
/*
|
||||||
|
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||||
|
* Licensed under the GNU General Public License,
|
||||||
|
* http://www.opensource.org/licenses/gpl-license
|
||||||
|
* Copyright 2006 Daniel Silverstone <dsilvers@digital-scurf.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* Mouse gesture core (implementation)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "netsurf/utils/log.h"
|
||||||
|
#include "netsurf/desktop/gesture_core.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** A gesture as used by the recognition machinery */
|
||||||
|
struct _internal_gesture {
|
||||||
|
struct _internal_gesture *next; /**< The next gesture in the list */
|
||||||
|
int gesture_tag; /**< The tag to return for this gesture */
|
||||||
|
int gesture_len; /**< The length of this gesture string */
|
||||||
|
char *gesture; /**< The gesture string reversed for matching */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _internal_gesture* InternalGesture;
|
||||||
|
|
||||||
|
/** A recogniser state. Commonly one in the application. Could have
|
||||||
|
* multiple (E.g. one for browser windows, one for the history window.
|
||||||
|
*/
|
||||||
|
struct _gesture_recogniser {
|
||||||
|
InternalGesture gestures; /**< The gestures registered */
|
||||||
|
Gesturer gesture_users; /**< The users of the gesture engine */
|
||||||
|
int max_len; /**< The maximum length the gestures in this recogniser */
|
||||||
|
int min_distance; /**< The minimum distance the mouse should move */
|
||||||
|
int max_nonmove; /**< The maximum number of data points before abort */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A gesturer state. Commonly one per browser window */
|
||||||
|
struct _gesturer_state {
|
||||||
|
GestureRecogniser recogniser; /**< The recogniser for this state */
|
||||||
|
Gesturer next; /* Next gesture state */
|
||||||
|
int last_x; /**< Last X coordinate fed to the gesture engine */
|
||||||
|
int last_y; /**< Last Y coordinate fed to the gesture engine */
|
||||||
|
int bored_count; /**< Num of boring recent add_point calls */
|
||||||
|
int elements; /**< Number of elements in the current gesture */
|
||||||
|
int nelements; /**< The max number of elements in this gesturer */
|
||||||
|
char *gesture; /**< The in-progress gesture string */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gesturer_notify_recognition_change(Gesturer gesturer);
|
||||||
|
|
||||||
|
/** Create a gesture recogniser.
|
||||||
|
*
|
||||||
|
* \return A new recogniser.
|
||||||
|
*/
|
||||||
|
GestureRecogniser gesture_recogniser_create(void)
|
||||||
|
{
|
||||||
|
GestureRecogniser ret = malloc(sizeof(struct _gesture_recogniser));
|
||||||
|
ret->gestures = NULL;
|
||||||
|
ret->gesture_users = NULL;
|
||||||
|
ret->max_len = 0;
|
||||||
|
ret->min_distance = 1000000; /* Extremely unlikely */
|
||||||
|
ret->max_nonmove = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add a gesture to the recogniser.
|
||||||
|
*
|
||||||
|
* \param recog The recogniser
|
||||||
|
* \param gesture_str The gesture string to add
|
||||||
|
* \param gesture_tag The tag to return for this gesture
|
||||||
|
*/
|
||||||
|
void gesture_recogniser_add(GestureRecogniser recog,
|
||||||
|
const char* gesture_str, int gesture_tag)
|
||||||
|
{
|
||||||
|
InternalGesture g = malloc(sizeof(struct _internal_gesture));
|
||||||
|
InternalGesture g2,g3;
|
||||||
|
int i;
|
||||||
|
Gesturer gest = recog->gesture_users;
|
||||||
|
|
||||||
|
g->gesture_tag = gesture_tag;
|
||||||
|
g->gesture_len = strlen(gesture_str);
|
||||||
|
g->gesture = malloc(g->gesture_len);
|
||||||
|
|
||||||
|
for(i = 0; i < g->gesture_len; ++i)
|
||||||
|
g->gesture[i] = gesture_str[g->gesture_len - i - 1];
|
||||||
|
|
||||||
|
g2 = recog->gestures; g3 = NULL;
|
||||||
|
while( g2 && g->gesture_len < g2->gesture_len ) g3=g3, g2 = g2->next;
|
||||||
|
if( g3 == NULL ) {
|
||||||
|
/* prev == NULL, this means we're inserting at the head */
|
||||||
|
recog->gestures = g; g->next = g2;
|
||||||
|
} else {
|
||||||
|
/* prev == something; we're inserting somewhere */
|
||||||
|
g3->next = g; g->next = g2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( recog->max_len < g->gesture_len ) recog->max_len = g->gesture_len;
|
||||||
|
|
||||||
|
while( gest != NULL ) {
|
||||||
|
gesturer_notify_recognition_change(gest);
|
||||||
|
gest = gest->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroy a gesture recogniser.
|
||||||
|
*
|
||||||
|
* Only call this after destroying all the gesturers for it.
|
||||||
|
*
|
||||||
|
* \param recog The recogniser to destroy.
|
||||||
|
*/
|
||||||
|
void gesture_recogniser_destroy(GestureRecogniser recog)
|
||||||
|
{
|
||||||
|
if( recog->gesture_users ) {
|
||||||
|
LOG(("Attempt to destroy a gesture recogniser with gesture users still registered."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while( recog->gestures ) {
|
||||||
|
InternalGesture g = recog->gestures;
|
||||||
|
recog->gestures = g->next;
|
||||||
|
free(g->gesture);
|
||||||
|
free(g);
|
||||||
|
}
|
||||||
|
free(recog);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the min distance the mouse has to move in order to be
|
||||||
|
* classed as having partaken of a gesture.
|
||||||
|
*
|
||||||
|
* \param recog The recogniser.
|
||||||
|
* \param min_distance The minimum distance in pixels
|
||||||
|
*/
|
||||||
|
void gesture_recogniser_set_distance_threshold(GestureRecogniser recog,
|
||||||
|
int min_distance)
|
||||||
|
{
|
||||||
|
recog->min_distance = min_distance * min_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the number of non-movement adds of points before the gesturer is
|
||||||
|
* internally reset instead of continuing to accumulate a gesture.
|
||||||
|
*
|
||||||
|
* \param recog The recogniser.
|
||||||
|
* \param max_nonmove The maximum number of non-movement adds.
|
||||||
|
*/
|
||||||
|
void gesture_recogniser_set_count_threshold(GestureRecogniser recog,
|
||||||
|
int max_nonmove)
|
||||||
|
{
|
||||||
|
recog->max_nonmove = max_nonmove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a gesturer.
|
||||||
|
*
|
||||||
|
* \param recog The gesture recogniser for this gesturer.
|
||||||
|
*
|
||||||
|
* \return The new gesturer object
|
||||||
|
*/
|
||||||
|
Gesturer gesturer_create(GestureRecogniser recog)
|
||||||
|
{
|
||||||
|
Gesturer ret = malloc(sizeof(struct _gesturer_state));
|
||||||
|
ret->recogniser = recog;
|
||||||
|
ret->next = recog->gesture_users;
|
||||||
|
recog->gesture_users = ret;
|
||||||
|
ret->last_x = 0;
|
||||||
|
ret->last_y = 0;
|
||||||
|
ret->bored_count = 0;
|
||||||
|
ret->elements = 0;
|
||||||
|
ret->nelements = recog->max_len;
|
||||||
|
ret->gesture = calloc(recog->max_len+1, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Clone a gesturer.
|
||||||
|
*
|
||||||
|
* \param gesturer The gesturer to clone
|
||||||
|
*
|
||||||
|
* \return A gesturer cloned from the parameter
|
||||||
|
*/
|
||||||
|
Gesturer gesturer_clone(Gesturer gesturer)
|
||||||
|
{
|
||||||
|
return gesturer_create(gesturer->recogniser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove this gesturer from its recogniser and destroy it.
|
||||||
|
*
|
||||||
|
* \param gesturer The gesturer to destroy.
|
||||||
|
*/
|
||||||
|
void gesturer_destroy(Gesturer gesturer)
|
||||||
|
{
|
||||||
|
Gesturer g = gesturer->recogniser->gesture_users, g2 = NULL;
|
||||||
|
while( g && g != gesturer ) g2 = g, g = g->next;
|
||||||
|
if( g2 == NULL ) {
|
||||||
|
/* This gesturer is first in the list */
|
||||||
|
gesturer->recogniser->gesture_users = gesturer->next;
|
||||||
|
} else {
|
||||||
|
g2->next = gesturer->next;
|
||||||
|
}
|
||||||
|
free(gesturer->gesture);
|
||||||
|
free(gesturer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Notify a gesturer that its recogniser has changed in some way */
|
||||||
|
static void gesturer_notify_recognition_change(Gesturer gesturer)
|
||||||
|
{
|
||||||
|
char *new_gesture = calloc(gesturer->recogniser->max_len+1, 1);
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < gesturer->elements; ++i)
|
||||||
|
new_gesture[i] = gesturer->gesture[i];
|
||||||
|
free(gesturer->gesture);
|
||||||
|
gesturer->gesture = new_gesture;
|
||||||
|
gesturer->nelements = gesturer->recogniser->max_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Clear the points associated with this gesturer.
|
||||||
|
*
|
||||||
|
* You might call this if the gesturer should be cleared because a mouse
|
||||||
|
* button was released or similar.
|
||||||
|
*
|
||||||
|
* \param gesturer The gesturer to clear.
|
||||||
|
*/
|
||||||
|
void gesturer_clear_points(Gesturer gesturer)
|
||||||
|
{
|
||||||
|
memset(gesturer->gesture, 0, gesturer->elements);
|
||||||
|
gesturer->elements = 0;
|
||||||
|
gesturer->bored_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define M_PI_8 (M_PI_4 / 2)
|
||||||
|
#define M_3_PI_8 (3 * M_PI_8)
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
float lower, upper;
|
||||||
|
bool x_neg, y_neg;
|
||||||
|
char direction;
|
||||||
|
} directions[12] = {
|
||||||
|
/* MIN MAX X_NEG Y_NEG DIRECTION */
|
||||||
|
{ 0.0, M_PI_8, false, false, '1' }, /* Right */
|
||||||
|
{ M_PI_8, M_3_PI_8, false, false, '2' }, /* Up/Right */
|
||||||
|
{ M_3_PI_8, INFINITY, false, false, '3' }, /* Up */
|
||||||
|
{ M_3_PI_8, INFINITY, true, false, '3' }, /* Up */
|
||||||
|
{ M_PI_8, M_3_PI_8, true, false, '4' }, /* Up/Left */
|
||||||
|
{ 0.0, M_PI_8, true, false, '5' }, /* Left */
|
||||||
|
{ 0.0, M_PI_8, true, true, '5' }, /* Left */
|
||||||
|
{ M_PI_8, M_3_PI_8, true, true, '6' }, /* Down/Left */
|
||||||
|
{ M_3_PI_8, INFINITY, true, true, '7' }, /* Down */
|
||||||
|
{ M_3_PI_8, INFINITY, false, true, '7' }, /* Down */
|
||||||
|
{ M_PI_8, M_3_PI_8, false, true, '8' }, /* Up/Right */
|
||||||
|
{ 0.0, M_PI_8, false, true, '1' } /* Right */
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef M_PI_8
|
||||||
|
#undef M_3_PI_8
|
||||||
|
|
||||||
|
static char gesturer_find_direction(Gesturer gesturer, int x, int y)
|
||||||
|
{
|
||||||
|
float dx = 0.0000000000001 + (x - gesturer->last_x);
|
||||||
|
float dy = -(0.0000000000001 + (y - gesturer->last_y));
|
||||||
|
float arc;
|
||||||
|
bool x_neg = dx < 0;
|
||||||
|
bool y_neg = dy < 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if( x_neg ) dx = -dx;
|
||||||
|
if( y_neg ) dy = -dy;
|
||||||
|
arc = atanf(dy/dx);
|
||||||
|
for( i = 0; i < 12; ++i ) {
|
||||||
|
if( directions[i].lower > arc || directions[i].upper <= arc )
|
||||||
|
continue; /* Not within this entry */
|
||||||
|
if( directions[i].x_neg != x_neg ||
|
||||||
|
directions[i].y_neg != y_neg )
|
||||||
|
continue; /* Signs not matching */
|
||||||
|
return directions[i].direction;
|
||||||
|
}
|
||||||
|
LOG(("Erm, fell off the end of the direction calculator"));
|
||||||
|
return 0; /* No direction */
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Indicate to a gesturer that a new mouse sample is available.
|
||||||
|
*
|
||||||
|
* Call this to provide a new position sample to the gesturer.
|
||||||
|
* If this is interesting, the gesturer will return a gesture tag
|
||||||
|
* as per the gesture recogniser it was constructed with. Otherwise
|
||||||
|
* it will return GESTURE_NONE which has the value -1.
|
||||||
|
*
|
||||||
|
* \param gesturer The gesturer to add the point to.
|
||||||
|
* \param x The X coordinate of the mouse pointer.
|
||||||
|
* \param y The Y coordinate of the mouse pointer.
|
||||||
|
*
|
||||||
|
* \return The gesture tag activated (or GESTURE_NONE if none)
|
||||||
|
*/
|
||||||
|
int gesturer_add_point(Gesturer gesturer, int x, int y)
|
||||||
|
{
|
||||||
|
int distance = ((gesturer->last_x - x) * (gesturer->last_x - x)) +
|
||||||
|
((gesturer->last_y - y) * (gesturer->last_y - y));
|
||||||
|
char last_direction = (gesturer->elements == 0) ? 0 :
|
||||||
|
(gesturer->gesture[0]);
|
||||||
|
char this_direction = gesturer_find_direction(gesturer, x, y);
|
||||||
|
InternalGesture ig = gesturer->recogniser->gestures;
|
||||||
|
int ret = GESTURE_NONE;
|
||||||
|
|
||||||
|
if( distance < gesturer->recogniser->min_distance ) {
|
||||||
|
gesturer->bored_count++;
|
||||||
|
if( gesturer->elements &&
|
||||||
|
(gesturer->bored_count >=
|
||||||
|
gesturer->recogniser->max_nonmove) ) {
|
||||||
|
LOG(("Bored now."));
|
||||||
|
gesturer_clear_points(gesturer);
|
||||||
|
}
|
||||||
|
if( gesturer->elements &&
|
||||||
|
gesturer->bored_count ==
|
||||||
|
(gesturer->recogniser->max_nonmove >> 1)) {
|
||||||
|
LOG(("Decided to look"));
|
||||||
|
while( ig && ig->gesture_len <= gesturer->elements ) {
|
||||||
|
if( strcmp(gesturer->gesture,
|
||||||
|
ig->gesture) == 0 )
|
||||||
|
ret = ig->gesture_tag;
|
||||||
|
ig = ig->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret; /* GESTURE_NONE or else a gesture found above */
|
||||||
|
}
|
||||||
|
/* We moved far enough that we care about the movement */
|
||||||
|
gesturer->last_x = x;
|
||||||
|
gesturer->last_y = y;
|
||||||
|
gesturer->bored_count = 0;
|
||||||
|
if( this_direction == last_direction ) {
|
||||||
|
return GESTURE_NONE; /* Nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shunt the gesture one up */
|
||||||
|
if( gesturer->elements ) {
|
||||||
|
if( gesturer->elements == gesturer->nelements )
|
||||||
|
gesturer->elements--;
|
||||||
|
memmove(gesturer->gesture+1, gesturer->gesture,
|
||||||
|
gesturer->elements);
|
||||||
|
}
|
||||||
|
gesturer->elements++;
|
||||||
|
gesturer->gesture[0] = this_direction;
|
||||||
|
LOG(("Gesture is currently: '%s'", gesturer->gesture));
|
||||||
|
return GESTURE_NONE;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||||
|
* Licensed under the GNU General Public License,
|
||||||
|
* http://www.opensource.org/licenses/gpl-license
|
||||||
|
* Copyright 2006 Daniel Silverstone <dsilvers@digital-scurf.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* Mouse gesture core (interface)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NETSURF_DESKTOP_GESTURE_CORE_H
|
||||||
|
#define _NETSURF_DESKTOP_GESTURE_CORE_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct _gesture_recogniser* GestureRecogniser;
|
||||||
|
typedef struct _gesturer_state* Gesturer;
|
||||||
|
|
||||||
|
GestureRecogniser gesture_recogniser_create(void);
|
||||||
|
void gesture_recogniser_add(GestureRecogniser recog,
|
||||||
|
const char* gesture_str, int gesture_tag);
|
||||||
|
void gesture_recogniser_destroy(GestureRecogniser recog);
|
||||||
|
void gesture_recogniser_set_distance_threshold(GestureRecogniser recog,
|
||||||
|
int min_distance);
|
||||||
|
void gesture_recogniser_set_count_threshold(GestureRecogniser recog,
|
||||||
|
int max_nonmove);
|
||||||
|
|
||||||
|
|
||||||
|
Gesturer gesturer_create(GestureRecogniser recog);
|
||||||
|
Gesturer gesturer_clone(Gesturer gesturer);
|
||||||
|
void gesturer_destroy(Gesturer gesturer);
|
||||||
|
int gesturer_add_point(Gesturer gesturer, int x, int y);
|
||||||
|
void gesturer_clear_points(Gesturer gesturer);
|
||||||
|
|
||||||
|
#define GESTURE_NONE -1
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,6 +19,7 @@
|
||||||
#include "netsurf/desktop/plotters.h"
|
#include "netsurf/desktop/plotters.h"
|
||||||
#include "netsurf/desktop/options.h"
|
#include "netsurf/desktop/options.h"
|
||||||
#include "netsurf/desktop/textinput.h"
|
#include "netsurf/desktop/textinput.h"
|
||||||
|
#include "netsurf/desktop/gesture_core.h"
|
||||||
#include "netsurf/gtk/gtk_gui.h"
|
#include "netsurf/gtk/gtk_gui.h"
|
||||||
#include "netsurf/gtk/gtk_plotters.h"
|
#include "netsurf/gtk/gtk_plotters.h"
|
||||||
#include "netsurf/gtk/gtk_window.h"
|
#include "netsurf/gtk/gtk_window.h"
|
||||||
|
@ -49,6 +50,7 @@ struct gui_window {
|
||||||
struct gtk_history_window *history_window;
|
struct gtk_history_window *history_window;
|
||||||
GtkWidget *history_window_widget;
|
GtkWidget *history_window_widget;
|
||||||
int caretx, carety, careth;
|
int caretx, carety, careth;
|
||||||
|
int last_x, last_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gtk_history_window {
|
struct gtk_history_window {
|
||||||
|
@ -101,6 +103,8 @@ static void gtk_perform_deferred_resize(void *p);
|
||||||
|
|
||||||
static wchar_t gdkkey_to_nskey(GdkEventKey *key);
|
static wchar_t gdkkey_to_nskey(GdkEventKey *key);
|
||||||
|
|
||||||
|
static void gtk_pass_mouse_position(void *p);
|
||||||
|
|
||||||
struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||||
struct browser_window *clone)
|
struct browser_window *clone)
|
||||||
{
|
{
|
||||||
|
@ -318,10 +322,29 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||||
gtk_widget_hide_on_delete, NULL);
|
gtk_widget_hide_on_delete, NULL);
|
||||||
|
|
||||||
#undef NS_SIGNAL_CONNECT
|
#undef NS_SIGNAL_CONNECT
|
||||||
|
|
||||||
|
if( !bw->gesturer ) {
|
||||||
|
/* Prepare a gesturer */
|
||||||
|
GestureRecogniser gr = gesture_recogniser_create();
|
||||||
|
bw->gesturer = gesturer_create(gr);
|
||||||
|
gesture_recogniser_add(gr, "732187", 100);
|
||||||
|
gesture_recogniser_set_distance_threshold(gr, 50);
|
||||||
|
gesture_recogniser_set_count_threshold(gr, 20);
|
||||||
|
schedule(5, gtk_pass_mouse_position, g);
|
||||||
|
}
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gtk_pass_mouse_position(void *p)
|
||||||
|
{
|
||||||
|
struct gui_window *g = (struct gui_window*)p;
|
||||||
|
if( g->bw->gesturer )
|
||||||
|
if( gesturer_add_point(g->bw->gesturer, g->last_x, g->last_y) == 100 )
|
||||||
|
exit(0);
|
||||||
|
schedule(5, gtk_pass_mouse_position, p);
|
||||||
|
}
|
||||||
|
|
||||||
void gui_window_zoomin_button_event(GtkWidget *widget, gpointer data)
|
void gui_window_zoomin_button_event(GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
struct gui_window *g = data;
|
struct gui_window *g = data;
|
||||||
|
@ -578,7 +601,8 @@ gboolean gui_window_motion_notify_event(GtkWidget *widget,
|
||||||
struct gui_window *g = data;
|
struct gui_window *g = data;
|
||||||
|
|
||||||
browser_window_mouse_track(g->bw, 0, event->x, event->y);
|
browser_window_mouse_track(g->bw, 0, event->x, event->y);
|
||||||
|
g->last_x = event->x;
|
||||||
|
g->last_y = event->y;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
makefile
6
makefile
|
@ -31,7 +31,7 @@ OBJECTS_IMAGE = bmp.o bmpread.o gif.o gifread.o ico.o jpeg.o \
|
||||||
|
|
||||||
OBJECTS_RISCOS = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
|
OBJECTS_RISCOS = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
|
||||||
OBJECTS_RISCOS += browser.o history_core.o netsurf.o selection.o \
|
OBJECTS_RISCOS += browser.o history_core.o netsurf.o selection.o \
|
||||||
textinput.o version.o # desktop/
|
textinput.o version.o gesture_core.o # desktop/
|
||||||
OBJECTS_RISCOS += 401login.o artworks.o assert.o awrender.o bitmap.o \
|
OBJECTS_RISCOS += 401login.o artworks.o assert.o awrender.o bitmap.o \
|
||||||
buffer.o configure.o debugwin.o \
|
buffer.o configure.o debugwin.o \
|
||||||
dialog.o download.o draw.o filetype.o font.o \
|
dialog.o download.o draw.o filetype.o font.o \
|
||||||
|
@ -64,7 +64,7 @@ OBJECTS_DEBUGRO += artworks.o awrender.o bitmap.o draw.o \
|
||||||
OBJECTS_GTK = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
|
OBJECTS_GTK = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
|
||||||
OBJECTS_GTK += filetyped.o # debug/
|
OBJECTS_GTK += filetyped.o # debug/
|
||||||
OBJECTS_GTK += browser.o history_core.o netsurf.o selection.o textinput.o \
|
OBJECTS_GTK += browser.o history_core.o netsurf.o selection.o textinput.o \
|
||||||
version.o # desktop/
|
version.o gesture_core.o # desktop/
|
||||||
OBJECTS_GTK += font_pango.o gtk_bitmap.o gtk_gui.o \
|
OBJECTS_GTK += font_pango.o gtk_bitmap.o gtk_gui.o \
|
||||||
gtk_schedule.o gtk_thumbnail.o \
|
gtk_schedule.o gtk_thumbnail.o \
|
||||||
gtk_plotters.o gtk_treeview.o gtk_window.o # gtk/
|
gtk_plotters.o gtk_treeview.o gtk_window.o # gtk/
|
||||||
|
@ -120,7 +120,7 @@ CFLAGS_NCOS = $(CFLAGS_RISCOS) -Dncos
|
||||||
CFLAGS_DEBUG = -std=c9x -D_BSD_SOURCE -DDEBUG_BUILD $(WARNFLAGS) -I.. \
|
CFLAGS_DEBUG = -std=c9x -D_BSD_SOURCE -DDEBUG_BUILD $(WARNFLAGS) -I.. \
|
||||||
$(PLATFORM_CFLAGS_DEBUG) -g
|
$(PLATFORM_CFLAGS_DEBUG) -g
|
||||||
CFLAGS_GTK = -std=c9x -D_BSD_SOURCE -D_POSIX_C_SOURCE -Dgtk \
|
CFLAGS_GTK = -std=c9x -D_BSD_SOURCE -D_POSIX_C_SOURCE -Dgtk \
|
||||||
$(WARNFLAGS) -I.. -g -O \
|
$(WARNFLAGS) -I.. -g -O0 -Wformat=2 \
|
||||||
`pkg-config --cflags gtk+-2.0` `xml2-config --cflags`
|
`pkg-config --cflags gtk+-2.0` `xml2-config --cflags`
|
||||||
|
|
||||||
# Stop GCC under Cygwin throwing a fit
|
# Stop GCC under Cygwin throwing a fit
|
||||||
|
|
Loading…
Reference in New Issue