1 /* wmshutdown - dockapp to shutdown or reboot your machine
3 * Copyright 2001, 2002 Rafael V. Aroca <rafael@linuxqos.cjb.net>
4 * Copyright 2014 Doug Torrance <dtorrance@piedmont.edu>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "wmshutdown.xpm"
32 GTK_RESPONSE_HIBERNATE
35 #define HALT_METHOD "PowerOff"
36 #define REBOOT_METHOD "Reboot"
37 #define SUSPEND_METHOD "Suspend"
38 #define HIBERNATE_METHOD "Hibernate"
39 #define DBUS_PATH "/org/freedesktop/login1"
40 #define DBUS_INTERFACE "org.freedesktop.login1.Manager"
41 #define DBUS_DESTINATION "org.freedesktop.login1"
43 static int showVersion
;
44 static gboolean show_suspend
= FALSE
;
45 static gboolean show_hibernate
= FALSE
;
47 GtkWidget
*dialog
= NULL
;
49 static GOptionEntry entries
[] = {
50 { "version", 'v', 0, G_OPTION_ARG_NONE
, &showVersion
,
51 "Display version information", NULL
},
52 { "suspend", 's', 0, G_OPTION_ARG_NONE
, &show_suspend
,
53 "Show 'suspend' button", NULL
},
54 { "hibernate", 'b', 0, G_OPTION_ARG_NONE
, &show_hibernate
,
55 "Show 'hibernate' button", NULL
},
59 /* gtk3 dockapp code based on wmpasman by Brad Jorsch
60 * <anomie@users.sourceforge.net>
61 * http://sourceforge.net/projects/wmpasman */
63 GtkWidget
*cria_dock(GtkWidget
*mw
, unsigned int s
)
68 Window mainwin
, iw
, w
, p
, dummy1
, *dummy2
;
73 display
= gdk_display_get_default();
74 foobox
= gtk_window_new(GTK_WINDOW_POPUP
);
76 gtk_window_set_wmclass(GTK_WINDOW(mw
), g_get_prgname(), "DockApp");
77 gtk_widget_set_size_request(foobox
, 47, 47);
79 gtk_widget_realize(mw
);
80 gtk_widget_realize(foobox
);
82 d
= GDK_DISPLAY_XDISPLAY(display
);
83 mainwin
= GDK_WINDOW_XID(gtk_widget_get_window(mw
));
84 iw
= GDK_WINDOW_XID(gtk_widget_get_window(foobox
));
85 XQueryTree(d
, mainwin
, &dummy1
, &p
, &dummy2
, &dummy3
);
88 w
= XCreateSimpleWindow(d
, p
, 0, 0, 1, 1, 0, 0, 0);
89 XReparentWindow(d
, mainwin
, w
, 0, 0);
91 gtk_widget_show(foobox
);
92 wmHints
= XGetWMHints(d
, mainwin
);
94 wmHints
= XAllocWMHints();
95 wmHints
->flags
|= IconWindowHint
;
96 wmHints
->icon_window
= iw
;
97 XSetWMHints(d
, mainwin
, wmHints
);
99 XReparentWindow(d
, mainwin
, p
, 0, 0);
100 XDestroyWindow(d
, w
);
107 gtk_widget_destroy(dialog
);
111 void handle_click(GtkWidget
*widget
, gpointer data
)
113 GDBusConnection
*connection
;
114 GDBusMessage
*message
, *reply
;
115 GError
*error
= NULL
;
117 gchar
*method
= (gchar
*)data
;
121 connection
= g_bus_get_sync(G_BUS_TYPE_SYSTEM
, NULL
, &error
);
122 message
= g_dbus_message_new_method_call(
127 g_dbus_message_set_body(message
, g_variant_new("(b)", TRUE
));
128 g_dbus_message_set_destination(message
, DBUS_DESTINATION
);
129 reply
= g_dbus_connection_send_message_with_reply_sync(
130 connection
, message
, 0, -1, NULL
, NULL
, &error
);
132 if (g_dbus_message_get_message_type(reply
) ==
133 G_DBUS_MESSAGE_TYPE_ERROR
) {
136 dialog
= gtk_message_dialog_new(
137 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
138 GTK_DIALOG_DESTROY_WITH_PARENT
,
142 g_strcompress(g_variant_print(
143 g_dbus_message_get_body(reply
),
145 gtk_dialog_run(GTK_DIALOG(dialog
));
146 gtk_widget_destroy(dialog
);
149 g_object_unref(message
);
150 g_object_unref(reply
);
151 g_object_unref(connection
);
154 void button_press(GtkWidget
*widget
, GdkEvent
*event
)
157 GtkWidget
*halt_button
;
158 GtkWidget
*reboot_button
;
159 GtkWidget
*suspend_button
;
160 GtkWidget
*hibernate_button
;
161 GtkWidget
*cancel_button
;
162 GdkEventButton
*bevent
;
166 bevent
= (GdkEventButton
*)event
;
167 switch (bevent
->button
) {
171 dialog
= gtk_dialog_new();
172 label
= gtk_label_new("Shutdown confirmation");
173 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
174 GTK_DIALOG(dialog
))),
177 gtk_dialog_add_buttons(GTK_DIALOG(dialog
),
178 "Halt", GTK_RESPONSE_HALT
,
179 "Reboot", GTK_RESPONSE_REBOOT
, NULL
);
180 halt_button
= gtk_dialog_get_widget_for_response(
183 reboot_button
= gtk_dialog_get_widget_for_response(
185 GTK_RESPONSE_REBOOT
);
186 g_signal_connect(halt_button
,
188 G_CALLBACK(handle_click
),
190 g_signal_connect(reboot_button
,
192 G_CALLBACK(handle_click
),
196 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Suspend",
197 GTK_RESPONSE_SUSPEND
, NULL
);
199 gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog
),
200 GTK_RESPONSE_SUSPEND
);
201 g_signal_connect(suspend_button
,
203 G_CALLBACK(handle_click
),
206 if (show_hibernate
) {
207 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Hibernate",
208 GTK_RESPONSE_HIBERNATE
, NULL
);
210 gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog
),
211 GTK_RESPONSE_HIBERNATE
);
212 g_signal_connect(hibernate_button
,
214 G_CALLBACK(handle_click
),
218 gtk_dialog_add_buttons(GTK_DIALOG(dialog
), "Cancel",
219 GTK_RESPONSE_CANCEL
, NULL
);
220 cancel_button
= gtk_dialog_get_widget_for_response(
222 GTK_RESPONSE_CANCEL
);
223 g_signal_connect(cancel_button
,
228 g_signal_connect(dialog
, "destroy", G_CALLBACK(fecha
), NULL
);
229 gtk_widget_show_all(dialog
);
236 int main(int argc
, char *argv
[])
238 GError
*error
= NULL
;
239 GOptionContext
*context
;
245 gtk_init(&argc
, &argv
);
247 context
= g_option_context_new(
248 "- dockapp to shutdown or reboot your machine");
249 g_option_context_add_main_entries(context
, entries
, NULL
);
250 g_option_context_add_group(context
, gtk_get_option_group(TRUE
));
251 g_option_context_parse(context
, &argc
, &argv
, &error
);
254 printf(PACKAGE_STRING
"\n");
258 gtkiw
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
259 dockArea
= cria_dock(gtkiw
, 47);
261 pixbuf
= gdk_pixbuf_new_from_xpm_data(image_name
);
262 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
263 gtk_widget_show(pixmap
);
264 gtk_container_add(GTK_CONTAINER(dockArea
), pixmap
);
266 gtk_widget_add_events(dockArea
, GDK_BUTTON_PRESS_MASK
);
267 g_signal_connect(dockArea
, "button-press-event",
268 G_CALLBACK(button_press
), NULL
);