/[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 28 by matty, Wed Jun 20 13:54:48 2001 UTC revision 29 by matty, Fri Sep 14 03:38:39 2001 UTC
# Line 25  Line 25 
25    
26  extern int width;  extern int width;
27  extern int height;  extern int height;
28  extern BOOL motion;  extern BOOL sendmotion;
 extern BOOL grab_keyboard;  
29  extern BOOL fullscreen;  extern BOOL fullscreen;
 extern int private_colormap;  
30    
 static int bpp;  
 static int depth;  
31  static Display *display;  static Display *display;
32  static Window wnd;  static Window wnd;
33  static GC gc;  static GC gc;
34  static Visual *visual;  static Visual *visual;
35  static uint32 *colmap;  static int depth;
36    static int bpp;
37  #define Ctrans(col) ( private_colormap ? col : colmap[col])  static BOOL backpixmap;
38    
39  #define L_ENDIAN  static BOOL owncolmap;
40  int screen_msbfirst = 0;  static Colormap xcolmap;
41    static uint32 white;
42    static uint32 *colmap;
43    
44  static uint8 *translate(int width, int height, uint8 *data);  #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )
45    #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
46    #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
47    
48  static int rop2_map[] = {  static int rop2_map[] = {
49          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 64  static int rop2_map[] = { Line 64  static int rop2_map[] = {
64          GXset                   /* 1 */          GXset                   /* 1 */
65  };  };
66    
67    #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
68    #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
69    
70    static void
71    translate8(uint8 *data, uint8 *out, uint8 *end)
72    {
73            while (out < end)
74                    *(out++) = (uint8)colmap[*(data++)];
75    }
76    
77  static void  static void
78  xwin_set_function(uint8 rop2)  translate16(uint8 *data, uint16 *out, uint16 *end)
79  {  {
80          static uint8 last_rop2 = ROP2_COPY;          while (out < end)
81                    *(out++) = (uint16)colmap[*(data++)];
82    }
83    
84          if (last_rop2 != rop2)  /* XXX endianness */
85    static void
86    translate24(uint8 *data, uint8 *out, uint8 *end)
87    {
88            uint32 value;
89    
90            while (out < end)
91          {          {
92                  XSetFunction(display, gc, rop2_map[rop2]);                  value = colmap[*(data++)];
93                  last_rop2 = rop2;                  *(out++) = value;
94                    *(out++) = value >> 8;
95                    *(out++) = value >> 16;
96          }          }
97  }  }
98    
99  static void  static void
100  xwin_grab_keyboard()  translate32(uint8 *data, uint32 *out, uint32 *end)
101  {  {
102          XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,          while (out < end)
103                        CurrentTime);                  *(out++) = colmap[*(data++)];
104  }  }
105    
106  static void  static uint8 *
107  xwin_ungrab_keyboard()  translate(int width, int height, uint8 *data)
108  {  {
109          XUngrabKeyboard(display, CurrentTime);          int size = width * height * bpp/8;
110            uint8 *out = xmalloc(size);
111            uint8 *end = out + size;
112    
113            switch (bpp)
114            {
115                    case 8:
116                            translate8(data, out, end);
117                            break;
118    
119                    case 16:
120                            translate16(data, (uint16 *)out, (uint16 *)end);
121                            break;
122    
123                    case 24:
124                            translate24(data, out, end);
125                            break;
126    
127                    case 32:
128                            translate32(data, (uint32 *)out, (uint32 *)end);
129                            break;
130            }
131    
132            return out;
133  }  }
134    
135    #define L_ENDIAN
136    int screen_msbfirst = 0;
137    
138    
139  BOOL  BOOL
140  ui_create_window(char *title)  ui_create_window(char *title)
141  {  {
# Line 97  ui_create_window(char *title) Line 144  ui_create_window(char *title)
144          XSizeHints *sizehints;          XSizeHints *sizehints;
145          unsigned long input_mask;          unsigned long input_mask;
146          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
147          int count;          Screen *screen;
148            int i;
149    
150    
151          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
152          if (display == NULL)          if (display == NULL)
# Line 106  ui_create_window(char *title) Line 155  ui_create_window(char *title)
155                  return False;                  return False;
156          }          }
157    
158          visual = DefaultVisual(display, DefaultScreen(display));          screen = DefaultScreenOfDisplay(display);
159          depth = DefaultDepth(display, DefaultScreen(display));          visual = DefaultVisualOfScreen(screen);
160          pfm = XListPixmapFormats(display, &count);          depth = DefaultDepthOfScreen(screen);
161    
162            pfm = XListPixmapFormats(display, &i);
163          if (pfm != NULL)          if (pfm != NULL)
164          {          {
165                  while (count--)                  /* Use maximum bpp for this depth - this is generally
166                       desirable, e.g. 24 bits->32 bits. */
167                    while (i--)
168                  {                  {
169                          if ((pfm + count)->depth == depth                          if ((pfm[i].depth == depth)
170                              && (pfm + count)->bits_per_pixel > bpp)                              && (pfm[i].bits_per_pixel > bpp))
171                          {                          {
172                                  bpp = (pfm + count)->bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
173                          }                          }
174                  }                  }
175                  XFree(pfm);                  XFree(pfm);
# Line 129  ui_create_window(char *title) Line 182  ui_create_window(char *title)
182                  return False;                  return False;
183          }          }
184    
185          width &= ~3; /* make width nicely divisible */          if (depth <= 8)
186                    owncolmap = True;
187            else
188                    xcolmap = DefaultColormapOfScreen(screen);
189    
190            white = WhitePixelOfScreen(screen);
191            attribs.background_pixel = BlackPixelOfScreen(screen);
192            attribs.backing_store = DoesBackingStore(screen);
193    
194          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          if (attribs.backing_store == NotUseful)
195          attribs.backing_store = Always;                  backpixmap = True;
196    
197          if (fullscreen)          if (fullscreen)
198          {          {
199                  attribs.override_redirect = True;                  attribs.override_redirect = True;
200                  width = WidthOfScreen(DefaultScreenOfDisplay(display));                  width = WidthOfScreen(screen);
201                  height = HeightOfScreen(DefaultScreenOfDisplay(display));                  height = HeightOfScreen(screen);
                 XSetInputFocus(display, PointerRoot, RevertToPointerRoot,  
                                CurrentTime);  
202          }          }
203          else          else
204          {          {
205                  attribs.override_redirect = False;                  attribs.override_redirect = False;
206          }          }
207    
208          wnd = XCreateWindow(display, DefaultRootWindow(display),          width &= ~3; /* make width a multiple of 32 bits */
209    
210            wnd = XCreateWindow(display, RootWindowOfScreen(screen),
211                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
212                              InputOutput, CopyFromParent,                              InputOutput, CopyFromParent,
213                              CWBackingStore | CWBackPixel | CWOverrideRedirect,                              CWBackingStore | CWBackPixel | CWOverrideRedirect,
# Line 157  ui_create_window(char *title) Line 217  ui_create_window(char *title)
217    
218          classhints = XAllocClassHint();          classhints = XAllocClassHint();
219          if (classhints != NULL)          if (classhints != NULL)
   
220          {          {
221                  classhints->res_name = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
                 classhints->res_class = "rdesktop";  
222                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(display, wnd, classhints);
223                  XFree(classhints);                  XFree(classhints);
224          }          }
# Line 168  ui_create_window(char *title) Line 226  ui_create_window(char *title)
226          sizehints = XAllocSizeHints();          sizehints = XAllocSizeHints();
227          if (sizehints)          if (sizehints)
228          {          {
229                  sizehints->flags =                  sizehints->flags = PMinSize | PMaxSize;
230                          PPosition | PSize | PMinSize | PMaxSize | PBaseSize;                  sizehints->min_width = sizehints->max_width = width;
231                  sizehints->min_width = width;                  sizehints->min_height = sizehints->max_height = height;
                 sizehints->max_width = width;  
                 sizehints->min_height = height;  
                 sizehints->max_height = height;  
                 sizehints->base_width = width;  
                 sizehints->base_height = height;  
232                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(display, wnd, sizehints);
233                  XFree(sizehints);                  XFree(sizehints);
234          }          }
235    
236          input_mask = KeyPressMask | KeyReleaseMask;          input_mask = KeyPressMask | KeyReleaseMask
237          input_mask |= ButtonPressMask | ButtonReleaseMask;                          | ButtonPressMask | ButtonReleaseMask
238          if (motion)                          | EnterWindowMask | LeaveWindowMask;
239    
240            if (sendmotion)
241                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
         if (grab_keyboard)  
                 input_mask |= EnterWindowMask | LeaveWindowMask;  
242    
243          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
244          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
# Line 338  ui_process_events() Line 391  ui_process_events()
391                                  break;                                  break;
392    
393                          case EnterNotify:                          case EnterNotify:
394                                  if (grab_keyboard)                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,
395                                          xwin_grab_keyboard();                                                GrabModeAsync, CurrentTime);
396                                  break;                                  break;
397    
398                          case LeaveNotify:                          case LeaveNotify:
399                                  if (grab_keyboard)                                  XUngrabKeyboard(display, CurrentTime);
                                         xwin_ungrab_keyboard();  
400                                  break;                                  break;
401                  }                  }
402          }          }
# Line 362  ui_create_bitmap(int width, int height, Line 414  ui_create_bitmap(int width, int height,
414          XImage *image;          XImage *image;
415          Pixmap bitmap;          Pixmap bitmap;
416          uint8 *tdata;          uint8 *tdata;
417          tdata = (private_colormap ? data : translate(width, height, data));  
418            tdata = (owncolmap ? data : translate(width, height, data));
419          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
420          image =          image = XCreateImage(display, visual, depth, ZPixmap,
421                  XCreateImage(display, visual,                               0, tdata, width, height, 8, 0);
                              depth, ZPixmap,  
                              0, tdata, width, height, BitmapPad(display), 0);  
