~sbeattie/ubuntu/lucid/vnc4/lp556147

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xnest/Color.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: Color.c,v 1.3 2000/08/17 19:53:27 cpqbld Exp $ */
 
2
/*
 
3
 
 
4
Copyright 1993 by Davor Matic
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software
 
7
and its documentation for any purpose is hereby granted without fee,
 
8
provided that the above copyright notice appear in all copies and that
 
9
both that copyright notice and this permission notice appear in
 
10
supporting documentation.  Davor Matic makes no representations about
 
11
the suitability of this software for any purpose.  It is provided "as
 
12
is" without express or implied warranty.
 
13
 
 
14
*/
 
15
#include "X.h"
 
16
#include "Xproto.h"
 
17
#include "scrnintstr.h"
 
18
#include "window.h"
 
19
#include "windowstr.h"
 
20
#include "colormapst.h"
 
21
#include "resource.h"
 
22
 
 
23
#include "Xnest.h"
 
24
 
 
25
 
 
26
#include "Display.h"
 
27
#include "Screen.h"
 
28
#include "Color.h"
 
29
#include "Visual.h"
 
30
#include "XNWindow.h"
 
31
#include "Args.h"
 
32
 
 
33
static ColormapPtr InstalledMaps[MAXSCREENS];
 
34
 
 
35
Bool xnestCreateColormap(pCmap)
 
36
     ColormapPtr pCmap;
 
37
{
 
38
  VisualPtr pVisual;
 
39
  XColor *colors;
 
40
  int i, ncolors;
 
41
  Pixel red, green, blue;
 
42
  Pixel redInc, greenInc, blueInc;
 
43
 
 
44
  pVisual = pCmap->pVisual;
 
45
  ncolors = pVisual->ColormapEntries;
 
46
 
 
47
  pCmap->devPriv = (pointer)xalloc(sizeof(xnestPrivColormap));
 
48
  
 
49
  xnestColormapPriv(pCmap)->colormap = 
 
50
    XCreateColormap(xnestDisplay,
 
51
                    xnestDefaultWindows[pCmap->pScreen->myNum],
 
52
                    xnestVisual(pVisual),
 
53
                    (pVisual->class & DynamicClass) ? 
 
54
                    AllocAll : AllocNone);
 
55
 
 
56
  
 
57
  switch (pVisual->class) {
 
58
  case StaticGray: /* read only */
 
59
    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
 
60
    for (i = 0; i < ncolors; i++)
 
61
      colors[i].pixel = i;
 
62
    XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
 
63
    for (i = 0; i < ncolors; i++) {
 
64
      pCmap->red[i].co.local.red = colors[i].red;
 
65
      pCmap->red[i].co.local.green = colors[i].red;
 
66
      pCmap->red[i].co.local.blue = colors[i].red;
 
67
    }
 
68
    xfree(colors);
 
69
    break;
 
70
 
 
71
  case StaticColor: /* read only */
 
72
    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
 
73
    for (i = 0; i < ncolors; i++)
 
74
      colors[i].pixel = i;
 
75
    XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
 
76
    for (i = 0; i < ncolors; i++) {
 
77
      pCmap->red[i].co.local.red = colors[i].red;
 
78
      pCmap->red[i].co.local.green = colors[i].green;
 
79
      pCmap->red[i].co.local.blue = colors[i].blue;
 
80
    }
 
81
    xfree(colors);
 
82
    break;
 
83
    
 
84
  case TrueColor: /* read only */
 
85
    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
 
86
    red = green = blue = 0L;
 
87
    redInc = lowbit(pVisual->redMask);
 
88
    greenInc = lowbit(pVisual->greenMask);
 
89
    blueInc = lowbit(pVisual->blueMask);
 
90
    for (i = 0; i < ncolors; i++) {
 
91
      colors[i].pixel = red | green | blue;
 
92
      red += redInc;
 
93
      if (red > pVisual->redMask) red = 0L;
 
94
      green += greenInc;
 
95
      if (green > pVisual->greenMask) green = 0L;
 
96
      blue += blueInc;
 
97
      if (blue > pVisual->blueMask) blue = 0L;
 
98
    }
 
99
    XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
 
100
    for (i = 0; i < ncolors; i++) {
 
101
      pCmap->red[i].co.local.red = colors[i].red;
 
102
      pCmap->green[i].co.local.green = colors[i].green;
 
103
      pCmap->blue[i].co.local.blue = colors[i].blue;
 
104
    }
 
105
    xfree(colors);
 
106
    break;
 
107
    
 
108
  case GrayScale: /* read and write */
 
109
    break;
 
110
 
 
111
  case PseudoColor: /* read and write */
 
112
    break;
 
113
 
 
114
  case DirectColor: /* read and write */
 
115
    break;
 
116
  }
 
117
  
 
118
  return True;
 
119
}
 
