toggle full screen

git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@99 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Jay Sorg 2002-08-24 20:04:56 +00:00
parent 8d4995f623
commit a7c00fc2e6
3 changed files with 143 additions and 68 deletions

View File

@ -80,7 +80,7 @@ void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
void rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode); void rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode);
/* xwin.c */ /* xwin.c */
BOOL ui_init(void); BOOL ui_init(void);
BOOL ui_create_window(char *title); BOOL ui_create_window();
void ui_destroy_window(void); void ui_destroy_window(void);
void ui_select(int rdp_socket); void ui_select(int rdp_socket);
void ui_move_pointer(int x, int y); void ui_move_pointer(int x, int y);

View File

@ -2,17 +2,17 @@
rdesktop: A Remote Desktop Protocol client. rdesktop: A Remote Desktop Protocol client.
Entrypoint and utility functions Entrypoint and utility functions
Copyright (C) Matthew Chapman 1999-2001 Copyright (C) Matthew Chapman 1999-2001
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@ -29,6 +29,7 @@
#include <sys/times.h> /* times */ #include <sys/times.h> /* times */
#include "rdesktop.h" #include "rdesktop.h"
char title[32];
char username[16]; char username[16];
char hostname[16]; char hostname[16];
char keymapname[16]; char keymapname[16];
@ -78,7 +79,6 @@ main(int argc, char *argv[])
char *askpass_result; char *askpass_result;
char shell[32]; char shell[32];
char directory[32]; char directory[32];
char title[32];
struct passwd *pw; struct passwd *pw;
char *server, *p; char *server, *p;
uint32 flags; uint32 flags;
@ -247,7 +247,7 @@ main(int argc, char *argv[])
printf("Connection successful.\n"); printf("Connection successful.\n");
if (ui_create_window(title)) if (ui_create_window())
{ {
rdp_main_loop(); rdp_main_loop();
ui_destroy_window(); ui_destroy_window();

199
xwin.c
View File

@ -32,6 +32,7 @@ extern int height;
extern BOOL sendmotion; extern BOOL sendmotion;
extern BOOL fullscreen; extern BOOL fullscreen;
extern BOOL grab_keyboard; extern BOOL grab_keyboard;
extern char title[];
Display *display = NULL; Display *display = NULL;
static int x_socket; static int x_socket;
@ -40,6 +41,8 @@ static GC gc;
static Visual *visual; static Visual *visual;
static int depth; static int depth;
static int bpp; static int bpp;
static int dpy_width;
static int dpy_height;
/* endianness */ /* endianness */
static BOOL host_be; static BOOL host_be;
@ -67,6 +70,10 @@ static XIC IC = NULL;
/* Compose support */ /* Compose support */
BOOL enable_compose = False; BOOL enable_compose = False;
/* toggle fullscreen globals */
static XSetWindowAttributes attribs;
static unsigned long input_mask;
#define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) ) #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
#define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col)); #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
#define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col)); #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
@ -260,17 +267,74 @@ ui_init()
} }
BOOL BOOL
ui_create_window(char *title) ui_create_window_obj(int xpos, int ypos, int width, int height, int valuemask)
{ {
XSetWindowAttributes attribs;
XClassHint *classhints; XClassHint *classhints;
XSizeHints *sizehints; XSizeHints *sizehints;
unsigned long input_mask; XEvent xevent;
Screen *screen;
screen = DefaultScreenOfDisplay(display);
wnd = XCreateWindow(display, RootWindowOfScreen(screen), xpos,
ypos, width, height, 0, CopyFromParent,
InputOutput, CopyFromParent, valuemask, &attribs);
XStoreName(display, wnd, title);
classhints = XAllocClassHint();
if (classhints != NULL)
{
classhints->res_name = classhints->res_class = "rdesktop";
XSetClassHint(display, wnd, classhints);
XFree(classhints);
}
sizehints = XAllocSizeHints();
if (sizehints)
{
sizehints->flags = PMinSize | PMaxSize;
sizehints->min_width = sizehints->max_width = width;
sizehints->min_height = sizehints->max_height = height;
XSetWMNormalHints(display, wnd, sizehints);
XFree(sizehints);
}
if (enable_compose)
input_mask |= init_inputmethod();
XSelectInput(display, wnd, input_mask);
gc = XCreateGC(display, wnd, 0, NULL);
XMapWindow(display, wnd);
/* Wait for VisibilityNotify Event */
for (;;) {
XNextEvent(display, &xevent);
if (xevent.type == VisibilityNotify)
break;
}
if (ownbackstore)
backstore = XCreatePixmap(display, wnd, width, height, depth);
/* clear the window so that cached data is not viewed upon start... */
XSetBackground(display, gc, 0);
XSetForeground(display, gc, 0);
FILL_RECTANGLE(0, 0, width, height);
/* make sure the window is focused */
XSetInputFocus(display, wnd, RevertToPointerRoot, CurrentTime);
}
BOOL
ui_create_window()
{
XPixmapFormatValues *pfm; XPixmapFormatValues *pfm;
Screen *screen; Screen *screen;
uint16 test; uint16 test;
int i; int i;
XEvent xevent;
x_socket = ConnectionNumber(display); x_socket = ConnectionNumber(display);
screen = DefaultScreenOfDisplay(display); screen = DefaultScreenOfDisplay(display);
@ -315,11 +379,14 @@ ui_create_window(char *title)
if (attribs.backing_store == NotUseful) if (attribs.backing_store == NotUseful)
ownbackstore = True; ownbackstore = True;
dpy_width = WidthOfScreen(screen);
dpy_height = HeightOfScreen(screen);
if (fullscreen) if (fullscreen)
{ {
attribs.override_redirect = True; attribs.override_redirect = True;
width = WidthOfScreen(screen); width = dpy_width;
height = HeightOfScreen(screen); height = dpy_height;
} }
else else
{ {
@ -328,35 +395,10 @@ ui_create_window(char *title)
width = (width + 3) & ~3; /* make width a multiple of 32 bits */ width = (width + 3) & ~3; /* make width a multiple of 32 bits */
wnd = XCreateWindow(display, RootWindowOfScreen(screen),
0, 0, width, height, 0, CopyFromParent,
InputOutput, CopyFromParent,
CWBackingStore | CWBackPixel | CWOverrideRedirect, &attribs);
XStoreName(display, wnd, title);
classhints = XAllocClassHint();
if (classhints != NULL)
{
classhints->res_name = classhints->res_class = "rdesktop";
XSetClassHint(display, wnd, classhints);
XFree(classhints);
}
sizehints = XAllocSizeHints();
if (sizehints)
{
sizehints->flags = PMinSize | PMaxSize;
sizehints->min_width = sizehints->max_width = width;
sizehints->min_height = sizehints->max_height = height;
XSetWMNormalHints(display, wnd, sizehints);
XFree(sizehints);
}
xkeymap_init2();
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask | FocusChangeMask; VisibilityChangeMask | FocusChangeMask;
if (grab_keyboard) if (grab_keyboard)
input_mask |= EnterWindowMask | LeaveWindowMask; input_mask |= EnterWindowMask | LeaveWindowMask;
if (sendmotion) if (sendmotion)
@ -365,29 +407,12 @@ ui_create_window(char *title)
if (ownbackstore) if (ownbackstore)
input_mask |= ExposureMask; input_mask |= ExposureMask;
if (enable_compose) if (fullscreen)
input_mask |= init_inputmethod(); ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel | CWOverrideRedirect);
else
ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
XSelectInput(display, wnd, input_mask); xkeymap_init2();
gc = XCreateGC(display, wnd, 0, NULL);
if (ownbackstore)
backstore = XCreatePixmap(display, wnd, width, height, depth);
XMapWindow(display, wnd);
/* Wait for VisibilityNotify Event */
for (;;) {
XNextEvent(display, &xevent);
if (xevent.type == VisibilityNotify)
break;
}
/* clear the window so that cached data is not viewed upon start... */
XSetBackground(display, gc, 0);
XSetForeground(display, gc, 0);
FILL_RECTANGLE(0, 0, width, height);
return True; return True;
} }
@ -407,6 +432,56 @@ ui_destroy_window()
display = NULL; display = NULL;
} }
void
reset_keys()
{
/* reset keys */
uint32 ev_time;
ev_time = time(NULL);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
}
void
toggle_fullscreen()
{
/* save window contents */
Pixmap pixmap;
pixmap = XCreatePixmap(display, wnd, width, height, depth);
if (ownbackstore)
XCopyArea(display, backstore, pixmap, gc, 0, 0, width, height, 0, 0);
else
XCopyArea(display, wnd, pixmap, gc, 0, 0, width, height, 0, 0);
fullscreen = fullscreen ? False : True;
close_inputmethod();
if (ownbackstore)
XFreePixmap(display, backstore);
XFreeGC(display, gc);
XDestroyWindow(display, wnd);
if (fullscreen) {
attribs.override_redirect = True;
ui_create_window_obj(0, 0, dpy_width, dpy_height,
CWBackingStore | CWBackPixel | CWOverrideRedirect);
}
else {
attribs.override_redirect = False;
ui_create_window_obj(0, 0, width, height,
CWBackingStore | CWBackPixel);
}
ui_set_cursor(cache_get_cursor(0));
ui_move_pointer(width / 2, height / 2);
reset_keys();
/* restore window contents */
if (ownbackstore)
XCopyArea(display, pixmap, backstore, gc, 0, 0, width, height, 0, 0);
XCopyArea(display, pixmap, wnd, gc, 0, 0, width, height, 0, 0);
XFreePixmap(display, pixmap);
}
static void static void
xwin_process_events() xwin_process_events()
{ {
@ -420,7 +495,7 @@ xwin_process_events()
char str[256]; char str[256];
Status status; Status status;
/* Refresh keyboard mapping if it has changed. This is important for /* Refresh keyboard mapping if it has changed. This is important for
Xvnc, since it allocates keycodes dynamically */ Xvnc, since it allocates keycodes dynamically */
if (XCheckTypedEvent(display, MappingNotify, &xevent)) if (XCheckTypedEvent(display, MappingNotify, &xevent))
{ {
@ -464,6 +539,12 @@ xwin_process_events()
str, sizeof(str), &keysym, NULL); str, sizeof(str), &keysym, NULL);
} }
/* FIXME needs alt modifier */
if (keysym == XK_Break) /* toggle full screen */
{
toggle_fullscreen();
break;
}
ksname = get_ksname(keysym); ksname = get_ksname(keysym);
DEBUG_KBD(("\nKeyPress for (keysym 0x%lx, %s)\n", keysym, ksname)); DEBUG_KBD(("\nKeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
@ -530,13 +611,7 @@ xwin_process_events()
break; break;
case FocusOut: case FocusOut:
/* reset keys */ reset_keys();
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
/* fall through */ /* fall through */
case LeaveNotify: case LeaveNotify:
if (grab_keyboard) if (grab_keyboard)