Merge branch 'backport' into work
Conflicts: openbox/actions/all.h openbox/event.c openbox/prompt.c
This commit is contained in:
commit
37705f444e
12 changed files with 449 additions and 15 deletions
13
Makefile.am
13
Makefile.am
|
@ -31,6 +31,7 @@ lib_LTLIBRARIES = \
|
|||
|
||||
bin_PROGRAMS = \
|
||||
openbox/openbox \
|
||||
tools/gdm-control/gdm-control \
|
||||
tools/gnome-panel-control/gnome-panel-control
|
||||
|
||||
dist_secretbin_SCRIPTS = \
|
||||
|
@ -190,6 +191,7 @@ openbox_openbox_SOURCES = \
|
|||
openbox/actions/if.c \
|
||||
openbox/actions/kill.c \
|
||||
openbox/actions/layer.c \
|
||||
openbox/actions/session.c \
|
||||
openbox/actions/lower.c \
|
||||
openbox/actions/maximize.c \
|
||||
openbox/actions/move.c \
|
||||
|
@ -292,6 +294,17 @@ tools_gnome_panel_control_gnome_panel_control_LDADD = \
|
|||
tools_gnome_panel_control_gnome_panel_control_SOURCES = \
|
||||
tools/gnome-panel-control/gnome-panel-control.c
|
||||
|
||||
## gdm-control ##
|
||||
|
||||
tools_gdm_control_gdm_control_CPPFLAGS = \
|
||||
$(X_CFLAGS) \
|
||||
$(GLIB_CFLAGS)
|
||||
tools_gdm_control_gdm_control_LDADD = \
|
||||
$(X_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
tools_gdm_control_gdm_control_SOURCES = \
|
||||
tools/gdm-control/gdm-control.c
|
||||
|
||||
|
||||
## default button masks ##
|
||||
dist_docxbm_DATA = \
|
||||
|
|
|
@ -331,6 +331,45 @@
|
|||
</item>
|
||||
</menu>
|
||||
|
||||
<menu id="system-menu" label="System">
|
||||
<item label="Openbox Configuration Manager">
|
||||
<action name="Execute">
|
||||
<command>obconf</command>
|
||||
<startupnotify><enabled>yes</enabled></startupnotify>
|
||||
</action>
|
||||
</item>
|
||||
<item label="Gnome Control Center">
|
||||
<action name="Execute">
|
||||
<command>gnome-control-center</command>
|
||||
<startupnotify><enabled>yes</enabled></startupnotify>
|
||||
</action>
|
||||
</item>
|
||||
<item label="KDE Control Center">
|
||||
<action name="Execute">
|
||||
<command>kcontrol</command>
|
||||
<startupnotify><enabled>yes</enabled></startupnotify>
|
||||
</action>
|
||||
</item>
|
||||
<item label="Manage Cups Printers">
|
||||
<action name="Execute">
|
||||
<command>xdg-open http://localhost:631/</command>
|
||||
<startupnotify>
|
||||
<enabled>no</enabled>
|
||||
<icon>cups</icon>
|
||||
</startupnotify>
|
||||
</action>
|
||||
</item>
|
||||
<separator />
|
||||
<item label="Reconfigure Openbox">
|
||||
<action name="Reconfigure" />
|
||||
</item>
|
||||
<item label="Exit Openbox">
|
||||
<action name="Exit">
|
||||
<prompt>yes</prompt>
|
||||
</action>
|
||||
</item>
|
||||
</menu>
|
||||
|
||||
<menu id="root-menu" label="Openbox 3">
|
||||
<separator label="Applications" />
|
||||
<menu id="apps-accessories-menu"/>
|
||||
|
@ -342,18 +381,10 @@
|
|||
<menu id="apps-term-menu"/>
|
||||
<menu id="apps-fileman-menu"/>
|
||||
<separator label="System" />
|
||||
<item label="ObConf">
|
||||
<action name="Execute">
|
||||
<command>obconf</command>
|
||||
<startupnotify><enabled>yes</enabled></startupnotify>
|
||||
</action>
|
||||
</item>
|
||||
<item label="Reconfigure">
|
||||
<action name="Reconfigure" />
|
||||
</item>
|
||||
<menu id="system-menu"/>
|
||||
<separator />
|
||||
<item label="Exit">
|
||||
<action name="Exit">
|
||||
<item label="Logout">
|
||||
<action name="SessionLogout">
|
||||
<prompt>yes</prompt>
|
||||
</action>
|
||||
</item>
|
||||
|
|
|
@ -9,6 +9,7 @@ void action_all_startup(void)
|
|||
action_reconfigure_startup();
|
||||
action_exit_startup();
|
||||
action_restart_startup();
|
||||
action_session_startup();
|
||||
action_cyclewindows_startup();
|
||||
action_breakchroot_startup();
|
||||
action_close_startup();
|
||||
|
|
|
@ -10,6 +10,7 @@ void action_showdesktop_startup(void);
|
|||
void action_reconfigure_startup(void);
|
||||
void action_exit_startup(void);
|
||||
void action_restart_startup(void);
|
||||
void action_session_startup(void);
|
||||
void action_cyclewindows_startup(void);
|
||||
void action_breakchroot_startup(void);
|
||||
void action_close_startup(void);
|
||||
|
|
|
@ -21,6 +21,7 @@ static gpointer setup_func(xmlNodePtr node)
|
|||
Options *o;
|
||||
|
||||
o = g_new0(Options, 1);
|
||||
o->prompt = TRUE;
|
||||
|
||||
if ((n = obt_parse_find_node(node, "prompt")))
|
||||
o->prompt = obt_parse_node_bool(n);
|
||||
|
|
71
openbox/actions/session.c
Normal file
71
openbox/actions/session.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "openbox/actions.h"
|
||||
#include "openbox/prompt.h"
|
||||
#include "openbox/session.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#ifndef USE_SM
|
||||
void action_logout_startup(void) {}
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
gboolean prompt;
|
||||
gboolean silent;
|
||||
} Options;
|
||||
|
||||
static gpointer setup_func(xmlNodePtr node);
|
||||
static gboolean logout_func(ObActionsData *data, gpointer options);
|
||||
|
||||
void action_session_startup(void)
|
||||
{
|
||||
actions_register("SessionLogout", setup_func, NULL, logout_func,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static gpointer setup_func(xmlNodePtr node)
|
||||
{
|
||||
xmlNodePtr n;
|
||||
Options *o;
|
||||
|
||||
o = g_new0(Options, 1);
|
||||
o->prompt = TRUE;
|
||||
|
||||
if ((n = obt_parse_find_node(node, "prompt")))
|
||||
o->prompt = obt_parse_node_bool(n);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static void prompt_cb(ObPrompt *p, gint result, gpointer data)
|
||||
{
|
||||
Options *o = data;
|
||||
if (result)
|
||||
session_request_logout(o->silent);
|
||||
g_free(o);
|
||||
prompt_unref(p);
|
||||
}
|
||||
|
||||
/* Always return FALSE because its not interactive */
|
||||
static gboolean logout_func(ObActionsData *data, gpointer options)
|
||||
{
|
||||
Options *o = options;
|
||||
|
||||
if (o->prompt) {
|
||||
Options *o2;
|
||||
ObPrompt *p;
|
||||
ObPromptAnswer answers[] = {
|
||||
{ _("Cancel"), 0 },
|
||||
{ _("Log out"), 1 }
|
||||
};
|
||||
|
||||
o2 = g_memdup(o, sizeof(Options));
|
||||
p = prompt_new(_("Are you sure you want to log out?"),
|
||||
answers, 2, 0, 0, prompt_cb, o2);
|
||||
prompt_show(p, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
prompt_cb(NULL, 1, NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1726,7 +1726,8 @@ static gboolean event_handle_menu_input(XEvent *ev)
|
|||
|
||||
else if (keycode == ob_keycode(OB_KEY_LEFT)) {
|
||||
/* Left goes to the parent menu */
|
||||
menu_frame_select(frame, NULL, TRUE);
|
||||
if (frame->parent)
|
||||
menu_frame_select(frame, NULL, TRUE);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,6 @@ static void prompt_layout(ObPrompt *self)
|
|||
self->button[i].width = bw;
|
||||
self->button[i].height = bh;
|
||||
RrMinSize(prompt_a_focus, &bw, &bh);
|
||||
g_print("button w %d h %d\n", bw, bh);
|
||||
self->button[i].width = MAX(self->button[i].width, bw);
|
||||
self->button[i].height = MAX(self->button[i].height, bh);
|
||||
RrMinSize(prompt_a_press, &bw, &bh);
|
||||
|
@ -386,8 +385,6 @@ static void setup_button_focus_tex(ObPromptElement *e, RrAppearance *a,
|
|||
a->texture[4].data.lineart.x2 = e->width - r - 1;
|
||||
a->texture[4].data.lineart.y1 = t;
|
||||
a->texture[4].data.lineart.y2 = e->height - b - 1;
|
||||
|
||||
g_print("setting x2 %d\n", e->width - r - 1);
|
||||
}
|
||||
|
||||
static void render_button(ObPrompt *self, ObPromptElement *e)
|
||||
|
|
|
@ -33,6 +33,7 @@ GSList *session_desktop_names = NULL;
|
|||
void session_startup(gint argc, gchar **argv) {}
|
||||
void session_shutdown(gboolean permanent) {}
|
||||
GList* session_state_find(struct _ObClient *c) { return NULL; }
|
||||
void session_request_logout(gboolean silent) {}
|
||||
#else
|
||||
|
||||
#include "debug.h"
|
||||
|
@ -813,4 +814,20 @@ static void session_load_file(const gchar *path)
|
|||
obt_parse_instance_unref(i);
|
||||
}
|
||||
|
||||
void session_request_logout(gboolean silent)
|
||||
{
|
||||
if (sm_conn) {
|
||||
SmcRequestSaveYourself(sm_conn,
|
||||
SmSaveBoth,
|
||||
TRUE, /* logout */
|
||||
(silent ?
|
||||
SmInteractStyleNone : SmInteractStyleAny),
|
||||
TRUE, /* if false, with GSM, it shows the old
|
||||
logout prompt */
|
||||
TRUE); /* global */
|
||||
}
|
||||
else
|
||||
g_message(_("Not connected to a session manager"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,4 +53,6 @@ void session_shutdown(gboolean permanent);
|
|||
|
||||
GList* session_state_find(struct _ObClient *c);
|
||||
|
||||
void session_request_logout(gboolean silent);
|
||||
|
||||
#endif
|
||||
|
|
4
tools/gdm-control/Makefile
Normal file
4
tools/gdm-control/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
all clean install:
|
||||
$(MAKE) -C ../.. -$(MAKEFLAGS) $@
|
||||
|
||||
.PHONY: all clean install
|
295
tools/gdm-control/gdm-control.c
Normal file
295
tools/gdm-control/gdm-control.c
Normal file
|
@ -0,0 +1,295 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xauth.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INVALID,
|
||||
NONE,
|
||||
SHUTDOWN,
|
||||
REBOOT,
|
||||
SUSPEND,
|
||||
SWITCHUSER
|
||||
} Action;
|
||||
|
||||
#define GDM_PROTOCOL_SOCKET_PATH1 "/var/run/gdm_socket"
|
||||
#define GDM_PROTOCOL_SOCKET_PATH2 "/tmp/.gdm_socket"
|
||||
|
||||
#define GDM_PROTOCOL_MSG_CLOSE "CLOSE"
|
||||
#define GDM_PROTOCOL_MSG_VERSION "VERSION"
|
||||
#define GDM_PROTOCOL_MSG_AUTHENTICATE "AUTH_LOCAL"
|
||||
#define GDM_PROTOCOL_MSG_QUERY_ACTION "QUERY_LOGOUT_ACTION"
|
||||
#define GDM_PROTOCOL_MSG_SET_ACTION "SET_SAFE_LOGOUT_ACTION"
|
||||
#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER"
|
||||
|
||||
#define GDM_ACTION_STR_NONE GDM_PROTOCOL_MSG_SET_ACTION" NONE"
|
||||
#define GDM_ACTION_STR_SHUTDOWN GDM_PROTOCOL_MSG_SET_ACTION" HALT"
|
||||
#define GDM_ACTION_STR_REBOOT GDM_PROTOCOL_MSG_SET_ACTION" REBOOT"
|
||||
#define GDM_ACTION_STR_SUSPEND GDM_PROTOCOL_MSG_SET_ACTION" SUSPEND"
|
||||
|
||||
#define GDM_MIT_MAGIC_COOKIE_LEN 16
|
||||
|
||||
static int fd = 0;
|
||||
|
||||
static void gdm_disconnect()
|
||||
{
|
||||
if (fd > 0)
|
||||
close(fd);
|
||||
fd = 0;
|
||||
}
|
||||
|
||||
static char* get_display_number(void)
|
||||
{
|
||||
char *display_name;
|
||||
char *retval;
|
||||
char *p;
|
||||
|
||||
display_name = XDisplayName(NULL);
|
||||
|
||||
p = strchr(display_name, ':');
|
||||
if (!p)
|
||||
return g_strdup ("0");
|
||||
|
||||
while (*p == ':') p++;
|
||||
|
||||
retval = g_strdup (p);
|
||||
|
||||
p = strchr (retval, '.');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char* gdm_send_protocol_msg (const char *msg)
|
||||
{
|
||||
GString *retval;
|
||||
char buf[256];
|
||||
char *p;
|
||||
int len;
|
||||
|
||||
p = g_strconcat(msg, "\n", NULL);
|
||||
if (write (fd, p, strlen(p)) < 0) {
|
||||
g_free (p);
|
||||
|
||||
g_warning ("Failed to send message to GDM: %s",
|
||||
g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
g_free (p);
|
||||
|
||||
p = NULL;
|
||||
retval = NULL;
|
||||
while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) {
|
||||
buf[len] = '\0';
|
||||
|
||||
if (!retval)
|
||||
retval = g_string_new(buf);
|
||||
else
|
||||
retval = g_string_append(retval, buf);
|
||||
|
||||
if ((p = strchr(retval->str, '\n')))
|
||||
break;
|
||||
}
|
||||
|
||||
if (p) *p = '\0';
|
||||
|
||||
return retval ? g_string_free(retval, FALSE) : NULL;
|
||||
}
|
||||
|
||||
static gboolean gdm_authenticate()
|
||||
{
|
||||
FILE *f;
|
||||
Xauth *xau;
|
||||
const char *xau_path;
|
||||
char *display_number;
|
||||
gboolean retval;
|
||||
|
||||
if (!(xau_path = XauFileName()))
|
||||
return FALSE;
|
||||
|
||||
if (!(f = fopen(xau_path, "r")))
|
||||
return FALSE;
|
||||
|
||||
retval = FALSE;
|
||||
display_number = get_display_number();
|
||||
|
||||
while ((xau = XauReadAuth(f))) {
|
||||
char buffer[40]; /* 2*16 == 32, so 40 is enough */
|
||||
char *msg;
|
||||
char *response;
|
||||
int i;
|
||||
|
||||
if (xau->family != FamilyLocal ||
|
||||
strncmp (xau->number, display_number, xau->number_length) ||
|
||||
strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) ||
|
||||
xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN)
|
||||
{
|
||||
XauDisposeAuth(xau);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++)
|
||||
g_snprintf(buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]);
|
||||
|
||||
XauDisposeAuth(xau);
|
||||
|
||||
msg = g_strdup_printf(GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer);
|
||||
response = gdm_send_protocol_msg(msg);
|
||||
g_free (msg);
|
||||
|
||||
if (response && !strcmp(response, "OK")) {
|
||||
/*auth_cookie = g_strdup(buffer);*/
|
||||
g_free(response);
|
||||
retval = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (response);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean gdm_connect()
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
char *response;
|
||||
|
||||
assert(fd <= 0);
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
g_warning("Failed to create GDM socket: %s", g_strerror (errno));
|
||||
gdm_disconnect();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_file_test(GDM_PROTOCOL_SOCKET_PATH1, G_FILE_TEST_EXISTS))
|
||||
strcpy(addr.sun_path, GDM_PROTOCOL_SOCKET_PATH1);
|
||||
else
|
||||
strcpy(addr.sun_path, GDM_PROTOCOL_SOCKET_PATH2);
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
if (connect(fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
|
||||
g_warning("Failed to establish a connection with GDM: %s",
|
||||
g_strerror(errno));
|
||||
gdm_disconnect();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
response = gdm_send_protocol_msg(GDM_PROTOCOL_MSG_VERSION);
|
||||
if (!response || strncmp(response, "GDM ", strlen("GDM ") != 0)) {
|
||||
g_free(response);
|
||||
|
||||
g_warning("Failed to get protocol version from GDM");
|
||||
gdm_disconnect();
|
||||
return FALSE;
|
||||
}
|
||||
g_free(response);
|
||||
|
||||
if (!gdm_authenticate()) {
|
||||
g_warning("Failed to authenticate with GDM");
|
||||
gdm_disconnect();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
Action a = INVALID;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "--help")) {
|
||||
a = INVALID;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--none")) {
|
||||
a = NONE;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--shutdown")) {
|
||||
a = SHUTDOWN;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--reboot")) {
|
||||
a = REBOOT;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--suspend")) {
|
||||
a = SUSPEND;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--switch-user")) {
|
||||
a = SWITCHUSER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!a) {
|
||||
printf("Usage: gdm-control ACTION\n\n");
|
||||
printf("Actions:\n");
|
||||
printf(" --help Display this help and exit\n");
|
||||
printf(" --none Do nothing special when the current session ends\n");
|
||||
printf(" --shutdown Shutdown the computer when the current session ends\n");
|
||||
printf(" --reboot Reboot the computer when the current session ends\n");
|
||||
printf(" --suspend Suspend the computer when the current session ends\n");
|
||||
printf(" --switch-user Log in as a new user (this works immediately)\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
char *d, *response;
|
||||
const char *action_string;
|
||||
|
||||
d = XDisplayName(NULL);
|
||||
if (!d) {
|
||||
fprintf(stderr,
|
||||
"Unable to fina an X display specified by the DISPLAY "
|
||||
"environment variable. Ensure that it is set correctly.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (a) {
|
||||
case NONE:
|
||||
action_string = GDM_ACTION_STR_NONE;
|
||||
break;
|
||||
case SHUTDOWN:
|
||||
action_string = GDM_ACTION_STR_SHUTDOWN;
|
||||
break;
|
||||
case REBOOT:
|
||||
action_string = GDM_ACTION_STR_REBOOT;
|
||||
break;
|
||||
case SUSPEND:
|
||||
action_string = GDM_ACTION_STR_SUSPEND;
|
||||
break;
|
||||
case SWITCHUSER:
|
||||
action_string = GDM_PROTOCOL_MSG_FLEXI_XSERVER;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (gdm_connect()) {
|
||||
response = gdm_send_protocol_msg(action_string);
|
||||
g_free(response);
|
||||
gdm_disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue