static void clutter_stage_win32_set_fullscreen (ClutterStageWindow *stage_window, gboolean value) { ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window); HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd; LONG old_style = GetWindowLongW (hwnd, GWL_STYLE); ClutterStageStateEvent event; if (value) stage_win32->state |= CLUTTER_STAGE_STATE_FULLSCREEN; else stage_win32->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN; if (hwnd) { /* Update the window style but preserve the visibility */ SetWindowLongW (hwnd, GWL_STYLE, get_window_style (stage_win32) | (old_style & WS_VISIBLE)); /* Update the window size */ if (value) { get_fullscreen_rect (stage_win32); SetWindowPos (hwnd, HWND_TOP, stage_win32->fullscreen_rect.left, stage_win32->fullscreen_rect.top, stage_win32->fullscreen_rect.right - stage_win32->fullscreen_rect.left, stage_win32->fullscreen_rect.bottom - stage_win32->fullscreen_rect.top, 0); } else { int full_width, full_height; get_full_window_size (stage_win32, stage_win32->win_width, stage_win32->win_height, &full_width, &full_height); SetWindowPos (stage_win32->hwnd, NULL, 0, 0, full_width, full_height, SWP_NOZORDER | SWP_NOMOVE); } CLUTTER_SET_PRIVATE_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_SYNC_MATRICES); } /* Report the state change */ memset (&event, 0, sizeof (event)); event.type = CLUTTER_STAGE_STATE; event.stage = CLUTTER_STAGE (stage_win32->wrapper); event.new_state = stage_win32->state; event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN; clutter_event_put ((ClutterEvent *) &event); }
static void _method_cb (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, DbusInput *self) { if (g_strcmp0 (method_name, "ControlKey") == 0) { guint keyflag; ClutterEvent *event; ClutterKeyEvent *kevent; g_variant_get (parameters, "(u)", &keyflag); event = clutter_event_new (CLUTTER_KEY_PRESS); kevent = (ClutterKeyEvent *)event; kevent->flags = 0; kevent->source = NULL; kevent->stage = CLUTTER_STAGE (self->stage); kevent->keyval = keyflag; kevent->time = time (NULL); /* KEY PRESS */ clutter_event_put (event); /* KEY RELEASE */ kevent->type = CLUTTER_KEY_RELEASE; clutter_event_put (event); clutter_event_free (event); } g_dbus_method_invocation_return_value (invocation, NULL); }
/* This is an IBus workaround. The flow of events with IBus is that every time * it gets gets a key event, it: * * Sends it to the daemon via D-Bus asynchronously * When it gets an reply, synthesizes a new GdkEvent and puts it into the * GDK event queue with gdk_event_put(), including * IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop. * * (Normally, IBus uses the GTK+ key snooper mechanism to get the key * events early, but since our key events aren't visible to GTK+ key snoopers, * IBus will instead get the events via the standard * GtkIMContext.filter_keypress() mechanism.) * * There are a number of potential problems here; probably the worst * problem is that IBus doesn't forward the timestamp with the event * so that every key event that gets delivered ends up with * GDK_CURRENT_TIME. This creates some very subtle bugs; for example * if you have IBus running and a keystroke is used to trigger * launching an application, focus stealing prevention won't work * right. http://code.google.com/p/ibus/issues/detail?id=1184 * * In any case, our normal flow of key events is: * * GDK filter function => clutter_x11_handle_event => clutter actor * * So, if we see a key event that gets delivered via the GDK event handler * function - then we know it must be one of these synthesized events, and * we should push it back to clutter. * * To summarize, the full key event flow with IBus is: * * GDK filter function * => Mutter * => gnome_cinnamon_plugin_xevent_filter() * => clutter_x11_handle_event() * => clutter event delivery to actor * => gtk_im_context_filter_event() * => sent to IBus daemon * => response received from IBus daemon * => gdk_event_put() * => GDK event handler * => <this function> * => clutter_event_put() * => clutter event delivery to actor * * Anything else we see here we just pass on to the normal GDK event handler * gtk_main_do_event(). */ static void gnome_cinnamon_gdk_event_handler (GdkEvent *event_gdk, gpointer data) { if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE) { ClutterActor *stage; Window stage_xwindow; stage = clutter_stage_get_default (); stage_xwindow = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); if (GDK_WINDOW_XID (event_gdk->key.window) == stage_xwindow) { ClutterDeviceManager *device_manager = clutter_device_manager_get_default (); ClutterInputDevice *keyboard = clutter_device_manager_get_core_device (device_manager, CLUTTER_KEYBOARD_DEVICE); ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE); event_clutter->key.time = event_gdk->key.time; event_clutter->key.flags = CLUTTER_EVENT_NONE; event_clutter->key.stage = CLUTTER_STAGE (stage); event_clutter->key.source = NULL; /* This depends on ClutterModifierType and GdkModifierType being * identical, which they are currently. (They both match the X * modifier state in the low 16-bits and have the same extensions.) */ event_clutter->key.modifier_state = event_gdk->key.state; event_clutter->key.keyval = event_gdk->key.keyval; event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode; event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval); event_clutter->key.device = keyboard; clutter_event_put (event_clutter); clutter_event_free (event_clutter); return; } } gtk_main_do_event (event_gdk); }
// ClutterEvent putBack() Puts <code>self</code> back to event queue. IO_METHOD(IoClutterEvent, putBack) { clutter_event_put(IOCEVENT(self)); return self; }
IO_METHOD(IoClutterEvent, put) { clutter_event_put(IOCEVENT(IoMessage_locals_clutterEventArgAt_(m, locals, 0))); return self; }
static void mex_mmkeys_control (MexMMkeys *self, const gchar *key) { MexMMkeysPrivate *priv = MEX_MMKEYS (self)->priv; ClutterEvent *event; ClutterKeyEvent *kevent; event = clutter_event_new (CLUTTER_KEY_PRESS); kevent = (ClutterKeyEvent *)event; /* These don't change */ kevent->flags = 0; kevent->source = priv->stage; kevent->stage = CLUTTER_STAGE (priv->stage); if (g_strcmp0 (key, "Play") == 0) { kevent->keyval = CLUTTER_KEY_AudioPlay; goto end; } if (g_strcmp0 (key, "Pause") == 0) { kevent->keyval = CLUTTER_KEY_AudioPause; goto end; } if (g_strcmp0 (key, "Stop") == 0) { kevent->keyval = CLUTTER_KEY_AudioStop; goto end; } if (g_strcmp0 (key, "FastForward") == 0) { kevent->keyval = CLUTTER_KEY_AudioForward; goto end; } if (g_strcmp0 (key, "Rewind") == 0) { kevent->keyval = CLUTTER_KEY_AudioRewind; goto end; } if (g_strcmp0 (key, "Next") == 0) { kevent->keyval = CLUTTER_KEY_AudioNext; goto end; } if (g_strcmp0 (key, "Previous") == 0) { kevent->keyval = CLUTTER_KEY_AudioPrev; goto end; } /* One day we might be able to get volume keys from gnome setting daemon: * https://bugzilla.gnome.org/show_bug.cgi?id=647166 * In the meantime you can get these keys by unbinding them */ if (g_strcmp0 (key, "VolumeUp") == 0) { kevent->keyval = CLUTTER_KEY_AudioRaiseVolume; goto end; } if (g_strcmp0 (key, "VolumeDown") == 0) { kevent->keyval = CLUTTER_KEY_AudioLowerVolume; goto end; } if (g_strcmp0 (key, "VolumeMute") == 0) { kevent->keyval = CLUTTER_KEY_AudioMute; goto end; } return; end: kevent->time = time (NULL); clutter_event_put (event); clutter_event_free (event); }