~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to lefty/ws/mswin32/gcommon.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#pragma prototyped
 
2
/* Lefteris Koutsofios - AT&T Bell Laboratories */
 
3
 
 
4
#include "common.h"
 
5
#include "g.h"
 
6
#include "gcommon.h"
 
7
#include "mem.h"
 
8
 
 
9
#define WCU widget->u.c
 
10
#define WVU widget->u.v
 
11
 
 
12
FILE *Gxfp;
 
13
int Gxfd;
 
14
int Gpopdownflag;
 
15
int Gdepth;
 
16
int Gnocallbacks;
 
17
int menuselected;
 
18
int menupoped;
 
19
 
 
20
char *Gbufp = NULL;
 
21
int Gbufn = 0, Gbufi = 0;
 
22
 
 
23
PIXpoint_t *Gppp;
 
24
int Gppn, Gppi;
 
25
 
 
26
Gfont_t *Gfontp;
 
27
int Gfontn;
 
28
 
 
29
static HFONT deffont;
 
30
static int twobmouse;
 
31
static HWND palettechanged;
 
32
 
 
33
LRESULT CALLBACK LeftyWndProc (HWND, UINT, WPARAM, LPARAM);
 
34
LRESULT CALLBACK ArrayWndProc (HWND, UINT, WPARAM, LPARAM);
 
35
LRESULT CALLBACK CanvasWndProc (HWND, UINT, WPARAM, LPARAM);
 
36
LRESULT CALLBACK LabelWndProc (HWND, UINT, WPARAM, LPARAM);
 
37
LRESULT CALLBACK ScrollWndProc (HWND, UINT, WPARAM, LPARAM);
 
38
 
 
39
static void processcommand (Gwidget_t *, WPARAM, LPARAM);
 
40
static void handleresize (Gwidget_t *);
 
41
 
 
42
int Ginitgraphics (void) {
 
43
    WNDCLASS wc;
 
44
    HDC hdc;
 
45
    ATOM rtn;
 
46
 
 
47
    if (!hprevinstance) {
 
48
        wc.style = NULL;
 
49
        wc.lpfnWndProc = LeftyWndProc;
 
50
        wc.cbClsExtra = 0;
 
51
        wc.cbWndExtra = 0;
 
52
        wc.hInstance = hinstance;
 
53
        wc.hIcon = LoadIcon ((HINSTANCE) NULL, IDI_APPLICATION);
 
54
        wc.hCursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);
 
55
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
 
56
        wc.lpszMenuName = 0;
 
57
        wc.lpszClassName = "LeftyClass";
 
58
        if (!(rtn = RegisterClass (&wc)))
 
59
            panic (POS, "GXinit", "register class rtn = %d", (int) rtn);
 
60
 
 
61
        wc.style = NULL;
 
62
        wc.lpfnWndProc = ArrayWndProc;
 
63
        wc.cbClsExtra = 0;
 
64
        wc.cbWndExtra = 0;
 
65
        wc.hInstance = hinstance;
 
66
        wc.hIcon = LoadIcon ((HINSTANCE) NULL, IDI_APPLICATION);
 
67
        wc.hCursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);
 
68
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
 
69
        wc.lpszMenuName = 0;
 
70
        wc.lpszClassName = "ArrayClass";
 
71
        if (!(rtn = RegisterClass (&wc)))
 
72
            panic (POS, "GXinit", "register class rtn = %d", (int) rtn);
 
73
 
 
74
        wc.style = CS_OWNDC;
 
75
        wc.lpfnWndProc = CanvasWndProc;
 
76
        wc.cbClsExtra = 0;
 
77
        wc.cbWndExtra = 0;
 
78
        wc.hInstance = hinstance;
 
79
        wc.hIcon = LoadIcon ((HINSTANCE) NULL, IDI_APPLICATION);
 
80
        wc.hCursor = NULL;
 
81
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
 
82
        wc.lpszMenuName = 0;
 
83
        wc.lpszClassName = "CanvasClass";
 
84
        if (!(rtn = RegisterClass (&wc)))
 
85
            panic (POS, "GXinit", "register class rtn = %d", (int) rtn);
 
86
 
 
87
        wc.style = NULL;
 
88
        wc.lpfnWndProc = ScrollWndProc;
 
89
        wc.cbClsExtra = 0;
 
90
        wc.cbWndExtra = 0;
 
91
        wc.hInstance = hinstance;
 
92
        wc.hIcon = LoadIcon ((HINSTANCE) NULL, IDI_APPLICATION);
 
93
        wc.hCursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);
 
94
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
 
95
        wc.lpszMenuName = 0;
 
96
        wc.lpszClassName = "ScrollClass";
 
97
        if (!(rtn = RegisterClass (&wc)))
 
98
            panic (POS, "GXinit", "register class rtn = %d", (int) rtn);
 
99
 
 
100
        wc.style = NULL;
 
101
        wc.lpfnWndProc = LabelWndProc;
 
102
        wc.cbClsExtra = 0;
 
103
        wc.cbWndExtra = 0;
 
104
        wc.hInstance = hinstance;
 
105
        wc.hIcon = LoadIcon ((HINSTANCE) NULL, IDI_APPLICATION);
 
106
        wc.hCursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);
 
107
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
 
108
        wc.lpszMenuName = 0;
 
109
        wc.lpszClassName = "LabelClass";
 
110
        if (!(rtn = RegisterClass (&wc)))
 
111
            panic (POS, "GXinit", "register class rtn = %d", (int) rtn);
 
112
    }
 
113
    if (getenv ("LEFTY3BMOUSE"))
 
114
        twobmouse = FALSE;
 
115
    else
 
116
        twobmouse = TRUE;
 
117
    hdc = GetDC ((HWND) NULL);
 
118
    Gdepth = GetDeviceCaps (hdc, BITSPIXEL);
 
119
    deffont = GetStockObject (SYSTEM_FONT);
 
120
#ifndef FEATURE_MS
 
121
    if (!(Gxfp = fopen ("/dev/windows", "r")))
 
122
        panic (POS, "GXinit", "cannot open windows device");
 
123
    Gxfd = fileno (Gxfp);
 
124
#endif
 
125
    Gpopdownflag = FALSE;
 
126
    Gbufp = Marrayalloc ((long) BUFINCR * BUFSIZE);
 
127
    Gbufn = BUFINCR;
 
128
    Gppp = Marrayalloc ((long) PPINCR * PPSIZE);
 
129
    Gppn = PPINCR;
 
130
    Gfontp = Marrayalloc ((long) FONTSIZE);
 
131
    Gfontn = 1;
 
132
    Gfontp[0].name = strdup ("default");
 
133
    if (!Gdefaultfont)
 
134
        Gfontp[0].font = deffont;
 
135
    else if (Gdefaultfont[0] != '\000')
 
136
        Gfontp[0].font = CreateFont (0, 0, 0, 0, 0,
 
137
                0, 0, 0, 0, 0, 0, 0, 0, Gdefaultfont);
 
138
    else
 
139
        Gfontp[0].font = NULL;
 
140
    ReleaseDC ((HWND) NULL, hdc);
 
141
    Gnocallbacks = FALSE;
 
142
    return 0;
 
143
}
 
144
 
 
145
int Gtermgraphics (void) {
 
146
    int fi;
 
147
 
 
148
    for (fi = 0; fi < Gfontn; fi++)
 
149
        free (Gfontp[fi].name);
 
150
    Marrayfree (Gfontp), Gfontp = NULL, Gfontn = 0;
 
151
    Marrayfree (Gppp), Gppp = NULL, Gppn = 0;
 
152
    Marrayfree (Gbufp), Gbufp = NULL, Gbufn = 0;
 
153
    return 0;
 
154
}
 
155
 
 
156
int Gsync (void) {
 
157
    return 0;
 
158
}
 
159
 
 
160
int Gresetbstate (int wi) {
 
161
    Gcw_t *cw;
 
162
    int bn;
 
163
 
 
164
    cw = Gwidgets[wi].u.c;
 
165
    bn = cw->bstate[0] + cw->bstate[1] + cw->bstate[2];
 
166
    cw->bstate[0] = cw->bstate[1] = cw->bstate[2] = 0;
 
167
    cw->buttonsdown -= bn;
 
168
    Gbuttonsdown -= bn;
 
169
    return 0;
 
170
}
 
171
 
 
172
int Gprocessevents (int waitflag, Geventmode_t mode) {
 
173
    MSG msg;
 
174
    int rtn;
 
175
 
 
176
    rtn = 0;
 
177
    switch (waitflag) {
 
178
    case TRUE:
 
179
        if (!GetMessage(&msg, (HWND) NULL, (UINT) NULL, (UINT) NULL))
 
180
            exit (msg.wParam);
 
181
        TranslateMessage(&msg);
 
182
        DispatchMessage(&msg);
 
183
        if (mode == G_ONEEVENT)
 
184
            return 1;
 
185
        rtn = 1;
 
186
        /* FALL THROUGH */
 
187
    case FALSE:
 
188
        while (PeekMessage(&msg, (HWND) 0, (UINT) 0, (UINT) 0, PM_REMOVE)) {
 
189
            if (msg.message == WM_QUIT)
 
190
                exit (msg.wParam);
 
191
            TranslateMessage(&msg);
 
192
            DispatchMessage(&msg);
 
193
            if (mode == G_ONEEVENT)
 
194
                return 1;
 
195
            rtn = 1;
 
196
        }
 
197
        break;
 
198
    }
 
199
    return rtn;
 
200
}
 
201
 
 
202
LRESULT CALLBACK LeftyWndProc (HWND hwnd,
 
203
        UINT message, WPARAM wparam, LPARAM lparam) {
 
204
    Gwidget_t *widget;
 
205
    WINDOWPOS *wpos;
 
206
    Gevent_t gev;
 
207
 
 
208
    widget = findwidget (hwnd, G_VIEWWIDGET);
 
209
    switch (message) {
 
210
    case WM_WINDOWPOSCHANGED:
 
211
        if (Gnocallbacks || !widget)
 
212
            return (DefWindowProc(hwnd, message, wparam, lparam));
 
213
        wpos = (WINDOWPOS *) lparam;
 
214
        if (!(wpos->flags & SWP_NOSIZE))
 
215
            handleresize (widget);
 
216
        break;
 
217
    case WM_COMMAND:
 
218
        if (Gnocallbacks || !widget)
 
219
            return (DefWindowProc(hwnd, message, wparam, lparam));
 
220
        processcommand (widget, wparam, lparam);
 
221
        break;
 
222
    case WM_CLOSE:
 
223
        if (!widget)
 
224
            exit (0);
 
225
        if (WVU->closing)
 
226
            DestroyWindow (hwnd);
 
227
        if (Gnocallbacks)
 
228
            exit (0);
 
229
        gev.type = 0, gev.code = 0, gev.data = 0;
 
230
        gev.wi = widget - &Gwidgets[0];
 
231
        if (WVU->func)
 
232
            (*WVU->func) (&gev);
 
233
        else
 
234
            exit (0);
 
235
        break;
 
236
    case WM_PALETTECHANGED:
 
237
        palettechanged = (HWND) wparam;
 
238
        break;
 
239
    default:
 
240
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
241
    }
 
242
    return 0;
 
243
}
 
244
 
 
245
LRESULT CALLBACK ArrayWndProc (HWND hwnd,
 
246
        UINT message, WPARAM wparam, LPARAM lparam) {
 
247
    Gwidget_t *widget;
 
248
    WINDOWPOS *wpos;
 
249
 
 
250
    if (Gnocallbacks || !(widget = findwidget (hwnd, G_ARRAYWIDGET)))
 
251
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
252
    switch (message) {
 
253
    case WM_WINDOWPOSCHANGED:
 
254
        wpos = (WINDOWPOS *) lparam;
 
255
        if (!(wpos->flags & SWP_NOSIZE))
 
256
            handleresize (widget);
 
257
        break;
 
258
    case WM_COMMAND:
 
259
        processcommand (widget, wparam, lparam);
 
260
        break;
 
261
    default:
 
262
        return (DefWindowProc (hwnd, message, wparam, lparam));
 
263
    }
 
264
    return 0;
 
265
}
 