422    
         xwin_set_function(ROP2_COPY);  
423          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
424    
425          XFree(image);          XFree(image);
426          if (!private_colormap)          if (!owncolmap)
427                  xfree(tdata);                  xfree(tdata);
428          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
429  }  }
# Line 383  ui_paint_bitmap(int x, int y, int cx, in Line 433  ui_paint_bitmap(int x, int y, int cx, in
433                  int width, int height, uint8 *data)                  int width, int height, uint8 *data)
434  {  {
435          XImage *image;          XImage *image;
436          uint8 *tdata =          uint8 *tdata;
                 (private_colormap ? data : translate(width, height, data));  
         image =  
                 XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,  
                              height, BitmapPad(display), 0);  
437    
438          xwin_set_function(ROP2_COPY);          tdata = (owncolmap ? data : translate(width, height, data));
439            image = XCreateImage(display, visual, depth, ZPixmap,
440                                 0, tdata, width, height, 8, 0);
441    
         /* Window */  
442          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
443    
444          XFree(image);          XFree(image);
445          if (!private_colormap)          if (!owncolmap)
446                  xfree(tdata);                  xfree(tdata);
447  }  }
448    
449  void  void
450  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
451  {  {
452          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(display, (Pixmap)bmp);
 }  
   
 HCURSOR  
 ui_create_cursor(unsigned int x, unsigned int y, int width,  
                  int height, uint8 *mask, uint8 *data)  
 {  
         XImage *imagecursor;  
         XImage *imagemask;  
         Pixmap maskbitmap, cursorbitmap;  
         Cursor cursor;  
         XColor bg, fg;  
         GC lgc;  
         int i, x1, y1, scanlinelen;  
         uint8 *cdata, *cmask;  
         uint8 c;  
         cdata = (uint8 *) malloc(sizeof(uint8) * width * height);  
         if (!cdata)  
                 return NULL;  
         scanlinelen = (width + 7) >> 3;  
         cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);  
         if (!cmask)  
         {  
                 free(cdata);  
                 return NULL;  
         }  
         i = (height - 1) * scanlinelen;  
   
         if (!screen_msbfirst)  
         {  
                 while (i >= 0)  
                 {  
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 c = *(mask++);  
                                 cmask[i + x1] =  
                                         ((c & 0x1) << 7) | ((c & 0x2) << 5) |  
                                         ((c & 0x4) << 3) | ((c & 0x8) << 1) |  
                                         ((c & 0x10) >> 1) | ((c & 0x20) >> 3)  
                                         | ((c & 0x40) >> 5) | ((c & 0x80) >>  
                                                                7);  
                         }  
                         i -= scanlinelen;  
                 }  
         }  
         else  
         {  
                 while (i >= 0)  
                 {  
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 cmask[i + x1] = *(mask++);  
                         }  
                         i -= scanlinelen;  
                 }  
         }  
   
   
         fg.red = 0;  
         fg.blue = 0;  
         fg.green = 0;  
         fg.flags = DoRed | DoBlue | DoGreen;  
         bg.red = 65535;  
         bg.blue = 65535;  
         bg.green = 65535;  
         bg.flags = DoRed | DoBlue | DoGreen;  
         maskbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         lgc = XCreateGC(display, maskbitmap, 0, NULL);  
         XSetFunction(display, lgc, GXcopy);  
         imagemask =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,  
                              height, 8, 0);  
         imagecursor =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,  
                              height, 8, 0);  
         for (y1 = height - 1; y1 >= 0; y1--)  
                 for (x1 = 0; x1 < width; x1++)  
                 {  
                         if (data[0] >= 0x80 || data[1] >= 0x80  
                             || data[2] >= 0x80)  
                                 if (XGetPixel(imagemask, x1, y1))  
   
                                 {  
                                         XPutPixel(imagecursor, x1, y1, 0);  
                                         XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */  
                                 }  
   
                                 else  
                                         XPutPixel(imagecursor, x1, y1, 1);  
   
                         else  
                                 XPutPixel(imagecursor, x1, y1,  
                                           XGetPixel(imagemask, x1, y1));  
                         data += 3;  
                 }  
         XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,  
                   height);  
         XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,  
                   height); XFree(imagemask);  
         XFree(imagecursor);  
         free(cmask);  
         free(cdata);  
         XFreeGC(display, lgc);  
         cursor =  
                 XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,  
                                     &bg, x, y);  
         XFreePixmap(display, maskbitmap);  
         XFreePixmap(display, cursorbitmap);  
         return (HCURSOR) cursor;  
 }  
   
 void  
 ui_set_cursor(HCURSOR cursor)  
 {  
         XDefineCursor(display, wnd, (Cursor) cursor);  
 }  
   
 void  
 ui_destroy_cursor(HCURSOR cursor)  
 {  
         XFreeCursor(display, (Cursor) cursor);  
453  }  }
454    
455  HGLYPH  HGLYPH
# Line 544  ui_create_glyph(int width, int height, u Line 471  ui_create_glyph(int width, int height, u
471          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
472          XInitImage(image);          XInitImage(image);
473    
         XSetFunction(display, gc, GXcopy);  
