--- np2/x11/gtk2/gtk_wrapper.c 2004/07/14 16:01:40 1.1 +++ np2/x11/gtk2/gtk_wrapper.c 2012/01/23 05:00:13 1.15 @@ -10,8 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,16 +23,33 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "compiler.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif -#include #include #include +#include +#include +#include + +#include +#include #include "gtk2/xnp2.h" #include +extern int verbose; +extern volatile sig_atomic_t np2running; + +#ifdef DEBUG +#ifndef VERBOSE +#define VERBOSE(s) if (verbose) g_printerr s +#endif /* !VERBOSE */ +#else /* !DEBUG */ +#define VERBOSE(s) +#endif /* DEBUG */ void gtk_scale_set_default_values(GtkScale *scale) @@ -52,48 +67,311 @@ gdk_window_set_pointer(GdkWindow *w, gin Display *xdisplay; Window xwindow; - if (w) { - xdisplay = GDK_WINDOW_XDISPLAY(w); - xwindow = GDK_WINDOW_XWINDOW(w); - XWarpPointer(xdisplay, None, xwindow, 0, 0, 0, 0, x, y); - } + g_return_if_fail(w != NULL); + + xdisplay = GDK_WINDOW_XDISPLAY(w); + xwindow = GDK_WINDOW_XWINDOW(w); + XWarpPointer(xdisplay, None, xwindow, 0, 0, 0, 0, x, y); } -int -is_32bpp(GdkWindow *w) +gboolean +gdk_window_get_pixmap_format(GdkWindow *w, GdkVisual *visual, pixmap_format_t *fmtp) { Display *xdisplay; XPixmapFormatValues *format; - int nbit = 0; int count; int i; - if (w == NULL) - return 0; + g_return_val_if_fail(w != NULL, FALSE); + g_return_val_if_fail(visual != NULL, FALSE); + g_return_val_if_fail(fmtp != NULL, FALSE); xdisplay = GDK_WINDOW_XDISPLAY(w); format = XListPixmapFormats(xdisplay, &count); - if (format != 0) { + if (format) { for (i = 0; i < count; i++) { - if (format[i].depth != 24) - continue; - - if (format[i].bits_per_pixel == 32) { - nbit = 32; - } else { - nbit = 24; + if (visual->depth == format[i].depth) { + fmtp->depth = format[i].depth; + fmtp->bits_per_pixel = format[i].bits_per_pixel; + fmtp->scanline_pad = format[i].scanline_pad; + XFree(format); + return TRUE; } - break; } XFree(format); + } + return FALSE; +} + +/* + * Full screen support. + */ +extern int ignore_fullscreen_mode; +static int use_xvid; +static int use_netwm; +static int is_fullscreen; + +#ifdef HAVE_XF86VIDMODE +#include + +static XF86VidModeModeInfo **modes = NULL; +static int modeidx = -1; +static XF86VidModeModeInfo *saved_modes; +static XF86VidModeModeInfo orig_mode; +static Display *fs_xdisplay; +static int fs_xscreen; +static int view_x, view_y; +static gint orig_x, orig_y; + +static inline Bool +XF86VidModeGetModeInfo(Display *d, int s, XF86VidModeModeInfo *info) +{ + XF86VidModeModeLine *line; + + memset(info, 0, sizeof(*info)); + line = (void *)((char *)info + sizeof(info->dotclock)); + + return XF86VidModeGetModeLine(d, s, (int *)&info->dotclock, line); +} + +static int +check_xvid(GtkWidget *widget) +{ + gboolean ret = FALSE; + GdkWindow *w; + Display *xdisplay; + int xscreen; + XF86VidModeModeInfo mode; + int event_base, error_base; + int major_ver, minor_ver; + int nmodes; + int i; + Bool rv; + + g_return_val_if_fail(widget != NULL, FALSE); - if (i == count) { - fprintf(stderr, "24bpp depth not support?\n"); - return 0; + w = widget->window; + xdisplay = GDK_WINDOW_XDISPLAY(w); + xscreen = XDefaultScreen(xdisplay); + + XLockDisplay(xdisplay); + + rv = XF86VidModeQueryExtension(xdisplay, &event_base, &error_base); + if (!rv) { + goto out; + } + + rv = XF86VidModeQueryVersion(xdisplay, &major_ver, &minor_ver); + if (!rv) { + goto out; + } + VERBOSE(("XF86VidMode Extension: ver.%d.%d detected\n", + major_ver, minor_ver)); + + rv = XF86VidModeGetModeInfo(xdisplay, xscreen, &mode); + if (rv) { + if ((mode.hdisplay == 640) && (mode.vdisplay == 480)) { + orig_mode = mode; + saved_modes = &orig_mode; + modes = &saved_modes; + modeidx = 0; + ret = TRUE; + goto out; + } + } + + rv = XF86VidModeGetAllModeLines(xdisplay, xscreen, &nmodes, &modes); + if (!rv) { + goto out; + } + VERBOSE(("XF86VidMode Extension: %d modes\n", nmodes)); + + for (i = 0; i < nmodes; i++) { + VERBOSE(("XF86VidMode Extension: %d: %dx%d\n", i, + modes[i]->hdisplay, modes[i]->vdisplay)); + + if ((modes[i]->hdisplay == 640) + && (modes[i]->vdisplay == 480)) { + rv = XF86VidModeGetModeInfo(xdisplay, xscreen, + &orig_mode); + if (rv) { + VERBOSE(("found\n")); + modeidx = i; + ret = TRUE; + break; + } } + } + + if (ret) { + fs_xdisplay = xdisplay; + fs_xscreen = xscreen; } else { - fprintf(stderr, "Can't get PixmapFormats.\n"); + XFree(modes); + modes = NULL; + } + +out: + XUnlockDisplay(xdisplay); + + return ret; +} +#endif /* HAVE_XF86VIDMODE */ + +static int +check_netwm(GtkWidget *widget) +{ + Display *xdisplay; + Window root_window; + Atom _NET_SUPPORTED; + Atom _NET_WM_STATE_FULLSCREEN; + Atom type; + int format; + unsigned long nitems; + unsigned long remain; + unsigned char *prop; + guint32 *data; + int rv; + unsigned long i; + + g_return_val_if_fail(widget != NULL, 0); + + xdisplay = GDK_WINDOW_XDISPLAY(widget->window); + root_window = DefaultRootWindow(xdisplay); + + _NET_SUPPORTED = XInternAtom(xdisplay, "_NET_SUPPORTED", False); + _NET_WM_STATE_FULLSCREEN = XInternAtom(xdisplay, + "_NET_WM_STATE_FULLSCREEN", False); + + rv = XGetWindowProperty(xdisplay, root_window, _NET_SUPPORTED, + 0, 65536 / sizeof(guint32), False, AnyPropertyType, + &type, &format, &nitems, &remain, &prop); + if (rv != Success) { return 0; } - return (nbit == 32) ? 1 : 0; + if (type != XA_ATOM) { + return 0; + } + if (format != 32) { + return 0; + } + + rv = 0; + data = (guint32 *)prop; + for (i = 0; i < nitems; i++) { + if (data[i] == _NET_WM_STATE_FULLSCREEN) { + VERBOSE(("Support _NET_WM_STATE_FULLSCREEN\n")); + rv = 1; + break; + } + } + XFree(prop); + + return rv; +} + +int +gtk_window_init_fullscreen(GtkWidget *widget) +{ + +#ifdef HAVE_XF86VIDMODE + use_xvid = check_xvid(widget); +#endif + use_netwm = check_netwm(widget); + + if (use_xvid && (ignore_fullscreen_mode & 1)) { + VERBOSE(("Support XF86VidMode extension, but disabled\n")); + use_xvid = 0; + } + if (use_netwm && (ignore_fullscreen_mode & 2)) { + VERBOSE(("Support _NET_WM_STATE_FULLSCREEN, but disabled\n")); + use_netwm = 0; + } + + if (verbose) { + if (use_xvid) { + VERBOSE(("Using XF86VidMode extension\n")); + } else if (use_netwm) { + VERBOSE(("Using _NET_WM_STATE_FULLSCREEN\n")); + } else { + VERBOSE(("not supported\n")); + } + } + + return use_xvid; +} + +void +gtk_window_fullscreen_mode(GtkWidget *widget) +{ + + g_return_if_fail(widget != NULL); + g_return_if_fail(widget->window != NULL); + +#ifdef HAVE_XF86VIDMODE + if (use_xvid && modes != NULL && modeidx >= 0) { + GtkWindow *window = GTK_WINDOW(widget); + + XLockDisplay(fs_xdisplay); + + XF86VidModeLockModeSwitch(fs_xdisplay, fs_xscreen, True); + XF86VidModeGetViewPort(fs_xdisplay,fs_xscreen,&view_x,&view_y); + gdk_window_get_origin(widget->window, &orig_x, &orig_y); + if (window) + gtk_window_move(window, 0, 0); + XF86VidModeSwitchToMode(fs_xdisplay,fs_xscreen,modes[modeidx]); + + XUnlockDisplay(fs_xdisplay); + } +#endif /* HAVE_XF86VIDMODE */ + if (use_netwm) { + gtk_window_fullscreen(GTK_WINDOW(widget)); + } + is_fullscreen = 1; +} + +void +gtk_window_restore_mode(GtkWidget *widget) +{ + + g_return_if_fail(widget != NULL); + + if (!is_fullscreen) + return; + +#ifdef HAVE_XF86VIDMODE + if (use_xvid) { + XF86VidModeModeInfo mode; + int rv; + + if ((orig_mode.hdisplay == 0) || (orig_mode.vdisplay == 0)) + return; + + XLockDisplay(fs_xdisplay); + + rv = XF86VidModeGetModeInfo(fs_xdisplay, fs_xscreen, &mode); + if (rv) { + if ((orig_mode.hdisplay != mode.hdisplay) + || (orig_mode.vdisplay != mode.vdisplay)) { + XF86VidModeSwitchToMode(fs_xdisplay, fs_xscreen, + &orig_mode); + XF86VidModeLockModeSwitch(fs_xdisplay, + fs_xscreen, False); + } + if ((view_x != 0) || (view_y != 0)) { + XF86VidModeSetViewPort(fs_xdisplay, fs_xscreen, + view_x, view_y); + } + } + + if (np2running) { + gtk_window_move(GTK_WINDOW(widget), orig_x, orig_y); + } + + XUnlockDisplay(fs_xdisplay); + } +#endif /* HAVE_XF86VIDMODE */ + if (use_netwm) { + gtk_window_unfullscreen(GTK_WINDOW(widget)); + } }