266
 
 
267
LRESULT CALLBACK CanvasWndProc (HWND hwnd,
 
268
        UINT message, WPARAM wparam, LPARAM lparam) {
 
269
    Gwidget_t *widget;
 
270
    WINDOWPOS *wpos;
 
271
    PIXpoint_t pp;
 
272
    Gevent_t gev;
 
273
    POINT p;
 
274
    int wi, bn;
 
275
 
 
276
    if (Gnocallbacks || !(widget = findwidget (hwnd, G_CANVASWIDGET)))
 
277
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
278
    Gpopdownflag = FALSE;
 
279
    switch (message) {
 
280
    case WM_PAINT:
 
281
        if (palettechanged != hwnd)
 
282
            RealizePalette (widget->u.c->gc);
 
283
        Gneedredraw = widget->u.c->needredraw = TRUE;
 
284
        Gadjustclip (widget);
 
285
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
286
    case WM_WINDOWPOSCHANGED:
 
287
        wpos = (WINDOWPOS *) lparam;
 
288
        if (!(wpos->flags & SWP_NOSIZE))
 
289
            handleresize (widget);
 
290
        return 0;
 
291
    case WM_MOUSEACTIVATE:
 
292
        SetFocus (widget->w);
 
293
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
294
    case WM_COMMAND:
 
295
        processcommand (widget, wparam, lparam);
 
296
        return 0;
 
297
    case WM_CHAR:
 
298
        gev.type = G_KEYBD;
 
299
        gev.code = G_DOWN;   /* I don't know how to get up events so I make */
 
300
        Gpopdownflag = TRUE; /* the code after this switch send the up event */
 
301
        gev.data = wparam;
 
302
        GetCursorPos (&p);
 
303
        ScreenToClient (widget->w, &p);
 
304
        pp.x = p.x, pp.y = p.y;
 
305
        gev.p = ppixtodraw (widget, pp);
 
306
        /* continues after the end of this switch */
 
307
        break;
 
308
    case WM_LBUTTONDOWN:
 
309
    case WM_LBUTTONUP:
 
310
    case WM_MBUTTONDOWN:
 
311
    case WM_MBUTTONUP:
 
312
    case WM_RBUTTONDOWN:
 
313
    case WM_RBUTTONUP:
 
314
        gev.type = G_MOUSE;
 
315
        if (twobmouse) {
 
316
            if (message == WM_LBUTTONDOWN && (wparam & MK_CONTROL))
 
317
                message = WM_MBUTTONDOWN;
 
318
            if (message == WM_LBUTTONUP && (wparam & MK_CONTROL))
 
319
                message = WM_MBUTTONUP;
 
320
        }
 
321
        switch (message) {
 
322
        case WM_LBUTTONDOWN: gev.code = G_DOWN, gev.data = G_LEFT;   break;
 
323
        case WM_LBUTTONUP:   gev.code = G_UP,   gev.data = G_LEFT;   break;
 
324
        case WM_MBUTTONDOWN: gev.code = G_DOWN, gev.data = G_MIDDLE; break;
 
325
        case WM_MBUTTONUP:   gev.code = G_UP,   gev.data = G_MIDDLE; break;
 
326
        case WM_RBUTTONDOWN: gev.code = G_DOWN, gev.data = G_RIGHT;  break;
 
327
        case WM_RBUTTONUP:   gev.code = G_UP,   gev.data = G_RIGHT;  break;
 
328
        }
 
329
        pp.x = LOWORD (lparam), pp.y = HIWORD (lparam);
 
330
        gev.p = ppixtodraw (widget, pp);
 
331
        bn = WCU->bstate[gev.data];
 
332
        WCU->bstate[gev.data] = (gev.code == G_DOWN) ? 1 : 0;
 
333
        bn = WCU->bstate[gev.data] - bn;
 
334
        widget->u.c->buttonsdown += bn;
 
335
        Gbuttonsdown += bn;
 
336
        /* continues after the end of this switch */
 
337
        break;
 
338
    default:
 
339
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
340
    }
 
341
    wi = gev.wi = widget - &Gwidgets[0];
 
342
    if (widget->u.c->func)
 
343
        (*widget->u.c->func) (&gev);
 
344
    if (Gpopdownflag) {
 
345
        Gpopdownflag = FALSE;
 
346
        if (gev.code == G_DOWN) {
 
347
            gev.code = G_UP;
 
348
            widget = &Gwidgets[wi];
 
349
            WCU->bstate[gev.data] = 0;
 
350
            widget->u.c->buttonsdown--;
 
351
            Gbuttonsdown--;
 
352
            if (widget->inuse && widget->u.c->func)
 
353
                (*widget->u.c->func) (&gev);
 
354
        }
 
355
    }
 
356
    return 0;
 
357
}
 
