~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/Xaw/Porthole.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
/*
 
2
 * $Xorg: Porthole.c,v 1.4 2001/02/09 02:03:45 xorgcvs Exp $
 
3
 *
 
4
Copyright 1990, 1994, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 *
 
26
 * Author:  Jim Fulton, MIT X Consortium
 
27
 * 
 
28
 * This widget is a trivial clipping widget.  It is typically used with a
 
29
 * panner or scrollbar to navigate.
 
30
 */
 
31
/* $XFree86: xc/lib/Xaw/Porthole.c,v 1.7 2001/12/14 19:54:41 dawes Exp $ */
 
32
 
 
33
#include <X11/IntrinsicP.h>
 
34
#include <X11/StringDefs.h>
 
35
#include <X11/Xmu/Misc.h>
 
36
#include <X11/Xaw/PortholeP.h>
 
37
#include <X11/Xaw/XawInit.h>
 
38
#include "Private.h"
 
39
 
 
40
/*
 
41
 * Class Methods
 
42
 */
 
43
static void XawPortholeChangeManaged(Widget);
 
44
static XtGeometryResult XawPortholeGeometryManager(Widget, XtWidgetGeometry*,
 
45
                                                   XtWidgetGeometry*);
 
46
static XtGeometryResult XawPortholeQueryGeometry(Widget, XtWidgetGeometry*,
 
47
                                                 XtWidgetGeometry*);
 
48
static void XawPortholeRealize(Widget, Mask*, XSetWindowAttributes*);
 
49
static void XawPortholeResize(Widget);
 
50
 
 
51
/*
 
52
 * Prototypes
 
53
 */
 
54
static Widget find_child(PortholeWidget);
 
55
static void layout_child(PortholeWidget, Widget, XtWidgetGeometry*,
 
56
                         Position*, Position*, Dimension*, Dimension*);
 
57
static void SendReport(PortholeWidget, unsigned int);
 
58
 
 
59
/*
 
60
 * Initialization
 
61
 */
 
62
#define offset(field)   XtOffsetOf(PortholeRec, porthole.field)
 
63
static XtResource resources[] = {
 
64
  {
 
65
    XtNreportCallback,
 
66
    XtCReportCallback,
 
67
    XtRCallback,
 
68
    sizeof(XtPointer),
 
69
    offset(report_callbacks),
 
70
    XtRCallback,
 
71
    NULL
 
72
  },
 
73
};
 
74
#undef offset
 
75
 
 
76
#define Superclass      (&compositeClassRec)
 
77
PortholeClassRec portholeClassRec = {
 
78
  /* core */
 
79
  {
 
80
    (WidgetClass)Superclass,            /* superclass */
 
81
    "Porthole",                         /* class_name */
 
82
    sizeof(PortholeRec),                /* widget_size */
 
83
    XawInitializeWidgetSet,             /* class_initialize */
 
84
    NULL,                               /* class_part_initialize */
 
85
    False,                              /* class_inited */
 
86
    NULL,                               /* initialize */
 
87
    NULL,                               /* initialize_hook */
 
88
    XawPortholeRealize,                 /* realize */
 
89
    NULL,                               /* actions */
 
90
    0,                                  /* num_actions */
 
91
    resources,                          /* resources */
 
92
    XtNumber(resources),                /* num_resources */
 
93
    NULLQUARK,                          /* xrm_class */
 
94
    True,                               /* compress_motion */
 
95
    True,                               /* compress_exposure */
 
96
    True,                               /* compress_enterleave */
 
97
    False,                              /* visible_interest */
 
98
    NULL,                               /* destroy */
 
99
    XawPortholeResize,                  /* resize */
 
100
    NULL,                               /* expose */
 
101
    NULL,                               /* set_values */
 
102
    NULL,                               /* set_values_hook */
 
103
    XtInheritSetValuesAlmost,           /* set_values_almost */
 
104
    NULL,                               /* get_values_hook */
 
105
    NULL,                               /* accept_focus */
 
106
    XtVersion,                          /* version */
 
107
    NULL,                               /* callback_private */
 
108
    NULL,                               /* tm_table */
 
109
    XawPortholeQueryGeometry,           /* query_geometry */
 
110
    XtInheritDisplayAccelerator,        /* display_accelerator */
 
111
    NULL,                               /* extension */
 
112
  },
 
113
  /* composite */
 
114
  { 
 
115
    XawPortholeGeometryManager,         /* geometry_manager */
 
116
    XawPortholeChangeManaged,           /* change_managed */
 
117
    XtInheritInsertChild,               /* insert_child */
 
118
    XtInheritDeleteChild,               /* delete_child */
 
119
    NULL,                               /* extension */
 
120
  },
 
121
  { /* porthole */
 
122
    NULL,                               /* extension */
 
123
  },
 
124
};
 
125
 
 
126
WidgetClass portholeWidgetClass = (WidgetClass)&portholeClassRec;
 
127
 
 
128
/*
 
129
 * Implementation
 
130
 */
 
131
static Widget
 
