Bugzilla – Attachment 363 Details for
Bug 1052
Use EWMH for rdesktop fullscreen mode
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated patch for TL 3.1
vncviewer-ewmh-fullscreen.2.patch (text/plain), 37.73 KB, created by
Peter Åstrand
on 2010-05-31 14:05:57 CEST
(
hide
)
Description:
Updated patch for TL 3.1
Filename:
MIME Type:
Creator:
Peter Åstrand
Created:
2010-05-31 14:05:57 CEST
Size:
37.73 KB
patch
obsolete
>Index: tigervnc/unix/vncviewer/ewmhints.c >=================================================================== >--- tigervnc/unix/vncviewer/ewmhints.c (revision 0) >+++ tigervnc/unix/vncviewer/ewmhints.c (revision 0) >@@ -0,0 +1,1244 @@ >+/* -*- c-basic-offset: 8 -*- >+ rdesktop: A Remote Desktop Protocol client. >+ >+ Support functions for Extended Window Manager Hints, >+ http://www.freedesktop.org/wiki/Standards_2fwm_2dspec >+ >+ Copyright 2005 Peter Astrand <astrand@cendio.se> for Cendio AB >+ Copyright 2007 Pierre Ossman <ossman@cendio.se> for Cendio AB >+ >+ This program is free software: you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation, either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program 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 General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include <stdlib.h> >+#include <stdio.h> >+#include <string.h> >+#include <X11/Xlib.h> >+#include <X11/Xatom.h> >+#include <X11/Xutil.h> >+ >+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ >+#define _NET_WM_STATE_ADD 1 /* add/set property */ >+#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ >+ >+typedef unsigned int uint32; >+ >+// FIXME: Remove, this file shouldn't depend on seamlessrdp! >+#define SEAMLESSRDP_NORMAL 0 >+#define SEAMLESSRDP_MINIMIZED 1 >+#define SEAMLESSRDP_MAXIMIZED 2 >+ >+#ifndef EX_UNAVAILABLE >+#define EX_UNAVAILABLE 69 >+#endif >+ >+// FIXME: Need to think about this one... >+/* malloc; exit if out of memory */ >+static void * >+xmalloc(int size) >+{ >+ void *mem = malloc(size); >+ if (mem == NULL) >+ { >+ fprintf(stderr, "ERROR: xmalloc %d\n", size); >+ exit(EX_UNAVAILABLE); >+ } >+ return mem; >+} >+ >+ >+static Display *g_display; >+ >+static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom, >+ g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom, >+ g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom, >+ g_net_wm_state_modal_atom, g_net_wm_icon_atom, g_net_wm_state_above_atom, >+ g_net_wm_state_fullscreen_atom; >+ >+Atom g_net_wm_state_atom, g_net_wm_desktop_atom; >+ >+/* >+ Get window property value (32 bit format) >+ Returns zero on success, -1 on error >+*/ >+static int >+get_property_value(Window wnd, char *propname, long max_length, >+ unsigned long *nitems_return, unsigned char **prop_return, int nowarn) >+{ >+ int result; >+ Atom property; >+ Atom actual_type_return; >+ int actual_format_return; >+ unsigned long bytes_after_return; >+ >+ property = XInternAtom(g_display, propname, True); >+ if (property == None) >+ { >+ fprintf(stderr, "Atom %s does not exist\n", propname); >+ return (-1); >+ } >+ >+ result = XGetWindowProperty(g_display, wnd, property, 0, /* long_offset */ >+ max_length, /* long_length */ >+ False, /* delete */ >+ AnyPropertyType, /* req_type */ >+ &actual_type_return, >+ &actual_format_return, >+ nitems_return, &bytes_after_return, prop_return); >+ >+ if (result != Success) >+ { >+ fprintf(stderr, "XGetWindowProperty failed\n"); >+ return (-1); >+ } >+ >+ if (actual_type_return == None || actual_format_return == 0) >+ { >+ if (!nowarn) >+ fprintf(stderr, "Window is missing property %s\n", propname); >+ return (-1); >+ } >+ >+ if (bytes_after_return) >+ { >+ fprintf(stderr, "%s is too big for me\n", propname); >+ return (-1); >+ } >+ >+ if (actual_format_return != 32) >+ { >+ fprintf(stderr, "%s has bad format\n", propname); >+ return (-1); >+ } >+ >+ return (0); >+} >+ >+/* >+ Get current desktop number >+ Returns -1 on error >+*/ >+static int >+get_current_desktop(void) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ int current_desktop; >+ >+ if (get_property_value >+ (DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return, >+ &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return != 1) >+ { >+ fprintf(stderr, "_NET_CURRENT_DESKTOP has bad length\n"); >+ return (-1); >+ } >+ >+ current_desktop = *prop_return; >+ XFree(prop_return); >+ return current_desktop; >+} >+ >+/* >+ Get workarea geometry >+ Returns zero on success, -1 on error >+ */ >+ >+int >+get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height) >+{ >+ int current_desktop; >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ long *return_words; >+ const uint32 net_workarea_x_offset = 0; >+ const uint32 net_workarea_y_offset = 1; >+ const uint32 net_workarea_width_offset = 2; >+ const uint32 net_workarea_height_offset = 3; >+ const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */ >+ >+ if (get_property_value >+ (DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return, >+ &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return % 4) >+ { >+ fprintf(stderr, "_NET_WORKAREA has odd length\n"); >+ return (-1); >+ } >+ >+ current_desktop = get_current_desktop(); >+ >+ if (current_desktop < 0) >+ return -1; >+ >+ return_words = (long *) prop_return; >+ >+ *x = return_words[current_desktop * 4 + net_workarea_x_offset]; >+ *y = return_words[current_desktop * 4 + net_workarea_y_offset]; >+ *width = return_words[current_desktop * 4 + net_workarea_width_offset]; >+ *height = return_words[current_desktop * 4 + net_workarea_height_offset]; >+ >+ XFree(prop_return); >+ >+ return (0); >+ >+} >+ >+ >+ >+void >+ewmh_init(Display *display) >+{ >+ g_display = display; >+ /* FIXME: Use XInternAtoms */ >+ g_net_wm_state_maximized_vert_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); >+ g_net_wm_state_maximized_horz_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); >+ g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False); >+ g_net_wm_state_skip_taskbar_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False); >+ g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False); >+ g_net_wm_state_modal_atom = XInternAtom(g_display, "_NET_WM_STATE_MODAL", False); >+ g_net_wm_state_above_atom = XInternAtom(g_display, "_NET_WM_STATE_ABOVE", False); >+ g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False); >+ g_net_wm_state_fullscreen_atom = XInternAtom(g_display, "_NET_WM_STATE_FULLSCREEN", False); >+ g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False); >+ g_net_wm_name_atom = XInternAtom(g_display, "_NET_WM_NAME", False); >+ g_net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False); >+ g_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False); >+} >+ >+ >+/* >+ Get the window state: normal/minimized/maximized. >+*/ >+#ifndef MAKE_PROTO >+int >+ewmh_get_window_state(Window w) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ uint32 *return_words; >+ unsigned long item; >+ Bool maximized_vert, maximized_horz, hidden; >+ >+ maximized_vert = maximized_horz = hidden = False; >+ >+ if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return, 0) < 0) >+ return SEAMLESSRDP_NORMAL; >+ >+ return_words = (uint32 *) prop_return; >+ >+ for (item = 0; item < nitems_return; item++) >+ { >+ if (return_words[item] == g_net_wm_state_maximized_vert_atom) >+ maximized_vert = True; >+ if (return_words[item] == g_net_wm_state_maximized_horz_atom) >+ maximized_horz = True; >+ if (return_words[item] == g_net_wm_state_hidden_atom) >+ hidden = True; >+ } >+ >+ XFree(prop_return); >+ >+ if (maximized_vert && maximized_horz) >+ return SEAMLESSRDP_MAXIMIZED; >+ else if (hidden) >+ return SEAMLESSRDP_MINIMIZED; >+ else >+ return SEAMLESSRDP_NORMAL; >+} >+ >+static int >+ewmh_modify_state(Window wnd, Bool add, Atom atom1, Atom atom2) >+{ >+ Status status; >+ XEvent xevent; >+ >+ int result; >+ unsigned long nitems; >+ unsigned char *props; >+ uint32 state = WithdrawnState; >+ >+ /* The spec states that the window manager must respect any >+ _NET_WM_STATE attributes on a withdrawn window. In order words, we >+ modify the attributes directly for withdrawn windows and ask the WM >+ to do it for active windows. */ >+ result = get_property_value(wnd, "WM_STATE", 64, &nitems, &props, 1); >+ if ((result >= 0) && nitems) >+ { >+ state = *(uint32 *) props; >+ XFree(props); >+ } >+ >+ if (state == WithdrawnState) >+ { >+ if (add) >+ { >+ Atom atoms[2]; >+ >+ atoms[0] = atom1; >+ nitems = 1; >+ if (atom2) >+ { >+ atoms[1] = atom2; >+ nitems = 2; >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, >+ 32, PropModeAppend, (unsigned char *) atoms, nitems); >+ } >+ else >+ { >+ Atom *atoms; >+ int i; >+ >+ if (get_property_value(wnd, "_NET_WM_STATE", 64, &nitems, &props, 1) < 0) >+ return 0; >+ >+ atoms = (Atom *) props; >+ >+ for (i = 0; i < nitems; i++) >+ { >+ if ((atoms[i] == atom1) || (atom2 && (atoms[i] == atom2))) >+ { >+ if (i != (nitems - 1)) >+ memmove(&atoms[i], &atoms[i + 1], >+ sizeof(Atom) * (nitems - i - 1)); >+ nitems--; >+ i--; >+ } >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, >+ 32, PropModeReplace, (unsigned char *) atoms, nitems); >+ >+ XFree(props); >+ } >+ >+ return 0; >+ } >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = g_net_wm_state_atom; >+ xevent.xclient.format = 32; >+ if (add) >+ xevent.xclient.data.l[0] = _NET_WM_STATE_ADD; >+ else >+ xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE; >+ xevent.xclient.data.l[1] = atom1; >+ xevent.xclient.data.l[2] = atom2; >+ xevent.xclient.data.l[3] = 0; >+ xevent.xclient.data.l[4] = 0; >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ >+ return 0; >+} >+ >+ >+int ewmh_state_fullscreen(Window wnd, Bool fullscreen) >+{ >+ if (ewmh_modify_state(wnd, fullscreen, g_net_wm_state_fullscreen_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+/* >+ Set the window state: normal/minimized/maximized. >+ Returns -1 on failure. >+*/ >+int >+ewmh_change_state(Window wnd, int state) >+{ >+ /* >+ * Deal with the max atoms >+ */ >+ if (state == SEAMLESSRDP_MAXIMIZED) >+ { >+ if (ewmh_modify_state >+ (wnd, 1, g_net_wm_state_maximized_vert_atom, >+ g_net_wm_state_maximized_horz_atom) < 0) >+ return -1; >+ } >+ else >+ { >+ if (ewmh_modify_state >+ (wnd, 0, g_net_wm_state_maximized_vert_atom, >+ g_net_wm_state_maximized_horz_atom) < 0) >+ return -1; >+ } >+ >+ return 0; >+} >+ >+ >+int >+ewmh_get_window_desktop(Window wnd) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ int desktop; >+ >+ if (get_property_value(wnd, "_NET_WM_DESKTOP", 1, &nitems_return, &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return != 1) >+ { >+ fprintf(stderr, "_NET_WM_DESKTOP has bad length\n"); >+ return (-1); >+ } >+ >+ desktop = *prop_return; >+ XFree(prop_return); >+ return desktop; >+} >+ >+ >+int >+ewmh_move_to_desktop(Window wnd, unsigned int desktop) >+{ >+ Status status; >+ XEvent xevent; >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = g_net_wm_desktop_atom; >+ xevent.xclient.format = 32; >+ xevent.xclient.data.l[0] = desktop; >+ xevent.xclient.data.l[1] = 0; >+ xevent.xclient.data.l[2] = 0; >+ xevent.xclient.data.l[3] = 0; >+ xevent.xclient.data.l[4] = 0; >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ >+ return 0; >+} >+ >+void >+ewmh_set_wm_name(Window wnd, const char *title) >+{ >+ int len; >+ >+ len = strlen(title); >+ XChangeProperty(g_display, wnd, g_net_wm_name_atom, g_utf8_string_atom, >+ 8, PropModeReplace, (unsigned char *) title, len); >+} >+ >+ >+int >+ewmh_set_window_popup(Window wnd) >+{ >+ if (ewmh_modify_state >+ (wnd, 1, g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom) < 0) >+ return -1; >+ return 0; >+} >+ >+int >+ewmh_set_window_modal(Window wnd) >+{ >+ if (ewmh_modify_state(wnd, 1, g_net_wm_state_modal_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+void >+ewmh_set_icon(Window wnd, int width, int height, const char *rgba_data) >+{ >+ unsigned long nitems, i; >+ unsigned char *props; >+ unsigned long *cur_set, *new_set; >+ unsigned long *icon; >+ >+ cur_set = NULL; >+ new_set = NULL; >+ >+ if (get_property_value(wnd, "_NET_WM_ICON", 10000, &nitems, &props, 1) >= 0) >+ { >+ cur_set = (unsigned long *) props; >+ >+ for (i = 0; i < nitems;) >+ { >+ if (cur_set[i] == width && cur_set[i + 1] == height) >+ break; >+ >+ i += 2 + cur_set[i] * cur_set[i + 1]; >+ } >+ >+ if (i != nitems) >+ icon = cur_set + i; >+ else >+ { >+ new_set = xmalloc((nitems + width * height + 2) * sizeof(unsigned long)); >+ memcpy(new_set, cur_set, nitems * sizeof(unsigned long)); >+ icon = new_set + nitems; >+ nitems += width * height + 2; >+ } >+ } >+ else >+ { >+ new_set = xmalloc((width * height + 2) * sizeof(unsigned long)); >+ icon = new_set; >+ nitems = width * height + 2; >+ } >+ >+ icon[0] = width; >+ icon[1] = height; >+ >+ /* Convert RGBA -> ARGB */ >+ for (i = 0; i < width * height; i++) >+ { >+ icon[i + 2] = >+ rgba_data[i * 4 + 3] << 24 | >+ ((rgba_data[i * 4 + 0] << 16) & 0x00FF0000) | >+ ((rgba_data[i * 4 + 1] << 8) & 0x0000FF00) | >+ ((rgba_data[i * 4 + 2] << 0) & 0x000000FF); >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_icon_atom, XA_CARDINAL, 32, >+ PropModeReplace, (unsigned char *) (new_set ? new_set : cur_set), nitems); >+ >+ if (cur_set) >+ XFree(cur_set); >+ if (new_set) >+ free(new_set); >+} >+ >+void >+ewmh_del_icon(Window wnd, int width, int height) >+{ >+ unsigned long nitems, i, icon_size; >+ unsigned char *props; >+ unsigned long *cur_set, *new_set; >+ >+ cur_set = NULL; >+ new_set = NULL; >+ >+ if (get_property_value(wnd, "_NET_WM_ICON", 10000, &nitems, &props, 1) < 0) >+ return; >+ >+ cur_set = (unsigned long *) props; >+ >+ for (i = 0; i < nitems;) >+ { >+ if (cur_set[i] == width && cur_set[i + 1] == height) >+ break; >+ >+ i += 2 + cur_set[i] * cur_set[i + 1]; >+ } >+ >+ if (i == nitems) >+ goto out; >+ >+ icon_size = width * height + 2; >+ new_set = xmalloc((nitems - icon_size) * sizeof(unsigned long)); >+ >+ if (i != 0) >+ memcpy(new_set, cur_set, i * sizeof(unsigned long)); >+ if (i != nitems - icon_size) >+ memcpy(new_set + i, cur_set + i + icon_size, >+ (nitems - (i + icon_size)) * sizeof(unsigned long)); >+ >+ nitems -= icon_size; >+ >+ XChangeProperty(g_display, wnd, g_net_wm_icon_atom, XA_CARDINAL, 32, >+ PropModeReplace, (unsigned char *) new_set, nitems); >+ >+ free(new_set); >+ >+ out: >+ XFree(cur_set); >+} >+ >+int >+ewmh_set_window_above(Window wnd) >+{ >+ if (ewmh_modify_state(wnd, 1, g_net_wm_state_above_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+#endif /* MAKE_PROTO */ >+ >+ >+#if 0 >+ >+/* FIXME: _NET_MOVERESIZE_WINDOW is for pagers, not for >+ applications. We should implement _NET_WM_MOVERESIZE instead */ >+ >+int >+ewmh_net_moveresize_window(Window wnd, int x, int y, int width, int height) >+{ >+ Status status; >+ XEvent xevent; >+ Atom moveresize; >+ >+ moveresize = XInternAtom(g_display, "_NET_MOVERESIZE_WINDOW", False); >+ if (!moveresize) >+ { >+ return -1; >+ } >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = moveresize; >+ xevent.xclient.format = 32; >+ xevent.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11); >+ xevent.xclient.data.l[1] = x; >+ xevent.xclient.data.l[2] = y; >+ xevent.xclient.data.l[3] = width; >+ xevent.xclient.data.l[4] = height; >+ >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ return 0; >+} >+ >+#endif >+/* -*- c-basic-offset: 8 -*- >+ rdesktop: A Remote Desktop Protocol client. >+ >+ Support functions for Extended Window Manager Hints, >+ http://www.freedesktop.org/wiki/Standards_2fwm_2dspec >+ >+ Copyright 2005 Peter Astrand <astrand@cendio.se> for Cendio AB >+ Copyright 2007 Pierre Ossman <ossman@cendio.se> for Cendio AB >+ >+ This program is free software: you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation, either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program 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 General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include <stdlib.h> >+#include <stdio.h> >+#include <string.h> >+#include <X11/Xlib.h> >+#include <X11/Xatom.h> >+#include <X11/Xutil.h> >+ >+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ >+#define _NET_WM_STATE_ADD 1 /* add/set property */ >+#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ >+ >+typedef unsigned int uint32; >+ >+// FIXME: Remove, this file shouldn't depend on seamlessrdp! >+#define SEAMLESSRDP_NORMAL 0 >+#define SEAMLESSRDP_MINIMIZED 1 >+#define SEAMLESSRDP_MAXIMIZED 2 >+ >+#ifndef EX_UNAVAILABLE >+#define EX_UNAVAILABLE 69 >+#endif >+ >+// FIXME: Need to think about this one... >+/* malloc; exit if out of memory */ >+static void * >+xmalloc(int size) >+{ >+ void *mem = malloc(size); >+ if (mem == NULL) >+ { >+ fprintf(stderr, "ERROR: xmalloc %d\n", size); >+ exit(EX_UNAVAILABLE); >+ } >+ return mem; >+} >+ >+ >+static Display *g_display; >+ >+static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom, >+ g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom, >+ g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom, >+ g_net_wm_state_modal_atom, g_net_wm_icon_atom, g_net_wm_state_above_atom, >+ g_net_wm_state_fullscreen_atom; >+ >+Atom g_net_wm_state_atom, g_net_wm_desktop_atom; >+ >+/* >+ Get window property value (32 bit format) >+ Returns zero on success, -1 on error >+*/ >+static int >+get_property_value(Window wnd, char *propname, long max_length, >+ unsigned long *nitems_return, unsigned char **prop_return, int nowarn) >+{ >+ int result; >+ Atom property; >+ Atom actual_type_return; >+ int actual_format_return; >+ unsigned long bytes_after_return; >+ >+ property = XInternAtom(g_display, propname, True); >+ if (property == None) >+ { >+ fprintf(stderr, "Atom %s does not exist\n", propname); >+ return (-1); >+ } >+ >+ result = XGetWindowProperty(g_display, wnd, property, 0, /* long_offset */ >+ max_length, /* long_length */ >+ False, /* delete */ >+ AnyPropertyType, /* req_type */ >+ &actual_type_return, >+ &actual_format_return, >+ nitems_return, &bytes_after_return, prop_return); >+ >+ if (result != Success) >+ { >+ fprintf(stderr, "XGetWindowProperty failed\n"); >+ return (-1); >+ } >+ >+ if (actual_type_return == None || actual_format_return == 0) >+ { >+ if (!nowarn) >+ fprintf(stderr, "Window is missing property %s\n", propname); >+ return (-1); >+ } >+ >+ if (bytes_after_return) >+ { >+ fprintf(stderr, "%s is too big for me\n", propname); >+ return (-1); >+ } >+ >+ if (actual_format_return != 32) >+ { >+ fprintf(stderr, "%s has bad format\n", propname); >+ return (-1); >+ } >+ >+ return (0); >+} >+ >+/* >+ Get current desktop number >+ Returns -1 on error >+*/ >+static int >+get_current_desktop(void) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ int current_desktop; >+ >+ if (get_property_value >+ (DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return, >+ &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return != 1) >+ { >+ fprintf(stderr, "_NET_CURRENT_DESKTOP has bad length\n"); >+ return (-1); >+ } >+ >+ current_desktop = *prop_return; >+ XFree(prop_return); >+ return current_desktop; >+} >+ >+/* >+ Get workarea geometry >+ Returns zero on success, -1 on error >+ */ >+ >+int >+get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height) >+{ >+ int current_desktop; >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ long *return_words; >+ const uint32 net_workarea_x_offset = 0; >+ const uint32 net_workarea_y_offset = 1; >+ const uint32 net_workarea_width_offset = 2; >+ const uint32 net_workarea_height_offset = 3; >+ const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */ >+ >+ if (get_property_value >+ (DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return, >+ &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return % 4) >+ { >+ fprintf(stderr, "_NET_WORKAREA has odd length\n"); >+ return (-1); >+ } >+ >+ current_desktop = get_current_desktop(); >+ >+ if (current_desktop < 0) >+ return -1; >+ >+ return_words = (long *) prop_return; >+ >+ *x = return_words[current_desktop * 4 + net_workarea_x_offset]; >+ *y = return_words[current_desktop * 4 + net_workarea_y_offset]; >+ *width = return_words[current_desktop * 4 + net_workarea_width_offset]; >+ *height = return_words[current_desktop * 4 + net_workarea_height_offset]; >+ >+ XFree(prop_return); >+ >+ return (0); >+ >+} >+ >+ >+ >+void >+ewmh_init(Display *display) >+{ >+ g_display = display; >+ /* FIXME: Use XInternAtoms */ >+ g_net_wm_state_maximized_vert_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); >+ g_net_wm_state_maximized_horz_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); >+ g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False); >+ g_net_wm_state_skip_taskbar_atom = >+ XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False); >+ g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False); >+ g_net_wm_state_modal_atom = XInternAtom(g_display, "_NET_WM_STATE_MODAL", False); >+ g_net_wm_state_above_atom = XInternAtom(g_display, "_NET_WM_STATE_ABOVE", False); >+ g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False); >+ g_net_wm_state_fullscreen_atom = XInternAtom(g_display, "_NET_WM_STATE_FULLSCREEN", False); >+ g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False); >+ g_net_wm_name_atom = XInternAtom(g_display, "_NET_WM_NAME", False); >+ g_net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False); >+ g_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False); >+} >+ >+ >+/* >+ Get the window state: normal/minimized/maximized. >+*/ >+#ifndef MAKE_PROTO >+int >+ewmh_get_window_state(Window w) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ uint32 *return_words; >+ unsigned long item; >+ Bool maximized_vert, maximized_horz, hidden; >+ >+ maximized_vert = maximized_horz = hidden = False; >+ >+ if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return, 0) < 0) >+ return SEAMLESSRDP_NORMAL; >+ >+ return_words = (uint32 *) prop_return; >+ >+ for (item = 0; item < nitems_return; item++) >+ { >+ if (return_words[item] == g_net_wm_state_maximized_vert_atom) >+ maximized_vert = True; >+ if (return_words[item] == g_net_wm_state_maximized_horz_atom) >+ maximized_horz = True; >+ if (return_words[item] == g_net_wm_state_hidden_atom) >+ hidden = True; >+ } >+ >+ XFree(prop_return); >+ >+ if (maximized_vert && maximized_horz) >+ return SEAMLESSRDP_MAXIMIZED; >+ else if (hidden) >+ return SEAMLESSRDP_MINIMIZED; >+ else >+ return SEAMLESSRDP_NORMAL; >+} >+ >+static int >+ewmh_modify_state(Window wnd, Bool add, Atom atom1, Atom atom2) >+{ >+ Status status; >+ XEvent xevent; >+ >+ int result; >+ unsigned long nitems; >+ unsigned char *props; >+ uint32 state = WithdrawnState; >+ >+ /* The spec states that the window manager must respect any >+ _NET_WM_STATE attributes on a withdrawn window. In order words, we >+ modify the attributes directly for withdrawn windows and ask the WM >+ to do it for active windows. */ >+ result = get_property_value(wnd, "WM_STATE", 64, &nitems, &props, 1); >+ if ((result >= 0) && nitems) >+ { >+ state = *(uint32 *) props; >+ XFree(props); >+ } >+ >+ if (state == WithdrawnState) >+ { >+ if (add) >+ { >+ Atom atoms[2]; >+ >+ atoms[0] = atom1; >+ nitems = 1; >+ if (atom2) >+ { >+ atoms[1] = atom2; >+ nitems = 2; >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, >+ 32, PropModeAppend, (unsigned char *) atoms, nitems); >+ } >+ else >+ { >+ Atom *atoms; >+ int i; >+ >+ if (get_property_value(wnd, "_NET_WM_STATE", 64, &nitems, &props, 1) < 0) >+ return 0; >+ >+ atoms = (Atom *) props; >+ >+ for (i = 0; i < nitems; i++) >+ { >+ if ((atoms[i] == atom1) || (atom2 && (atoms[i] == atom2))) >+ { >+ if (i != (nitems - 1)) >+ memmove(&atoms[i], &atoms[i + 1], >+ sizeof(Atom) * (nitems - i - 1)); >+ nitems--; >+ i--; >+ } >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, >+ 32, PropModeReplace, (unsigned char *) atoms, nitems); >+ >+ XFree(props); >+ } >+ >+ return 0; >+ } >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = g_net_wm_state_atom; >+ xevent.xclient.format = 32; >+ if (add) >+ xevent.xclient.data.l[0] = _NET_WM_STATE_ADD; >+ else >+ xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE; >+ xevent.xclient.data.l[1] = atom1; >+ xevent.xclient.data.l[2] = atom2; >+ xevent.xclient.data.l[3] = 0; >+ xevent.xclient.data.l[4] = 0; >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ >+ return 0; >+} >+ >+ >+int ewmh_state_fullscreen(Window wnd, Bool fullscreen) >+{ >+ if (ewmh_modify_state(wnd, fullscreen, g_net_wm_state_fullscreen_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+/* >+ Set the window state: normal/minimized/maximized. >+ Returns -1 on failure. >+*/ >+int >+ewmh_change_state(Window wnd, int state) >+{ >+ /* >+ * Deal with the max atoms >+ */ >+ if (state == SEAMLESSRDP_MAXIMIZED) >+ { >+ if (ewmh_modify_state >+ (wnd, 1, g_net_wm_state_maximized_vert_atom, >+ g_net_wm_state_maximized_horz_atom) < 0) >+ return -1; >+ } >+ else >+ { >+ if (ewmh_modify_state >+ (wnd, 0, g_net_wm_state_maximized_vert_atom, >+ g_net_wm_state_maximized_horz_atom) < 0) >+ return -1; >+ } >+ >+ return 0; >+} >+ >+ >+int >+ewmh_get_window_desktop(Window wnd) >+{ >+ unsigned long nitems_return; >+ unsigned char *prop_return; >+ int desktop; >+ >+ if (get_property_value(wnd, "_NET_WM_DESKTOP", 1, &nitems_return, &prop_return, 0) < 0) >+ return (-1); >+ >+ if (nitems_return != 1) >+ { >+ fprintf(stderr, "_NET_WM_DESKTOP has bad length\n"); >+ return (-1); >+ } >+ >+ desktop = *prop_return; >+ XFree(prop_return); >+ return desktop; >+} >+ >+ >+int >+ewmh_move_to_desktop(Window wnd, unsigned int desktop) >+{ >+ Status status; >+ XEvent xevent; >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = g_net_wm_desktop_atom; >+ xevent.xclient.format = 32; >+ xevent.xclient.data.l[0] = desktop; >+ xevent.xclient.data.l[1] = 0; >+ xevent.xclient.data.l[2] = 0; >+ xevent.xclient.data.l[3] = 0; >+ xevent.xclient.data.l[4] = 0; >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ >+ return 0; >+} >+ >+void >+ewmh_set_wm_name(Window wnd, const char *title) >+{ >+ int len; >+ >+ len = strlen(title); >+ XChangeProperty(g_display, wnd, g_net_wm_name_atom, g_utf8_string_atom, >+ 8, PropModeReplace, (unsigned char *) title, len); >+} >+ >+ >+int >+ewmh_set_window_popup(Window wnd) >+{ >+ if (ewmh_modify_state >+ (wnd, 1, g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom) < 0) >+ return -1; >+ return 0; >+} >+ >+int >+ewmh_set_window_modal(Window wnd) >+{ >+ if (ewmh_modify_state(wnd, 1, g_net_wm_state_modal_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+void >+ewmh_set_icon(Window wnd, int width, int height, const char *rgba_data) >+{ >+ unsigned long nitems, i; >+ unsigned char *props; >+ unsigned long *cur_set, *new_set; >+ unsigned long *icon; >+ >+ cur_set = NULL; >+ new_set = NULL; >+ >+ if (get_property_value(wnd, "_NET_WM_ICON", 10000, &nitems, &props, 1) >= 0) >+ { >+ cur_set = (unsigned long *) props; >+ >+ for (i = 0; i < nitems;) >+ { >+ if (cur_set[i] == width && cur_set[i + 1] == height) >+ break; >+ >+ i += 2 + cur_set[i] * cur_set[i + 1]; >+ } >+ >+ if (i != nitems) >+ icon = cur_set + i; >+ else >+ { >+ new_set = xmalloc((nitems + width * height + 2) * sizeof(unsigned long)); >+ memcpy(new_set, cur_set, nitems * sizeof(unsigned long)); >+ icon = new_set + nitems; >+ nitems += width * height + 2; >+ } >+ } >+ else >+ { >+ new_set = xmalloc((width * height + 2) * sizeof(unsigned long)); >+ icon = new_set; >+ nitems = width * height + 2; >+ } >+ >+ icon[0] = width; >+ icon[1] = height; >+ >+ /* Convert RGBA -> ARGB */ >+ for (i = 0; i < width * height; i++) >+ { >+ icon[i + 2] = >+ rgba_data[i * 4 + 3] << 24 | >+ ((rgba_data[i * 4 + 0] << 16) & 0x00FF0000) | >+ ((rgba_data[i * 4 + 1] << 8) & 0x0000FF00) | >+ ((rgba_data[i * 4 + 2] << 0) & 0x000000FF); >+ } >+ >+ XChangeProperty(g_display, wnd, g_net_wm_icon_atom, XA_CARDINAL, 32, >+ PropModeReplace, (unsigned char *) (new_set ? new_set : cur_set), nitems); >+ >+ if (cur_set) >+ XFree(cur_set); >+ if (new_set) >+ free(new_set); >+} >+ >+void >+ewmh_del_icon(Window wnd, int width, int height) >+{ >+ unsigned long nitems, i, icon_size; >+ unsigned char *props; >+ unsigned long *cur_set, *new_set; >+ >+ cur_set = NULL; >+ new_set = NULL; >+ >+ if (get_property_value(wnd, "_NET_WM_ICON", 10000, &nitems, &props, 1) < 0) >+ return; >+ >+ cur_set = (unsigned long *) props; >+ >+ for (i = 0; i < nitems;) >+ { >+ if (cur_set[i] == width && cur_set[i + 1] == height) >+ break; >+ >+ i += 2 + cur_set[i] * cur_set[i + 1]; >+ } >+ >+ if (i == nitems) >+ goto out; >+ >+ icon_size = width * height + 2; >+ new_set = xmalloc((nitems - icon_size) * sizeof(unsigned long)); >+ >+ if (i != 0) >+ memcpy(new_set, cur_set, i * sizeof(unsigned long)); >+ if (i != nitems - icon_size) >+ memcpy(new_set + i, cur_set + i + icon_size, >+ (nitems - (i + icon_size)) * sizeof(unsigned long)); >+ >+ nitems -= icon_size; >+ >+ XChangeProperty(g_display, wnd, g_net_wm_icon_atom, XA_CARDINAL, 32, >+ PropModeReplace, (unsigned char *) new_set, nitems); >+ >+ free(new_set); >+ >+ out: >+ XFree(cur_set); >+} >+ >+int >+ewmh_set_window_above(Window wnd) >+{ >+ if (ewmh_modify_state(wnd, 1, g_net_wm_state_above_atom, 0) < 0) >+ return -1; >+ return 0; >+} >+ >+#endif /* MAKE_PROTO */ >+ >+ >+#if 0 >+ >+/* FIXME: _NET_MOVERESIZE_WINDOW is for pagers, not for >+ applications. We should implement _NET_WM_MOVERESIZE instead */ >+ >+int >+ewmh_net_moveresize_window(Window wnd, int x, int y, int width, int height) >+{ >+ Status status; >+ XEvent xevent; >+ Atom moveresize; >+ >+ moveresize = XInternAtom(g_display, "_NET_MOVERESIZE_WINDOW", False); >+ if (!moveresize) >+ { >+ return -1; >+ } >+ >+ xevent.type = ClientMessage; >+ xevent.xclient.window = wnd; >+ xevent.xclient.message_type = moveresize; >+ xevent.xclient.format = 32; >+ xevent.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11); >+ xevent.xclient.data.l[1] = x; >+ xevent.xclient.data.l[2] = y; >+ xevent.xclient.data.l[3] = width; >+ xevent.xclient.data.l[4] = height; >+ >+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False, >+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent); >+ if (!status) >+ return -1; >+ return 0; >+} >+ >+#endif >Index: tigervnc/unix/vncviewer/Makefile.in >=================================================================== >--- tigervnc/unix/vncviewer/Makefile.in (revision 20144) >+++ tigervnc/unix/vncviewer/Makefile.in (arbetskopia) >@@ -1,4 +1,4 @@ >-# Makefile.in generated by automake 1.11 from Makefile.am. >+# Makefile.in generated by automake 1.11.1 from Makefile.am. > # @configure_input@ > > # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, >@@ -57,7 +57,8 @@ > am__objects_1 = > am_vncviewer_OBJECTS = $(am__objects_1) \ > vncviewer-DesktopWindow.$(OBJEXT) vncviewer-CConn.$(OBJEXT) \ >- vncviewer-vncviewer.$(OBJEXT) vncviewer-buildtime.$(OBJEXT) >+ vncviewer-vncviewer.$(OBJEXT) vncviewer-buildtime.$(OBJEXT) \ >+ vncviewer-ewmhints.$(OBJEXT) > vncviewer_OBJECTS = $(am_vncviewer_OBJECTS) > vncviewer_DEPENDENCIES = $(top_builddir)/unix/tx/libtx.la \ > $(top_builddir)/common/rfb/librfb.la \ >@@ -179,7 +180,6 @@ > PACKAGE_NAME = @PACKAGE_NAME@ > PACKAGE_STRING = @PACKAGE_STRING@ > PACKAGE_TARNAME = @PACKAGE_TARNAME@ >-PACKAGE_URL = @PACKAGE_URL@ > PACKAGE_VERSION = @PACKAGE_VERSION@ > PATH_SEPARATOR = @PATH_SEPARATOR@ > POSUB = @POSUB@ >@@ -260,7 +260,7 @@ > OptionsDialog.h parameters.h PasswdDialog.h ServerDialog.h > > vncviewer_SOURCES = $(HDRS) DesktopWindow.cxx CConn.cxx vncviewer.cxx \ >- buildtime.c >+ buildtime.c ewmhints.c > > # X_CFLAGS are really CPPFLAGS > vncviewer_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/unix \ >@@ -364,6 +364,7 @@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncviewer-CConn.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncviewer-DesktopWindow.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncviewer-buildtime.Po@am__quote@ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncviewer-ewmhints.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncviewer-vncviewer.Po@am__quote@ > > .c.o: >@@ -401,6 +402,20 @@ > @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ > @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vncviewer_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vncviewer-buildtime.obj `if test -f 'buildtime.c'; then $(CYGPATH_W) 'buildtime.c'; else $(CYGPATH_W) '$(srcdir)/buildtime.c'; fi` > >+vncviewer-ewmhints.o: ewmhints.c >+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vncviewer_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vncviewer-ewmhints.o -MD -MP -MF $(DEPDIR)/vncviewer-ewmhints.Tpo -c -o vncviewer-ewmhints.o `test -f 'ewmhints.c' || echo '$(srcdir)/'`ewmhints.c >+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vncviewer-ewmhints.Tpo $(DEPDIR)/vncviewer-ewmhints.Po >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ewmhints.c' object='vncviewer-ewmhints.o' libtool=no @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ >+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vncviewer_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vncviewer-ewmhints.o `test -f 'ewmhints.c' || echo '$(srcdir)/'`ewmhints.c >+ >+vncviewer-ewmhints.obj: ewmhints.c >+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vncviewer_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vncviewer-ewmhints.obj -MD -MP -MF $(DEPDIR)/vncviewer-ewmhints.Tpo -c -o vncviewer-ewmhints.obj `if test -f 'ewmhints.c'; then $(CYGPATH_W) 'ewmhints.c'; else $(CYGPATH_W) '$(srcdir)/ewmhints.c'; fi` >+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vncviewer-ewmhints.Tpo $(DEPDIR)/vncviewer-ewmhints.Po >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ewmhints.c' object='vncviewer-ewmhints.obj' libtool=no @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ >+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vncviewer_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vncviewer-ewmhints.obj `if test -f 'ewmhints.c'; then $(CYGPATH_W) 'ewmhints.c'; else $(CYGPATH_W) '$(srcdir)/ewmhints.c'; fi` >+ > .cxx.o: > @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< > @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po >Index: tigervnc/unix/vncviewer/ewmhints.h >=================================================================== >--- tigervnc/unix/vncviewer/ewmhints.h (revision 0) >+++ tigervnc/unix/vncviewer/ewmhints.h (revision 0) >@@ -0,0 +1,22 @@ >+#ifdef __cplusplus >+extern "C" { >+#endif >+ >+void ewmh_init(Display *display); >+int ewmh_state_fullscreen(Window wnd, Bool fullscreen); >+ >+#ifdef __cplusplus >+} >+#endif >+ >+#ifdef __cplusplus >+extern "C" { >+#endif >+ >+void ewmh_init(Display *display); >+int ewmh_state_fullscreen(Window wnd, Bool fullscreen); >+ >+#ifdef __cplusplus >+} >+#endif >+ >Index: tigervnc/unix/vncviewer/CConn.cxx >=================================================================== >--- tigervnc/unix/vncviewer/CConn.cxx (revision 20144) >+++ tigervnc/unix/vncviewer/CConn.cxx (arbetskopia) >@@ -42,6 +42,7 @@ > #include "ServerDialog.h" > #include "PasswdDialog.h" > #include "parameters.h" >+#include "ewmhints.h" > > #define SCANSCRIPT "/opt/thinlinc/lib/tlclient/local-scan" > >@@ -69,6 +70,7 @@ > menuKeysym(0), menu(dpy, this), options(dpy, this), about(dpy), info(dpy), > reverseConnection(reverse), firstUpdate(true), pendingUpdate(false) > { >+ ewmh_init(dpy); > CharArray menuKeyStr(menuKey.getData()); > menuKeysym = XStringToKeysym(menuKeyStr.buf); > >@@ -754,6 +756,7 @@ > } > viewport->toplevel(windowNameStr.buf, this, argc, argv); > viewport->setBumpScroll(fullScreen); >+#if 0 > XSetWindowAttributes attr; > attr.override_redirect = fullScreen; > XChangeWindowAttributes(dpy, viewport->win(), CWOverrideRedirect, &attr); >@@ -761,15 +764,21 @@ > XChangeWindowAttributes(dpy, options.win(), CWOverrideRedirect, &attr); > XChangeWindowAttributes(dpy, about.win(), CWOverrideRedirect, &attr); > XChangeWindowAttributes(dpy, info.win(), CWOverrideRedirect, &attr); >- reconfigureViewport(); >+#endif >+ >+ ewmh_state_fullscreen(viewport->win(), fullScreen); >+ >+ //reconfigureViewport(); ?? >+ > menu.setTransientFor(viewport->win()); > viewport->map(); >- if (fullScreen) { >- XGrabKeyboard(dpy, desktop->win(), True, GrabModeAsync, GrabModeAsync, >- CurrentTime); >- } else { >- XUngrabKeyboard(dpy, CurrentTime); >- } >+// if (fullScreen) { >+// XGrabKeyboard(dpy, desktop->win(), True, GrabModeAsync, GrabModeAsync, >+// CurrentTime); >+// } else { >+// XUngrabKeyboard(dpy, CurrentTime); >+// } >+// > if (oldViewport) delete oldViewport; > } > >Index: tigervnc/unix/vncviewer/Makefile.am >=================================================================== >--- tigervnc/unix/vncviewer/Makefile.am (revision 20144) >+++ tigervnc/unix/vncviewer/Makefile.am (arbetskopia) >@@ -6,7 +6,7 @@ > OptionsDialog.h parameters.h PasswdDialog.h ServerDialog.h > > vncviewer_SOURCES = $(HDRS) DesktopWindow.cxx CConn.cxx vncviewer.cxx \ >- buildtime.c >+ buildtime.c ewmhints.c > # X_CFLAGS are really CPPFLAGS > vncviewer_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/unix \ > -I$(top_srcdir)/unix/tx -I$(top_srcdir)/intl \
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1052
:
355
| 363