~ubuntu-branches/ubuntu/saucy/python-scipy/saucy

« back to all changes in this revision

Viewing changes to Lib/sandbox/xplt/src/play/win/pscr.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * pscr.c -- $Id: pscr.c 685 2003-03-08 15:26:51Z travo $
3
 
 * routines to initialize graphics for MS Windows
4
 
 *
5
 
 * Copyright (c) 2000.  See accompanying LEGAL file for details.
6
 
 */
7
 
 
8
 
/* is this really necessary to get OCR_*?? */
9
 
#define OEMRESOURCE
10
 
 
11
 
#include "playw.h"
12
 
#include "pstdlib.h"
13
 
 
14
 
HINSTANCE w_app_instance = 0;
15
 
HWND w_main_window = 0;
16
 
 
17
 
p_scr w_screen;
18
 
 
19
 
static void (*won_expose)(void *c,int *xy)= 0;
20
 
static void (*won_destroy)(void *c)= 0;
21
 
static void (*won_resize)(void *c,int w,int h)= 0;
22
 
static void (*won_focus)(void *c,int in)= 0;
23
 
static void (*won_key)(void *c,int k,int md)= 0;
24
 
static void (*won_click)(void *c,int b,int md,int x,int y,unsigned long ms)=0;
25
 
static void (*won_motion)(void *c,int md,int x,int y)= 0;
26
 
static void (*won_deselect)(void *c)= 0;
27
 
 
28
 
LPCTSTR w_win_class = "w_win_class";
29
 
LPCTSTR w_menu_class = "w_menu_class";
30
 
 
31
 
static char *clip_text = 0;
32
 
static HWND clip_owner = 0;
33
 
static void clip_free(int force);
34
 
 
35
 
LONG APIENTRY WndProc ( 
36
 
    HWND         hWnd, 
37
 
    UINT     iMessage, 
38
 
    UINT         wParam, 
39
 
    LONG         lParam) 
40
 
{
41
 
  PAINTSTRUCT ps;
42
 
    switch (iMessage) {
43
 
    case WM_PAINT:
44
 
      BeginPaint(hWnd, &ps);
45
 
      EndPaint(hWnd, &ps);
46
 
      break;
47
 
    default:
48
 
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ; 
49
 
    }
50
 
    return 0;
51
 
}
52
 
 
53
 
void (*p_on_connect)(int dis, int fd) = 0;
54
 
 
55
 
p_scr *
56
 
p_connect(char *server_name)
57
 
{
58
 
  static int registered = 0;
59
 
  HDC dc0 = GetDC(0);
60
 
  RECT r;
61
 
  int i;
62
 
 
63
 
  if (server_name) return 0;
64
 
 
65
 
  w_screen.width = GetSystemMetrics(SM_CXSCREEN);
66
 
  w_screen.height = GetSystemMetrics(SM_CYSCREEN);
67
 
  w_screen.depth = GetDeviceCaps(dc0, BITSPIXEL);
68
 
 
69
 
  /* adjust width and height for taskbar, other toolbar garbage */
70
 
  if (SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&r, 0)) {
71
 
    w_screen.x0 = r.left;
72
 
    w_screen.y0 = r.top;
73
 
    w_screen.width = r.right - r.left;
74
 
    w_screen.height = r.bottom - r.top;
75
 
  }
76
 
 
77
 
  /* windows linetypes are unusably ugly for thin lines */
78
 
  /*w_screen.does_linetypes = GetDeviceCaps(dc0, LINECAPS) & LC_WIDESTYLED;*/
79
 
  w_screen.does_linetypes = 0;
80
 
  w_screen.does_rotext = GetDeviceCaps(dc0, TEXTCAPS) & TC_CR_90;
81
 
 
82
 
  w_screen.sys_colors[255-P_BLACK] = RGB(0,0,0);
83
 
  w_screen.sys_colors[255-P_WHITE] = RGB(255,255,255);
84
 
  w_screen.sys_colors[255-P_RED] = RGB(255,0,0);
85
 
  w_screen.sys_colors[255-P_GREEN] = RGB(0,255,0);
86
 
  w_screen.sys_colors[255-P_BLUE] = RGB(0,0,255);
87
 
  w_screen.sys_colors[255-P_CYAN] = RGB(0,255,255);
