CVS: rdesktop ewmhints.c, 1.13, 1.14 proto.h, 1.108, 1.109 seamless.c, 1.7, 1.8 xproto.h, 1.5, 1.6 xwin.c, 1.224, 1.225

Pierre Ossman <[email protected]> Mon, 18 Jun 2007 05:00:38 -0700
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv29820

Modified Files:
	ewmhints.c proto.h seamless.c xproto.h xwin.c 
Log Message:
Implement support for icons in SeamlessRDP.


Index: ewmhints.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/ewmhints.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** ewmhints.c	8 Jan 2007 04:47:05 -0000	1.13
--- ewmhints.c	18 Jun 2007 12:00:33 -0000	1.14
***************
*** 5,9 ****
     http://www.freedesktop.org/wiki/Standards_2fwm_2dspec
  
!    Copyright (C) Peter Astrand <[email protected]> 2005
     
     This program is free software; you can redistribute it and/or modify
--- 5,10 ----
     http://www.freedesktop.org/wiki/Standards_2fwm_2dspec
  
!    Copyright 2005 Peter Astrand <[email protected]> for Cendio AB
!    Copyright 2007 Pierre Ossman <[email protected]> for Cendio AB
     
     This program is free software; you can redistribute it and/or modify
***************
*** 35,39 ****
  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;
  
  Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
--- 36,41 ----
  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;
  
  Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
***************
*** 188,191 ****
--- 190,194 ----
  	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);
  }
***************
*** 424,427 ****
--- 427,537 ----
  }
  
+ void
+ ewmh_set_icon(Window wnd, int width, int height, const char *rgba_data)
+ {
+ 	unsigned long nitems, i;
+ 	unsigned char *props;
+ 	uint32 *cur_set, *new_set;
+ 	uint32 *icon;
+ 
+ 	cur_set = NULL;
+ 	new_set = NULL;
+ 
+ 	if (get_property_value(wnd, "_NET_WM_ICON", 10000, &nitems, &props, 1) >= 0)
+ 	{
+ 		cur_set = (uint32 *) 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) * 4);
+ 			memcpy(new_set, cur_set, nitems * 4);
+ 			icon = new_set + nitems;
+ 			nitems += width * height + 2;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		new_set = xmalloc((width * height + 2) * 4);
+ 		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)
+ 		xfree(new_set);
+ }
+ 
+ void
+ ewmh_del_icon(Window wnd, int width, int height)
+ {
+ 	unsigned long nitems, i, icon_size;
+ 	unsigned char *props;
+ 	uint32 *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 = (uint32 *) 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) * 4);
+ 
+ 	if (i != 0)
+ 		memcpy(new_set, cur_set, i * 4);
+ 	if (i != nitems - icon_size)
+ 		memcpy(new_set + i * 4, cur_set + i * 4 + icon_size, nitems - icon_size);
+ 
+ 	nitems -= icon_size;
+ 
+ 	XChangeProperty(g_display, wnd, g_net_wm_icon_atom, XA_CARDINAL, 32,
+ 			PropModeReplace, (unsigned char *) new_set, nitems);
+ 
+ 	xfree(new_set);
+ 
+       out:
+ 	XFree(cur_set);
+ }
+ 
  #endif /* MAKE_PROTO */
  

Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.108
retrieving revision 1.109
diff -C2 -d -r1.108 -r1.109
*** proto.h	11 Jan 2007 03:30:18 -0000	1.108
--- proto.h	18 Jun 2007 12:00:33 -0000	1.109
***************
*** 289,292 ****
--- 289,295 ----
  void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
  void ui_seamless_destroy_group(unsigned long id, unsigned long flags);
+ void ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
+ 			 const char *data, int chunk_len);
+ void ui_seamless_delicon(unsigned long id, const char *format, int width, int height);
  void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,
  			     unsigned long flags);
