Example #1
0
gboolean XInputUtils::onMouseLeaveNotifyEvent(GtkWidget* widget,
                                              GdkEventCrossing* event)
{
	if(!XInputUtils::enableLeafEnterWorkaround)
	{
		return FALSE;
	}

	INPUTDBG("leave notify (mode=%d, details=%d)\n", event->mode, event->detail);

	/* emergency disable XInput to avoid segfaults (GTK+ 2.17) or
	 interface non-responsiveness (GTK+ 2.18) */
	if (!gtk_check_version(2, 17, 0))
	{
		gdk_flush();
		gdk_error_trap_push();
		for (GList* dev_list = gdk_devices_list(); dev_list != NULL;
		     dev_list = dev_list->next)
		{
			GdkDevice* dev = GDK_DEVICE(dev_list->data);
			gdk_device_set_mode(dev, GDK_MODE_DISABLED);
		}
		gdk_flush();
		gdk_error_trap_pop();
	}
	return FALSE;
}
Example #2
0
gboolean XInputUtils::onMouseEnterNotifyEvent(GtkWidget* widget,
                                              GdkEventCrossing* event)
{
	if(!XInputUtils::enableLeafEnterWorkaround)
	{
		return FALSE;
	}

	INPUTDBG("enter notify\n");

	/* re-enable input devices after they've been emergency-disabled
	 by leave_notify */
	if (!gtk_check_version(2, 17, 0))
	{
		gdk_flush();
		gdk_error_trap_push();
		for (GList* dev_list = gdk_devices_list(); dev_list != NULL;
		     dev_list = dev_list->next)
		{
			GdkDevice* dev = GDK_DEVICE(dev_list->data);
			gdk_device_set_mode(dev, GDK_MODE_SCREEN);
		}
		gdk_flush();
		gdk_error_trap_pop();
	}
	return FALSE;
}
Example #3
0
gboolean gtk_xournal_button_release_event(GtkWidget* widget,
                                          GdkEventButton* event)
{
#ifdef INPUT_DEBUG
	gboolean isCore = (event->device == gdk_device_get_core_pointer());
	INPUTDBG("ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i",
	         gdk_device_get_name(event->device), event->x, event->y,
	         event->button, event->state, isCore);
#endif
	XInputUtils::fixXInputCoords((GdkEvent*) event, widget);

	if (event->button > 3)   // scroll wheel events
	{
		return true;
	}

	current_view = NULL;

	GtkXournal* xournal = GTK_XOURNAL(widget);

	Cursor* cursor = xournal->view->getCursor();
	ToolHandler* h = xournal->view->getControl()->getToolHandler();
	cursor->setMouseDown(false);

	xournal->inScrolling = false;

	EditSelection* sel = xournal->view->getSelection();
	if (sel)
	{
		sel->mouseUp();
	}

	bool res = false;
	if (xournal->currentInputPage)
	{
		xournal->currentInputPage->translateEvent((GdkEvent*) event, xournal->x,
		                                          xournal->y);
		res = xournal->currentInputPage->onButtonReleaseEvent(widget, event);
		xournal->currentInputPage = NULL;
	}

	EditSelection* tmpSelection = xournal->selection;
	xournal->selection = NULL;

	h->restoreLastConfig();

	// we need this workaround so it's possible to select something with the middle button
	if (tmpSelection)
	{
		xournal->view->setSelection(tmpSelection);
	}

	return res;
}
Example #4
0
gboolean gtk_xournal_scroll_event(GtkWidget * widget, GdkEventScroll * event) {
#ifdef INPUT_DEBUG
	// true: Core event, false: XInput event
	gboolean isCore = (event->device == gdk_device_get_core_pointer());

	INPUTDBG("Scroll (%s) (x,y)=(%.2f,%.2f), direction %d, modifier %x, isCore %i", gdk_device_get_name(event->device), event->x, event->y,
			event->direction, event->state, isCore);
#endif

	g_return_val_if_fail(GTK_XOURNAL(widget), FALSE);
	g_return_val_if_fail(event != NULL, FALSE);

	GtkXournal * xournal = GTK_XOURNAL(widget);
	return xournal->layout->scrollEvent(event);
}
Example #5
0
gboolean gtk_xournal_motion_notify_event(GtkWidget * widget, GdkEventMotion * event) {
#ifdef INPUT_DEBUG
		bool is_core = (event->device == gdk_device_get_core_pointer());
		INPUTDBG("MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x", is_core ? "core" : "xinput", event->x, event->y, event->state);
#endif

	XInputUtils::fixXInputCoords((GdkEvent*) event, widget);

	GtkXournal * xournal = GTK_XOURNAL(widget);
	ToolHandler * h = xournal->view->getControl()->getToolHandler();

	if (h->getToolType() == TOOL_HAND) {
		if (xournal->inScrolling) {
			gtk_xournal_scroll_mouse_event(xournal, event);
			return true;
		}
		return false;
	} else if (xournal->selection) {
		EditSelection * selection = xournal->selection;

		PageView * view = selection->getView();
		GdkEventMotion ev = *event;
		view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y);

		if (xournal->selection->isMoving()) {
			selection->mouseMove(ev.x, ev.y);
		} else {
			CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom());
			xournal->view->getCursor()->setMouseSelectionType(selType);
		}
		return true;
	}

	PageView * pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y);
	xournal->view->getCursor()->setInsidePage(pv != NULL);
	if (pv) {
		// allow events only to a single page!
		if (xournal->currentInputPage == NULL || pv == xournal->currentInputPage) {
			pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y);
			return pv->onMotionNotifyEvent(widget, event);;
		}
	}

	return false;
}
Example #6
0
gboolean gtk_xournal_button_press_event(GtkWidget* widget,
                                        GdkEventButton* event)
{
	/**
	 * true: Core event, false: XInput event
	 */
	gboolean isCore = (event->device == gdk_device_get_core_pointer());

	INPUTDBG("ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i",
	         gdk_device_get_name(event->device), event->x, event->y,
	         event->button, event->state, isCore);

	GtkXournal* xournal = GTK_XOURNAL(widget);
	Settings* settings = xournal->view->getControl()->getSettings();

	if(isCore && settings->isXinputEnabled() && settings->isIgnoreCoreEvents())
	{
		INPUTDBG2("gtk_xournal_button_press_event return false (ignore core)");
		return false;
	}

	XInputUtils::fixXInputCoords((GdkEvent*) event, widget);

	if (event->type != GDK_BUTTON_PRESS)
	{
		INPUTDBG2("gtk_xournal_button_press_event return false (event->type != GDK_BUTTON_PRESS)");
		return false; // this event is not handled here
	}

	if (event->button > 3)   // scroll wheel events
	{
		XInputUtils::handleScrollEvent(event, widget);
		INPUTDBG2("gtk_xournal_button_press_event return true handled scroll event");
		return true;
	}

	gtk_widget_grab_focus(widget);

	// none button release event was sent, send one now
	if (xournal->currentInputPage)
	{
		INPUTDBG2("gtk_xournal_button_press_event (xournal->currentInputPage != NULL)");

		GdkEventButton ev = *event;
		xournal->currentInputPage->translateEvent((GdkEvent*) &ev, xournal->x,
		                                          xournal->y);
		xournal->currentInputPage->onButtonReleaseEvent(widget, &ev);
	}

	ToolHandler* h = xournal->view->getControl()->getToolHandler();

	// Change the tool depending on the key or device
	if(change_tool(settings, event, xournal))
		return true;

	// hand tool don't change the selection, so you can scroll e.g.
	// with your touchscreen without remove the selection
	if (h->getToolType() == TOOL_HAND)
	{
		Cursor* cursor = xournal->view->getCursor();
		cursor->setMouseDown(true);
		xournal->lastMousePositionX = 0;
		xournal->lastMousePositionY = 0;
		xournal->inScrolling = true;
		gtk_widget_get_pointer(widget, &xournal->lastMousePositionX,
		                       &xournal->lastMousePositionY);

		INPUTDBG2("gtk_xournal_button_press_event (h->getToolType() == TOOL_HAND) return true");
		return true;
	}
	else if (xournal->selection)
	{
		EditSelection* selection = xournal->selection;

		PageView* view = selection->getView();
		GdkEventButton ev = *event;
		view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y);
		CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y,
		                                                                xournal->view->getZoom());
		if (selType)
		{

			if(selType == CURSOR_SELECTION_MOVE && event->button == 3)
			{
				selection->copySelection();
			}

			xournal->view->getCursor()->setMouseDown(true);
			xournal->selection->mouseDown(selType, ev.x, ev.y);
			INPUTDBG2("gtk_xournal_button_press_event (selection) return true");
			return true;
		}
		else
		{
			xournal->view->clearSelection();
			if(change_tool(settings, event, xournal))
				return true;
		}
	}

	PageView* pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x,
	                                                        event->y);

	current_view = pv;

	if (pv)
	{
		xournal->currentInputPage = pv;
		pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y);
		INPUTDBG2("gtk_xournal_button_press_event (pv->onButtonPressEvent) return");

		xournal->view->getDocument()->indexOf(pv->getPage());
		return pv->onButtonPressEvent(widget, event);
	}

	INPUTDBG2("gtk_xournal_button_press_event (not handled) return false");
	return false; // not handled
}
Example #7
0
void InputHandler::onButtonReleaseEvent(GdkEventButton * event, PageRef page) {
	XOJ_CHECK_TYPE(InputHandler);

	if (!this->tmpStroke) {
		return;
	}

	// Backward compatibility and also easier to handle for me;-)
	// I cannot draw a line with one point, to draw a visible line I need two points,
	// twice the same Point is also OK
	if (this->tmpStroke->getPointCount() == 1) {
		ArrayIterator<Point> it = this->tmpStroke->pointIterator();
		if (it.hasNext()) {
			this->tmpStroke->addPoint(it.next());
		}
		// No pressure sensitivity
		this->tmpStroke->clearPressure();
	}

	this->tmpStroke->freeUnusedPointItems();

	if (page.getSelectedLayerId() < 1) {
		// This creates a layer if none exists
		page.getSelectedLayer();
		page.setSelectedLayerId(1);
		xournal->getControl()->getWindow()->updateLayerCombobox();
	}

	Layer * layer = page.getSelectedLayer();

	UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler();

	undo->addUndoAction(new InsertUndoAction(page, layer, this->tmpStroke, this->redrawable));

	ToolHandler * h = xournal->getControl()->getToolHandler();
	if (h->isShapeRecognizer()) {
		if (this->reco == NULL) {
			this->reco = new ShapeRecognizer();
		}
		ShapeRecognizerResult * result = this->reco->recognizePatterns(this->tmpStroke);

		if (result != NULL) {
			UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler();

			Stroke * recognized = result->getRecognized();

			RecognizerUndoAction * recognizerUndo = new RecognizerUndoAction(page, this->redrawable, layer, this->tmpStroke, recognized);
			undo->addUndoAction(recognizerUndo);
			layer->addElement(result->getRecognized());

			Range range(recognized->getX(), recognized->getY());
			range.addPoint(recognized->getX() + recognized->getElementWidth(), recognized->getY() + recognized->getElementHeight());

			range.addPoint(this->tmpStroke->getX(), this->tmpStroke->getY());
			range.addPoint(this->tmpStroke->getX() + this->tmpStroke->getElementWidth(), this->tmpStroke->getY() + this->tmpStroke->getElementHeight());

			ListIterator<Stroke *> l = result->getSources();
			while (l.hasNext()) {
				Stroke * s = l.next();

				layer->removeElement(s, false);

				recognizerUndo->addSourceElement(s);

				range.addPoint(s->getX(), s->getY());
				range.addPoint(s->getX() + s->getElementWidth(), s->getY() + s->getElementHeight());
			}

			this->redrawable->rerenderRange(range);

			// delete the result object, this is not needed anymore, the stroke are not deleted with this
			delete result;
		} else {
			layer->addElement(this->tmpStroke);
			this->redrawable->rerenderElement(this->tmpStroke);
		}

	} else {
		layer->addElement(this->tmpStroke);
		this->redrawable->rerenderElement(this->tmpStroke);
	}

	this->tmpStroke = NULL;

	if (currentInputDevice == event->device) {
		currentInputDevice = NULL;
		INPUTDBG("currentInputDevice = NULL\n", 0);
	}

	this->tmpStrokeDrawElem = 0;
}
Example #8
0
gboolean gtk_xournal_button_press_event(GtkWidget * widget, GdkEventButton * event) {
	/**
	 * true: Core event, false: XInput event
	 */
	gboolean isCore = (event->device == gdk_device_get_core_pointer());

	INPUTDBG("ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i", gdk_device_get_name(event->device), event->x, event->y,
			event->button, event->state, isCore);

	GtkXournal * xournal = GTK_XOURNAL(widget);
	Settings * settings = xournal->view->getControl()->getSettings();

	if(isCore && settings->isXinputEnabled() && settings->isIgnoreCoreEvents()) {
		INPUTDBG2("gtk_xournal_button_press_event return false (ignore core)");
		return false;
	}

	XInputUtils::fixXInputCoords((GdkEvent*) event, widget);

	if (event->type != GDK_BUTTON_PRESS) {
		INPUTDBG2("gtk_xournal_button_press_event return false (event->type != GDK_BUTTON_PRESS)");
		return false; // this event is not handled here
	}

	if (event->button > 3) { // scroll wheel events
		XInputUtils::handleScrollEvent(event, widget);
		INPUTDBG2("gtk_xournal_button_press_event return true handled scroll event");
		return true;
	}

	gtk_widget_grab_focus(widget);

	ToolHandler * h = xournal->view->getControl()->getToolHandler();

	// none button release event was sent, send one now
	if (xournal->currentInputPage) {
		INPUTDBG2("gtk_xournal_button_press_event (xournal->currentInputPage != NULL)");

		GdkEventButton ev = *event;
		xournal->currentInputPage->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y);
		xournal->currentInputPage->onButtonReleaseEvent(widget, &ev);
	}

	// Change the tool depending on the key or device
	ButtonConfig * cfg = NULL;
	ButtonConfig * cfgTouch = settings->getTouchButtonConfig();
	if (event->button == 2) { // Middle Button
		cfg = settings->getMiddleButtonConfig();
	} else if (event->button == 3) { // Right Button
		cfg = settings->getRightButtonConfig();
	} else if (event->device->source == GDK_SOURCE_ERASER) {
		cfg = settings->getEraserButtonConfig();
	} else if (cfgTouch->device == event->device->name) {
		cfg = cfgTouch;

		// If an action is defined we do it, even if it's a drawing action...
		if (cfg->getDisableDrawing() && cfg->getAction() == TOOL_NONE) {
			ToolType tool = h->getToolType();
			if (tool == TOOL_PEN || tool == TOOL_ERASER || tool == TOOL_HILIGHTER) {
				printf("ignore touchscreen for drawing!\n");
				return true;
			}
		}
	}

	if (cfg && cfg->getAction() != TOOL_NONE) {
		h->copyCurrentConfig();
		cfg->acceptActions(h);
	}

	// hand tool don't change the selection, so you can scroll e.g.
	// with your touchscreen without remove the selection
	if (h->getToolType() == TOOL_HAND) {
		Cursor * cursor = xournal->view->getCursor();
		cursor->setMouseDown(true);
		xournal->lastMousePositionX = 0;
		xournal->lastMousePositionY = 0;
		xournal->inScrolling = true;
		gtk_widget_get_pointer(widget, &xournal->lastMousePositionX, &xournal->lastMousePositionY);

		INPUTDBG2("gtk_xournal_button_press_event (h->getToolType() == TOOL_HAND) return true");
		return true;
	} else if (xournal->selection) {
		EditSelection * selection = xournal->selection;

		PageView * view = selection->getView();
		GdkEventButton ev = *event;
		view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y);
		CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom());
		if (selType) {
			xournal->view->getCursor()->setMouseDown(true);
			xournal->selection->mouseDown(selType, ev.x, ev.y);
			INPUTDBG2("gtk_xournal_button_press_event (selection) return true");
			return true;
		} else {
			xournal->view->clearSelection();
		}
	}

	PageView * pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y);
	if (pv) {
		xournal->currentInputPage = pv;
		pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y);
		INPUTDBG2("gtk_xournal_button_press_event (pv->onButtonPressEvent) return");

		xournal->view->getDocument()->indexOf(pv->getPage());
		return pv->onButtonPressEvent(widget, event);
	}

	INPUTDBG2("gtk_xournal_button_press_event (not handled) return false");
	return false; // not handled
}