358
 
 
359
LRESULT CALLBACK LabelWndProc (HWND hwnd,
 
360
        UINT message, WPARAM wparam, LPARAM lparam) {
 
361
    Gwidget_t *widget;
 
362
    PAINTSTRUCT paintstruct;
 
363
    WINDOWPOS *wpos;
 
364
    Gevent_t gev;
 
365
    RECT r;
 
366
    HDC hdc;
 
367
    int wi;
 
368
 
 
369
    if (Gnocallbacks || !(widget = findwidget (hwnd, G_LABELWIDGET)))
 
370
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
371
    switch (message) {
 
372
    case WM_PAINT:
 
373
        hdc = BeginPaint (widget->w, &paintstruct);
 
374
        GetWindowText (widget->w, &Gbufp[0], Gbufn);
 
375
        GetClientRect (widget->w, &r);
 
376
        DrawText (hdc, (LPCSTR) &Gbufp[0], strlen (Gbufp), &r, DT_LEFT);
 
377
        EndPaint (widget->w, &paintstruct);
 
378
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
379
    case WM_WINDOWPOSCHANGED:
 
380
        wpos = (WINDOWPOS *) lparam;
 
381
        if (!(wpos->flags & SWP_NOSIZE))
 
382
            handleresize (widget);
 
383
        return 0;
 
384
    case WM_COMMAND:
 
385
        processcommand (widget, wparam, lparam);
 
386
        return 0;
 
387
    case WM_KEYDOWN:
 
388
    case WM_KEYUP:
 
389
        gev.type = G_KEYBD;
 
390
        gev.code = (message == WM_KEYDOWN) ? G_DOWN : G_UP;
 
391
        gev.data = wparam;
 
392
        /* continues after the end of this switch */
 
393
        break;
 
394
    case WM_LBUTTONDOWN:
 
395
    case WM_LBUTTONUP:
 
396
    case WM_MBUTTONDOWN:
 
397
    case WM_MBUTTONUP:
 
398
    case WM_RBUTTONDOWN:
 
399
    case WM_RBUTTONUP:
 
400
        gev.type = G_MOUSE;
 
401
        if (wparam & MK_CONTROL) {
 
402
            if (message == WM_LBUTTONDOWN)
 
403
                message = WM_MBUTTONDOWN;
 
404
            else if (message == WM_LBUTTONUP)
 
405
                message = WM_MBUTTONUP;
 
406
        }
 
407
        switch (message) {
 
408
        case WM_LBUTTONDOWN: gev.code = G_DOWN, gev.data = G_LEFT;   break;
 
409
        case WM_LBUTTONUP:   gev.code = G_UP,   gev.data = G_LEFT;   break;
 
410
        case WM_MBUTTONDOWN: gev.code = G_DOWN, gev.data = G_MIDDLE; break;
 
411
        case WM_MBUTTONUP:   gev.code = G_UP,   gev.data = G_MIDDLE; break;
 
412
        case WM_RBUTTONDOWN: gev.code = G_DOWN, gev.data = G_RIGHT;  break;
 
413
        case WM_RBUTTONUP:   gev.code = G_UP,   gev.data = G_RIGHT;  break;
 
414
        }
 
415
        /* continues after the end of this switch */
 
416
        break;
 
417
    default:
 
418
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
419
    }
 
420
    wi = gev.wi = widget - &Gwidgets[0];
 
421
    if (widget->u.l->func)
 
422
        (*widget->u.l->func) (&gev);
 
423
    if (Gpopdownflag) {
 
424
        Gpopdownflag = FALSE;
 
425
        if (gev.type == G_MOUSE && gev.code == G_DOWN) {
 
426
            gev.code = G_UP;
 
427
            widget = &Gwidgets[wi];
 
428
            if (widget->inuse && widget->u.l->func)
 
429
                (*widget->u.l->func) (&gev);
 
430
        }
 
431
    }
 
432
    return 0;
 
433
}
 
