summaryrefslogtreecommitdiff
path: root/plugins/mouse/gsd-locate-pointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mouse/gsd-locate-pointer.c')
-rw-r--r--plugins/mouse/gsd-locate-pointer.c504
1 files changed, 0 insertions, 504 deletions
diff --git a/plugins/mouse/gsd-locate-pointer.c b/plugins/mouse/gsd-locate-pointer.c
deleted file mode 100644
index 8582074..0000000
--- a/plugins/mouse/gsd-locate-pointer.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* msd-locate-pointer.c
- *
- * Copyright (C) 2008 Carlos Garnacho <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <gtk/gtk.h>
-#include "msd-timeline.h"
-#include "msd-locate-pointer.h"
-
-#include <gdk/gdkkeysyms.h>
-#include <gdk/gdkx.h>
-#include <X11/keysym.h>
-
-#define ANIMATION_LENGTH 750
-#define WINDOW_SIZE 101
-#define N_CIRCLES 4
-
-/* All circles are supposed to be moving when progress
- * reaches 0.5, and each of them are supposed to long
- * for half of the progress, hence the need of 0.5 to
- * get the circles interval, and the multiplication
- * by 2 to know a circle progress */
-#define CIRCLES_PROGRESS_INTERVAL (0.5 / N_CIRCLES)
-#define CIRCLE_PROGRESS(p) (MIN (1., ((gdouble) (p) * 2.)))
-
-typedef struct MsdLocatePointerData MsdLocatePointerData;
-
-struct MsdLocatePointerData
-{
- MsdTimeline *timeline;
- GtkWidget *widget;
- GdkWindow *window;
-
- gdouble progress;
-};
-
-static MsdLocatePointerData *data = NULL;
-
-static void
-locate_pointer_paint (MsdLocatePointerData *data,
- cairo_t *cr,
- gboolean composite)
-{
- GdkColor color;
- gdouble progress, circle_progress;
- gint width, height, i;
- GtkStyle *style;
-
- progress = data->progress;
-
- #if GTK_CHECK_VERSION(3, 0, 0)
- width = gdk_window_get_width(GDK_WINDOW(data->window));
- height = gdk_window_get_height(GDK_WINDOW(data->window));
- #else
- gdk_drawable_get_size(data->window, &width, &height);
- #endif
-
- style = gtk_widget_get_style (data->widget);
- color = style->bg[GTK_STATE_SELECTED];
-
- cairo_set_source_rgba (cr, 1., 1., 1., 0.);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
-
- for (i = 0; i <= N_CIRCLES; i++)
- {
- if (progress < 0.)
- break;
-
- circle_progress = MIN (1., (progress * 2));
- progress -= CIRCLES_PROGRESS_INTERVAL;
-
- if (circle_progress >= 1.)
- continue;
-
- if (composite)
- {
- cairo_set_source_rgba (cr,
- color.red / 65535.,
- color.green / 65535.,
- color.blue / 65535.,
- 1 - circle_progress);
- cairo_arc (cr,
- width / 2,
- height / 2,
- circle_progress * width / 2,
- 0, 2 * G_PI);
-
- cairo_fill (cr);
- cairo_stroke (cr);
- }
- else
- {
- cairo_set_source_rgb (cr, 0., 0., 0.);
- cairo_set_line_width (cr, 3.);
- cairo_arc (cr,
- width / 2,
- height / 2,
- circle_progress * width / 2,
- 0, 2 * G_PI);
- cairo_stroke (cr);
-
- cairo_set_source_rgb (cr, 1., 1., 1.);
- cairo_set_line_width (cr, 1.);
- cairo_arc (cr,
- width / 2,
- height / 2,
- circle_progress * width / 2,
- 0, 2 * G_PI);
- cairo_stroke (cr);
- }
- }
-}
-
-static gboolean
-locate_pointer_expose (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
-{
- MsdLocatePointerData *data = (MsdLocatePointerData *) user_data;
- cairo_t *cr;
-
- if (event->window != data->window)
- return FALSE;
-
- cr = gdk_cairo_create (data->window);
- locate_pointer_paint (data, cr, gtk_widget_is_composited (data->widget));
- cairo_destroy (cr);
-
- return TRUE;
-}
-
-static void
-update_shape (MsdLocatePointerData *data)
-{
- cairo_t *cr;
- GdkBitmap *mask;
-
- mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
- cr = gdk_cairo_create (mask);
- locate_pointer_paint (data, cr, FALSE);
- gdk_window_shape_combine_mask (data->window, mask, 0, 0);
- g_object_unref (mask);
- cairo_destroy (cr);
-}
-
-static void
-timeline_frame_cb (MsdTimeline *timeline,
- gdouble progress,
- gpointer user_data)
-{
- MsdLocatePointerData *data = (MsdLocatePointerData *) user_data;
- GdkScreen *screen;
- gint cursor_x, cursor_y;
-
- if (gtk_widget_is_composited (data->widget))
- {
- gdk_window_invalidate_rect (data->window, NULL, FALSE);
- data->progress = progress;
- }
- else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL)
- {
- /* only invalidate window each circle interval */
- update_shape (data);
- gdk_window_invalidate_rect (data->window, NULL, FALSE);
- data->progress += CIRCLES_PROGRESS_INTERVAL;
- }
-
- screen = gdk_drawable_get_screen (data->window);
- gdk_window_get_pointer (gdk_screen_get_root_window (screen),
- &cursor_x, &cursor_y, NULL);
- gdk_window_move (data->window,
- cursor_x - WINDOW_SIZE / 2,
- cursor_y - WINDOW_SIZE / 2);
-}
-
-static void
-set_transparent_shape (GdkWindow *window)
-{
- GdkBitmap *mask;
- cairo_t *cr;
-
- mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
- cr = gdk_cairo_create (mask);
-
- cairo_set_source_rgba (cr, 1., 1., 1., 0.);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
-
- gdk_window_shape_combine_mask (data->window, mask, 0, 0);
- g_object_unref (mask);
- cairo_destroy (cr);
-}
-
-static void
-unset_transparent_shape (GdkWindow *window)
-{
- gdk_window_shape_combine_mask (data->window, NULL, 0, 0);
-}
-
-static void
-composited_changed (GtkWidget *widget,
- MsdLocatePointerData *data)
-{
- if (!gtk_widget_is_composited (widget))
- set_transparent_shape (data->window);
- else
- unset_transparent_shape (data->window);
-}
-
-static void
-timeline_finished_cb (MsdTimeline *timeline,
- gpointer user_data)
-{
- MsdLocatePointerData *data = (MsdLocatePointerData *) user_data;
-
- /* set transparent shape and hide window */
- if (!gtk_widget_is_composited (data->widget))
- set_transparent_shape (data->window);
-
- gdk_window_hide (data->window);
-}
-
-static void
-create_window (MsdLocatePointerData *data,
- GdkScreen *screen)
-{
- GdkColormap *colormap;
- GdkVisual *visual;
- GdkWindowAttr attributes;
-
- colormap = gdk_screen_get_rgba_colormap (screen);
- visual = gdk_screen_get_rgba_visual (screen);
-
- if (!colormap)
- {
- colormap = gdk_screen_get_rgb_colormap (screen);
- visual = gdk_screen_get_rgb_visual (screen);
- }
-
- attributes.window_type = GDK_WINDOW_TEMP;
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = visual;
- attributes.colormap = colormap;
- attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK;
- attributes.width = 1;
- attributes.height = 1;
-
- data->window = gdk_window_new (gdk_screen_get_root_window (screen),
- &attributes,
- GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
-
- gdk_window_set_user_data (data->window, data->widget);
-}
-
-static MsdLocatePointerData *
-msd_locate_pointer_data_new (GdkScreen *screen)
-{
- MsdLocatePointerData *data;
-
- data = g_new0 (MsdLocatePointerData, 1);
-
- /* this widget will never be shown, it's
- * mainly used to get signals/events from
- */
- data->widget = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_realize (data->widget);
-
- g_signal_connect (G_OBJECT (data->widget), "expose_event",
- G_CALLBACK (locate_pointer_expose),
- data);
-
- data->timeline = msd_timeline_new (ANIMATION_LENGTH);
- g_signal_connect (data->timeline, "frame",
- G_CALLBACK (timeline_frame_cb), data);
- g_signal_connect (data->timeline, "finished",
- G_CALLBACK (timeline_finished_cb), data);
-
- create_window (data, screen);
-
- return data;
-}
-
-static void
-move_locate_pointer_window (MsdLocatePointerData *data,
- GdkScreen *screen)
-{
- gint cursor_x, cursor_y;
- GdkBitmap *mask;
- GdkColor col;
- GdkGC *gc;
-
- gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL);
-
- gdk_window_move_resize (data->window,
- cursor_x - WINDOW_SIZE / 2,
- cursor_y - WINDOW_SIZE / 2,
- WINDOW_SIZE, WINDOW_SIZE);
-
- col.pixel = 0;
- mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
-
- gc = gdk_gc_new (mask);
- gdk_gc_set_foreground (gc, &col);
- gdk_draw_rectangle (mask, gc, TRUE, 0, 0, WINDOW_SIZE, WINDOW_SIZE);
-
- /* allow events to happen through the window */
- gdk_window_input_shape_combine_mask (data->window, mask, 0, 0);
-
- g_object_unref (mask);
- g_object_unref (gc);
-}
-
-void
-msd_locate_pointer (GdkScreen *screen)
-{
- if (!data)
- data = msd_locate_pointer_data_new (screen);
-
- msd_timeline_pause (data->timeline);
- msd_timeline_rewind (data->timeline);
-
- /* Create again the window if it is not for the current screen */
- if (gdk_screen_get_number (screen) != gdk_screen_get_number (gdk_drawable_get_screen (data->window)))
- {
- gdk_window_set_user_data (data->window, NULL);
- gdk_window_destroy (data->window);
-
- create_window (data, screen);
- }
-
- data->progress = 0.;
-
- g_signal_connect (data->widget, "composited-changed",
- G_CALLBACK (composited_changed), data);
-
- move_locate_pointer_window (data, screen);
- composited_changed (data->widget, data);
- gdk_window_show (data->window);
-
- msd_timeline_start (data->timeline);
-}
-
-
-#define KEYBOARD_GROUP_SHIFT 13
-#define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14))
-
-/* Owen magic */
-static GdkFilterReturn
-filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- XEvent *xev = (XEvent *) xevent;
- guint keyval;
- gint group;
-
- GdkScreen *screen = (GdkScreen *)data;
-
- if (xev->type == KeyPress || xev->type == KeyRelease)
- {
- /* get the keysym */
- group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT;
- gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
- xev->xkey.keycode,
- xev->xkey.state,
- group,
- &keyval,
- NULL, NULL, NULL);
- if (keyval == GDK_Control_L || keyval == GDK_Control_R)
- {
- if (xev->type == KeyPress)
- {
- XAllowEvents (xev->xkey.display,
- SyncKeyboard,
- xev->xkey.time);
- }
- else
- {
- XAllowEvents (xev->xkey.display,
- AsyncKeyboard,
- xev->xkey.time);
- msd_locate_pointer (screen);
- }
- }
- else
- {
- XAllowEvents (xev->xkey.display,
- ReplayKeyboard,
- xev->xkey.time);
- XUngrabKeyboard (gdk_x11_get_default_xdisplay (),
- xev->xkey.time);
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-static void
-set_locate_pointer (void)
-{
- GdkKeymapKey *keys;
- GdkDisplay *display;
- int n_screens;
- int n_keys;
- gboolean has_entries;
- static const guint keyvals[] = { GDK_Control_L, GDK_Control_R };
- unsigned j;
-
- display = gdk_display_get_default ();
- n_screens = gdk_display_get_n_screens (display);
-
- for (j = 0 ; j < G_N_ELEMENTS (keyvals) ; j++)
- {
- has_entries = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
- keyvals[j],
- &keys,
- &n_keys);
- if (has_entries)
- {
- gint i, j;
- for (i = 0; i < n_keys; i++)
- {
- for (j=0; j< n_screens; j++)
- {
- GdkScreen *screen;
- Window xroot;
-
- screen = gdk_display_get_screen (display, j);
- xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen));
-
- XGrabKey (GDK_DISPLAY_XDISPLAY (display),
- keys[i].keycode,
- 0,
- xroot,
- False,
- GrabModeAsync,
- GrabModeSync);
- XGrabKey (GDK_DISPLAY_XDISPLAY (display),
- keys[i].keycode,
- LockMask,
- xroot,
- False,
- GrabModeAsync,
- GrabModeSync);
- XGrabKey (GDK_DISPLAY_XDISPLAY (display),
- keys[i].keycode,
- Mod2Mask,
- xroot,
- False,
- GrabModeAsync,
- GrabModeSync);
- XGrabKey (GDK_DISPLAY_XDISPLAY (display),
- keys[i].keycode,
- Mod4Mask,
- xroot,
- False,
- GrabModeAsync,
- GrabModeSync);
- }
- }
-
- g_free (keys);
-
- for (i = 0; i < n_screens; i++)
- {
- GdkScreen *screen;
-
- screen = gdk_display_get_screen (display, i);
- gdk_window_add_filter (gdk_screen_get_root_window (screen),
- filter,
- screen);
- }
- }
- }
-}
-
-
-int
-main (int argc, char *argv[])
-{
- gtk_init (&argc, &argv);
-
- set_locate_pointer ();
-
- gtk_main ();
-
- return 0;
-}
-