Added --enable-fbmanager. This is some experimental code that lets several
2001-06-25 Alexander Larsson <alexl@redhat.com> * configure.in: Added --enable-fbmanager. This is some experimental code that lets several GtkFB apps coordinate their access to the framebuffer. * acconfig.h: Added ENABLE_FB_MANAGER. * gdk/linux-fb/Makefile.am: Added gdkfbmanager and gdkfbswitch. * gdk/linux-fb/gdkkeyboard-fb.c: * gdk/linux-fb/gdkmouse-fb.c: * gdk/linux-fb/gdkprivate-fb.h: Split device init and open so that they can be opened and closed while switched away. * gdk/linux-fb/gdkmain-fb.c: Add the basic manager communication. * gdk/linux-fb/gdkrender-fb.c: Don't update to the shadow fb if we're blocked by the fb manager.
This commit is contained in:
parent
4168b47803
commit
75fd7f09af
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
2001-06-25 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Added --enable-fbmanager. This is some experimental code
|
||||||
|
that lets several GtkFB apps coordinate their access to the
|
||||||
|
framebuffer.
|
||||||
|
|
||||||
|
* acconfig.h:
|
||||||
|
Added ENABLE_FB_MANAGER.
|
||||||
|
|
||||||
|
* gdk/linux-fb/Makefile.am:
|
||||||
|
Added gdkfbmanager and gdkfbswitch.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkkeyboard-fb.c:
|
||||||
|
* gdk/linux-fb/gdkmouse-fb.c:
|
||||||
|
* gdk/linux-fb/gdkprivate-fb.h:
|
||||||
|
Split device init and open so that
|
||||||
|
they can be opened and closed while switched
|
||||||
|
away.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkmain-fb.c:
|
||||||
|
Add the basic manager communication.
|
||||||
|
|
||||||
|
* gdk/linux-fb/gdkrender-fb.c:
|
||||||
|
Don't update to the shadow fb if we're
|
||||||
|
blocked by the fb manager.
|
||||||
|
|
||||||
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Jun 24 22:15:16 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* docs/Changes-2.0.txt: Add note about child property
|
* docs/Changes-2.0.txt: Add note about child property
|
||||||
|
@ -50,6 +50,9 @@
|
|||||||
/* Define to use shadowfb in the linux-fb port */
|
/* Define to use shadowfb in the linux-fb port */
|
||||||
#undef ENABLE_SHADOW_FB
|
#undef ENABLE_SHADOW_FB
|
||||||
|
|
||||||
|
/* Define to use a fb manager in the linux-fb port */
|
||||||
|
#undef ENABLE_FB_MANAGER
|
||||||
|
|
||||||
#undef XINPUT_NONE
|
#undef XINPUT_NONE
|
||||||
#undef XINPUT_GXI
|
#undef XINPUT_GXI
|
||||||
#undef XINPUT_XFREE
|
#undef XINPUT_XFREE
|
||||||
|
10
configure.in
10
configure.in
@ -136,6 +136,8 @@ esac
|
|||||||
|
|
||||||
AC_ARG_ENABLE(shadowfb, [ --disable-shadowfb disable shadowfb support for linux-fb],,enable_shadowfb=yes)
|
AC_ARG_ENABLE(shadowfb, [ --disable-shadowfb disable shadowfb support for linux-fb],,enable_shadowfb=yes)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(fbmanager, [ --enable-fbmanager enable framebuffer manager support (GtkFB)],enable_fbmanager=yes,enable_fbmanager=no)
|
||||||
|
|
||||||
if test "x$enable_debug" = "xyes"; then
|
if test "x$enable_debug" = "xyes"; then
|
||||||
test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
|
test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
|
||||||
GTK_DEBUG_FLAGS="-DG_ENABLE_DEBUG"
|
GTK_DEBUG_FLAGS="-DG_ENABLE_DEBUG"
|
||||||
@ -853,12 +855,20 @@ if test "x$gdktarget" = "xlinux-fb"; then
|
|||||||
AC_DEFINE(ENABLE_SHADOW_FB)
|
AC_DEFINE(ENABLE_SHADOW_FB)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$enable_fbmanager = xyes ; then
|
||||||
|
AC_DEFINE(ENABLE_FB_MANAGER)
|
||||||
|
AM_CONDITIONAL(ENABLE_FB_MANAGER, true)
|
||||||
|
else
|
||||||
|
AM_CONDITIONAL(ENABLE_FB_MANAGER, false)
|
||||||
|
fi
|
||||||
|
|
||||||
GDK_EXTRA_CFLAGS="$FREETYPE_CFLAGS"
|
GDK_EXTRA_CFLAGS="$FREETYPE_CFLAGS"
|
||||||
GDK_EXTRA_LIBS="$FREETYPE_LIBS $GDK_EXTRA_LIBS"
|
GDK_EXTRA_LIBS="$FREETYPE_LIBS $GDK_EXTRA_LIBS"
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_LINUX_FB, true)
|
AM_CONDITIONAL(USE_LINUX_FB, true)
|
||||||
else
|
else
|
||||||
AM_CONDITIONAL(USE_LINUX_FB, false)
|
AM_CONDITIONAL(USE_LINUX_FB, false)
|
||||||
|
AM_CONDITIONAL(ENABLE_FB_MANAGER, false)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(gdktargetlib)
|
AC_SUBST(gdktargetlib)
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
if ENABLE_FB_MANAGER
|
||||||
|
bin_PROGRAMS = gdkfbmanager gdkfbswitch
|
||||||
|
else
|
||||||
|
bin_PROGRAMS =
|
||||||
|
endif
|
||||||
|
|
||||||
libgdkincludedir = $(includedir)/gtk-2.0/gdk
|
libgdkincludedir = $(includedir)/gtk-2.0/gdk
|
||||||
libgdkfbincludedir = $(includedir)/gtk-2.0/gdk/linux-fb
|
libgdkfbincludedir = $(includedir)/gtk-2.0/gdk/linux-fb
|
||||||
|
|
||||||
@ -61,14 +67,17 @@ libgdk_linux_fb_la_SOURCES = \
|
|||||||
mipolyutil.c \
|
mipolyutil.c \
|
||||||
miscanfill.h \
|
miscanfill.h \
|
||||||
mispans.h \
|
mispans.h \
|
||||||
|
mispans.c \
|
||||||
mistruct.h \
|
mistruct.h \
|
||||||
mitypes.h \
|
mitypes.h \
|
||||||
miwideline.c \
|
miwideline.c \
|
||||||
miwideline.h \
|
miwideline.h \
|
||||||
mizerclip.c \
|
mizerclip.c \
|
||||||
mizerline.c \
|
mizerline.c \
|
||||||
mispans.c \
|
gdkpango-fb.c \
|
||||||
gdkpango-fb.c
|
gdkfbmanager.h
|
||||||
mispans.c
|
|
||||||
|
gdkfbmanager_sources = gdkfbmanager.c
|
||||||
|
gdkfbswitch_sources = gdkfbswitch.c
|
||||||
|
|
||||||
EXTRA_DIST=x-cursors.xbm
|
EXTRA_DIST=x-cursors.xbm
|
||||||
|
406
gdk/linux-fb/gdkfbmanager.c
Normal file
406
gdk/linux-fb/gdkfbmanager.c
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "gdkfbmanager.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int socket;
|
||||||
|
int pid; /* -1 if not initialized */
|
||||||
|
} Client;
|
||||||
|
|
||||||
|
GHashTable *clients = NULL;
|
||||||
|
GHashTable *new_clients = NULL;
|
||||||
|
Client *current_owner = NULL;
|
||||||
|
|
||||||
|
int master_socket;
|
||||||
|
|
||||||
|
int create_master_socket (void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
fd = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf ("Error creating socket: %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink ("/tmp/.fb.manager");
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy (addr.sun_path, "/tmp/.fb.manager");
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
|
||||||
|
{
|
||||||
|
printf ("Unable to bind socket: %s\n", strerror(errno));
|
||||||
|
close (fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (listen (fd, 10) < 0)
|
||||||
|
{
|
||||||
|
printf ("Unable to listen on socket: %s\n", strerror(errno));
|
||||||
|
close (fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
master_socket = fd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_new_client (void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
Client *client;
|
||||||
|
int true_val;
|
||||||
|
|
||||||
|
fd = accept (master_socket, NULL, NULL);
|
||||||
|
|
||||||
|
client = g_new (Client, 1);
|
||||||
|
client->socket = fd;
|
||||||
|
client->pid = -1;
|
||||||
|
|
||||||
|
true_val = 1;
|
||||||
|
setsockopt (fd, SOL_SOCKET, SO_PASSCRED,
|
||||||
|
&true_val, sizeof (true_val));
|
||||||
|
|
||||||
|
g_print ("Handling new client %p conntecting, fd = %d\n", client, fd);
|
||||||
|
|
||||||
|
g_hash_table_insert (new_clients, client, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fd_data
|
||||||
|
{
|
||||||
|
fd_set *read_fds;
|
||||||
|
fd_set *exception_fds;
|
||||||
|
int max_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
send_message (Client *client, enum FBManagerMessageType type, int data)
|
||||||
|
{
|
||||||
|
struct FBManagerMessage msg;
|
||||||
|
|
||||||
|
msg.msg_type = type;
|
||||||
|
msg.data = data;
|
||||||
|
|
||||||
|
send (client->socket, &msg, sizeof (msg), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
wait_for_ack (Client *client, int timeout_secs)
|
||||||
|
{
|
||||||
|
struct FBManagerMessage msg;
|
||||||
|
int res;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(client->socket, &rfds);
|
||||||
|
|
||||||
|
tv.tv_sec = timeout_secs;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
res = select (client->socket+1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (res == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
res = recv (client->socket, &msg, sizeof (msg), 0);
|
||||||
|
if (res != sizeof (msg))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (msg.msg_type == FB_MANAGER_ACK)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
find_another_client (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Client **res;
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
res = user_data;
|
||||||
|
|
||||||
|
if (*res)
|
||||||
|
return;
|
||||||
|
|
||||||
|
client = value;
|
||||||
|
if (client != current_owner)
|
||||||
|
*res = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
switch_to_client (Client *client)
|
||||||
|
{
|
||||||
|
g_print ("Switch_to_client, client=%p, current_owner=%p\n", client, current_owner);
|
||||||
|
|
||||||
|
if ((current_owner == client) && (client != NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (current_owner)
|
||||||
|
{
|
||||||
|
g_print ("switching from client fd=%d\n", current_owner->socket);
|
||||||
|
send_message (current_owner, FB_MANAGER_SWITCH_FROM, 0);
|
||||||
|
wait_for_ack (current_owner, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_owner = client;
|
||||||
|
|
||||||
|
if (current_owner)
|
||||||
|
{
|
||||||
|
g_print ("switching to client fd=%d\n", current_owner->socket);
|
||||||
|
send_message (current_owner, FB_MANAGER_SWITCH_TO, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
close_client (Client *client)
|
||||||
|
{
|
||||||
|
Client *other_client;
|
||||||
|
g_print ("Closing client %p (fd=%d)\n",
|
||||||
|
client, client->socket);
|
||||||
|
|
||||||
|
if (current_owner == client)
|
||||||
|
{
|
||||||
|
other_client = NULL;
|
||||||
|
g_hash_table_foreach (clients,
|
||||||
|
find_another_client,
|
||||||
|
&other_client);
|
||||||
|
current_owner = NULL;
|
||||||
|
/* FIXME: This is a hack around the fact that the serial
|
||||||
|
mouse driver had problems with opening and closing
|
||||||
|
the device almost at the same time.
|
||||||
|
*/
|
||||||
|
sleep (1);
|
||||||
|
switch_to_client (other_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (client->socket);
|
||||||
|
g_free (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns TRUE if the client was closed */
|
||||||
|
gboolean
|
||||||
|
read_client_data (Client *client)
|
||||||
|
{
|
||||||
|
struct FBManagerMessage fb_message;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char control_buffer[256];
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
int res;
|
||||||
|
struct ucred *creds;
|
||||||
|
Client *new_client;
|
||||||
|
|
||||||
|
iov.iov_base = &fb_message;
|
||||||
|
iov.iov_len = sizeof (fb_message);
|
||||||
|
|
||||||
|
cmsg = (struct cmsghdr *)control_buffer;
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = cmsg;
|
||||||
|
msg.msg_controllen = 256;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
|
g_print ("Reading client data:");
|
||||||
|
res = recvmsg (client->socket, &msg, 0);
|
||||||
|
g_print ("%d bytes, (error: %s)\n", res,
|
||||||
|
strerror (errno));
|
||||||
|
|
||||||
|
if (res < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (res == 0)
|
||||||
|
{
|
||||||
|
close_client (client);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != sizeof (fb_message))
|
||||||
|
{
|
||||||
|
g_warning ("Packet with wrong size %d recieved", res);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fb_message.msg_type) {
|
||||||
|
case FB_MANAGER_NEW_CLIENT:
|
||||||
|
if (client->pid != -1)
|
||||||
|
{
|
||||||
|
g_warning ("Got a NEW_CLIENT message from an old client");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
creds = NULL;
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
cmsg != NULL;
|
||||||
|
cmsg = CMSG_NXTHDR(&msg,cmsg))
|
||||||
|
{
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
|
cmsg->cmsg_type == SCM_CREDENTIALS)
|
||||||
|
{
|
||||||
|
creds = (struct ucred *) CMSG_DATA(cmsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (creds == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Got no credentials in NEW_CLIENT message");
|
||||||
|
close_client (client);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
client->pid = creds->pid;
|
||||||
|
|
||||||
|
g_hash_table_insert (clients, GINT_TO_POINTER (client->pid), client);
|
||||||
|
|
||||||
|
g_print ("New client connected. Pid=%d\n", (int)creds->pid);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case FB_MANAGER_REQUEST_SWITCH_TO_PID:
|
||||||
|
if (client->pid == -1)
|
||||||
|
{
|
||||||
|
g_warning ("Got a message from an uninitialized client");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_client = g_hash_table_lookup (clients, GINT_TO_POINTER (fb_message.data));
|
||||||
|
if (new_client)
|
||||||
|
switch_to_client (new_client);
|
||||||
|
else
|
||||||
|
g_warning ("Switchto unknown PID");
|
||||||
|
break;
|
||||||
|
case FB_MANAGER_ACK:
|
||||||
|
if (client->pid == -1)
|
||||||
|
{
|
||||||
|
g_warning ("Got a message from an uninitialized client");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_warning ("Got an unexpected ACK");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning ("Got unknown package type %d", fb_message.msg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns TRUE if the client was closed */
|
||||||
|
gboolean
|
||||||
|
handle_client_data (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Client *client;
|
||||||
|
struct fd_data *data;
|
||||||
|
|
||||||
|
client = value;
|
||||||
|
data = user_data;
|
||||||
|
|
||||||
|
if (FD_ISSET (client->socket, data->exception_fds))
|
||||||
|
{
|
||||||
|
close_client (client);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (FD_ISSET (client->socket, data->read_fds))
|
||||||
|
{
|
||||||
|
return read_client_data (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_fds (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
struct fd_data *data;
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
client = value;
|
||||||
|
data = user_data;
|
||||||
|
|
||||||
|
FD_SET (client->socket, data->read_fds);
|
||||||
|
FD_SET (client->socket, data->exception_fds);
|
||||||
|
data->max_fd = MAX (data->max_fd,
|
||||||
|
client->socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main_loop (void)
|
||||||
|
{
|
||||||
|
fd_set read_fds;
|
||||||
|
fd_set exception_fds;
|
||||||
|
struct fd_data data;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
FD_ZERO (&read_fds);
|
||||||
|
FD_ZERO (&exception_fds);
|
||||||
|
FD_SET (master_socket, &read_fds);
|
||||||
|
|
||||||
|
data.read_fds = &read_fds;
|
||||||
|
data.exception_fds = &exception_fds;
|
||||||
|
data.max_fd = master_socket;
|
||||||
|
|
||||||
|
g_hash_table_foreach (clients,
|
||||||
|
set_fds,
|
||||||
|
&data);
|
||||||
|
g_hash_table_foreach (new_clients,
|
||||||
|
set_fds,
|
||||||
|
&data);
|
||||||
|
|
||||||
|
|
||||||
|
res = select (data.max_fd+1,
|
||||||
|
&read_fds, NULL, &exception_fds,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (FD_ISSET (master_socket, &read_fds))
|
||||||
|
handle_new_client ();
|
||||||
|
|
||||||
|
g_hash_table_foreach_remove (clients,
|
||||||
|
handle_client_data,
|
||||||
|
&data);
|
||||||
|
g_hash_table_foreach_remove (new_clients,
|
||||||
|
handle_client_data,
|
||||||
|
&data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
clients = g_hash_table_new (g_direct_hash,
|
||||||
|
g_direct_equal);
|
||||||
|
new_clients = g_hash_table_new (g_direct_hash,
|
||||||
|
g_direct_equal);
|
||||||
|
|
||||||
|
create_master_socket ();
|
||||||
|
|
||||||
|
main_loop ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
37
gdk/linux-fb/gdkfbmanager.h
Normal file
37
gdk/linux-fb/gdkfbmanager.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* GDK - The GIMP Drawing Kit
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __GDK_FB_MANAGER_H__
|
||||||
|
#define __GDK_FB_MANAGER_H__
|
||||||
|
|
||||||
|
enum FBManagerMessageType {
|
||||||
|
/* manager -> client */
|
||||||
|
FB_MANAGER_SWITCH_TO,
|
||||||
|
FB_MANAGER_SWITCH_FROM, /* requires ack */
|
||||||
|
|
||||||
|
/* client -> manager */
|
||||||
|
FB_MANAGER_NEW_CLIENT,
|
||||||
|
FB_MANAGER_REQUEST_SWITCH_TO_PID,
|
||||||
|
FB_MANAGER_ACK,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FBManagerMessage {
|
||||||
|
enum FBManagerMessageType msg_type;
|
||||||
|
int data;
|
||||||
|
};
|
||||||
|
#endif /* __GDK_FB_MANAGER_H__ */
|
75
gdk/linux-fb/gdkfbswitch.c
Normal file
75
gdk/linux-fb/gdkfbswitch.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include "gdkfbmanager.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
struct msghdr msg = {0};
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct ucred credentials;
|
||||||
|
struct FBManagerMessage init_msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char buf[CMSG_SPACE (sizeof (credentials))]; /* ancillary data buffer */
|
||||||
|
int *fdptr;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
g_print ("usage: fbswitch <pid>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy (addr.sun_path, "/tmp/.fb.manager");
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
|
||||||
|
{
|
||||||
|
g_print ("connect failed\n");
|
||||||
|
close (fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials.pid = getpid ();
|
||||||
|
credentials.uid = geteuid ();
|
||||||
|
credentials.gid = getegid ();
|
||||||
|
|
||||||
|
init_msg.msg_type = FB_MANAGER_NEW_CLIENT;
|
||||||
|
iov.iov_base = &init_msg;
|
||||||
|
iov.iov_len = sizeof (init_msg);
|
||||||
|
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = buf;
|
||||||
|
msg.msg_controllen = sizeof buf;
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg->cmsg_type = SCM_CREDENTIALS;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN (sizeof (credentials));
|
||||||
|
/* Initialize the payload: */
|
||||||
|
fdptr = (int *)CMSG_DATA (cmsg);
|
||||||
|
memcpy (fdptr, &credentials, sizeof (credentials));
|
||||||
|
/* Sum of the length of all control messages in the buffer: */
|
||||||
|
msg.msg_controllen = cmsg->cmsg_len;
|
||||||
|
|
||||||
|
res = sendmsg (fd, &msg, 0);
|
||||||
|
|
||||||
|
init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID;
|
||||||
|
init_msg.data = atoi (argv[1]);
|
||||||
|
/* Request a switch-to */
|
||||||
|
send (fd, &init_msg, sizeof (init_msg), 0);
|
||||||
|
g_print ("requested a switch to pid %d\n", init_msg.data);
|
||||||
|
}
|
@ -167,17 +167,18 @@ gdk_fb_keyboard_modifiers ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gdk_fb_keyboard_open (void)
|
gdk_fb_keyboard_init (gboolean open_dev)
|
||||||
{
|
{
|
||||||
GdkFBKeyboard *keyb;
|
GdkFBKeyboard *keyb;
|
||||||
GdkFBKeyboardDevice *device;
|
|
||||||
char *keyb_type;
|
char *keyb_type;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
keyb = g_new0 (GdkFBKeyboard, 1);
|
gdk_fb_keyboard = g_new0 (GdkFBKeyboard, 1);
|
||||||
|
keyb = gdk_fb_keyboard;
|
||||||
keyb->fd = -1;
|
keyb->fd = -1;
|
||||||
|
|
||||||
keyb_type = getenv ("GDK_KEYBOARD_TYPE");
|
keyb_type = getenv ("GDK_KEYBOARD_TYPE");
|
||||||
|
|
||||||
if (!keyb_type)
|
if (!keyb_type)
|
||||||
keyb_type = "xlate";
|
keyb_type = "xlate";
|
||||||
|
|
||||||
@ -193,19 +194,29 @@ gdk_fb_keyboard_open (void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = &keyb_devs[i];
|
keyb->dev = &keyb_devs[i];
|
||||||
|
|
||||||
keyb->dev = device;
|
if (open_dev)
|
||||||
|
return gdk_fb_keyboard_open ();
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdk_fb_keyboard_open (void)
|
||||||
|
{
|
||||||
|
GdkFBKeyboard *keyb;
|
||||||
|
GdkFBKeyboardDevice *device;
|
||||||
|
|
||||||
|
keyb = gdk_fb_keyboard;
|
||||||
|
device = keyb->dev;
|
||||||
|
|
||||||
if (!device->open(keyb))
|
if (!device->open(keyb))
|
||||||
{
|
{
|
||||||
g_warning ("Keyboard driver open failed");
|
g_warning ("Keyboard driver open failed");
|
||||||
g_free (keyb);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_fb_keyboard = keyb;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +224,6 @@ void
|
|||||||
gdk_fb_keyboard_close (void)
|
gdk_fb_keyboard_close (void)
|
||||||
{
|
{
|
||||||
gdk_fb_keyboard->dev->close(gdk_fb_keyboard);
|
gdk_fb_keyboard->dev->close(gdk_fb_keyboard);
|
||||||
g_free (gdk_fb_keyboard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -903,6 +913,7 @@ xlate_close (GdkFBKeyboard *kb)
|
|||||||
|
|
||||||
g_source_remove (kb->io_tag);
|
g_source_remove (kb->io_tag);
|
||||||
g_io_channel_unref (kb->io);
|
g_io_channel_unref (kb->io);
|
||||||
|
kb->fd = -1;
|
||||||
/* don't close kb->fd, it is the tty from gdk_display */
|
/* don't close kb->fd, it is the tty from gdk_display */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +39,14 @@
|
|||||||
#include <sys/kd.h>
|
#include <sys/kd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include "gdk.h"
|
#include "gdk.h"
|
||||||
|
|
||||||
#include "gdkprivate-fb.h"
|
#include "gdkprivate-fb.h"
|
||||||
#include "gdkinternals.h"
|
#include "gdkinternals.h"
|
||||||
|
#include "gdkfbmanager.h"
|
||||||
|
|
||||||
/* Private variable declarations
|
/* Private variable declarations
|
||||||
*/
|
*/
|
||||||
@ -484,6 +488,159 @@ gdk_fb_set_mode (GdkFBDisplay *display)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_FB_MANAGER
|
||||||
|
static void
|
||||||
|
gdk_fb_switch_from (void)
|
||||||
|
{
|
||||||
|
g_print ("Switch from\n");
|
||||||
|
gdk_shadow_fb_stop_updates ();
|
||||||
|
gdk_fb_mouse_close ();
|
||||||
|
gdk_fb_keyboard_close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_fb_switch_to (void)
|
||||||
|
{
|
||||||
|
g_print ("switch_to\n");
|
||||||
|
gdk_shadow_fb_update (0, 0,
|
||||||
|
gdk_display->fb_width,
|
||||||
|
gdk_display->fb_height);
|
||||||
|
|
||||||
|
if (!gdk_fb_keyboard_open ())
|
||||||
|
g_warning ("Failed to re-initialize keyboard");
|
||||||
|
|
||||||
|
if (!gdk_fb_mouse_open ())
|
||||||
|
g_warning ("Failed to re-initialize mouse");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_fb_manager_callback (GIOChannel *gioc,
|
||||||
|
GIOCondition cond,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
struct FBManagerMessage msg;
|
||||||
|
GdkFBDisplay *display;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
display = data;
|
||||||
|
|
||||||
|
res = recv (display->manager_fd, &msg, sizeof (msg), 0);
|
||||||
|
|
||||||
|
if (res==0)
|
||||||
|
{
|
||||||
|
g_source_remove (gdk_display->manager_tag);
|
||||||
|
/*g_io_channel_unref (kb->io);*/
|
||||||
|
close (gdk_display->manager_fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != sizeof (msg))
|
||||||
|
{
|
||||||
|
g_warning ("Got wrong size message");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg.msg_type)
|
||||||
|
{
|
||||||
|
case FB_MANAGER_SWITCH_FROM:
|
||||||
|
g_print ("Got switch from message\n");
|
||||||
|
display->manager_blocked = TRUE;
|
||||||
|
gdk_fb_switch_from ();
|
||||||
|
msg.msg_type = FB_MANAGER_ACK;
|
||||||
|
send (display->manager_fd, &msg, sizeof (msg), 0);
|
||||||
|
break;
|
||||||
|
case FB_MANAGER_SWITCH_TO:
|
||||||
|
g_print ("Got switch to message\n");
|
||||||
|
display->manager_blocked = FALSE;
|
||||||
|
gdk_fb_switch_to ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning ("Got unknown message");
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_FB_MANAGER */
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_fb_manager_connect (GdkFBDisplay *display)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
struct msghdr msg = {0};
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct ucred credentials;
|
||||||
|
struct FBManagerMessage init_msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char buf[CMSG_SPACE (sizeof (credentials))]; /* ancillary data buffer */
|
||||||
|
int *fdptr;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
display->manager_blocked = FALSE;
|
||||||
|
display->manager_fd = -1;
|
||||||
|
|
||||||
|
#ifdef ENABLE_FB_MANAGER
|
||||||
|
fd = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
g_print ("socket: %d\n", fd);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy (addr.sun_path, "/tmp/.fb.manager");
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
|
||||||
|
{
|
||||||
|
g_print ("connect failed\n");
|
||||||
|
close (fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials.pid = getpid ();
|
||||||
|
credentials.uid = geteuid ();
|
||||||
|
credentials.gid = getegid ();
|
||||||
|
|
||||||
|
init_msg.msg_type = FB_MANAGER_NEW_CLIENT;
|
||||||
|
iov.iov_base = &init_msg;
|
||||||
|
iov.iov_len = sizeof (init_msg);
|
||||||
|
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = buf;
|
||||||
|
msg.msg_controllen = sizeof buf;
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg->cmsg_type = SCM_CREDENTIALS;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN (sizeof (credentials));
|
||||||
|
/* Initialize the payload: */
|
||||||
|
fdptr = (int *)CMSG_DATA (cmsg);
|
||||||
|
memcpy (fdptr, &credentials, sizeof (credentials));
|
||||||
|
/* Sum of the length of all control messages in the buffer: */
|
||||||
|
msg.msg_controllen = cmsg->cmsg_len;
|
||||||
|
|
||||||
|
res = sendmsg (fd, &msg, 0);
|
||||||
|
|
||||||
|
display->manager_fd = fd;
|
||||||
|
display->manager_blocked = TRUE;
|
||||||
|
|
||||||
|
display->manager_tag = g_io_add_watch (g_io_channel_unix_new (fd),
|
||||||
|
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
|
||||||
|
gdk_fb_manager_callback,
|
||||||
|
display);
|
||||||
|
|
||||||
|
init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID;
|
||||||
|
init_msg.data = getpid ();
|
||||||
|
|
||||||
|
/* Request a switch-to */
|
||||||
|
send (fd, &init_msg, sizeof (init_msg), 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static GdkFBDisplay *
|
static GdkFBDisplay *
|
||||||
gdk_fb_display_new ()
|
gdk_fb_display_new ()
|
||||||
{
|
{
|
||||||
@ -658,7 +815,9 @@ _gdk_windowing_init_check (int argc, char **argv)
|
|||||||
|
|
||||||
gdk_shadow_fb_init ();
|
gdk_shadow_fb_init ();
|
||||||
|
|
||||||
if (!gdk_fb_keyboard_open ())
|
gdk_fb_manager_connect (gdk_display);
|
||||||
|
|
||||||
|
if (!gdk_fb_keyboard_init (!gdk_display->manager_blocked))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to initialize keyboard");
|
g_warning ("Failed to initialize keyboard");
|
||||||
gdk_fb_display_destroy (gdk_display);
|
gdk_fb_display_destroy (gdk_display);
|
||||||
@ -666,7 +825,7 @@ _gdk_windowing_init_check (int argc, char **argv)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gdk_fb_mouse_open ())
|
if (!gdk_fb_mouse_init (!gdk_display->manager_blocked))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to initialize mouse");
|
g_warning ("Failed to initialize mouse");
|
||||||
gdk_fb_keyboard_close ();
|
gdk_fb_keyboard_close ();
|
||||||
@ -679,6 +838,7 @@ _gdk_windowing_init_check (int argc, char **argv)
|
|||||||
|
|
||||||
gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
|
gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1041,8 +1201,10 @@ gdk_windowing_exit (void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
gdk_fb_mouse_close ();
|
gdk_fb_mouse_close ();
|
||||||
|
/*leak g_free (gdk_fb_mouse);*/
|
||||||
|
|
||||||
gdk_fb_keyboard_close ();
|
gdk_fb_keyboard_close ();
|
||||||
|
/*leak g_free (gdk_fb_keyboard);*/
|
||||||
|
|
||||||
gdk_fb_display_destroy (gdk_display);
|
gdk_fb_display_destroy (gdk_display);
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
typedef struct _GdkFBMouse GdkFBMouse;
|
typedef struct _GdkFBMouse GdkFBMouse;
|
||||||
typedef struct _GdkFBMouseDevice GdkFBMouseDevice;
|
typedef struct _GdkFBMouseDevice GdkFBMouseDevice;
|
||||||
@ -275,17 +277,15 @@ static GdkFBMouseDevice mouse_devs[] =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gdk_fb_mouse_open (void)
|
gdk_fb_mouse_init (gboolean open_dev)
|
||||||
{
|
{
|
||||||
GdkFBMouse *mouse;
|
|
||||||
GdkFBMouseDevice *device;
|
|
||||||
char *mouse_type;
|
char *mouse_type;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mouse = g_new0 (GdkFBMouse, 1);
|
gdk_fb_mouse = g_new0 (GdkFBMouse, 1);
|
||||||
mouse->fd = -1;
|
gdk_fb_mouse->fd = -1;
|
||||||
|
|
||||||
mouse_type = getenv ("GDK_MOUSE_TYPE");
|
mouse_type = getenv ("GDK_MOUSE_TYPE");
|
||||||
if (!mouse_type)
|
if (!mouse_type)
|
||||||
mouse_type = "ps2";
|
mouse_type = "ps2";
|
||||||
@ -302,34 +302,56 @@ gdk_fb_mouse_open (void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = &mouse_devs[i];
|
gdk_fb_mouse->dev = &mouse_devs[i];
|
||||||
|
|
||||||
mouse->dev = device;
|
gdk_fb_mouse->x = gdk_display->fb_width / 2;
|
||||||
|
gdk_fb_mouse->y = gdk_display->fb_height / 2;
|
||||||
|
|
||||||
mouse->x = gdk_display->fb_width / 2;
|
if (open_dev)
|
||||||
mouse->y = gdk_display->fb_height / 2;
|
return gdk_fb_mouse_open ();
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!device->open(mouse))
|
gboolean
|
||||||
|
gdk_fb_mouse_open (void)
|
||||||
|
{
|
||||||
|
GdkFBMouseDevice *device;
|
||||||
|
|
||||||
|
device = gdk_fb_mouse->dev;
|
||||||
|
|
||||||
|
if (!device->open(gdk_fb_mouse))
|
||||||
{
|
{
|
||||||
g_warning ("Mouse driver open failed");
|
g_warning ("Mouse driver open failed");
|
||||||
g_free (mouse);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse->io = g_io_channel_unix_new (mouse->fd);
|
gdk_fb_mouse->io =
|
||||||
mouse->io_tag = g_io_add_watch (mouse->io, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_mouse_io, mouse);
|
g_io_channel_unix_new (gdk_fb_mouse->fd);
|
||||||
|
gdk_fb_mouse->io_tag =
|
||||||
|
g_io_add_watch (gdk_fb_mouse->io,
|
||||||
|
G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
|
||||||
|
handle_mouse_io, gdk_fb_mouse);
|
||||||
|
|
||||||
gdk_fb_mouse = mouse;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_fb_mouse_close (void)
|
gdk_fb_mouse_close (void)
|
||||||
{
|
{
|
||||||
g_source_remove (gdk_fb_mouse->io_tag);
|
if (gdk_fb_mouse->io_tag)
|
||||||
gdk_fb_mouse->dev->close(gdk_fb_mouse);
|
{
|
||||||
g_io_channel_unref (gdk_fb_mouse->io);
|
g_source_remove (gdk_fb_mouse->io_tag);
|
||||||
g_free (gdk_fb_mouse);
|
gdk_fb_mouse->io_tag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdk_fb_mouse->dev->close(gdk_fb_mouse);
|
||||||
|
|
||||||
|
if (gdk_fb_mouse->io)
|
||||||
|
{
|
||||||
|
g_io_channel_unref (gdk_fb_mouse->io);
|
||||||
|
gdk_fb_mouse->io = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -427,6 +449,7 @@ static void
|
|||||||
gdk_fb_mouse_ps2_close (GdkFBMouse *mouse)
|
gdk_fb_mouse_ps2_close (GdkFBMouse *mouse)
|
||||||
{
|
{
|
||||||
close (mouse->fd);
|
close (mouse->fd);
|
||||||
|
mouse->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -501,7 +524,10 @@ gdk_fb_mouse_ms_open (GdkFBMouse *mouse)
|
|||||||
|
|
||||||
fd = gdk_fb_mouse_dev_open ("/dev/mouse", O_RDWR);
|
fd = gdk_fb_mouse_dev_open ("/dev/mouse", O_RDWR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return FALSE;
|
{
|
||||||
|
g_print ("Error opening /dev/mouse: %s\n", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
while ((i = read (fd, buf, sizeof(buf))) > 0)
|
while ((i = read (fd, buf, sizeof(buf))) > 0)
|
||||||
g_print ("Got %d bytes of junk from /dev/mouse\n", i);
|
g_print ("Got %d bytes of junk from /dev/mouse\n", i);
|
||||||
@ -526,6 +552,7 @@ static void
|
|||||||
gdk_fb_mouse_ms_close (GdkFBMouse *mouse)
|
gdk_fb_mouse_ms_close (GdkFBMouse *mouse)
|
||||||
{
|
{
|
||||||
close (mouse->fd);
|
close (mouse->fd);
|
||||||
|
mouse->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -148,6 +148,11 @@ struct _GdkFBDisplay
|
|||||||
struct fb_var_screeninfo modeinfo;
|
struct fb_var_screeninfo modeinfo;
|
||||||
struct fb_var_screeninfo orig_modeinfo;
|
struct fb_var_screeninfo orig_modeinfo;
|
||||||
int red_byte, green_byte, blue_byte; /* For truecolor */
|
int red_byte, green_byte, blue_byte; /* For truecolor */
|
||||||
|
|
||||||
|
/* fb manager */
|
||||||
|
int manager_fd;
|
||||||
|
int manager_tag;
|
||||||
|
int manager_blocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -414,7 +419,6 @@ extern GdkEventMask _gdk_fb_keyboard_grab_events;
|
|||||||
extern gboolean _gdk_fb_keyboard_grab_owner_events;
|
extern gboolean _gdk_fb_keyboard_grab_owner_events;
|
||||||
|
|
||||||
extern GdkFBDisplay *gdk_display;
|
extern GdkFBDisplay *gdk_display;
|
||||||
extern GdkDrawableClass _gdk_fb_drawable_class;
|
|
||||||
extern FILE *debug_out;
|
extern FILE *debug_out;
|
||||||
GdkEvent *gdk_event_make(GdkWindow *window,
|
GdkEvent *gdk_event_make(GdkWindow *window,
|
||||||
GdkEventType type,
|
GdkEventType type,
|
||||||
@ -436,8 +440,10 @@ void gdk_fb_redraw_all(void);
|
|||||||
void gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window);
|
void gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window);
|
||||||
|
|
||||||
guint gdk_fb_keyboard_modifiers (void);
|
guint gdk_fb_keyboard_modifiers (void);
|
||||||
|
gboolean gdk_fb_keyboard_init (gboolean open_dev);
|
||||||
gboolean gdk_fb_keyboard_open (void);
|
gboolean gdk_fb_keyboard_open (void);
|
||||||
void gdk_fb_keyboard_close (void);
|
void gdk_fb_keyboard_close (void);
|
||||||
|
gboolean gdk_fb_mouse_init (gboolean open_dev);
|
||||||
gboolean gdk_fb_mouse_open (void);
|
gboolean gdk_fb_mouse_open (void);
|
||||||
void gdk_fb_mouse_close (void);
|
void gdk_fb_mouse_close (void);
|
||||||
void gdk_fb_mouse_get_info (gint *x,
|
void gdk_fb_mouse_get_info (gint *x,
|
||||||
|
@ -1406,6 +1406,9 @@ gdk_shadow_fb_update (gint minx, gint miny, gint maxx, gint maxy)
|
|||||||
{
|
{
|
||||||
struct itimerval timeout;
|
struct itimerval timeout;
|
||||||
|
|
||||||
|
if (gdk_display->manager_blocked)
|
||||||
|
return;
|
||||||
|
|
||||||
g_assert (minx <= maxx);
|
g_assert (minx <= maxx);
|
||||||
g_assert (miny <= maxy);
|
g_assert (miny <= maxy);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user