120
 
 
121
void xnestDestroyColormap (pCmap)
 
122
     ColormapPtr pCmap;
 
123
{
 
124
  XFreeColormap(xnestDisplay, xnestColormap(pCmap));
 
125
  xfree(pCmap->devPriv);
 
126
}
 
127
 
 
128
#define SEARCH_PREDICATE \
 
129
  (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
 
130
 
 
131
static int xnestCountInstalledColormapWindows(pWin, ptr)
 
132
     WindowPtr pWin;
 
133
     pointer ptr;
 
134
{
 
135
  xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
 
136
  int i;
 
137
  
 
138
  for (i = 0; i < icws->numCmapIDs; i++)
 
139
    if (SEARCH_PREDICATE) {
 
140
      icws->numWindows++;
 
141
      return WT_DONTWALKCHILDREN;
 
142
    }
 
143
  
 
144
  return WT_WALKCHILDREN;
 
145
}
 
146
 
 
147
static int xnestGetInstalledColormapWindows(pWin, ptr)
 
148
     WindowPtr pWin;
 
149
     pointer ptr;
 
150
{
 
151
  xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
 
152
  int i;
 
153
  
 
154
  for (i = 0; i < icws->numCmapIDs; i++)
 
155
    if (SEARCH_PREDICATE) {
 
156
      icws->windows[icws->index++] = xnestWindow(pWin);
 
157
      return WT_DONTWALKCHILDREN;
 
158
    }
 
159
  
 
160
  return WT_WALKCHILDREN;
 
161
}
 
162
 
 
163
static Window *xnestOldInstalledColormapWindows = NULL;
 
164
static int xnestNumOldInstalledColormapWindows = 0;
 
165
 
 
166
static Bool xnestSameInstalledColormapWindows(windows, numWindows)
 
167
     Window *windows;
 
168
     int numWindows;
 
169
{
 
170
  if (xnestNumOldInstalledColormapWindows != numWindows) 
 
171
    return False;
 
172
 
 
173
  if (xnestOldInstalledColormapWindows == windows) 
 
174
    return True;
 
175
 
 
176
  if (xnestOldInstalledColormapWindows == NULL || windows == NULL) 
 
177
    return False;
 
178
 
 
179
  if (memcmp(xnestOldInstalledColormapWindows, windows, 
 
180
           numWindows * sizeof(Window))) 
 
181
    return False;
 
182
 
 
183
  return True;
 
184
}
 
185
 
 
186
void xnestSetInstalledColormapWindows(pScreen)
 
187
     ScreenPtr pScreen;
 
188
{
 
189
  xnestInstalledColormapWindows icws;
 
190
  int numWindows;
 
191
  
 
192
  icws.cmapIDs = (Colormap *)xalloc(pScreen->maxInstalledCmaps *
 
193
                                    sizeof(Colormap));
 
194
  icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
 
195
  icws.numWindows = 0;
 
196
  WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer)&icws);
 
197
  if (icws.numWindows) {
 
198
    icws.windows = (Window *)xalloc((icws.numWindows + 1) * sizeof(Window));
 
199
    icws.index = 0;
 
200
    WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer)&icws);
 
201
    icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
 
202
    numWindows = icws.numWindows + 1;
 
203
  }
 
204
  else {
 
205
    icws.windows = NULL;
 
206
    numWindows = 0;
 
207
  }
 
208
  
 
209
  xfree(icws.cmapIDs);
 
210
  
 
211
  if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
 
212
    if (xnestOldInstalledColormapWindows)
 
213
      xfree(xnestOldInstalledColormapWindows);
 
214
 
 
215
#ifdef _XSERVER64
 
216
    {
 
217
      int i;
 
218
      Window64 *windows = (Window64 *)xalloc(numWindows * sizeof(Window64));
 
219
 
 
220
      for(i = 0; i < numWindows; ++i)
 
221
          windows[i] = icws.windows[i];
 
222
      XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
 
223
                            windows, numWindows);
 
224
      xfree(windows);
 
225
    }
 
226
#else
 
227
    XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
 
228
                          icws.windows, numWindows);
 
229
#endif
 
230
 
 
231
    xnestOldInstalledColormapWindows = icws.windows;
 
232
    xnestNumOldInstalledColormapWindows = icws.numWindows;
 
233
 
 
234
#ifdef DUMB_WINDOW_MANAGERS
 
235
    /* 
 
236
      This code is for dumb window managers.
 
237
      This will only work with default local visual colormaps.
 
238
      */
 
239
    if (icws.numWindows)
 
240
      {
 
241
        WindowPtr pWin;
 
242
        Visual *visual;
 
243
        ColormapPtr pCmap;
 
244
        
 
245
        pWin = xnestWindowPtr(icws.windows[0]);
 
246
        visual = xnestVisualFromID(pScreen, wVisual(pWin));
 
247
        
 
248
        if (visual == xnestDefaultVisual(pScreen))
 
249
          pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), 
 
