/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/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 1033 by astrand, Tue Dec 27 08:58:57 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 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 1065  ui_init(void) Line 1091  ui_init(void)
1091          else if (g_width < 0)          else if (g_width < 0)
1092          {          {
1093                  /* Percent of screen */                  /* Percent of screen */
1094                    if (-g_width >= 100)
1095                            g_using_full_workarea = True;
1096                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1097                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1098          }          }
# Line 1072  ui_init(void) Line 1100  ui_init(void)
1100          {          {
1101                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1102                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
1103                    g_using_full_workarea = True;
1104    
1105                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1106                  {                  {
# Line 1138  ui_create_window(void) Line 1167  ui_create_window(void)
1167          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1168          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1169    
1170            /* Handle -x-y portion of geometry string */
1171            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1172                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1173            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1174                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1175    
1176          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1177          attribs.border_pixel = WhitePixelOfScreen(g_screen);          attribs.border_pixel = WhitePixelOfScreen(g_screen);
1178          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
# Line 1181  ui_create_window(void) Line 1216  ui_create_window(void)
1216          if (sizehints)          if (sizehints)
1217          {          {
1218                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1219                    if (g_pos)
1220                            sizehints->flags |= PPosition;
1221                  sizehints->min_width = sizehints->max_width = g_width;                  sizehints->min_width = sizehints->max_width = g_width;
1222                  sizehints->min_height = sizehints->max_height = g_height;                  sizehints->min_height = sizehints->max_height = g_height;
1223                  XSetWMNormalHints(g_display, g_wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
# Line 1193  ui_create_window(void) Line 1230  ui_create_window(void)
1230          }          }
1231    
1232          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1233                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1234    
1235          if (g_sendmotion)          if (g_sendmotion)
1236                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
# Line 1307  xwin_toggle_fullscreen(void) Line 1344  xwin_toggle_fullscreen(void)
1344          }          }
1345  }  }
1346    
1347  /* Process all events in Xlib queue  static void
1348    handle_button_event(XEvent xevent, BOOL down)
1349    {
1350            uint16 button, flags = 0;
1351            g_last_gesturetime = xevent.xbutton.time;
1352            button = xkeymap_translate_button(xevent.xbutton.button);
1353            if (button == 0)
1354                    return;
1355    
1356            if (down)
1357                    flags = MOUSE_FLAG_DOWN;
1358    
1359            /* Stop moving window when button is released, regardless of cursor position */
1360            if (g_moving_wnd && (xevent.type == ButtonRelease))
1361                    g_moving_wnd = False;
1362    
1363            /* If win_button_size is nonzero, enable single app mode */
1364            if (xevent.xbutton.y < g_win_button_size)
1365            {
1366                    /*  Check from right to left: */
1367                    if (xevent.xbutton.x >= g_width - g_win_button_size)
1368                    {
1369                            /* The close button, continue */
1370                            ;
1371                    }
1372                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 2)
1373                    {
1374                            /* The maximize/restore button. Do not send to
1375                               server.  It might be a good idea to change the
1376                               cursor or give some other visible indication
1377                               that rdesktop inhibited this click */
1378                            if (xevent.type == ButtonPress)
1379                                    return;
1380                    }
1381                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)
1382                    {
1383                            /* The minimize button. Iconify window. */
1384                            if (xevent.type == ButtonRelease)
1385                            {
1386                                    /* Release the mouse button outside the minimize button, to prevent the
1387                                       actual minimazation to happen */
1388                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1389                                    XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));
1390                                    return;
1391                            }
1392                    }
1393                    else if (xevent.xbutton.x <= g_win_button_size)
1394                    {
1395                            /* The system menu. Ignore. */
1396                            if (xevent.type == ButtonPress)
1397                                    return;
1398                    }
1399                    else
1400                    {
1401                            /* The title bar. */
1402                            if (xevent.type == ButtonPress)
1403                            {
1404                                    if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea)
1405                                    {
1406                                            g_moving_wnd = True;
1407                                            g_move_x_offset = xevent.xbutton.x;
1408                                            g_move_y_offset = xevent.xbutton.y;
1409                                    }
1410                                    return;
1411                            }
1412                    }
1413            }
1414    
1415            rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1416                           flags | button, xevent.xbutton.x, xevent.xbutton.y);
1417    }
1418    
1419    /* Process events in Xlib queue
1420     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1421  static int  static int
1422  xwin_process_events(void)  xwin_process_events(void)
1423  {  {
1424          XEvent xevent;          XEvent xevent;
1425          KeySym keysym;          KeySym keysym;
         uint16 button, flags;  
1426          uint32 ev_time;          uint32 ev_time;
         key_translation tr;  
1427          char str[256];          char str[256];
1428          Status status;          Status status;
1429            int events = 0;
1430    
1431          while (XPending(g_display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1432          {          {
1433                  XNextEvent(g_display, &xevent);                  XNextEvent(g_display, &xevent);
1434    
# Line 1330  xwin_process_events(void) Line 1438  xwin_process_events(void)
1438                          continue;                          continue;
1439                  }                  }
1440    
                 flags = 0;  
   
1441                  switch (xevent.type)                  switch (xevent.type)
1442                  {                  {
1443                          case VisibilityNotify:                          case VisibilityNotify:
# Line 1368  xwin_process_events(void) Line 1474  xwin_process_events(void)
1474                                                        str, sizeof(str), &keysym, NULL);                                                        str, sizeof(str), &keysym, NULL);
1475                                  }                                  }
1476    
1477                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1478                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1479    
1480                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1481                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1482                                          break;                                          break;
1483    
1484                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1485                                                             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);  
   
1486                                  break;                                  break;
1487    
1488                          case KeyRelease:                          case KeyRelease:
# Line 1393  xwin_process_events(void) Line 1490  xwin_process_events(void)
1490                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1491                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1492    
1493                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1494                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1495    
1496                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1497                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1498                                          break;                                          break;
1499    
1500                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1501                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, False, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);  
1502                                  break;                                  break;
1503    
1504                          case ButtonPress:                          case ButtonPress:
1505                                  flags = MOUSE_FLAG_DOWN;                                  handle_button_event(xevent, True);
1506                                  /* fall through */                                  break;
1507    
1508                          case ButtonRelease:                          case ButtonRelease:
1509                                  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);  
1510                                  break;                                  break;
1511    
1512                          case MotionNotify:                          case MotionNotify:
# Line 1564  xwin_process_events(void) Line 1599  xwin_process_events(void)
1599                          case PropertyNotify:                          case PropertyNotify:
1600                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1601                                  break;                                  break;
1602                            case MapNotify:
1603                                    rdp_send_client_window_status(1);
1604                                    break;
1605                            case UnmapNotify:
1606                                    rdp_send_client_window_status(0);
1607                                    break;
1608                  }                  }
1609          }          }
1610          /* Keep going */          /* Keep going */
# Line 2166  ui_rect( Line 2207  ui_rect(
2207          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2208  }  }
2209    
2210    void
2211    ui_polygon(uint8 opcode,
2212               /* mode */ uint8 fillmode,
2213               /* dest */ POINT * point, int npoints,
2214               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2215    {
2216            uint8 style, i, ipattern[8];
2217            Pixmap fill;
2218    
2219            SET_FUNCTION(opcode);
2220    
2221            switch (fillmode)
2222            {
2223                    case ALTERNATE:
2224                            XSetFillRule(g_display, g_gc, EvenOddRule);
2225                            break;
2226                    case WINDING:
2227                            XSetFillRule(g_display, g_gc, WindingRule);
2228                            break;
2229                    default:
2230                            unimpl("fill mode %d\n", fillmode);
2231            }
2232    
2233            if (brush)
2234                    style = brush->style;
2235            else
2236                    style = 0;
2237    
2238            switch (style)
2239            {
2240                    case 0: /* Solid */
2241                            SET_FOREGROUND(fgcolour);
2242                            FILL_POLYGON((XPoint *) point, npoints);
2243                            break;
2244    
2245                    case 2: /* Hatch */
2246                            fill = (Pixmap) ui_create_glyph(8, 8,
2247                                                            hatch_patterns + brush->pattern[0] * 8);
2248                            SET_FOREGROUND(fgcolour);
2249                            SET_BACKGROUND(bgcolour);
2250                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2251                            XSetStipple(g_display, g_gc, fill);
2252                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2253                            FILL_POLYGON((XPoint *) point, npoints);
2254                            XSetFillStyle(g_display, g_gc, FillSolid);
2255                            XSetTSOrigin(g_display, g_gc, 0, 0);
2256                            ui_destroy_glyph((HGLYPH) fill);
2257                            break;
2258    
2259                    case 3: /* Pattern */
2260                            for (i = 0; i != 8; i++)
2261                                    ipattern[7 - i] = brush->pattern[i];
2262                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2263                            SET_FOREGROUND(bgcolour);
2264                            SET_BACKGROUND(fgcolour);
2265                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2266                            XSetStipple(g_display, g_gc, fill);
2267                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2268                            FILL_POLYGON((XPoint *) point, npoints);
2269                            XSetFillStyle(g_display, g_gc, FillSolid);
2270                            XSetTSOrigin(g_display, g_gc, 0, 0);
2271                            ui_destroy_glyph((HGLYPH) fill);
2272                            break;
2273    
2274                    default:
2275                            unimpl("brush %d\n", brush->style);
2276            }
2277    
2278            RESET_FUNCTION(opcode);
2279    }
2280    
2281    void
2282    ui_polyline(uint8 opcode,
2283                /* dest */ POINT * points, int npoints,
2284                /* pen */ PEN * pen)
2285    {
2286            /* TODO: set join style */
2287            SET_FUNCTION(opcode);
2288            SET_FOREGROUND(pen->colour);
2289            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2290            if (g_ownbackstore)
2291                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2292                               CoordModePrevious);
2293            RESET_FUNCTION(opcode);
2294    }
2295    
2296    void
2297    ui_ellipse(uint8 opcode,
2298               /* mode */ uint8 fillmode,
2299               /* dest */ int x, int y, int cx, int cy,
2300               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2301    {
2302            uint8 style, i, ipattern[8];
2303            Pixmap fill;
2304    
2305            SET_FUNCTION(opcode);
2306    
2307            if (brush)
2308                    style = brush->style;
2309            else
2310                    style = 0;
2311    
2312            switch (style)
2313            {
2314                    case 0: /* Solid */
2315                            SET_FOREGROUND(fgcolour);
2316                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2317                            break;
2318    
2319                    case 2: /* Hatch */
2320                            fill = (Pixmap) ui_create_glyph(8, 8,
2321                                                            hatch_patterns + brush->pattern[0] * 8);
2322                            SET_FOREGROUND(fgcolour);
2323                            SET_BACKGROUND(bgcolour);
2324                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2325                            XSetStipple(g_display, g_gc, fill);
2326                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2327                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2328                            XSetFillStyle(g_display, g_gc, FillSolid);
2329                            XSetTSOrigin(g_display, g_gc, 0, 0);
2330                            ui_destroy_glyph((HGLYPH) fill);
2331                            break;
2332    
2333                    case 3: /* Pattern */
2334                            for (i = 0; i != 8; i++)
2335                                    ipattern[7 - i] = brush->pattern[i];
2336                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2337                            SET_FOREGROUND(bgcolour);
2338                            SET_BACKGROUND(fgcolour);
2339                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2340                            XSetStipple(g_display, g_gc, fill);
2341                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2342                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2343                            XSetFillStyle(g_display, g_gc, FillSolid);
2344                            XSetTSOrigin(g_display, g_gc, 0, 0);
2345                            ui_destroy_glyph((HGLYPH) fill);
2346                            break;
2347    
2348                    default:
2349                            unimpl("brush %d\n", brush->style);
2350            }
2351    
2352            RESET_FUNCTION(opcode);
2353    }
2354    
2355  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2356  void  void
2357  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 2221  ui_draw_glyph(int mixmode, Line 2407  ui_draw_glyph(int mixmode,
2407  }  }
2408    
2409  void  void
2410  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,
2411               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2412               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2413               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2414  {  {
2415            /* TODO: use brush appropriately */
2416    
2417          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2418          int i, j, xyoffset, x1, y1;          int i, j, xyoffset, x1, y1;
2419          DATABLOB *entry;          DATABLOB *entry;
# Line 2257  ui_draw_text(uint8 font, uint8 flags, in Line 2445  ui_draw_text(uint8 font, uint8 flags, in
2445                  switch (text[i])                  switch (text[i])
2446                  {                  {
2447                          case 0xff:                          case 0xff:
2448                                  if (i + 2 < length)                                  /* At least two bytes needs to follow */
2449                                          cache_put_text(text[i + 1], text, text[i + 2]);                                  if (i + 3 > length)
                                 else  
2450                                  {                                  {
2451                                          error("this shouldn't be happening\n");                                          warning("Skipping short 0xff command:");
2452                                          exit(1);                                          for (j = 0; j < length; j++)
2453                                                    fprintf(stderr, "%02x ", text[j]);
2454                                            fprintf(stderr, "\n");
2455                                            i = length = 0;
2456                                            break;
2457                                  }                                  }
2458                                    cache_put_text(text[i + 1], text, text[i + 2]);
2459                                    i += 3;
2460                                    length -= i;
2461                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
2462                                  length -= i + 3;                                  text = &(text[i]);
                                 text = &(text[i + 3]);  
2463                                  i = 0;                                  i = 0;
2464                                  break;                                  break;
2465    
2466                          case 0xfe:                          case 0xfe:
2467                                    /* At least one byte needs to follow */
2468                                    if (i + 2 > length)
2469                                    {
2470                                            warning("Skipping short 0xfe command:");
2471                                            for (j = 0; j < length; j++)
2472                                                    fprintf(stderr, "%02x ", text[j]);
2473                                            fprintf(stderr, "\n");
2474                                            i = length = 0;
2475                                            break;
2476                                    }
2477                                  entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
2478                                  if (entry != NULL)                                  if (entry->data != NULL)
2479                                  {                                  {
2480                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] == 0)
2481                                               0) && (!(flags & TEXT2_IMPLICIT_X)))                                              && (!(flags & TEXT2_IMPLICIT_X)) && (i + 2 < length))
2482                                          {                                          {
2483                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
2484                                                          y += text[i + 2];                                                          y += text[i + 2];

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

  ViewVC Help
Powered by ViewVC 1.1.26