434
 
 
435
LRESULT CALLBACK ScrollWndProc (HWND hwnd,
 
436
        UINT message, WPARAM wparam, LPARAM lparam) {
 
437
    Gwidget_t *widget, *child;
 
438
    WINDOWPOS *wpos;
 
439
    PIXpoint_t po;
 
440
    RECT r;
 
441
    int dummy, dx, dy, wi;
 
442
 
 
443
    if (Gnocallbacks || !(widget = findwidget (hwnd, G_SCROLLWIDGET)))
 
444
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
445
    switch (message) {
 
446
    case WM_WINDOWPOSCHANGED:
 
447
        wpos = (WINDOWPOS *) lparam;
 
448
        if (!(wpos->flags & SWP_NOSIZE))
 
449
            handleresize (widget);
 
450
        break;
 
451
    case WM_HSCROLL:
 
452
    case WM_VSCROLL:
 
453
        for (wi = 0; wi < Gwidgetn; wi++) {
 
454
            child = &Gwidgets[wi];
 
455
            if (child->inuse && child->pwi == widget - &Gwidgets[0])
 
456
                break;
 
457
        }
 
458
        if (wi == Gwidgetn)
 
459
            return (DefWindowProc(hwnd, message, wparam, lparam));
 
460
        GetClientRect (widget->w, &r);
 
461
        GetScrollRange (widget->w, SB_HORZ, &dummy, &dx);
 
462
        GetScrollRange (widget->w, SB_VERT, &dummy, &dy);
 
463
        po.x = GetScrollPos (widget->w, SB_HORZ);
 
464
        po.y = GetScrollPos (widget->w, SB_VERT);
 
465
        switch (message) {
 
466
        case WM_HSCROLL:
 
467
            switch (LOWORD (wparam)) {
 
468
            case SB_BOTTOM:        po.x = dx;                  break;
 
469
            case SB_LINEDOWN:      po.x += 10;                 break;
 
470
            case SB_LINEUP:        po.x -= 10;                 break;
 
471
            case SB_PAGEDOWN:      po.x += (r.right - r.left); break;
 
472
            case SB_PAGEUP:        po.x -= (r.right - r.left); break;
 
473
            case SB_THUMBPOSITION: po.x = HIWORD (wparam);     break;
 
474
            case SB_THUMBTRACK:    po.x = HIWORD (wparam);     break;
 
475
            case SB_TOP:           po.x = 0;                   break;
 
476
            }
 
477
            po.x = min (po.x, dx);
 
478
            po.x = max (po.x, 0);
 
479
            SetScrollPos (widget->w, SB_HORZ, po.x, TRUE);
 
480
            SetWindowPos (child->w, (HWND) NULL, -po.x, -po.y, 0, 0,
 
481
                    SWP_NOSIZE | SWP_NOZORDER);
 
482
            break;
 
483
        case WM_VSCROLL:
 
484
            switch (LOWORD (wparam)) {
 
485
            case SB_BOTTOM:        po.y = dy;                  break;
 
486
            case SB_LINEDOWN:      po.y += 10;                 break;
 
487
            case SB_LINEUP:        po.y -= 10;                 break;
 
488
            case SB_PAGEDOWN:      po.y += (r.bottom - r.top); break;
 
489
            case SB_PAGEUP:        po.y -= (r.bottom - r.top); break;
 
490
            case SB_THUMBPOSITION: po.y = HIWORD (wparam);     break;
 
491
            case SB_THUMBTRACK:    po.y = HIWORD (wparam);     break;
 
492
            case SB_TOP:           po.y = 0;                   break;
 
493
            }
 
494
            po.y = min (po.y, dy);
 
495
            po.y = max (po.y, 0);
 
496
            SetScrollPos (widget->w, SB_VERT, po.y, TRUE);
 
497
            SetWindowPos (child->w, (HWND) NULL, -po.x, -po.y, 0, 0,
 
498
                    SWP_NOSIZE | SWP_NOZORDER);
 
499
            break;
 
500
        }
 
501
        break;
 
502
    default:
 
503
        return (DefWindowProc(hwnd, message, wparam, lparam));
 
504
    }
 
505
    return 0;
 
506
}
 