88
 
  w_screen.sys_colors[255-P_MAGENTA] = RGB(255,0,255);
89
 
  w_screen.sys_colors[255-P_YELLOW] = RGB(255,255,0);
90
 
  w_screen.sys_colors[255-P_BG] = GetSysColor(COLOR_WINDOW);
91
 
  w_screen.sys_colors[255-P_FG] = GetSysColor(COLOR_WINDOWTEXT);
92
 
  w_screen.sys_colors[255-P_GRAYD] = RGB(100,100,100);
93
 
  w_screen.sys_colors[255-P_GRAYC] = RGB(150,150,150);
94
 
  w_screen.sys_colors[255-P_GRAYB] = RGB(190,190,190);
95
 
  w_screen.sys_colors[255-P_GRAYA] = RGB(214,214,214);
96
 
  w_screen.sys_colors[255-P_XOR] = 0xffffff;  /* really fg^bg, but unused */
97
 
  i = GetDeviceCaps(dc0, NUMRESERVED);
98
 
  if (w_screen.depth==8 && i>1 && i<=32 &&
99
 
      (GetDeviceCaps(dc0, RASTERCAPS)&RC_PALETTE) &&
100
 
      GetDeviceCaps(dc0, SIZEPALETTE)==256) {
101
 
    PALETTEENTRY *pal = p_malloc(sizeof(PALETTEENTRY)*i);
102
 
    if (pal) {
103
 
      struct {
104
 
        WORD version;
105
 
        WORD nentries;
106
 
        PALETTEENTRY entry[32];
107
 
      } yuck;
108
 
      HPALETTE syspal;
109
 
      int sz = GetDeviceCaps(dc0, SIZEPALETTE);
110
 
      int n = i;
111
 
      w_screen.sys_offset = n/2;
112
 
      w_screen.sys_pal = pal;
113
 
      GetSystemPaletteEntries(dc0, 0, n/2, pal);
114
 
      GetSystemPaletteEntries(dc0, sz-n/2, n/2, pal+n/2);
115
 
      yuck.version = 0x300;
116
 
      yuck.nentries = n;
117
 
      for (i=0 ; i<n ; i++) yuck.entry[i] = pal[i];
118
 
      syspal = CreatePalette((LOGPALETTE *)&yuck);
119
 
      if (syspal) {
120
 
        int j;
121
 
        for (i=0 ; i<15 ; i++) {
122
 
          j = GetNearestPaletteIndex(syspal, w_screen.sys_colors[i]);
123
 
          if (j == CLR_INVALID) PALETTEINDEX(0);
124
 
          w_screen.sys_index[i] = PALETTEINDEX(j);
125
 
        }
126
 
        DeleteObject(syspal);
127
 
      }
128
 
    }
129
 
  } else {
130
 
    for (i=0 ; i<15 ; i++) w_screen.sys_index[i] = w_screen.sys_colors[i];
131
 
    w_screen.sys_offset = 0;
132
 
    w_screen.sys_pal = 0;
133
 
  }
134
 
 
135
 
  w_screen.gui_font = GetStockObject(ANSI_FIXED_FONT);
136
 
  /* w_screen.def_palette = GetStockObject(DEFAULT_PALETTE); */
137
 
  /* w_screen.null_brush = GetStockObject(NULL_BRUSH); */
138
 
  /* w_screen.null_pen = CreatePen(PS_NULL, 0, 0); */
139
 
 
140
 
  for (i=0 ; i<W_FONTS_CACHED ; i++) {
141
 
    w_screen.font_order[i] = i;
142
 
    w_screen.font_cache[i].hfont = 0;
143
 
  }
144
 
  w_screen.font_win = 0;
145
 
 
146
 
  {
147
 
    char *sys_cursor[P_NONE] = {
148
 
      IDC_ARROW, IDC_CROSS, IDC_IBEAM, 0, 0, 0, 0,
149
 
      IDC_SIZENS, IDC_SIZEWE, IDC_SIZEALL, 0, 0, 0 };
150
 
    int i;
151
 
    for (i=0 ; i<P_NONE ; i++) {
152
 
      if (sys_cursor[i])
153
 
        w_screen.cursors[i] = LoadCursor(0, sys_cursor[i]);
154
 
      else
155
 
        w_screen.cursors[i] = 0;
156
 
    }
157
 
  }