***************
*** 308,318 ****
  unsigned int seamless_send_focus(unsigned long id, unsigned long flags);
  /* scard.c */
- void scardSetInfo(uint32 device, uint32 id, uint32 bytes_out);
- int scard_enum_devices(uint32 * id, char *optarg);
  void scard_lock(int lock);
  void scard_unlock(int lock);
- STREAM scard_tcp_init(void);
- void scard_tcp_connect(void);
- void scard_tcp_reset_state(void);
  
  /* *INDENT-OFF* */
--- 311,316 ----

Index: seamless.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/seamless.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** seamless.c	13 Jun 2007 14:53:32 -0000	1.7
--- seamless.c	18 Jun 2007 12:00:33 -0000	1.8
***************
*** 2,6 ****
     rdesktop: A Remote Desktop Protocol client.
     Seamless Windows support
!    Copyright (C) Peter Astrand <[email protected]> 2005-2007
  
     This program is free software; you can redistribute it and/or modify
--- 2,7 ----
     rdesktop: A Remote Desktop Protocol client.
     Seamless Windows support
!    Copyright 2005-2007 Peter Astrand <[email protected]> for Cendio AB
!    Copyright 2007 Pierre Ossman <[email protected]> for Cendio AB
  
     This program is free software; you can redistribute it and/or modify
***************
*** 32,35 ****
--- 33,37 ----
  static VCHANNEL *seamless_channel;
  static unsigned int seamless_serial;
+ static char icon_buf[1024];
  
  static char *
***************
*** 136,140 ****
  	else if (!strcmp("SETICON", tok1))
  	{
! 		unimpl("SeamlessRDP SETICON1\n");
  	}
  	else if (!strcmp("POSITION", tok1))