474          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
475    
476          XFree(image);          XFree(image);
477          XFreeGC(display, gc);          XFreeGC(display, gc);
478            return (HGLYPH)bitmap;
         return (HGLYPH) bitmap;  
479  }  }
480    
481  void  void
482  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
483  {  {
484          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap)glyph);
485  }  }
486    
487  HCOLOURMAP  HCURSOR
488  ui_create_colourmap(COLOURMAP *colours)  ui_create_cursor(unsigned int x, unsigned int y, int width,
489                     int height, uint8 *andmask, uint8 *xormask)
490  {  {
491          if (!private_colormap)          HGLYPH maskglyph, cursorglyph;
492            XColor bg, fg;
493            Cursor xcursor;
494            uint8 *cursor, *pcursor;
495            uint8 *mask, *pmask;
496            uint8 nextbit;
497            int scanline, offset;
498            int i, j;
499    
500            scanline = (width + 7) / 8;
501            offset = scanline * height;
502    
503            cursor = xmalloc(offset);
504            memset(cursor, 0, offset);
505    
506            mask = xmalloc(offset);
507            memset(mask, 0, offset);
508    
509            /* approximate AND and XOR masks with a monochrome X pointer */
510            for (i = 0; i < height; i++)
511          {          {
512                  COLOURENTRY *entry;                  offset -= scanline;
513                  int i, ncolours = colours->ncolours;                  pcursor = &cursor[offset];
514                  uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);                  pmask = &mask[offset];
515                  for (i = 0; i < ncolours; i++)  
516                    for (j = 0; j < scanline; j++)
517                  {                  {
518                          XColor xc;                          for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
519                          entry = &colours->colours[i];                          {
520                          xc.red = entry->red << 8;                                  if (xormask[0] || xormask[1] || xormask[2])
521                          xc.green = entry->green << 8;                                  {
522                          xc.blue = entry->blue << 8;                                          *pcursor |= (~(*andmask) & nextbit);
523                          XAllocColor(display,                                          *pmask |= nextbit;
524                                      DefaultColormap(display,                                  }
525                                                      DefaultScreen(display)),                                  else
526                                      &xc);                                  {
527                          /* XXX Check return value */                                          *pcursor |= ((*andmask) & nextbit);
528                          nc[i] = xc.pixel;                                          *pmask |= (~(*andmask) & nextbit);
529                                    }
530    
531                                    xormask += 3;
532                            }
533    
534                            andmask++;
535                            pcursor++;
536                            pmask++;
537                  }                  }
                 return nc;  
538          }          }
539          else  
540            fg.red = fg.blue = fg.green = 0xffff;
541            bg.red = bg.blue = bg.green = 0x0000;
542            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
543    
544            cursorglyph = ui_create_glyph(width, height, cursor);
545            maskglyph = ui_create_glyph(width, height, mask);
546            
547            xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
548                                    (Pixmap)maskglyph, &fg, &bg, x, y);
549    
550            ui_destroy_glyph(maskglyph);
551            ui_destroy_glyph(cursorglyph);
552            xfree(mask);
553            xfree(cursor);
554            return (HCURSOR)xcursor;
555    }
556    
557    void
558    ui_set_cursor(HCURSOR cursor)
559    {
560            XDefineCursor(display, wnd, (Cursor)cursor);
561    }
562    
563    void
564    ui_destroy_cursor(HCURSOR cursor)
565    {
566            XFreeCursor(display, (Cursor)cursor);
567    }
568    
569    #define MAKE_XCOLOR(xc,c) \
570                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
571                    (xc)->green = ((c)->green << 8) | (c)->green; \
572                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
573                    (xc)->flags = DoRed | DoGreen | DoBlue;
574    
575    HCOLOURMAP
576    ui_create_colourmap(COLOURMAP *colours)
577    {
578            COLOURENTRY *entry;
579            int i, ncolours = colours->ncolours;
580    
581            if (owncolmap)
582          {          {
                 COLOURENTRY *entry;  
583                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
584                  Colormap map;                  Colormap map;
585                  int i, ncolours = colours->ncolours;  
586                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = xmalloc(sizeof(XColor) * ncolours);
587                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
588                  {                  {
589                          entry = &colours->colours[i];                          entry = &colours->colours[i];
590                          xentry = &xcolours[i];                          xentry = &xcolours[i];
   
591                          xentry->pixel = i;                          xentry->pixel = i;
592                          xentry->red = entry->red << 8;                          MAKE_XCOLOR(xentry, entry);
                         xentry->blue = entry->blue << 8;  
                         xentry->green = entry->green << 8;  
                         xentry->flags = DoRed | DoBlue | DoGreen;  
593                  }                  }
594    
595                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(display, wnd, visual, AllocAll);
596                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
597    
598                  xfree(xcolours);                  xfree(xcolours);
599                  return (HCOLOURMAP) map;                  return (HCOLOURMAP)map;
600            }
601            else
602            {
603                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
604                    XColor xentry;
605    
606                    for (i = 0; i < ncolours; i++)
607                    {
608                            entry = &colours->colours[i];
609                            MAKE_XCOLOR(&xentry, entry);
610    
611                            if (XAllocColor(display, xcolmap, &xentry) != 0)
612                                    map[i] = xentry.pixel;
613                            else
614                                    map[i] = white;
615                    }
616    
617                    return map;
618          }          }
619  }  }
620    
621  void  void
622  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
623  {  {
624          XFreeColormap(display, (Colormap) map);          if (owncolmap)
625                    XFreeColormap(display, (Colormap)map);
626            else
627                    xfree(map);
628  }  }
629    
630  void  void
631  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
632  {  {
633            if (owncolmap)
634          /* XXX, change values of all pixels on the screen if the new colmap                  XSetWindowColormap(display, wnd, (Colormap)map);
          * doesn't have the same values as the old one? */  
         if (!private_colormap)  
                 colmap = map;  
635          else          else
636          {                  colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap) map);  
                 if (fullscreen)  
                         XInstallColormap(display, (Colormap) map);  
         }  