507
 
 
508
static void processcommand (Gwidget_t *widget, WPARAM wparam, LPARAM lparam) {
 
509
    Gwidget_t *child;
 
510
    WORD l;
 
511
    int n;
 
512
 
 
513
    if (lparam == 0) { /* it's a menu */
 
514
        if (LOWORD (wparam) != 999)
 
515
            menuselected = LOWORD (wparam);
 
516
        menupoped = FALSE;
 
517
        return;
 
518
    }
 
519
    if (!(LOWORD (wparam) > 0 && LOWORD (wparam) < Gwidgetn))
 
520
        return;
 
521
    child = &Gwidgets[LOWORD (wparam)];
 
522
    if (!child->inuse)
 
523
        return;
 
524
 
 
525
    switch (child->type) {
 
526
    case G_TEXTWIDGET:
 
527
        if (HIWORD (wparam) == EN_CHANGE) { /* it's a text widget message */
 
528
            if ((n = SendMessage (child->w, EM_GETLINECOUNT, 0, 0L)) < 2)
 
529
                return;
 
530
            *((WORD *) &Gbufp[0]) = Gbufn - 1;
 
531
            l = SendMessage (child->w, EM_GETLINE, n - 1,
 
532
                    (LPARAM) (LPSTR) &Gbufp[0]);
 
533
            if (l != 0)
 
534
                return; /* no carriage return yet */
 
535
            *((WORD *) &Gbufp[0]) = Gbufn - 1;
 
536
            l = SendMessage (child->w, EM_GETLINE, n - 2,
 
537
                    (LPARAM) (LPSTR) &Gbufp[0]);
 
538
            Gbufp[l] = 0;
 
539
            if (l > 0 && child->u.t->func)
 
540
                (*child->u.t->func) (child - &Gwidgets[0], &Gbufp[0]);
 
541
        }
 
542
        break;
 
543
    case G_BUTTONWIDGET:
 
544
        if (child->u.b->func)
 
545
             (*child->u.b->func) (child - &Gwidgets[0], child->udata);
 
546
        break;
 
547
    }
 
548
}
 
549
 
 
550
void Gadjustwrect (Gwidget_t *parent, PIXsize_t *psp) {
 
551
    RECT r;
 
552
 
 
553
    GetClientRect (parent->w, &r);
 
554
    switch (parent->type) {
 
555
    case G_ARRAYWIDGET:
 
556
        if (parent->u.a->data.type == G_AWHARRAY)
 
557
            psp->y = r.bottom - r.top;
 
558
        else
 
559
            psp->x = r.right - r.left;
 
560
        break;
 
561
    case G_SCROLLWIDGET:
 
562
        psp->x = max (psp->x, r.right - r.left);
 
563
        psp->y = max (psp->y, r.bottom - r.top);
 
564
        break;
 
565
    case G_VIEWWIDGET:
 
566
    case G_QUERYWIDGET:
 
567
        psp->x = r.right - r.left;
 
568
        psp->y = r.bottom - r.top;
 
569
        break;
 
570
    }
 
571
}
 
572
 
 
573
static void handleresize (Gwidget_t *widget) {
 
574
    Gwidget_t *parent, *child;
 
575
    PIXsize_t ps1, ps2;
 
576
    PIXpoint_t po;
 
577
    DWORD wflags1, wflags2;
 
578
    RECT r;
 
579
    int dx, dy, wi, i;
 
580
 
 
581
    wflags1 = SWP_NOMOVE | SWP_NOZORDER;
 
582
    wflags2 = SWP_NOSIZE | SWP_NOZORDER;
 
583
    GetWindowRect (widget->w, &r);
 
584
    ps1.x = r.right - r.left, ps1.y = r.bottom - r.top;
 
585
    ps2 = ps1;
 
586
    /* first, take care of parent */
 
587
    parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi];
 
588
    if (!parent)
 
589
        goto handlechildren;
 
590
    switch (parent->type) {
 
591
    case G_VIEWWIDGET:
 
592
        Gadjustwrect (parent, &ps1);
 
593
        if (ps1.x != ps2.x || ps1.y != ps2.y) {
 
594
            Gnocallbacks = TRUE;
 
595
            SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps1.x, ps1.y, wflags1);
 
596
            Gnocallbacks = FALSE;
 
597
        }
 
598
        break;
 
599
    case G_ARRAYWIDGET:
 
