/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 828 by stargo, Sun Mar 6 21:11:18 2005 UTC revision 988 by astrand, Thu Aug 25 20:27:45 2005 UTC
# Line 32  extern int g_width; Line 32  extern int g_width;
32  extern int g_height;  extern int g_height;
33  extern int g_xpos;  extern int g_xpos;
34  extern int g_ypos;  extern int g_ypos;
35    extern int g_pos;
36  extern BOOL g_sendmotion;  extern BOOL g_sendmotion;
37  extern BOOL g_fullscreen;  extern BOOL g_fullscreen;
38  extern BOOL g_grab_keyboard;  extern BOOL g_grab_keyboard;
# Line 119  PixelColour; Line 120  PixelColour;
120          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
121  }  }
122    
123    #define FILL_POLYGON(p,np)\
124    { \
125            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
126            if (g_ownbackstore) \
127                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
128    }
129    
130    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
131    { \
132            switch (m) \
133            { \
134                    case 0: /* Outline */ \
135                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
136                            if (g_ownbackstore) \
137                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
138                            break; \
139                    case 1: /* Filled */ \
140                            XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \
141                                     cx, cy, 0, 360*64); \
142                            if (g_ownbackstore) \
143                                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \
144                            break; \
145            } \
146    }
147    
148  /* colour maps */  /* colour maps */
149  extern BOOL g_owncolmap;  extern BOOL g_owncolmap;
150  static Colormap g_xcolmap;  static Colormap g_xcolmap;
# Line 1138  ui_create_window(void) Line 1164  ui_create_window(void)
1164          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1165          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1166    
1167            /* Handle -x-y portion of geometry string */
1168            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1169                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1170            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1171                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1172    
1173          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1174          attribs.border_pixel = WhitePixelOfScreen(g_screen);          attribs.border_pixel = WhitePixelOfScreen(g_screen);
1175          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
# Line 1181  ui_create_window(void) Line 1213  ui_create_window(void)
1213          if (sizehints)          if (sizehints)
1214          {          {
1215                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1216                    if (g_pos)
1217                            sizehints->flags |= PPosition;
1218                  sizehints->min_width = sizehints->max_width = g_width;                  sizehints->min_width = sizehints->max_width = g_width;
1219                  sizehints->min_height = sizehints->max_height = g_height;                  sizehints->min_height = sizehints->max_height = g_height;
1220                  XSetWMNormalHints(g_display, g_wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
# Line 1193  ui_create_window(void) Line 1227  ui_create_window(void)
1227          }          }
1228    
1229          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1230                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1231    
1232          if (g_sendmotion)          if (g_sendmotion)
1233                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
# Line 1307  xwin_toggle_fullscreen(void) Line 1341  xwin_toggle_fullscreen(void)
1341          }          }
1342  }  }
1343    
1344  /* Process all events in Xlib queue  static void
1345    handle_button_event(XEvent xevent, BOOL down)
1346    {
1347            uint16 button, flags = 0;
1348            g_last_gesturetime = xevent.xbutton.time;
1349            button = xkeymap_translate_button(xevent.xbutton.button);
1350            if (button == 0)
1351                    return;
1352    
1353            if (down)
1354                    flags = MOUSE_FLAG_DOWN;
1355    
1356            /* Stop moving window when button is released, regardless of cursor position */
1357            if (g_moving_wnd && (xevent.type == ButtonRelease))
1358                    g_moving_wnd = False;
1359    
1360            /* If win_button_size is nonzero, enable single app mode */
1361            if (xevent.xbutton.y < g_win_button_size)
1362            {
1363                    /*  Check from right to left: */
1364                    if (xevent.xbutton.x >= g_width - g_win_button_size)
1365                    {
1366                            /* The close button, continue */
1367                            ;
1368                    }
1369                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 2)
1370                    {
1371                            /* The maximize/restore button. Do not send to
1372                               server.  It might be a good idea to change the
1373                               cursor or give some other visible indication
1374                               that rdesktop inhibited this click */
1375                            if (xevent.type == ButtonPress)
1376                                    return;
1377                    }
1378                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)
1379                    {
1380                            /* The minimize button. Iconify window. */
1381                            if (xevent.type == ButtonRelease)
1382                            {
1383                                    /* Release the mouse button outside the minimize button, to prevent the
1384                                       actual minimazation to happen */
1385                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1386                                    XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));
1387                                    return;
1388                            }
1389                    }
1390                    else if (xevent.xbutton.x <= g_win_button_size)
1391                    {
1392                            /* The system menu. Ignore. */
1393                            if (xevent.type == ButtonPress)
1394                                    return;
1395                    }
1396                    else
1397                    {
1398                            /* The title bar. */
1399                            if (xevent.type == ButtonPress)
1400                            {
1401                                    if (!g_fullscreen && g_hide_decorations)
1402                                    {
1403                                            g_moving_wnd = True;
1404                                            g_move_x_offset = xevent.xbutton.x;
1405                                            g_move_y_offset = xevent.xbutton.y;
1406                                    }
1407                                    return;
1408                            }
1409                    }
1410            }
1411    
1412            rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1413                           flags | button, xevent.xbutton.x, xevent.xbutton.y);
1414    }
1415    
1416    /* Process events in Xlib queue
1417     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1418  static int  static int
1419  xwin_process_events(void)  xwin_process_events(void)
1420  {  {
1421          XEvent xevent;          XEvent xevent;
1422          KeySym keysym;          KeySym keysym;
         uint16 button, flags;  
1423          uint32 ev_time;          uint32 ev_time;
         key_translation tr;  
1424          char str[256];          char str[256];
1425          Status status;          Status status;
1426            int events = 0;
1427    
1428          while (XPending(g_display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1429          {          {
1430                  XNextEvent(g_display, &xevent);                  XNextEvent(g_display, &xevent);
1431    
# Line 1330  xwin_process_events(void) Line 1435  xwin_process_events(void)
1435                          continue;                          continue;
1436                  }                  }
1437    
                 flags = 0;  
   
1438                  switch (xevent.type)                  switch (xevent.type)
1439                  {                  {
1440                          case VisibilityNotify:                          case VisibilityNotify:
# Line 1368  xwin_process_events(void) Line 1471  xwin_process_events(void)
1471                                                        str, sizeof(str), &keysym, NULL);                                                        str, sizeof(str), &keysym, NULL);
1472                                  }                                  }
1473    
1474                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1475                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1476    
1477                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1478                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1479                                          break;                                          break;
1480    
1481                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1482                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, True, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 save_remote_modifiers(tr.scancode);  
                                 ensure_remote_modifiers(ev_time, tr);  
                                 rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);  
                                 restore_remote_modifiers(ev_time, tr.scancode);  
   
1483                                  break;                                  break;
1484    
1485                          case KeyRelease:                          case KeyRelease:
# Line 1393  xwin_process_events(void) Line 1487  xwin_process_events(void)
1487                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1488                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1489    
1490                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1491                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1492    
1493                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1494                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1495                                          break;                                          break;
1496    
1497                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1498                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, False, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);  
1499                                  break;                                  break;
1500    
1501                          case ButtonPress:                          case ButtonPress:
1502                                  flags = MOUSE_FLAG_DOWN;                                  handle_button_event(xevent, True);
1503                                  /* fall through */                                  break;
1504    
1505                          case ButtonRelease:                          case ButtonRelease:
1506                                  g_last_gesturetime = xevent.xbutton.time;                                  handle_button_event(xevent, False);
                                 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);  