--- 138,200 ----
  	else if (!strcmp("SETICON", tok1))
  	{
! 		int chunk, width, height, len;
! 		char byte[3];
! 
! 		if (!tok8)
! 			return False;
! 
! 		id = strtoul(tok3, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		chunk = strtoul(tok4, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		width = strtoul(tok6, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		height = strtoul(tok7, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		byte[2] = '\0';
! 		len = 0;
! 		while (*tok8 != '\0')
! 		{
! 			byte[0] = *tok8;
! 			tok8++;
! 			if (*tok8 == '\0')
! 				return False;
! 			byte[1] = *tok8;
! 			tok8++;
! 
! 			icon_buf[len] = strtol(byte, NULL, 16);
! 			len++;
! 		}
! 
! 		ui_seamless_seticon(id, tok5, width, height, chunk, icon_buf, len);
! 	}
! 	else if (!strcmp("DELICON", tok1))
! 	{
! 		int width, height;
! 
! 		if (!tok6)
! 			return False;
! 
! 		id = strtoul(tok3, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		width = strtoul(tok5, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		height = strtoul(tok6, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		ui_seamless_delicon(id, tok4, width, height);
  	}
  	else if (!strcmp("POSITION", tok1))

Index: xproto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xproto.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** xproto.h	27 Mar 2006 08:17:33 -0000	1.5
--- xproto.h	18 Jun 2007 12:00:33 -0000	1.6
***************
*** 10,11 ****
--- 10,13 ----
  int ewmh_set_window_popup(Window wnd);
  int ewmh_set_window_modal(Window wnd);
+ void ewmh_set_icon(Window wnd, int width, int height, const char *rgba_data);
+ void ewmh_del_icon(Window wnd, int width, int height);

Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.224
retrieving revision 1.225
diff -C2 -d -r1.224 -r1.225
*** xwin.c	14 May 2007 12:11:15 -0000	1.224
--- xwin.c	18 Jun 2007 12:00:33 -0000	1.225
***************
*** 3,6 ****
--- 3,7 ----
     User interface services - X Window System
     Copyright (C) Matthew Chapman 1999-2007
+    Copyright 2007 Pierre Ossman <[email protected]> for Cendio AB
  
     This program is free software; you can redistribute it and/or modify
***************
*** 75,78 ****
--- 76,83 ----
  	int outpos_width, outpos_height;
  
+ 	unsigned int icon_size;
+ 	unsigned int icon_offset;
+ 	char icon_buffer[32 * 32 * 4];
+ 
  	struct _seamless_window *next;
  } seamless_window;
***************
*** 3453,3465 ****
  
  	sw = xmalloc(sizeof(seamless_window));
  	sw->wnd = wnd;
  	sw->id = id;
- 	sw->behind = 0;
  	sw->group = sw_find_group(group, False);
  	sw->group->refcnt++;
- 	sw->xoffset = 0;
- 	sw->yoffset = 0;
- 	sw->width = 0;
- 	sw->height = 0;
  	sw->state = SEAMLESSRDP_NOTYETMAPPED;
  	sw->desktop = 0;
--- 3458,3468 ----
  
  	sw = xmalloc(sizeof(seamless_window));
+ 
+ 	memset(sw, 0, sizeof(seamless_window));
+ 
  	sw->wnd = wnd;
  	sw->id = id;
  	sw->group = sw_find_group(group, False);
  	sw->group->refcnt++;
  	sw->state = SEAMLESSRDP_NOTYETMAPPED;
  	sw->desktop = 0;
***************
*** 3529,3532 ****
--- 3532,3622 ----
  
  void
+ ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
+ 		    const char *data, int chunk_len)
+ {
+ 	seamless_window *sw;
+ 
+ 	if (!g_seamless_active)
+ 		return;
+ 
+ 	sw = sw_get_window_by_id(id);
+ 	if (!sw)
+ 	{
+ 		warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
+ 		return;
+ 	}
+ 
+ 	if (chunk == 0)
+ 	{
+ 		if (sw->icon_size)
+ 			warning("ui_seamless_seticon: New icon started before previous completed\n");
+ 
+ 		if (strcmp(format, "RGBA") != 0)
+ 		{
+ 			warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
+ 			return;
+ 		}
+ 
+ 		sw->icon_size = width * height * 4;
+ 		if (sw->icon_size > 32 * 32 * 4)
+ 		{
+ 			warning("ui_seamless_seticon: Icon too large (%d bytes)\n", sw->icon_size);
+ 			sw->icon_size = 0;
+ 			return;
+ 		}
+ 
+ 		sw->icon_offset = 0;
+ 	}
+ 	else
+ 	{
+ 		if (!sw->icon_size)
+ 			return;
+ 	}
+ 
+ 	if (chunk_len > (sw->icon_size - sw->icon_offset))
+ 	{
+ 		warning("ui_seamless_seticon: Too large chunk received (%d bytes > %d bytes)\n",
+ 			chunk_len, sw->icon_size - sw->icon_offset);
+ 		sw->icon_size = 0;
+ 		return;
+ 	}
+ 
+ 	memcpy(sw->icon_buffer + sw->icon_offset, data, chunk_len);
+ 	sw->icon_offset += chunk_len;
+ 
+ 	if (sw->icon_offset == sw->icon_size)
+ 	{
+ 		ewmh_set_icon(sw->wnd, width, height, sw->icon_buffer);
+ 		sw->icon_size = 0;
+ 	}
+ }
+ 
+ 
+ void
+ ui_seamless_delicon(unsigned long id, const char *format, int width, int height)
+ {
+ 	seamless_window *sw;
+ 
+ 	if (!g_seamless_active)
+ 		return;
+ 
+ 	sw = sw_get_window_by_id(id);
+ 	if (!sw)
+ 	{
+ 		warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
+ 		return;
+ 	}
+ 
+ 	if (strcmp(format, "RGBA") != 0)
+ 	{
+ 		warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
+ 		return;
+ 	}
+ 
+ 	ewmh_del_icon(sw->wnd, width, height);
+ }
+ 
+ 
+ void
  ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
  {


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/