158
 
 
159
 
  w_screen.first_menu = w_screen.active = 0;
160
 
 
161
 
  if (!registered) {
162
 
    WNDCLASSEX class_data;
163
 
    class_data.cbSize = sizeof(WNDCLASSEX);
164
 
    class_data.style = CS_OWNDC;
165
 
    class_data.lpfnWndProc = (WNDPROC)w_winproc;
166
 
    class_data.cbClsExtra = 0;
167
 
    class_data.cbWndExtra = 0;
168
 
    class_data.hInstance = w_app_instance;
169
 
    class_data.hIcon = 0;
170
 
    class_data.hCursor = 0;
171
 
    class_data.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
172
 
    class_data.lpszMenuName = 0;
173
 
    class_data.lpszClassName = w_win_class;
174
 
    class_data.hIconSm = 0;
175
 
    if (!RegisterClassEx(&class_data)) return 0;
176
 
 
177
 
    class_data.cbSize = sizeof(WNDCLASSEX);
178
 
    class_data.style = CS_OWNDC | CS_SAVEBITS;
179
 
    class_data.lpfnWndProc = (WNDPROC)w_winproc;
180
 
    class_data.cbClsExtra = 0;
181
 
    class_data.cbWndExtra = 0;
182
 
    class_data.hInstance = w_app_instance;
183
 
    class_data.hIcon = 0;
184
 
    class_data.hCursor = 0;
185
 
    class_data.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
186
 
    class_data.lpszMenuName = 0;
187
 
    class_data.lpszClassName = w_menu_class;
188
 
    class_data.hIconSm = 0;
189
 
    if (!RegisterClassEx(&class_data)) return 0;
190
 
    registered = 1;
191
 
  }
192
 
 
193
 
  if (p_on_connect) p_on_connect(0, -1);
194
 
 
195
 
  return &w_screen;
196
 
}
197
 
 
198
 
int
199
 
p_sshape(p_scr *s, int *width, int *height)
200
 
{
201
 
  *width = s->width;
202
 
  *height = s->height;
203
 
  return s->depth;
204
 
}
205
 
 
206
 
/* ARGSUSED */
207
 
p_scr *
208
 
p_multihead(p_scr *other, int number)
209
 
{
210
 
  return 0;
211
 
}
212
 
 
213
 
/* ARGSUSED */
214
 
void
215
 
p_disconnect(p_scr *s)
216
 
{
217
 
  int i;
218
 
  if (p_on_connect) p_on_connect(1, -1);
219
 
  for (i=0 ; i<W_FONTS_CACHED && s->font_cache[i].hfont ; i++) {
220
 
    DeleteObject(s->font_cache[i].hfont);
221
 
    s->font_cache[i].hfont = 0;
222
 
  }
223
 
  for (i=3 ; i<=12 ; i++) {
224
 
    if ((i>6 && i<10) || !s->cursors[i] || s->cursors[i]==s->cursors[0])
225
 
      continue;
226
 
    DestroyCursor(s->cursors[i]);
227
 
    s->cursors[i] = s->cursors[0];
228
 
  }
229
 
  if (s->sys_pal) p_free(s->sys_pal), s->sys_pal = 0;
230
 
}
231
 
 
232
 
/* ARGSUSED */
233
 
void
234
 
p_gui(void (*on_expose)(void *c, int *xy),
235
 
      void (*on_destroy)(void *c),
236
 
      void (*on_resize)(void *c,int w,int h),
237
 
      void (*on_focus)(void *c,int in),
238
 
      void (*on_key)(void *c,int k,int md),
239
 
      void (*on_click)(void *c,int b,int md,int x,int y,
240
 
                       unsigned long ms),
241
 
      void (*on_motion)(void *c,int md,int x,int y),
242
 
      void (*on_deselect)(void *c),
243
 
      void (*on_panic)(p_scr *s))
244
 
{
245
 
  won_expose = on_expose;
246
 
  won_destroy = on_destroy;
247
 
  won_resize = on_resize;
248
 
  won_focus = on_focus;
249
 
  won_key = on_key;
250
 
  won_click = on_click;
251
 
  won_motion = on_motion;
252
 
  won_deselect = on_deselect;
253
 
}
254
 
 
255
 
