/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

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

revision 821 by jdmeijer, Mon Feb 28 01:15:45 2005 UTC revision 1041 by astrand, Tue Jan 24 12:25:49 2006 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Matthew Chapman 1999-2005
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     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
# 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 78  static Pixmap g_backstore = 0; Line 79  static Pixmap g_backstore = 0;
79  static BOOL g_moving_wnd;  static BOOL g_moving_wnd;
80  static int g_move_x_offset = 0;  static int g_move_x_offset = 0;
81  static int g_move_y_offset = 0;  static int g_move_y_offset = 0;
82    static BOOL g_using_full_workarea = False;
83    
84  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
85  extern int g_dsp_fd;  extern int g_dsp_fd;
# Line 90  extern BOOL g_rdpsnd; Line 92  extern BOOL g_rdpsnd;
92  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
93  typedef struct  typedef struct
94  {  {
95          uint32 flags;          unsigned long flags;
96          uint32 functions;          unsigned long functions;
97          uint32 decorations;          unsigned long decorations;
98          sint32 inputMode;          long inputMode;
99          uint32 status;          unsigned long status;
100  }  }
101  PropMotifWmHints;  PropMotifWmHints;
102    
# Line 119  PixelColour; Line 121  PixelColour;
121          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); \
122  }  }
123    
124    #define FILL_POLYGON(p,np)\
125    { \
126            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
127            if (g_ownbackstore) \
128                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
129    }
130    
131    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
132    { \
133            switch (m) \
134            { \
135                    case 0: /* Outline */ \
136                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
137                            if (g_ownbackstore) \
138                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
139                            break; \
140                    case 1: /* Filled */ \
141                            XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
142                            if (g_ownbackstore) \
143                                    XFillArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
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 662  translate16to32(const uint16 * data, uin Line 688  translate16to32(const uint16 * data, uin
688                  }                  }
689                  else                  else
690                  {                  {
691                            while (out < end)
692                          {                          {
693                                  pixel = *(data++);                                  pixel = *(data++);
694                                  SPLITCOLOUR16(pixel, pc);                                  SPLITCOLOUR16(pixel, pc);
# Line 764  translate24to32(const uint8 * data, uint Line 791  translate24to32(const uint8 * data, uint
791          if (g_arch_match)          if (g_arch_match)
792          {          {
793                  /* *INDENT-OFF* */                  /* *INDENT-OFF* */
794    #ifdef NEED_ALIGN
795                  REPEAT4                  REPEAT4
796                  (                  (
 #ifdef NEED_ALIGN  
797                          *(out++) = *(data++);                          *(out++) = *(data++);
798                          *(out++) = *(data++);                          *(out++) = *(data++);
799                          *(out++) = *(data++);                          *(out++) = *(data++);
800                          *(out++) = 0;                          *(out++) = 0;
801                    )
802  #else  #else
803                          *((uint32 *) out) = *((uint32 *) data);                  REPEAT4
804                          out += 4;                  (
805                          data += 3;                   /* Only read 3 bytes. Reading 4 bytes means reading beyond buffer. */
806  #endif                   *((uint32 *) out) = *((uint16 *) data) + (*((uint8 *) data + 2) << 16);
807                     out += 4;
808                     data += 3;
809                  )                  )
810    #endif
811                  /* *INDENT-ON* */                  /* *INDENT-ON* */
812          }          }
813          else if (g_xserver_be)          else if (g_xserver_be)
# Line 1061  ui_init(void) Line 1092  ui_init(void)
1092          else if (g_width < 0)          else if (g_width < 0)
1093          {          {
1094                  /* Percent of screen */                  /* Percent of screen */
1095                    if (-g_width >= 100)
1096                            g_using_full_workarea = True;
1097                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1098                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1099          }          }
# Line 1068  ui_init(void) Line 1101  ui_init(void)
1101          {          {
1102                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1103                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
1104                    g_using_full_workarea = True;
1105    
1106                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1107                  {                  {
# Line 1134  ui_create_window(void) Line 1168  ui_create_window(void)
1168          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1169          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1170    
1171            /* Handle -x-y portion of geometry string */
1172            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1173                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1174            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1175                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1176    
1177          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1178          attribs.border_pixel = WhitePixelOfScreen(g_screen);          attribs.border_pixel = WhitePixelOfScreen(g_screen);
1179          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
# Line 1177  ui_create_window(void) Line 1217  ui_create_window(void)
1217          if (sizehints)          if (sizehints)
1218          {          {
1219                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1220                    if (g_pos)
1221                            sizehints->flags |= PPosition;
1222                  sizehints->min_width = sizehints->max_width = g_width;                  sizehints->min_width = sizehints->max_width = g_width;
1223                  sizehints->min_height = sizehints->max_height = g_height;                  sizehints->min_height = sizehints->max_height = g_height;
1224                  XSetWMNormalHints(g_display, g_wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
# Line 1189  ui_create_window(void) Line 1231  ui_create_window(void)
1231          }          }
1232    
1233          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1234                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1235    
1236          if (g_sendmotion)          if (g_sendmotion)
1237                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
# Line 1303  xwin_toggle_fullscreen(void) Line 1345  xwin_toggle_fullscreen(void)
1345          }          }
1346  }  }
1347    
1348  /* Process all events in Xlib queue  static void
1349    handle_button_event(XEvent xevent, BOOL down)
1350    {
1351            uint16 button, flags = 0;
1352            g_last_gesturetime = xevent.xbutton.time;
1353            button = xkeymap_translate_button(xevent.xbutton.button);
1354            if (button == 0)
1355                    return;
1356    
1357            if (down)
1358                    flags = MOUSE_FLAG_DOWN;
1359    
1360            /* Stop moving window when button is released, regardless of cursor position */
1361            if (g_moving_wnd && (xevent.type == ButtonRelease))
1362                    g_moving_wnd = False;
1363    
1364            /* If win_button_size is nonzero, enable single app mode */
1365            if (xevent.xbutton.y < g_win_button_size)
1366            {
1367                    /*  Check from right to left: */
1368                    if (xevent.xbutton.x >= g_width - g_win_button_size)
1369                    {
1370                            /* The close button, continue */
1371                            ;
1372                    }
1373                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 2)
1374                    {
1375                            /* The maximize/restore button. Do not send to
1376                               server.  It might be a good idea to change the
1377                               cursor or give some other visible indication
1378                               that rdesktop inhibited this click */
1379                            if (xevent.type == ButtonPress)
1380                                    return;
1381                    }
1382                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)
1383                    {
1384                            /* The minimize button. Iconify window. */
1385                            if (xevent.type == ButtonRelease)
1386                            {
1387                                    /* Release the mouse button outside the minimize button, to prevent the
1388                                       actual minimazation to happen */
1389                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1390                                    XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));
1391                                    return;
1392                            }
1393                    }
1394                    else if (xevent.xbutton.x <= g_win_button_size)
1395                    {
1396                            /* The system menu. Ignore. */
1397                            if (xevent.type == ButtonPress)
1398                                    return;
1399                    }
1400                    else
1401                    {
1402                            /* The title bar. */
1403                            if (xevent.type == ButtonPress)
1404                            {
1405                                    if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea)
1406                                    {
1407                                            g_moving_wnd = True;
1408                                            g_move_x_offset = xevent.xbutton.x;
1409                                            g_move_y_offset = xevent.xbutton.y;
1410                                    }
1411                                    return;
1412                            }
1413                    }
1414            }
1415    
1416            rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1417                           flags | button, xevent.xbutton.x, xevent.xbutton.y);
1418    }
1419    
1420    /* Process events in Xlib queue
1421     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1422  static int  static int
1423  xwin_process_events(void)  xwin_process_events(void)
1424  {  {
1425          XEvent xevent;          XEvent xevent;
1426          KeySym keysym;          KeySym keysym;
         uint16 button, flags;  
1427          uint32 ev_time;          uint32 ev_time;
         key_translation tr;  
1428          char str[256];          char str[256];
1429          Status status;          Status status;
1430            int events = 0;
1431    
1432          while (XPending(g_display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1433          {          {
1434                  XNextEvent(g_display, &xevent);                  XNextEvent(g_display, &xevent);
1435    
# Line 1326  xwin_process_events(void) Line 1439  xwin_process_events(void)
1439                          continue;                          continue;
1440                  }                  }
1441    
                 flags = 0;  
   
1442                  switch (xevent.type)                  switch (xevent.type)
1443                  {                  {
1444                          case VisibilityNotify:                          case VisibilityNotify:
# Line 1364  xwin_process_events(void) Line 1475  xwin_process_events(void)
1475                                                        str, sizeof(str), &keysym, NULL);                                                        str, sizeof(str), &keysym, NULL);
1476                                  }                                  }
1477    
1478                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1479                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1480    
1481                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1482                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1483                                          break;                                          break;
1484    
1485                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1486                                                             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);  
   
1487                                  break;                                  break;
1488    
1489                          case KeyRelease:                          case KeyRelease:
# Line 1389  xwin_process_events(void) Line 1491  xwin_process_events(void)
1491                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1492                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1493    
1494                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1495                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1496    
1497                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1498                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1499                                          break;                                          break;
1500    
1501                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1502                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, False, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);  
1503                                  break;                                  break;
1504    
1505                          case ButtonPress:                          case ButtonPress:
1506                                  flags = MOUSE_FLAG_DOWN;                                  handle_button_event(xevent, True);
1507                                  /* fall through */                                  break;
1508    
1509                          case ButtonRelease:                          case ButtonRelease:
1510                                  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);  
1511                                  break;                                  break;
1512    
1513                          case MotionNotify:                          case MotionNotify:
# Line 1560  xwin_process_events(void) Line 1600  xwin_process_events(void)
1600                          case PropertyNotify:                          case PropertyNotify:
1601                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1602                                  break;                                  break;
1603                            case MapNotify:
1604                                    rdp_send_client_window_status(1);
1605                                    break;
1606                            case UnmapNotify:
1607                                    rdp_send_client_window_status(0);
1608                                    break;
1609                  }                  }
1610          }          }
1611          /* Keep going */          /* Keep going */
# Line 2162  ui_rect( Line 2208  ui_rect(
2208          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2209  }  }
2210    
2211    void
2212    ui_polygon(uint8 opcode,
2213               /* mode */ uint8 fillmode,
2214               /* dest */ POINT * point, int npoints,
2215               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2216    {
2217            uint8 style, i, ipattern[8];
2218            Pixmap fill;
2219    
2220            SET_FUNCTION(opcode);
2221    
2222            switch (fillmode)
2223            {
2224                    case ALTERNATE:
2225                            XSetFillRule(g_display, g_gc, EvenOddRule);
2226                            break;
2227                    case WINDING:
2228                            XSetFillRule(g_display, g_gc, WindingRule);
2229                            break;
2230                    default:
2231                            unimpl("fill mode %d\n", fillmode);
2232            }
2233    
2234            if (brush)
2235                    style = brush->style;
2236            else
2237                    style = 0;
2238    
2239            switch (style)
2240            {
2241                    case 0: /* Solid */
2242                            SET_FOREGROUND(fgcolour);
2243                            FILL_POLYGON((XPoint *) point, npoints);
2244                            break;
2245    
2246                    case 2: /* Hatch */
2247                            fill = (Pixmap) ui_create_glyph(8, 8,
2248                                                            hatch_patterns + brush->pattern[0] * 8);
2249                            SET_FOREGROUND(fgcolour);
2250                            SET_BACKGROUND(bgcolour);
2251                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2252                            XSetStipple(g_display, g_gc, fill);
2253                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2254                            FILL_POLYGON((XPoint *) point, npoints);
2255                            XSetFillStyle(g_display, g_gc, FillSolid);
2256                            XSetTSOrigin(g_display, g_gc, 0, 0);
2257                            ui_destroy_glyph((HGLYPH) fill);
2258                            break;
2259    
2260                    case 3: /* Pattern */
2261                            for (i = 0; i != 8; i++)
2262                                    ipattern[7 - i] = brush->pattern[i];
2263                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2264                            SET_FOREGROUND(bgcolour);
2265                            SET_BACKGROUND(fgcolour);
2266                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2267                            XSetStipple(g_display, g_gc, fill);
2268                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2269                            FILL_POLYGON((XPoint *) point, npoints);
2270                            XSetFillStyle(g_display, g_gc, FillSolid);
2271                            XSetTSOrigin(g_display, g_gc, 0, 0);
2272                            ui_destroy_glyph((HGLYPH) fill);
2273                            break;
2274    
2275                    default:
2276                            unimpl("brush %d\n", brush->style);
2277            }
2278    
2279            RESET_FUNCTION(opcode);
2280    }
2281    
2282    void
2283    ui_polyline(uint8 opcode,
2284                /* dest */ POINT * points, int npoints,
2285                /* pen */ PEN * pen)
2286    {
2287            /* TODO: set join style */
2288            SET_FUNCTION(opcode);
2289            SET_FOREGROUND(pen->colour);
2290            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2291            if (g_ownbackstore)
2292                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2293                               CoordModePrevious);
2294            RESET_FUNCTION(opcode);
2295    }
2296    
2297    void
2298    ui_ellipse(uint8 opcode,
2299               /* mode */ uint8 fillmode,
2300               /* dest */ int x, int y, int cx, int cy,
2301               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2302    {
2303            uint8 style, i, ipattern[8];
2304            Pixmap fill;
2305    
2306            SET_FUNCTION(opcode);
2307    
2308            if (brush)
2309                    style = brush->style;
2310            else
2311                    style = 0;
2312    
2313            switch (style)
2314            {
2315                    case 0: /* Solid */
2316                            SET_FOREGROUND(fgcolour);
2317                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2318                            break;
2319    
2320                    case 2: /* Hatch */
2321                            fill = (Pixmap) ui_create_glyph(8, 8,
2322                                                            hatch_patterns + brush->pattern[0] * 8);
2323                            SET_FOREGROUND(fgcolour);
2324                            SET_BACKGROUND(bgcolour);
2325                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2326                            XSetStipple(g_display, g_gc, fill);
2327                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2328                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2329                            XSetFillStyle(g_display, g_gc, FillSolid);
2330                            XSetTSOrigin(g_display, g_gc, 0, 0);
2331                            ui_destroy_glyph((HGLYPH) fill);
2332                            break;
2333    
2334                    case 3: /* Pattern */
2335                            for (i = 0; i != 8; i++)
2336                                    ipattern[7 - i] = brush->pattern[i];
2337                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2338                            SET_FOREGROUND(bgcolour);
2339                            SET_BACKGROUND(fgcolour);
2340                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2341                            XSetStipple(g_display, g_gc, fill);
2342                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2343                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2344                            XSetFillStyle(g_display, g_gc, FillSolid);
2345                            XSetTSOrigin(g_display, g_gc, 0, 0);
2346                            ui_destroy_glyph((HGLYPH) fill);
2347                            break;
2348    
2349                    default:
2350                            unimpl("brush %d\n", brush->style);
2351            }
2352    
2353            RESET_FUNCTION(opcode);
2354    }
2355    
2356  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2357  void  void
2358  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 2217  ui_draw_glyph(int mixmode, Line 2408  ui_draw_glyph(int mixmode,
2408  }  }
2409    
2410  void  void
2411  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,
2412               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2413               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2414               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2415  {  {
2416            /* TODO: use brush appropriately */
2417    
2418          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2419          int i, j, xyoffset, x1, y1;          int i, j, xyoffset, x1, y1;
2420          DATABLOB *entry;          DATABLOB *entry;
# Line 2253  ui_draw_text(uint8 font, uint8 flags, in Line 2446  ui_draw_text(uint8 font, uint8 flags, in
2446                  switch (text[i])                  switch (text[i])
2447                  {                  {
2448                          case 0xff:                          case 0xff:
2449                                  if (i + 2 < length)                                  /* At least two bytes needs to follow */
2450                                          cache_put_text(text[i + 1], text, text[i + 2]);                                  if (i + 3 > length)
                                 else  
2451                                  {                                  {
2452                                          error("this shouldn't be happening\n");                                          warning("Skipping short 0xff command:");
2453                                          exit(1);                                          for (j = 0; j < length; j++)
2454                                                    fprintf(stderr, "%02x ", text[j]);
2455                                            fprintf(stderr, "\n");
2456                                            i = length = 0;
2457                                            break;
2458                                  }                                  }
2459                                    cache_put_text(text[i + 1], text, text[i + 2]);
2460                                    i += 3;
2461                                    length -= i;
2462                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
2463                                  length -= i + 3;                                  text = &(text[i]);
                                 text = &(text[i + 3]);  
2464                                  i = 0;                                  i = 0;
2465                                  break;                                  break;
2466    
2467                          case 0xfe:                          case 0xfe:
2468                                    /* At least one byte needs to follow */
2469                                    if (i + 2 > length)
2470                                    {
2471                                            warning("Skipping short 0xfe command:");
2472                                            for (j = 0; j < length; j++)
2473                                                    fprintf(stderr, "%02x ", text[j]);
2474                                            fprintf(stderr, "\n");
2475                                            i = length = 0;
2476                                            break;
2477                                    }
2478                                  entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
2479                                  if (entry != NULL)                                  if (entry->data != NULL)
2480                                  {                                  {
2481                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] == 0)
2482                                               0) && (!(flags & TEXT2_IMPLICIT_X)))                                              && (!(flags & TEXT2_IMPLICIT_X)) && (i + 2 < length))
2483                                          {                                          {
2484                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
2485                                                          y += text[i + 2];                                                          y += text[i + 2];

Legend:
Removed from v.821  
changed lines
  Added in v.1041

  ViewVC Help
Powered by ViewVC 1.1.26