250
                                              RT_COLORMAP);
 
251
        else
 
252
          pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap, 
 
253
                                              RT_COLORMAP);
 
254
        
 
255
        XSetWindowColormap(xnestDisplay, 
 
256
                           xnestDefaultWindows[pScreen->myNum],
 
257
                           xnestColormap(pCmap));
 
258
      }
 
259
#endif /* DUMB_WINDOW_MANAGERS */
 
260
  }
 
261
  else
 
262
    if (icws.windows) xfree(icws.windows);
 
263
}
 
264
 
 
265
void xnestSetScreenSaverColormapWindow(pScreen)
 
266
     ScreenPtr pScreen;
 
267
{
 
268
  if (xnestOldInstalledColormapWindows)
 
269
    xfree(xnestOldInstalledColormapWindows);
 
270
  
 
271
#ifdef _XSERVER64
 
272
  {
 
273
    Window64 window;
 
274
 
 
275
    window = xnestScreenSaverWindows[pScreen->myNum];
 
276
    XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
 
277
                          &window, 1);
 
278
    xnestScreenSaverWindows[pScreen->myNum] = window;
 
279
  }
 
280
#else
 
281
  XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
 
282
                        &xnestScreenSaverWindows[pScreen->myNum], 1);
 
283
#endif /* _XSERVER64 */
 
284
  
 
285
  xnestOldInstalledColormapWindows = NULL;
 
286
  xnestNumOldInstalledColormapWindows = 0;
 
287
 
 
288
  xnestDirectUninstallColormaps(pScreen);
 
289
}
 
290
 
 
291
void xnestDirectInstallColormaps(pScreen)
 
292
     ScreenPtr pScreen;
 
293
{
 
294
  int i, n;
 
295
  Colormap pCmapIDs[MAXCMAPS];
 
296
  
 
297
  if (!xnestDoDirectColormaps) return;
 
298
 
 
299
  n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
 
300
 
 
301
  for (i = 0; i < n; i++) {
 
302
    ColormapPtr pCmap;
 
303
    
 
304
    pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
 
305
    if (pCmap)
 
306
      XInstallColormap(xnestDisplay, xnestColormap(pCmap));
 
307
  }
 
308
}
 
309
 
 
310
void xnestDirectUninstallColormaps(pScreen)
 
311
     ScreenPtr pScreen;
 
312
{
 
313
  int i, n;
 
314
  Colormap pCmapIDs[MAXCMAPS];
 
315
 
 
316
  if (!xnestDoDirectColormaps) return;
 
317
 
 
318
  n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
 
319
 
 
320
  for (i = 0; i < n; i++) {
 
321
    ColormapPtr pCmap;
 
322
    
 
323
    pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
 
324
    if (pCmap)
 
325
      XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
 
326
  }
 
327
}
 
328
 
 
329
void xnestInstallColormap(pCmap)
 
330
     ColormapPtr pCmap;
 
331
{
 
332
  int index;
 
333
  ColormapPtr pOldCmap;
 
334
  
 
335
  index = pCmap->pScreen->myNum;
 
336
  pOldCmap = InstalledMaps[index];
 
337
  
 
338
  if(pCmap != pOldCmap)
 
339
    {
 
340
      xnestDirectUninstallColormaps(pCmap->pScreen);
 
341
 
 
342
      /* Uninstall pInstalledMap. Notify all interested parties. */
 
343
      if(pOldCmap != (ColormapPtr)None)
 
344
        WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
 
345
      
 
346
      InstalledMaps[index] = pCmap;
 
347
      WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
 
348
      
 
349
      xnestSetInstalledColormapWindows(pCmap->pScreen);
 
350
      xnestDirectInstallColormaps(pCmap->pScreen);
 
351
    }
 
352
}
 
353
 
 
354
void xnestUninstallColormap(pCmap)
 
355
     ColormapPtr pCmap;
 
356
{
 
357
  int index;
 
358
  ColormapPtr pCurCmap;
 
359
  
 
360
  index = pCmap->pScreen->myNum;
 
361
  pCurCmap = InstalledMaps[index];
 
362
  
 
363
  if(pCmap == pCurCmap)
 
364
    {
 
365
      if (pCmap->mid != pCmap->pScreen->defColormap)
 
366
        {
 
367
          pCurCmap = (ColormapPtr)LookupIDByType(pCmap->pScreen->defColormap,
 
368
                                                 RT_COLORMAP);
 
369
          (*pCmap->pScreen->InstallColormap)(pCurCmap);
 
370
        }
 
371
    }
 
372
}
 
373
 
 
374
static Bool xnestInstalledDefaultColormap = False;
 
375
 
 
376
int xnestListInstalledColormaps(pScreen, pCmapIDs)
 