132
find_child(PortholeWidget pw)
 
133
{
 
134
    Widget *children;
 
135
    unsigned int i;
 
136
 
 
137
    /*
 
138
     * Find the managed child on which we should operate.  Ignore multiple
 
139
     * managed children
 
140
     */
 
141
    for (i = 0, children = pw->composite.children;
 
142
         i < pw->composite.num_children; i++, children++)
 
143
        if (XtIsManaged(*children))
 
144
            return (*children);
 
145
 
 
146
    return (NULL);
 
147
}
 
148
 
 
149
static void
 
150
SendReport(PortholeWidget pw, unsigned int changed)
 
151
{
 
152
    Widget child = find_child(pw);
 
153
 
 
154
    if (pw->porthole.report_callbacks && child) {
 
155
        XawPannerReport prep;
 
156
 
 
157
        prep.changed = changed;
 
158
        prep.slider_x = -XtX(child);    /* porthole is "inner" */
 
159
        prep.slider_y = -XtY(child);    /* child is outer since it is larger */
 
160
        prep.slider_width = XtWidth(pw);
 
161
        prep.slider_height = XtHeight(pw);
 
162
        prep.canvas_width = XtWidth(child);
 
163
        prep.canvas_height = XtHeight(child);
 
164
        XtCallCallbackList((Widget)pw, pw->porthole.report_callbacks,
 
165
                           (XtPointer)&prep);
 
166
    }
 
167
}
 
168
 
 
169
static void
 
170
layout_child(PortholeWidget pw, Widget child, XtWidgetGeometry *geomp,
 
171
             Position *xp, Position *yp, Dimension *widthp, Dimension *heightp)
 
172
{
 
173
    Position minx, miny;
 
174
 
 
175
    *xp = XtX(child);                   /* default to current values */
 
176
    *yp = XtY(child);
 
177
    *widthp = XtWidth(child);
 
178
    *heightp = XtHeight(child);
 
179
    if (geomp) {                        /* mix in any requested changes */
 
180
        if (geomp->request_mode & CWX)
 
181
            *xp = geomp->x;
 
182
        if (geomp->request_mode & CWY)
 
183
            *yp = geomp->y;
 
184
        if (geomp->request_mode & CWWidth)
 
185
            *widthp = geomp->width;
 
186
        if (geomp->request_mode & CWHeight)
 
187
            *heightp = geomp->height;
 
188
    }
 
189
 
 
190
    /*
 
191
     * Make sure that the child is at least as large as the porthole; there
 
192
     * is no maximum size
 
193
     */
 
194
    if (*widthp < XtWidth(pw)) *widthp = XtWidth(pw);
 
195
    if (*heightp < XtHeight(pw)) *heightp = XtHeight(pw);
 
196
 
 
197
    /*
 
198
     * Make sure that the child is still on the screen.  Note that this must
 
199
     * be done *after* the size computation so that we know where to put it
 
200
     */
 
201
    minx = (Position)XtWidth(pw) - (Position)*widthp;
 
202
    miny = (Position)XtHeight(pw) - (Position)*heightp;
 
203
 
 
204
    if (*xp < minx)
 
205
        *xp = minx;
 
206
    if (*yp < miny)
 
207
        *yp = miny;
 
208
 
 
209
    if (*xp > 0)
 
210
        *xp = 0;
 
211
    if (*yp > 0)
 
212
        *yp = 0;
 
213
}
 
214
 
 
215
static void
 
216
XawPortholeRealize(Widget gw, Mask *valueMask, XSetWindowAttributes *attr)
 
217
{
 
218
    attr->bit_gravity = NorthWestGravity;
 
219
    *valueMask |= CWBitGravity;
 
220
 
 
221
    if (XtWidth(gw) < 1)
 
222
        XtWidth(gw) = 1;
 
223
    if (XtHeight(gw) < 1)
 
224
        XtHeight(gw) = 1;
 
225
    (*portholeWidgetClass->core_class.superclass->core_class.realize)
 
226
        (gw, valueMask, attr);
 
227
}
 
228
 
 
229
static void
 
230
XawPortholeResize(Widget gw)
 
231
{
 
232
    PortholeWidget pw = (PortholeWidget)gw;
 
233
    Widget child = find_child(pw);
 
234
 
 
235
    /*
 
236
     * If we have a child, we need to make sure that it is at least as big
 
237
     * as we are and in the right place
 
238
     */
 
239
    if (child) {
 
240
        Position x, y;
 
241
        Dimension width, height;
 
242
 
 
243
        layout_child(pw, child, NULL, &x, &y, &width, &height);
 
244
        XtConfigureWidget(child, x, y, width, height, 0);
 
245
    }
 
246
 
 
247
    SendReport(pw, XawPRCanvasWidth | XawPRCanvasHeight);
 
248
}
 
249
 
 
250
static XtGeometryResult
 
251
XawPortholeQueryGeometry(Widget gw, XtWidgetGeometry *intended,
 
252
                         XtWidgetGeometry *preferred)
 
