[PATCH 9/9] desktop-shell: add unlock dialog
Pekka Paalanen
ppaalanen at gmail.com
Tue Nov 15 03:34:56 PST 2011
The unclock dialog is just a normal window with a green ball in it. When
you click the ball, the screen will be unlocked.
Made for testing the screen locking.
Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
clients/desktop-shell.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 162 insertions(+), 3 deletions(-)
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 75127ab..bd68ede 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2011 Kristian Høgsberg
+ * Copyright © 2011 Collabora, Ltd.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -43,6 +44,8 @@ struct desktop {
struct panel *panel;
struct window *background;
const char *background_path;
+ struct unlock_dialog *unlock_dialog;
+ struct task unlock_task;
};
struct panel {
@@ -58,6 +61,14 @@ struct panel_item {
const char *path;
};
+struct unlock_dialog {
+ struct window *window;
+ struct item *button;
+ int closing;
+
+ struct desktop *desktop;
+};
+
static char *key_background_image;
static uint32_t key_panel_color;
static char *key_launcher_icon;
@@ -294,6 +305,144 @@ background_draw(struct window *window, int width, int height, const char *path)
}
static void
+unlock_dialog_draw(struct unlock_dialog *dialog)
+{
+ struct rectangle allocation;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pat;
+ double cx, cy, r, f;
+
+ window_draw(dialog->window);
+
+ surface = window_get_surface(dialog->window);
+ cr = cairo_create(surface);
+ window_get_child_allocation(dialog->window, &allocation);
+ cairo_rectangle(cr, allocation.x, allocation.y,
+ allocation.width, allocation.height);
+ cairo_clip(cr);
+ cairo_push_group(cr);
+ cairo_translate(cr, allocation.x, allocation.y);
+
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
+ cairo_paint(cr);
+
+ if (window_get_focus_item(dialog->window) == dialog->button)
+ f = 1.0;
+ else
+ f = 0.7;
+
+ cx = allocation.width / 2.0;
+ cy = allocation.height / 2.0;
+ r = (cx < cy ? cx : cy) * 0.4;
+ pat = cairo_pattern_create_radial(cx, cy, r * 0.7, cx, cy, r);
+ cairo_pattern_add_color_stop_rgb(pat, 0.0, 0, 0.86 * f, 0);
+ cairo_pattern_add_color_stop_rgb(pat, 0.85, 0.2 * f, f, 0.2 * f);
+ cairo_pattern_add_color_stop_rgb(pat, 1.0, 0, 0.86 * f, 0);
+ cairo_set_source(cr, pat);
+ cairo_arc(cr, cx, cy, r, 0.0, 2.0 * M_PI);
+ cairo_fill(cr);
+
+ item_set_allocation(dialog->button,
+ allocation.x + cx - r,
+ allocation.y + cy - r, 2 * r, 2 * r);
+ cairo_pattern_destroy(pat);
+
+ cairo_pop_group_to_source(cr);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ window_flush(dialog->window);
+ cairo_surface_destroy(surface);
+}
+
+static void
+unlock_dialog_button_handler(struct window *window,
+ struct input *input, uint32_t time,
+ int button, int state, void *data)
+{
+ struct unlock_dialog *dialog = data;
+ struct desktop *desktop = dialog->desktop;
+ struct item *focus;
+
+ focus = window_get_focus_item(dialog->window);
+ if (focus && button == BTN_LEFT) {
+ if (state == 0 && !dialog->closing) {
+ display_defer(desktop->display, &desktop->unlock_task);
+ dialog->closing = 1;
+ }
+ }
+}
+
+static void
+unlock_dialog_redraw_handler(struct window *window, void *data)
+{
+ struct unlock_dialog *dialog = data;
+
+ unlock_dialog_draw(dialog);
+}
+
+static void
+unlock_dialog_keyboard_focus_handler(struct window *window,
+ struct input *device, void *data)
+{
+ window_schedule_redraw(window);
+}
+
+static void
+unlock_dialog_item_focus_handler(struct window *window,
+ struct item *focus, void *data)
+{
+ window_schedule_redraw(window);
+}
+
+static struct unlock_dialog *
+unlock_dialog_create(struct display *display)
+{
+ struct unlock_dialog *dialog;
+
+ dialog = malloc(sizeof *dialog);
+ if (!dialog)
+ return NULL;
+ memset(dialog, 0, sizeof *dialog);
+
+ dialog->window = window_create(display, 260, 230);
+ window_set_title(dialog->window, "Unlock your desktop");
+
+ window_set_user_data(dialog->window, dialog);
+ window_set_redraw_handler(dialog->window, unlock_dialog_redraw_handler);
+ window_set_keyboard_focus_handler(dialog->window,
+ unlock_dialog_keyboard_focus_handler);
+ window_set_button_handler(dialog->window, unlock_dialog_button_handler);
+ window_set_item_focus_handler(dialog->window,
+ unlock_dialog_item_focus_handler);
+ dialog->button = window_add_item(dialog->window, NULL);
+
+ unlock_dialog_draw(dialog);
+
+ return dialog;
+}
+
+static void
+unlock_dialog_destroy(struct unlock_dialog *dialog)
+{
+ window_destroy(dialog->window);
+ free(dialog);
+}
+
+static void
+unlock_dialog_finish(struct task *task, uint32_t events)
+{
+ struct desktop *desktop =
+ container_of(task, struct desktop, unlock_task);
+
+ desktop_shell_unlock(desktop->shell);
+ unlock_dialog_destroy(desktop->unlock_dialog);
+ desktop->unlock_dialog = NULL;
+}
+
+static void
desktop_shell_configure(void *data,
struct desktop_shell *desktop_shell,
uint32_t time, uint32_t edges,
@@ -315,8 +464,16 @@ static void
desktop_shell_prepare_lock_surface(void *data,
struct desktop_shell *desktop_shell)
{
- /* no-op for now */
- desktop_shell_unlock(desktop_shell);
+ struct desktop *desktop = data;
+
+ if (!desktop->unlock_dialog) {
+ desktop->unlock_dialog =
+ unlock_dialog_create(desktop->display);
+ desktop->unlock_dialog->desktop = desktop;
+ }
+
+ desktop_shell_set_lock_surface(desktop_shell,
+ window_get_wl_surface(desktop->unlock_dialog->window));
}
static const struct desktop_shell_listener listener = {
@@ -356,9 +513,11 @@ launcher_section_done(void *data)
int main(int argc, char *argv[])
{
- struct desktop desktop;
+ struct desktop desktop = { 0 };
char *config_file;
+ desktop.unlock_task.run = unlock_dialog_finish;
+
desktop.display = display_create(&argc, &argv, NULL);
if (desktop.display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
--
1.7.3.4
More information about the wayland-devel
mailing list