637  }  }
638    
639  void  void
# Line 665  void Line 670  void
670  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
671             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
672  {  {
673          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
674          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
675            RESET_FUNCTION(opcode);
676  }  }
677    
678  void  void
# Line 675  ui_patblt(uint8 opcode, Line 680  ui_patblt(uint8 opcode,
680            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
681            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
682  {  {
         Display *dpy = display;  
683          Pixmap fill;          Pixmap fill;
         uint8 i, ipattern[8];  
684    
685          xwin_set_function(opcode);          SET_FUNCTION(opcode);
686    
687          switch (brush->style)          switch (brush->style)
688          {          {
689                  case 0: /* Solid */                  case 0: /* Solid */
690                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(fgcolour);
691                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
692                          break;                          break;
693    
694                  case 3: /* Pattern */                  case 3: /* Pattern */
695                          for (i = 0; i != 8; i++)                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
696                                  ipattern[i] = ~brush->pattern[i];  
697                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          SET_FOREGROUND(bgcolour);
698                            SET_BACKGROUND(fgcolour);
699                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          XSetFillStyle(display, gc, FillOpaqueStippled);
700                          XSetBackground(dpy, gc, Ctrans(bgcolour));                          XSetStipple(display, gc, fill);
701                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                         XSetStipple(dpy, gc, fill);  
702    
703                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
704    
705                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
706                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH)fill);
707                          break;                          break;
708    
709                  default:                  default:
710                          NOTIMP("brush %d\n", brush->style);                          NOTIMP("brush %d\n", brush->style);
711          }          }
712    
713            RESET_FUNCTION(opcode);
714  }  }
715    
716  void  void
# Line 714  ui_screenblt(uint8 opcode, Line 718  ui_screenblt(uint8 opcode,
718               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
719               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
720  {  {
721          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
722          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
723            RESET_FUNCTION(opcode);
724  }  }
725    
726  void  void
# Line 724  ui_memblt(uint8 opcode, Line 728  ui_memblt(uint8 opcode,
728            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
729            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
730  {  {
731          xwin_set_function(opcode);          SET_FUNCTION(opcode);
732            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
733          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          RESET_FUNCTION(opcode);
734  }  }
735    
736  void  void
# Line 754  ui_triblt(uint8 opcode, Line 758  ui_triblt(uint8 opcode,
758                                    brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
759                          break;                          break;
760    
761                  case 0xc0:                  case 0xc0:      /* PSa */
762                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
763                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
764                                    fgcolour);                                    fgcolour);
# Line 771  ui_line(uint8 opcode, Line 775  ui_line(uint8 opcode,
775          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
776          /* pen */ PEN *pen)          /* pen */ PEN *pen)
777  {  {
778          xwin_set_function(opcode);          SET_FUNCTION(opcode);
779            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, Ctrans(pen->colour));  
780          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
781            RESET_FUNCTION(opcode);
782  }  }
783    
784  void  void
# Line 782  ui_rect( Line 786  ui_rect(
786                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
787                 /* brush */ int colour)                 /* brush */ int colour)
788  {  {
789          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
   
         XSetForeground(display, gc, Ctrans(colour));  
790          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
791  }  }
792    
# Line 794  ui_draw_glyph(int mixmode, Line 796  ui_draw_glyph(int mixmode,
796                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
797                int fgcolour)                int fgcolour)
798  {  {
799          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
800            SET_BACKGROUND(bgcolour);
801    
802          xwin_set_function(ROP2_COPY);          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
803                          ? FillStippled : FillOpaqueStippled);
804            XSetStipple(display, gc, (Pixmap)glyph);
805            XSetTSOrigin(display, gc, x, y);
806    
807            XFillRectangle(display, wnd, gc, x, y, cx, cy);
808    
809          XSetForeground(display, gc, Ctrans(fgcolour));          XSetFillStyle(display, gc, FillSolid);
         switch (mixmode)  
         {  
                 case MIX_TRANSPARENT:  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
   
                 case MIX_OPAQUE:  
                         XSetBackground(display, gc, Ctrans(bgcolour));  
 /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillOpaqueStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
   
                 default:  
                         NOTIMP("mix %d\n", mixmode);  
         }  
810  }  }
811    
812  void  void
# Line 832  ui_draw_text(uint8 font, uint8 flags, in Line 816  ui_draw_text(uint8 font, uint8 flags, in
816               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int bgcolour, int fgcolour, uint8 *text, uint8 length)
817  {  {
818          FONTGLYPH *glyph;          FONTGLYPH *glyph;
819          int i, xyoffset;          int i, offset;
820    
821          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
822    
823          if (boxcx > 1)          if (boxcx > 1)
824                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
# Line 848  ui_draw_text(uint8 font, uint8 flags, in Line 831  ui_draw_text(uint8 font, uint8 flags, in
831                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
832    
833                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
   
834                  {                  {
835                          xyoffset = text[++i];                          offset = text[++i];
836                          if ((xyoffset & 0x80))                          if (offset & 0x80)
837                          {                                  offset = ((offset & 0x7f) << 8) | text[++i];
                                 if (flags & 0x04)       /* vertical text */  
                                         y += text[++i] | (text[++i] << 8);  
                                 else  
                                         x += text[++i] | (text[++i] << 8);  
                         }  
                         else  
                         {  
                                 if (flags & 0x04)       /* vertical text */  
                                         y += xyoffset;  
                                 else  
                                         x += xyoffset;  
                         }  
838    
839                            if (flags & TEXT2_VERTICAL)
840                                    y += offset;
841                            else
842                                    x += offset;
843                  }                  }
844    
845                  if (glyph != NULL)                  if (glyph != NULL)
846                  {                  {
847                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
# Line 888  ui_desktop_save(uint32 offset, int x, in Line 863  ui_desktop_save(uint32 offset, int x, in
863          XImage *image;          XImage *image;
864    
865          pix = XCreatePixmap(display, wnd, cx, cy, depth);          pix = XCreatePixmap(display, wnd, cx, cy, depth);
         xwin_set_function(ROP2_COPY);  
   
866          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
867    
868          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
869    
870          offset *= bpp/8;          offset *= bpp/8;
# Line 911  ui_desktop_restore(uint32 offset, int x, Line 885  ui_desktop_restore(uint32 offset, int x,
885          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp/8);
886          if (data == NULL)          if (data == NULL)
887                  return;                  return;
888          image =  
889                  XCreateImage(display, visual,          image = XCreateImage(display, visual, depth, ZPixmap,
                              depth, ZPixmap,  
890                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
891                               cx * bpp/8);                               cx * bpp/8);
892          xwin_set_function(ROP2_COPY);  
893          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
894          XFree(image);          XFree(image);
895  }  }
896    
 /* unroll defines, used to make the loops a bit more readable... */  
 #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp  
 #define unroll8Lefts(uexp) case 7: uexp \  
         case 6: uexp \  
         case 5: uexp \  
         case 4: uexp \  
         case 3: uexp \  
         case 2: uexp \  
         case 1: uexp  
   
 static uint8 *  
 translate(int width, int height, uint8 *data)  
 {  
         uint32 i;  
         uint32 size = width * height;  
         uint8 *d2 = xmalloc(size * bpp/8);  
         uint8 *d3 = d2;  
         uint32 pix;  
         i = (size & ~0x7);  
   
         /* XXX: where are the bits swapped??? */  
 #ifdef L_ENDIAN                 /* little-endian */  
         /* big-endian screen */  
         if (screen_msbfirst)  
         {  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 24;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                 }  
         }  
         else  
         {                       /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
   
 #else /* bigendian-compiled */  
         if (screen_msbfirst)  
         {  
                 /* big-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
         else  
         {  
                 /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 24;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
 #endif  
   
         return d2;  
 }  

Legend:
Removed from v.28  
changed lines
  Added in v.29

  ViewVC Help
Powered by ViewVC 1.1.26