253
{
 
254
    PortholeWidget pw = (PortholeWidget)gw;
 
255
    Widget child = find_child(pw);
 
256
 
 
257
    if (child) {
 
258
#define SIZEONLY (CWWidth | CWHeight)
 
259
        preferred->request_mode = SIZEONLY;
 
260
        preferred->width = XtWidth(child);
 
261
        preferred->height = XtHeight(child);
 
262
 
 
263
        if ((intended->request_mode & SIZEONLY) == SIZEONLY &&
 
264
            intended->width == preferred->width &&
 
265
            intended->height == preferred->height)
 
266
            return (XtGeometryYes);
 
267
        else if (preferred->width == XtWidth(pw) &&
 
268
                 preferred->height == XtHeight(pw))
 
269
            return (XtGeometryNo);
 
270
 
 
271
        return (XtGeometryAlmost);
 
272
#undef SIZEONLY
 
273
    }
 
274
 
 
275
    return (XtGeometryNo);
 
276
}
 
277
 
 
278
static XtGeometryResult
 
279
XawPortholeGeometryManager(Widget w, XtWidgetGeometry *req,
 
280
                           XtWidgetGeometry *reply)
 
281
{
 
282
    PortholeWidget pw = (PortholeWidget) w->core.parent;
 
283
    Widget child = find_child(pw);
 
284
    Bool okay = True;
 
285
 
 
286
    if (child != w)
 
287
        return (XtGeometryNo);
 
288
 
 
289
    *reply = *req;                      /* assume we'll grant everything */
 
290
 
 
291
    if ((req->request_mode & CWBorderWidth) && req->border_width != 0) {
 
292
        reply->border_width = 0;
 
293
        okay = False;
 
294
    }
 
295
 
 
296
    layout_child(pw, child, req, &reply->x, &reply->y,
 
297
                 &reply->width, &reply->height);
 
298
 
 
299
    if ((req->request_mode & CWX) && req->x != reply->x)
 
300
        okay = False;
 
301
    if ((req->request_mode & CWY) && req->x != reply->x)
 
302
        okay = False;
 
303
    if ((req->request_mode & CWWidth) && req->width != reply->width)
 
304
        okay = False;
 
305
    if ((req->request_mode & CWHeight) && req->height != reply->height)
 
306
        okay = False;
 
307
 
 
308
    /*
 
309
     * If we failed on anything, simply return without touching widget
 
310
     */
 
311
    if (!okay)
 
312
        return (XtGeometryAlmost);
 
313
 
 
314
    /*
 
315
     * If not just doing a query, update widget and send report.  Note that
 
316
     * we will often set fields that weren't requested because we want to keep
 
317
     * the child visible
 
318
     */
 
319
    if (!(req->request_mode & XtCWQueryOnly)) {
 
320
        unsigned int changed = 0;
 
321
 
 
322
        if (XtX(child) != reply->x) {
 
323
            changed |= XawPRSliderX;
 
324
            XtX(child) = reply->x;
 
325
        }
 
326
        if (XtY(child) != reply->y) {
 
327
            changed |= XawPRSliderY;
 
328
            XtY(child) = reply->y;
 
329
        }
 
330
        if (XtWidth(child) != reply->width) {
 
331
            changed |= XawPRSliderWidth;
 
332
            XtWidth(child) = reply->width;
 
333
        }
 
334
        if (XtHeight(child) != reply->height) {
 
335
            changed |= XawPRSliderHeight;
 
336
            XtHeight(child) = reply->height;
 
337
        }
 
338
        if (changed)
 
339
            SendReport(pw, changed);
 
340
    }
 
341
 
 
342
    return (XtGeometryYes);             /* success! */
 
343
}
 
344
 
 
345
static void
 
346
XawPortholeChangeManaged(Widget gw)
 
347
{
 
348
    PortholeWidget pw = (PortholeWidget)gw;
 
349
    Widget child = find_child (pw);     /* ignore extra children */
 
350
 
 
351
    if (child) {
 
352
        if (!XtIsRealized (gw)) {
 
353
            XtWidgetGeometry geom, retgeom;
 
354
 
 
355
            geom.request_mode = 0;
 
356
            if (XtWidth(pw) == 0) {
 
357
                geom.width = XtWidth(child);
 
358
                geom.request_mode |= CWWidth;
 
359
            }
 
360
            if (XtHeight(pw) == 0) {
 
361
                geom.height = XtHeight(child);
 
362
                geom.request_mode |= CWHeight;
 
363
            }
 
364
            if (geom.request_mode &&
 
365
                XtMakeGeometryRequest (gw, &geom, &retgeom)
 
366
                == XtGeometryAlmost)
 
367
                (void)XtMakeGeometryRequest(gw, &retgeom, NULL);
 
368
        }
 
369
        
 
370
        XtResizeWidget(child, Max(XtWidth(child), XtWidth(pw)),
 
371
                       Max(XtHeight(child), XtHeight(pw)), 0);
 
372
 
 
373
        SendReport(pw, XawPRAll);
 
374
    }
 
375
}