1507                                  break;                                  break;
1508    
1509                          case MotionNotify:                          case MotionNotify:
# Line 1564  xwin_process_events(void) Line 1596  xwin_process_events(void)
1596                          case PropertyNotify:                          case PropertyNotify:
1597                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1598                                  break;                                  break;
1599                            case MapNotify:
1600                                    rdp_send_client_window_status(1);
1601                                    break;
1602                            case UnmapNotify:
1603                                    rdp_send_client_window_status(0);
1604                                    break;
1605                  }                  }
1606          }          }
1607          /* Keep going */          /* Keep going */
# Line 2166  ui_rect( Line 2204  ui_rect(
2204          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2205  }  }
2206    
2207    void
2208    ui_polygon(uint8 opcode,
2209               /* mode */ uint8 fillmode,
2210               /* dest */ POINT * point, int npoints,
2211               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2212    {
2213            uint8 style, i, ipattern[8];
2214            Pixmap fill;
2215    
2216            SET_FUNCTION(opcode);
2217    
2218            switch (fillmode)
2219            {
2220                    case ALTERNATE:
2221                            XSetFillRule(g_display, g_gc, EvenOddRule);
2222                            break;
2223                    case WINDING:
2224                            XSetFillRule(g_display, g_gc, WindingRule);
2225                            break;
2226                    default:
2227                            unimpl("fill mode %d\n", fillmode);
2228            }
2229    
2230            if (brush)
2231                    style = brush->style;
2232            else
2233                    style = 0;
2234    
2235            switch (style)
2236            {
2237                    case 0: /* Solid */
2238                            SET_FOREGROUND(fgcolour);
2239                            FILL_POLYGON((XPoint *) point, npoints);
2240                            break;
2241    
2242                    case 2: /* Hatch */
2243                            fill = (Pixmap) ui_create_glyph(8, 8,
2244                                                            hatch_patterns + brush->pattern[0] * 8);
2245                            SET_FOREGROUND(fgcolour);
2246                            SET_BACKGROUND(bgcolour);
2247                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2248                            XSetStipple(g_display, g_gc, fill);
2249                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2250                            FILL_POLYGON((XPoint *) point, npoints);
2251                            XSetFillStyle(g_display, g_gc, FillSolid);
2252                            XSetTSOrigin(g_display, g_gc, 0, 0);
2253                            ui_destroy_glyph((HGLYPH) fill);
2254                            break;
2255    
2256                    case 3: /* Pattern */
2257                            for (i = 0; i != 8; i++)
2258                                    ipattern[7 - i] = brush->pattern[i];
2259                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2260                            SET_FOREGROUND(bgcolour);
2261                            SET_BACKGROUND(fgcolour);
2262                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2263                            XSetStipple(g_display, g_gc, fill);
2264                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2265                            FILL_POLYGON((XPoint *) point, npoints);
2266                            XSetFillStyle(g_display, g_gc, FillSolid);
2267                            XSetTSOrigin(g_display, g_gc, 0, 0);
2268                            ui_destroy_glyph((HGLYPH) fill);
2269                            break;
2270    
2271                    default:
2272                            unimpl("brush %d\n", brush->style);
2273            }
2274    
2275            RESET_FUNCTION(opcode);
2276    }
2277    
2278    void
2279    ui_polyline(uint8 opcode,
2280                /* dest */ POINT * points, int npoints,
2281                /* pen */ PEN * pen)
2282    {
2283            /* TODO: set join style */
2284            SET_FUNCTION(opcode);
2285            SET_FOREGROUND(pen->colour);
2286            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2287            if (g_ownbackstore)
2288                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2289                               CoordModePrevious);
2290            RESET_FUNCTION(opcode);
2291    }
2292    
2293    void
2294    ui_ellipse(uint8 opcode,
2295               /* mode */ uint8 fillmode,
2296               /* dest */ int x, int y, int cx, int cy,
2297               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2298    {
2299            uint8 style, i, ipattern[8];
2300            Pixmap fill;
2301    
2302            SET_FUNCTION(opcode);
2303    
2304            if (brush)
2305                    style = brush->style;
2306            else
2307                    style = 0;
2308    
2309            switch (style)
2310            {
2311                    case 0: /* Solid */
2312                            SET_FOREGROUND(fgcolour);
2313                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2314                            break;
2315    
2316                    case 2: /* Hatch */
2317                            fill = (Pixmap) ui_create_glyph(8, 8,
2318                                                            hatch_patterns + brush->pattern[0] * 8);
2319                            SET_FOREGROUND(fgcolour);
2320                            SET_BACKGROUND(bgcolour);
2321                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2322                            XSetStipple(g_display, g_gc, fill);
2323                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2324                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2325                            XSetFillStyle(g_display, g_gc, FillSolid);
2326                            XSetTSOrigin(g_display, g_gc, 0, 0);
2327                            ui_destroy_glyph((HGLYPH) fill);
2328                            break;
2329    
2330                    case 3: /* Pattern */
2331                            for (i = 0; i != 8; i++)
2332                                    ipattern[7 - i] = brush->pattern[i];
2333                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2334                            SET_FOREGROUND(bgcolour);
2335                            SET_BACKGROUND(fgcolour);
2336                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2337                            XSetStipple(g_display, g_gc, fill);
2338                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2339                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2340                            XSetFillStyle(g_display, g_gc, FillSolid);
2341                            XSetTSOrigin(g_display, g_gc, 0, 0);
2342                            ui_destroy_glyph((HGLYPH) fill);
2343                            break;
2344    
2345                    default:
2346                            unimpl("brush %d\n", brush->style);
2347            }
2348    
2349            RESET_FUNCTION(opcode);
2350    }
2351    
2352  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2353  void  void
2354  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 2221  ui_draw_glyph(int mixmode, Line 2404  ui_draw_glyph(int mixmode,
2404  }  }
2405    
2406  void  void
2407  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y,
2408               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2409               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2410               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2411  {  {
2412            /* TODO: use brush appropriately */
2413    
2414          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2415          int i, j, xyoffset, x1, y1;          int i, j, xyoffset, x1, y1;
2416          DATABLOB *entry;          DATABLOB *entry;

Legend:
Removed from v.828  
changed lines
  Added in v.988

  ViewVC Help
Powered by ViewVC 1.1.26