377
     ScreenPtr pScreen;
 
378
     Colormap *pCmapIDs;
 
379
{
 
380
  if (xnestInstalledDefaultColormap) {
 
381
    *pCmapIDs = InstalledMaps[pScreen->myNum]->mid;
 
382
    return 1;
 
383
  }
 
384
  else
 
385
    return 0;
 
386
}
 
387
 
 
388
void xnestStoreColors(pCmap, nColors, pColors)
 
389
     ColormapPtr pCmap;
 
390
     int nColors;
 
391
     xColorItem *pColors;
 
392
{
 
393
  if (pCmap->pVisual->class & DynamicClass)
 
394
#ifdef _XSERVER64
 
395
  {
 
396
    int i;
 
397
    XColor *pColors64 = (XColor *)xalloc(nColors * sizeof(XColor) );
 
398
 
 
399
    for(i = 0; i < nColors; ++i)
 
400
    {
 
401
      pColors64[i].pixel = pColors[i].pixel;
 
402
      pColors64[i].red = pColors[i].red;
 
403
      pColors64[i].green = pColors[i].green;
 
404
      pColors64[i].blue = pColors[i].blue;
 
405
      pColors64[i].flags = pColors[i].flags;
 
406
    }
 
407
    XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
 
408
    xfree(pColors64);
 
409
  }
 
410
#else
 
411
    XStoreColors(xnestDisplay, xnestColormap(pCmap),
 
412
                 (XColor *)pColors, nColors);
 
413
#endif
 
414
}
 
415
 
 
416
void xnestResolveColor(pRed, pGreen, pBlue, pVisual)
 
417
     unsigned short *pRed;
 
418
     unsigned short *pGreen;
 
419
     unsigned short *pBlue;
 
420
     VisualPtr pVisual;
 
421
{
 
422
  int shift;
 
423
  unsigned int lim;
 
424
  
 
425
  shift = 16 - pVisual->bitsPerRGBValue;
 
426
  lim = (1 << pVisual->bitsPerRGBValue) - 1;
 
427
 
 
428
  if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
 
429
    {
 
430
      /* rescale to rgb bits */
 
431
      *pRed = ((*pRed >> shift) * 65535) / lim;
 
432
      *pGreen = ((*pGreen >> shift) * 65535) / lim;
 
433
      *pBlue = ((*pBlue >> shift) * 65535) / lim;
 
434
    }
 
435
  else if (pVisual->class == GrayScale)
 
436
    {
 
437
      /* rescale to gray then rgb bits */
 
438
      *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
 
439
      *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
 
440
    }
 
441
  else if (pVisual->class == StaticGray)
 
442
    {
 
443
      unsigned int limg;
 
444
 
 
445
      limg = pVisual->ColormapEntries - 1;
 
446
      /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
 
447
      *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
 
448
      *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
 
449
      *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
 
450
    }
 
451
  else
 
452
    {
 
453
      unsigned limr, limg, limb;
 
454
      
 
455
      limr = pVisual->redMask >> pVisual->offsetRed;
 
456
      limg = pVisual->greenMask >> pVisual->offsetGreen;
 
457
      limb = pVisual->blueMask >> pVisual->offsetBlue;
 
458
      /* rescale to [0..limN] then [0..65535] then rgb bits */
 
459
      *pRed = ((((((*pRed * (limr + 1)) >> 16) *
 
460
                  65535) / limr) >> shift) * 65535) / lim;
 
461
      *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
 
462
                    65535) / limg) >> shift) * 65535) / lim;
 
463
      *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
 
464
                   65535) / limb) >> shift) * 65535) / lim;
 
465
    }
 
466
}
 
467
 
 
468
Bool xnestCreateDefaultColormap(pScreen)
 
469
    ScreenPtr   pScreen;
 
470
{
 
471
  VisualPtr   pVisual;
 
472
  ColormapPtr pCmap;
 
473
  unsigned short zero = 0, ones = 0xFFFF;  
 
474
  Pixel wp, bp;
 
475
 
 
476
  for (pVisual = pScreen->visuals;
 
477
       pVisual->vid != pScreen->rootVisual;
 
478
       pVisual++);
 
479
 
 
480
  if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
 
481
                     (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
 
482
      != Success)
 
483
    return False;
 
484
 
 
485
  wp = pScreen->whitePixel;
 
486
  bp = pScreen->blackPixel;
 
487
  if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
 
488
       Success) ||
 
489
      (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
 
490
       Success))
 
491
    return FALSE;
 
492
  pScreen->whitePixel = wp;
 
493
  pScreen->blackPixel = bp;
 
494
  (*pScreen->InstallColormap)(pCmap);
 
495
 
 
496
  xnestInstalledDefaultColormap = True;
 
497
 
 
498
  return True;
 
499
}