[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

Fullscreen rdesktop - demonstration example



What do you people think about this suggestion:

- When rdesktop is run in fullscreen mode, it creates two
  windows, one small, normal window (without override_redirect)
  that places itself on the desktop (with window manager
  decorations and all - just like a regular window like xterm),
  and a fullscreen window (just like the current behaviour).

- The small, normal window is approx. 150 x 50 pixels large and
  contains for example a bitmap like this one:
    http://www.math.ntnu.no/~perhov/tmp/rdesktop.gif
  (without the real windows logo, as that may be copyrighted.
  This one was made for demonstration purposes only.)

- Left-clicking on the lower right pixel in the fullscreen
  window unmaps (minimizes) the fullscreen window.

    (If this collides with normal windows usage, it could be
    changed to e.g. a Shift-click or a triple click).

- Clicking in the small window remaps the fullscreen window.


A patch suggestion (relative to 1.0.0pl19.7.2) is attached. It's
only a suggestion, because it's probably got bugs, the small
window is black (not filled with a bitmap logo), and there's no
way to turn off the magic behaviour of the lower right pixel. It
does however demonstrate the principle.


-- 
Per Kristian Hove <Per.Hove@math.ntnu.no>
Principal engineer
Dept. of Mathematical Sciences
Norwegian University of Science and Technology

diff -ru xwin.c.orig xwin.c
--- xwin.c.orig	Thu Aug 23 10:40:05 2001
+++ xwin.c	Thu Oct 18 18:56:30 2001
@@ -27,6 +27,7 @@
 #include <sys/time.h>
 #include "rdesktop.h"
 #include <stdlib.h>
+#include <signal.h>
 
 #include "keymap_wrap.c"
 
@@ -47,6 +48,7 @@
 static int depth = -1;
 static Display *display = NULL;
 static Window wnd;
+static Window wnd2;
 static GC gc = NULL;
 static GC back_gc = NULL;
 static GC glyph_gc = NULL;
@@ -79,6 +81,29 @@
 
 
 
+void
+sigusr_func (int s)
+{
+  switch (s)
+
+  {
+  case SIGUSR1:
+    // STATUS ("Got SIGUSR1, unmapping window. Send SIGUSR2 to map window.\n");
+    STATUS ("Fullscreen window minimized. Click on the rdesktop logo to restore the window\n");
+    XUnmapWindow (display, wnd);
+    break;
+  case SIGUSR2:
+    // STATUS ("Received SIGUSR2, mapping window.\n");
+    XMapRaised (display, wnd);
+    break;
+  default:
+    break;
+  }
+
+  XFlush (display);
+}
+
+
 int
 ui_select_fd ()
 {
@@ -106,6 +131,7 @@
   KeyCode *keycode;
   int i,j;
   XModifierKeymap *modmap;
+  static struct sigaction sigusr_act;
 
 #ifdef HAVE_XINERAMA
   int screens;
@@ -210,14 +236,29 @@
      XCreateWindow (display, DefaultRootWindow (display), 0, 0, width, height,
 		   0, CopyFromParent, InputOutput, CopyFromParent,
 		   CWBackingStore | CWBackPixel | CWOverrideRedirect, &attribs);
+   wnd2 =
+     XCreateWindow (display, DefaultRootWindow (display), 0, 0, 160, 48,
+		   0, CopyFromParent, InputOutput, CopyFromParent,
+		   CWBackingStore | CWBackPixel , &attribs);
+
+   /* Prepare signal handler for SIGUSR1 and SIGUSR2 */
+   sigusr_act.sa_handler = sigusr_func;
     }
   else {
    wnd =
      XCreateWindow (display, DefaultRootWindow (display), 0, 0, width, height,
 		   0, CopyFromParent, InputOutput, CopyFromParent,
 		   CWBackingStore | CWBackPixel , &attribs);
+
+   /* Prepare signal handler for SIGUSR1 and SIGUSR2 */
+   sigusr_act.sa_handler = SIG_IGN;
     }
 
+  /* Install signal handler for SIGUSR1 and SIGUSR2 */
+  sigfillset(&(sigusr_act.sa_mask));
+  sigaction(SIGUSR1, &sigusr_act, NULL);
+  sigaction(SIGUSR2, &sigusr_act, NULL);
+
   DEBUG("ui_create_window(): geometry selected:%ux%u\n",width,height);
 
   sizehints = XAllocSizeHints ();
@@ -234,6 +275,7 @@
       XFree (sizehints);
     }
   XStoreName (display, wnd, title);
+  XStoreName (display, wnd2, title);
   classhints = XAllocClassHint ();
   if (classhints != NULL)
 
@@ -251,9 +293,10 @@
   if (grab_keyboard)
     input_mask |= EnterWindowMask | LeaveWindowMask;
   XSelectInput (display, wnd, input_mask);
+  XSelectInput (display, wnd2, input_mask & ~(KeyPressMask | KeyReleaseMask));
   gc = XCreateGC (display, wnd, 0, NULL);
   IM = XOpenIM (display, NULL, NULL, NULL);
-  XMapWindow( display, wnd );
+  XMapWindow( display, wnd2 );
 
   /* Wait for the MapNotify Event */
   for(;;) {
@@ -262,6 +305,17 @@
     if (e.type == MapNotify)
       break;
   }
+
+  XMapRaised( display, wnd );
+
+  /* Wait for the MapNotify Event */
+  for(;;) {
+    XEvent e;
+    XNextEvent(display, &e);
+    if (e.type == MapNotify)
+      break;
+  }
+
   /* Create a pixmap for backing the window */
   if( backing_store == BS_PIXMAP )
   { 
@@ -324,6 +378,7 @@
         XCloseIM (IM);
   XFreeGC (display, gc);
   XDestroyWindow (display, wnd);
+  XDestroyWindow (display, wnd2);
   XCloseDisplay (display);
   display = NULL;
 }
@@ -446,6 +501,21 @@
   if (display == NULL)
     return;
 
+  if (fullscreen)
+  while (XCheckWindowEvent (display, wnd2, ~0, &event))
+    {
+      ev_time = time (NULL);
+      switch (event.type)
+
+	{
+	case ButtonPress:
+	    sigusr_func(SIGUSR2);
+	    break;
+	default:
+	    break;
+	}
+    }
+
   while (XCheckWindowEvent (display, wnd, ~0, &event))
     {
       ev_time = time (NULL);
@@ -616,6 +686,14 @@
 	  break;
 	case ButtonPress:
 	  button = xwin_translate_mouse (event.xbutton.button);
+
+	  // fprintf(stderr, "ButtonPress (%d,%d)\n", event.xbutton.x, event.xbutton.y);
+	  if (fullscreen && (event.xbutton.button == 1) &&
+		(event.xbutton.x+1 == width) && (event.xbutton.y+1 == height))
+          {
+	  	sigusr_func(SIGUSR1);
+		break;
+          }
 
 	  if (button == 0){
 	         /* horrible wheelmouse hack */