600
        Gnocallbacks = TRUE;
 
601
        Gawresize (parent);
 
602
        Gnocallbacks = FALSE;
 
603
        break;
 
604
    case G_SCROLLWIDGET:
 
605
        Gnocallbacks = TRUE;
 
606
        for (i = 0; i  < 2; i++) {
 
607
            Gadjustwrect (parent, &ps1);
 
608
            if (ps1.x > ps2.x || ps1.y > ps2.y)
 
609
                SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps1.x, ps1.y,
 
610
                        wflags1);
 
611
            GetClientRect (parent->w, &r);
 
612
            ps2.x = r.right - r.left, ps2.y = r.bottom - r.top;
 
613
            dx = max (0, ps1.x - ps2.x);
 
614
            dy = max (0, ps1.y - ps2.y);
 
615
            SetScrollRange (parent->w, SB_HORZ, 0, dx, TRUE);
 
616
            SetScrollRange (parent->w, SB_VERT, 0, dy, TRUE);
 
617
            po.x = GetScrollPos (parent->w, SB_HORZ);
 
618
            po.y = GetScrollPos (parent->w, SB_VERT);
 
619
            po.x = min (po.x, dx);
 
620
            po.x = max (po.x, 0);
 
621
            SetScrollPos (parent->w, SB_HORZ, po.x, TRUE);
 
622
            po.y = min (po.y, dy);
 
623
            po.y = max (po.y, 0);
 
624
            SetScrollPos (parent->w, SB_VERT, po.y, TRUE);
 
625
            SetWindowPos (widget->w, (HWND) NULL, -po.x, -po.y, 0, 0, wflags2);
 
626
            ps2 = ps1;
 
627
        }
 
628
        Gnocallbacks = FALSE;
 
629
        break;
 
630
    }
 
631
 
 
632
handlechildren:
 
633
    for (wi = 0; wi < Gwidgetn; wi++) {
 
634
        child = &Gwidgets[wi];
 
635
        if (child->inuse && child->pwi == widget - &Gwidgets[0])
 
636
            break;
 
637
    }
 
638
    if (wi == Gwidgetn)
 
639
        return;
 
640
    GetWindowRect (child->w, &r);
 
641
    ps1.x = r.right - r.left, ps1.y = r.bottom - r.top;
 
642
    ps2 = ps1;
 
643
    switch (widget->type) {
 
644
    case G_VIEWWIDGET:
 
645
        Gadjustwrect (widget, &ps1);
 
646
        if (ps1.x != ps2.x || ps1.y != ps2.y)
 
647
            SetWindowPos (child->w, (HWND) NULL, 0, 0, ps1.x, ps1.y, wflags1);
 
648
        break;
 
649
    case G_ARRAYWIDGET:
 
650
        Gawresize (widget);
 
651
        break;
 
652
    case G_SCROLLWIDGET:
 
653
        Gadjustwrect (widget, &ps1);
 
654
        if (ps1.x > ps2.x || ps1.y > ps2.y)
 
655
            SetWindowPos (child->w, (HWND) NULL, 0, 0, ps1.x, ps1.y, wflags1);
 
656
        GetClientRect (widget->w, &r);
 
657
        ps2.x = r.right - r.left, ps2.y = r.bottom - r.top;
 
658
        dx = max (0, ps1.x - ps2.x);
 
659
        dy = max (0, ps1.y - ps2.y);
 
660
        SetScrollRange (widget->w, SB_HORZ, 0, dx, TRUE);
 
661
        SetScrollRange (widget->w, SB_VERT, 0, dy, TRUE);
 
662
        po.x = GetScrollPos (widget->w, SB_HORZ);
 
663
        po.y = GetScrollPos (widget->w, SB_VERT);
 
664
        po.x = min (po.x, dx);
 
665
        po.x = max (po.x, 0);
 
666
        SetScrollPos (widget->w, SB_HORZ, po.x, TRUE);
 
667
        po.y = min (po.y, dy);
 
668
        po.y = max (po.y, 0);
 
669
        SetScrollPos (widget->w, SB_VERT, po.y, TRUE);
 
670
        SetWindowPos (child->w, (HWND) NULL, -po.x, -po.y, 0, 0, wflags2);
 
671
        break;
 
672
    }
 
673
}