/* ARGSUSED */
256
 
void
257
 
p_flush(p_win *w)
258
 
{
259
 
  GdiFlush();
260
 
}
261
 
 
262
 
void
263
 
p_clear(p_win *w)
264
 
{
265
 
  RECT r;
266
 
  if (!p_signalling && GetClientRect(w->w? w->w : w->parent->w, &r)) {
267
 
    if (w->dc) {
268
 
      HBRUSH b = CreateSolidBrush(w_color(w, w->bg));
269
 
      if (b) {
270
 
        FillRect(w->dc, &r, b);
271
 
        DeleteObject(b);
272
 
      }
273
 
    }
274
 
  }
275
 
}
276
 
 
277
 
void
278
 
p_winloc(p_win *w, int *x, int *y)
279
 
{
280
 
  POINT p;
281
 
  p.x = p.y = 0;
282
 
  if (w->w && ClientToScreen(w->w, &p)) {
283
 
    *x = p.x - w->s->x0;
284
 
    *y = p.y - w->s->y0;
285
 
  } else {
286
 
    *x = *y = 0;
287
 
  }
288
 
}
289
 
 
290
 
void
291
 
p_resize(p_win *w, int width, int height)
292
 
{
293
 
  HWND hw = w->w;
294
 
  if (hw) {
295
 
    RECT rin, rout;
296
 
    if (GetClientRect(hw, &rin)) {
297
 
      if (w->ancestor) hw = w->ancestor;
298
 
      if (GetWindowRect(hw, &rout)) {
299
 
        width += (rout.right-rout.left) - rin.right;
300
 
        height += (rout.bottom-rout.top) - rin.bottom;
301
 
      }
302
 
    }
303
 
    SetWindowPos(hw, 0, 0,0, width,height,
304
 
                 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
305
 
  }
306
 
}
307
 
 
308
 
void
309
 
p_raise(p_win *w)
310
 
{
311
 
  ShowWindow(w->w, SW_SHOW);
312
 
  /* also SetActiveWindow, SetForegroundWindow */
313
 
  BringWindowToTop(w->w);
314
 
}
315
 
 
316
 
int w_nwins = 0;
317
 
 
318
 
LRESULT CALLBACK
319
 
w_winproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
320
 
{
321
 
  p_win *pw = (p_win *)GetWindowLong(hwnd, GWL_USERDATA);
322
 
  if (pw && pw->w==hwnd) {
323
 
    int button = 0;
324
 
 
325
 
    if (msg == WM_CHAR) {  /* horrible design */
326
 
      if (won_key && pw->ctx) {
327
 
        int key = (int)(pw->keydown&&0xffff);
328
 
        if (!key) {
329
 
          int state = (int)(pw->keydown>>16);
330
 
          key = wp;
331
 
          if (GetKeyState(VK_SHIFT)<0) state |= P_SHIFT;
332
 
          if (GetKeyState(VK_CONTROL)<0) state |= P_CONTROL;
333
 
          if (HIWORD(lp)&KF_ALTDOWN) state |= P_ALT;  /* doesnt work */
334
 
          won_key(pw->ctx, key, state);
335
 
        }
336
 
        pw->keydown = 0;
337
 
      }
338
 
      return 0;
339
 
    }
340
 
    pw->keydown &= 0; /* ((unsigned long)P_META)<<16; */
341
 
 
342
 
    switch (msg) {
343
 
    case WM_PAINT:
344
 
      /* call BeginPaint or ValidateRect to avoid another WM_PAINT */
345
 
      if (won_expose && pw->ctx) {
346
 
        RECT r;
347
 
        int xy[4];
348
 
        if (GetUpdateRect(hwnd, &r, 0)) {
349
 
          xy[0] = r.left;
350
 
          xy[1] = r.top;
351
 
          xy[2] = r.right;
352
 
          xy[3] = r.bottom;
353
 
        } else {
354
 
          r.left = r.top = r.right = r.bottom = 0;
355
 
        }
356
 
        if (GetClientRect(hwnd, &r))
357
 
          won_expose(pw->ctx, (xy[0]<=0 && xy[1]<=0 && xy[2]>=r.right &&
358
 
                               xy[3]>=r.bottom)? 0 : xy);
359
 
      }
360
 
      ValidateRect(hwnd, 0);
361
 
      return 0;
362
 
    case WM_ERASEBKGND:
363
 
      p_clear(pw);
364
 
      return 1;
365
 
    case WM_SIZE:
366
 
      if (won_resize && pw->ctx && wp!=SIZE_MINIMIZED &&
367
 
          wp!=SIZE_MAXHIDE && wp!=SIZE_MAXSHOW) {
368
 
        int width = LOWORD(lp);
369
 
        int height = HIWORD(lp);
370
 
        won_resize(pw->ctx, width, height);
371
 
      }
372
 
      return 0;
373
 
    case WM_DESTROY:
374
 
      w_nwins--;
375
 
      pw->w = 0;
376
 
      pw->dc = 0;
377
 
      if (pw == pw->s->active) pw->s->active = 0;
378
 
      if (pw == pw->s->first_menu) {
379
 
        pw->s->first_menu = 0;
380
 
        ReleaseCapture();
381
 
      }
382
 
      if (hwnd == clip_owner) clip_free(1);
383
 
      if (pw->pixels) {
384
 
        p_free(pw->pixels);
385
 
        pw->pixels = 0;
386
 
      }
387
 
      if (pw->palette) {
388
 
        UnrealizeObject(pw->palette);
389
 
        DeleteObject(pw->palette);
390
 
        pw->palette = 0;
391
 
      }
392
 
      if (won_destroy && pw->ctx) won_destroy(pw->ctx);
393
 
      pw->ctx = 0;
394
 
      SetWindowLong(hwnd, GWL_USERDATA, (LONG)0);
395
 
      if (pw->ancestor) {
396
 
        hwnd = pw->ancestor;
397
 
        pw->ancestor = 0;
398
 
        SendMessage(hwnd, WM_CLOSE, 0, 0);
399
 
      }
400
 
      p_free(pw);
401
 
      return 0;
402
 
 
403
 
    case WM_SETFOCUS:
404
 
      if (pw->palette) {
405
 
        pw->s->active = pw;
406
 
        SelectPalette(pw->dc, pw->palette, 0);
407
 
        if (RealizePalette(pw->dc))
408
 
          InvalidateRect(hwnd, 0, 0);
409
 
        SelectPalette(pw->dc, pw->palette, 1);
410
 
        RealizePalette(pw->dc);
411
 
      }
412
 
      button = 1;
413
 
    case WM_KILLFOCUS:
414
 
      if (won_focus && pw->ctx)
415
 
        won_focus(pw->ctx, button);
416
 
      return 0;
417
 
 
418
 
    case WM_QUERYNEWPALETTE:
419
 
      if (pw->palette || pw->s->active) {
420
 
        if (!pw->palette) pw = pw->s->active;
421
 
        else if (pw->s->active != pw) pw->s->active = pw;
422
 
        SelectPalette(pw->dc, pw->palette, 0);
423
 
        button = RealizePalette(pw->dc);
424
 
        if (button) InvalidateRect(hwnd, 0, 0);
425
 
        SelectPalette(pw->dc, pw->palette, 1);
426
 
        RealizePalette(pw->dc);
427
 
      }
428
 
      return button;
429
 
 
430
 
    case WM_KEYDOWN:
431
 
      if (won_key && pw->ctx) {  /* wp is virtual key code */
432
 
        int key = 0;
433
 
        int state = 0; /* (int)((pw->keydown>>16)&P_META); */
434
 
        if (wp>=VK_NUMPAD0 && wp<=VK_F24) {
435
 
          if (wp<=VK_DIVIDE) {
436
 
            if (wp<=VK_NUMPAD9) key = (wp-VK_NUMPAD0) + '0';
437
 
            else if (wp==VK_MULTIPLY) key = '*';
438
 
            else if (wp==VK_ADD) key = '+';
439
 
            else if (wp==VK_SEPARATOR) key = '=';
440
 
            else if (wp==VK_SUBTRACT) key = '-';
441
 
            else if (wp==VK_DECIMAL) key = '.';
442
 
            else if (wp==VK_DIVIDE) key = '/';
443
 
            state |= P_KEYPAD;
444
 
          } else {
445
 
            key = (wp-VK_F1) + P_F1;
446
 
          }
447
 
        } else if (wp==VK_PRIOR) key = P_PGUP;
448
 
        else if (wp==VK_NEXT) key = P_PGDN;
449
 
        else if (wp==VK_END) key = P_END;
450
 
        else if (wp==VK_HOME) key = P_HOME;
451
 
        else if (wp==VK_LEFT) key = P_LEFT;
452
 
        else if (wp==VK_UP) key = P_UP;
453
 
        else if (wp==VK_RIGHT) key = P_RIGHT;
454
 
        else if (wp==VK_DOWN) key = P_DOWN;
455
 
        else if (wp==VK_INSERT) key = P_INSERT;
456
 
        else if (wp==VK_DELETE) key = 0x7f;
457
 
        if (key) {
458
 
          if (GetKeyState(VK_SHIFT)<0) state |= P_SHIFT;
459
 
          if (GetKeyState(VK_CONTROL)<0) state |= P_CONTROL;
460
 
          /* VK_MENU doesnt work */
461
 
          won_key(pw->ctx, key, state);
462
 
        } else if (wp==VK_SPACE && GetKeyState(VK_CONTROL)<0) {
463
 
          if (GetKeyState(VK_SHIFT)<0) state |= P_SHIFT;
464
 
          won_key(pw->ctx, 0, state);
465
 
          key = ' ';
466
 
        } else if (wp==VK_SHIFT || wp==VK_CONTROL || wp==VK_MENU ||
467
 
                   wp==VK_CAPITAL || wp==VK_NUMLOCK) {
468
 
          key = 0x8000;
469
 
        } else if (wp==VK_LWIN || wp==VK_RWIN) {
470
 
          /* state |= P_META;   this idea didnt work */
471
 
        }
472
 
        pw->keydown = (((unsigned long)state)<<16) | key;
473
 
      }
474
 
      return 0;
475
 
    case WM_KEYUP:
476
 
      /* if (wp==VK_LWIN || wp==VK_RWIN) pw->keydown = 0; */
477
 
      break;
478
 
 
479
 
    case WM_RBUTTONDOWN:
480
 
      button++;
481
 
    case WM_MBUTTONDOWN:
482
 
      button++;
483
 
    case WM_LBUTTONDOWN:
484
 
      button++;
485
 
    case WM_RBUTTONUP:
486
 
      button++;
487
 
    case WM_MBUTTONUP:
488
 
      button++;
489
 
    case WM_LBUTTONUP:
490
 
      button++;
491
 
      if (won_click && pw->ctx) {
492
 
        int x = LOWORD(lp);
493
 
        int y = HIWORD(lp);
494
 
        int state = 0;
495
 
        int down = (button>3);
496
 
        if (down) button -= 3;
497
 
        if (wp&MK_LBUTTON) state |= P_BTN1;
498
 
        if (wp&MK_MBUTTON) state |= P_BTN2;
499
 
        if (wp&MK_RBUTTON) state |= P_BTN3;
500
 
        if (wp&MK_CONTROL) state |= P_CONTROL;
501
 
        if (wp&MK_SHIFT) state |= P_SHIFT;
502
 
        /* if (GetKeyState(VK_MENU)<0) state |= P_ALT; doesnt work */
503
 
        /* P_META? */
504
 
        state ^= (1<<(button+2));  /* make consistent with X11 */
505
 
        won_click(pw->ctx, button, state, x, y, GetMessageTime());
506
 
      }
507
 
      return 0;
508
 
 
509
 
    case WM_MOUSEMOVE:
510
 
      if (won_motion && pw->ctx) {
511
 
        int x = LOWORD(lp);
512
 
        int y = HIWORD(lp);
513
 
        int state = 0;
514
 
        if (wp&MK_LBUTTON) state |= P_BTN1;
515
 
        if (wp&MK_MBUTTON) state |= P_BTN2;
516
 
        if (wp&MK_RBUTTON) state |= P_BTN3;
517
 
        if (wp&MK_CONTROL) state |= P_CONTROL;
518
 
        if (wp&MK_SHIFT) state |= P_SHIFT;
519
 
        /* P_META, P_ALT? */
520
 
        won_motion(pw->ctx, state, x, y);
521
 
        /* counting messages is problematic because p_qclear might remove
522
 
         * them, and servicing motion messages out of order seems a poor
523
 
         * idea -- so just deliver them all for now
524
 
         * -- perhaps play API should have a function to check if there are
525
 
         *    pending motion events? */
526
 
      }
527
 
      return 0;
528
 
 
529
 
    case WM_SETCURSOR:
530
 
      if (LOWORD(lp) == HTCLIENT) {
531
 
        SetCursor(pw->cursor);
532
 
        return 1;
533
 
      }
534
 
      break;
535
 
 
536
 
    case WM_DESTROYCLIPBOARD:
537
 
      clip_free(0);
538
 
      if (won_deselect && pw->ctx) won_deselect(pw->ctx);
539
 
      return 0;
540
 
    }
541
 
 
542
 
  } else if (msg == WM_CREATE) {
543
 
    LPCREATESTRUCT cs = (LPCREATESTRUCT)lp;
544
 
    pw = cs? cs->lpCreateParams : 0;
545
 
    if (pw) {
546
 
      HDC dc = GetDC(hwnd);
547
 
      SetWindowLong(hwnd, GWL_USERDATA, (LONG)pw);
548
 
      pw->w = hwnd;
549
 
      pw->dc = dc;
550
 
      SetBkColor(dc, w_color(pw, pw->bg));
551
 
      SetBkMode(dc, TRANSPARENT);
552
 
      SetTextAlign(dc, TA_LEFT | TA_BASELINE | TA_NOUPDATECP);
553
 
      if (pw->menu && !pw->s->first_menu)  {
554
 
        pw->s->first_menu = pw;
555
 
        SetCapture(hwnd);
556
 
      }
557
 
      w_nwins++;
558
 
      return 0;
559
 
    }
560
 
  }
561
 
 
562
 
  /* consider also DefFrameProc, DefMDIChildProc */
563
 
  return DefWindowProc(hwnd, msg, wp, lp);
564
 
}
565
 
 
566
 
static void
567
 
clip_free(int force)
568
 
{
569
 
  char *t = clip_text;
570
 
 
571
 
  if (force && clip_owner && OpenClipboard(0)) {
572
 
    EmptyClipboard();
573
 
    CloseClipboard();
574
 
  }
575
 
 
576
 
  clip_owner = 0;
577
 
  clip_text = 0;
578
 
  if (t) p_free(t);
579
 
}
580
 
 
581
 
int
582
 
p_scopy(p_win *w, char *string, int n)
583
 
{
584
 
  int result = 1;
585
 
  HWND owner = (string && (n>0))? w->w : 0;
586
 
  if (!p_signalling && OpenClipboard(owner)) {
587
 
    if (EmptyClipboard()) {
588
 
      int i;
589
 
      char *tedious = clip_text;
590
 
      clip_free(0);  /* actually called during EmptyClipboard */
591
 
      clip_text = p_strncat(0, string, n);
592
 
      tedious = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, n+1);
593
 
      string = tedious? GlobalLock(tedious) : 0;
594
 
      if (string) {
595
 
        for (i=0 ; clip_text[i] ; i++) string[i] = clip_text[i];
596
 
        string[i] = '\0';
597
 
        GlobalUnlock(tedious);
598
 
        SetClipboardData(CF_TEXT, tedious);
599
 
        clip_owner = owner;
600
 
        result = 0;
601
 
      }
602
 
    }
603
 
    CloseClipboard();
604
 
  }
605
 
  return result;
606
 
}
607
 
 
608
 
char *
609
 
p_spaste(p_win *w)
610
 
{
611
 
  if (p_signalling) return 0;
612
 
  if (!clip_owner && OpenClipboard(w->w)) {
613
 
    char *tedious = GetClipboardData(CF_TEXT);
614
 
    char *string = tedious? GlobalLock(tedious) : 0;
615
 
    clip_free(0);
616
 
    if (string) {
617
 
      clip_text = p_strcpy(string);
618
 
      GlobalUnlock(tedious);
619
 
    }
620
 
    CloseClipboard();
621
 
  }
622
 
  return clip_text;
623
 
}