--- sourceforge.net/trunk/rdesktop/xwin.c 2005/08/02 15:07:35 949 +++ sourceforge.net/trunk/rdesktop/xwin.c 2005/11/23 12:49:37 1030 @@ -79,6 +79,7 @@ static BOOL g_moving_wnd; static int g_move_x_offset = 0; static int g_move_y_offset = 0; +static BOOL g_using_full_workarea = False; #ifdef WITH_RDPSND extern int g_dsp_fd; @@ -137,10 +138,9 @@ XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \ break; \ case 1: /* Filled */ \ - XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \ - cx, cy, 0, 360*64); \ + XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \ if (g_ownbackstore) \ - XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \ + XFillArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \ break; \ } \ } @@ -1091,6 +1091,8 @@ else if (g_width < 0) { /* Percent of screen */ + if (-g_width >= 100) + g_using_full_workarea = True; g_height = HeightOfScreen(g_screen) * (-g_width) / 100; g_width = WidthOfScreen(g_screen) * (-g_width) / 100; } @@ -1098,6 +1100,7 @@ { /* Fetch geometry from _NET_WORKAREA */ uint32 x, y, cx, cy; + g_using_full_workarea = True; if (get_current_workarea(&x, &y, &cx, &cy) == 0) { @@ -1341,6 +1344,78 @@ } } +static void +handle_button_event(XEvent xevent, BOOL down) +{ + uint16 button, flags = 0; + g_last_gesturetime = xevent.xbutton.time; + button = xkeymap_translate_button(xevent.xbutton.button); + if (button == 0) + return; + + if (down) + flags = MOUSE_FLAG_DOWN; + + /* Stop moving window when button is released, regardless of cursor position */ + if (g_moving_wnd && (xevent.type == ButtonRelease)) + g_moving_wnd = False; + + /* If win_button_size is nonzero, enable single app mode */ + if (xevent.xbutton.y < g_win_button_size) + { + /* Check from right to left: */ + if (xevent.xbutton.x >= g_width - g_win_button_size) + { + /* The close button, continue */ + ; + } + else if (xevent.xbutton.x >= g_width - g_win_button_size * 2) + { + /* The maximize/restore button. Do not send to + server. It might be a good idea to change the + cursor or give some other visible indication + that rdesktop inhibited this click */ + if (xevent.type == ButtonPress) + return; + } + else if (xevent.xbutton.x >= g_width - g_win_button_size * 3) + { + /* The minimize button. Iconify window. */ + if (xevent.type == ButtonRelease) + { + /* Release the mouse button outside the minimize button, to prevent the + actual minimazation to happen */ + rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1); + XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display)); + return; + } + } + else if (xevent.xbutton.x <= g_win_button_size) + { + /* The system menu. Ignore. */ + if (xevent.type == ButtonPress) + return; + } + else + { + /* The title bar. */ + if (xevent.type == ButtonPress) + { + if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea) + { + g_moving_wnd = True; + g_move_x_offset = xevent.xbutton.x; + g_move_y_offset = xevent.xbutton.y; + } + return; + } + } + } + + rdp_send_input(time(NULL), RDP_INPUT_MOUSE, + flags | button, xevent.xbutton.x, xevent.xbutton.y); +} + /* Process events in Xlib queue Returns 0 after user quit, 1 otherwise */ static int @@ -1348,7 +1423,6 @@ { XEvent xevent; KeySym keysym; - uint16 button, flags; uint32 ev_time; char str[256]; Status status; @@ -1364,8 +1438,6 @@ continue; } - flags = 0; - switch (xevent.type) { case VisibilityNotify: @@ -1410,7 +1482,7 @@ break; xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state, - ev_time, True); + ev_time, True, 0); break; case KeyRelease: @@ -1426,72 +1498,15 @@ break; xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state, - ev_time, False); + ev_time, False, 0); break; case ButtonPress: - flags = MOUSE_FLAG_DOWN; - /* fall through */ + handle_button_event(xevent, True); + break; case ButtonRelease: - g_last_gesturetime = xevent.xbutton.time; - button = xkeymap_translate_button(xevent.xbutton.button); - if (button == 0) - break; - - /* If win_button_size is nonzero, enable single app mode */ - if (xevent.xbutton.y < g_win_button_size) - { - /* Stop moving window when button is released, regardless of cursor position */ - if (g_moving_wnd && (xevent.type == ButtonRelease)) - g_moving_wnd = False; - - /* Check from right to left: */ - - if (xevent.xbutton.x >= g_width - g_win_button_size) - { - /* The close button, continue */ - ; - } - else if (xevent.xbutton.x >= - g_width - g_win_button_size * 2) - { - /* The maximize/restore button. Do not send to - server. It might be a good idea to change the - cursor or give some other visible indication - that rdesktop inhibited this click */ - break; - } - else if (xevent.xbutton.x >= - g_width - g_win_button_size * 3) - { - /* The minimize button. Iconify window. */ - XIconifyWindow(g_display, g_wnd, - DefaultScreen(g_display)); - break; - } - else if (xevent.xbutton.x <= g_win_button_size) - { - /* The system menu. Ignore. */ - break; - } - else - { - /* The title bar. */ - if ((xevent.type == ButtonPress) && !g_fullscreen - && g_hide_decorations) - { - g_moving_wnd = True; - g_move_x_offset = xevent.xbutton.x; - g_move_y_offset = xevent.xbutton.y; - } - break; - - } - } - - rdp_send_input(time(NULL), RDP_INPUT_MOUSE, - flags | button, xevent.xbutton.x, xevent.xbutton.y); + handle_button_event(xevent, False); break; case MotionNotify: @@ -2430,22 +2445,29 @@ switch (text[i]) { case 0xff: - if (i + 2 < length) - cache_put_text(text[i + 1], text, text[i + 2]); - else + if (i + 3 > length) { - error("this shouldn't be happening\n"); - exit(1); + /* short command, skip */ + i = length = 0; + break; } + cache_put_text(text[i + 1], text, text[i + 2]); + i += 3; + length -= i; /* this will move pointer from start to first character after FF command */ - length -= i + 3; - text = &(text[i + 3]); + text = &(text[i]); i = 0; break; case 0xfe: + if (i + 3 > length) + { + /* short command, skip */ + i = length = 0; + break; + } entry = cache_get_text(text[i + 1]); - if (entry != NULL) + if (entry->data != NULL) { if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X))) @@ -2458,10 +2480,7 @@ for (j = 0; j < entry->size; j++) DO_GLYPH(((uint8 *) (entry->data)), j); } - if (i + 2 < length) - i += 3; - else - i += 2; + i += 3; length -= i; /* this will move pointer from start to first character after FE command */ text = &(text[i]);