~ubuntu-branches/ubuntu/jaunty/texlive-bin/jaunty-security

« back to all changes in this revision

Viewing changes to build/source/texk/windvi/windraw.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2008-06-26 23:14:59 UTC
  • mfrom: (2.1.30 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080626231459-y02rjsrgtafu83yr
Tags: 2007.dfsg.2-3
add missing source roadmap.fig of roadmap.eps in fontinst documentation
(Closes: #482915) (urgency medium due to RC bug)
(new patch add-missing-fontinst-source)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "wingui.h"
 
2
#include "xdvi-config.h"
 
3
#include "gsdll.h"
 
4
#include "version.h"
 
5
 
 
6
#ifndef WIN32
 
7
#include "WWWLib.h"
 
8
#include "WWWInit.h"
 
9
#endif
 
10
 
 
11
#ifdef HTEX
 
12
/* Application name and version for w3c-libwww routines.  
 
13
   This is what will show up in httpd's agent_log files. 
 
14
*/
 
15
#ifdef Omega
 
16
char *HTAppName = "owindvi";
 
17
#else
 
18
char *HTAppName = "windvi";
 
19
#endif
 
20
char *HTAppVersion = XDVERSION;
 
21
 
 
22
/* Create the anchor information stuff at the bottom of the page */
 
23
 
 
24
/* Anchor search: a dialog box */
 
25
/* anchorinfo = Ascii text widget */
 
26
 
 
27
char anchorsearchstring[1024];
 
28
char anchorask[] = "Access new URL:";
 
29
 
 
30
#endif
 
31
 
 
32
#define mask_mag(ev) ((ev & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) && !(ev & (MK_SHIFT | MK_CONTROL)))
 
33
#define mask_sethome(ev) ((ev & MK_LBUTTON) && (ev & MK_SHIFT))
 
34
#define mask_srcspecial(ev) ((ev & MK_RBUTTON) && (ev & MK_SHIFT))
 
35
#define mask_opennewframe(ev) ((ev & MK_LBUTTON) && (ev & MK_CONTROL))
 
36
 
 
37
/*****************************************************************************
 
38
  Drawing child window 
 
39
  ****************************************************************************/
 
40
HWND hWndDraw;
 
41
BOOL bDrawKeep = FALSE;
 
42
HDC hdcDrawSave = 0;
 
43
static HRGN hrgnScroll = 0;
 
44
 
 
45
LRESULT CALLBACK DrawProc(HWND, UINT, WPARAM, LPARAM);
 
46
 
 
47
/* Drawing window message table definition. */
 
48
MSD rgmsdDraw[] =
 
49
{
 
50
    {WM_CREATE,     MsgDrawCreate    },
 
51
    /*    {WM_SIZE,       MsgDrawSize      }, */
 
52
    {WM_HSCROLL,    MsgDrawHScroll   },
 
53
    {WM_VSCROLL,    MsgDrawVScroll   },
 
54
    {WM_MOUSEMOVE,  MsgDrawMousemove },
 
55
    /* {WM_COMMAND,    MsgDrawCommand   }, */
 
56
    {WM_PAINT,      MsgDrawPaint     },
 
57
    /*    {WM_ERASEBKGND, MsgDrawEraseBkgnd}, */
 
58
    /*    {WM_NCPAINT,    MsgDrawNCPaint     }, */
 
59
    {WM_LBUTTONDOWN,MsgDrawEnterMagL },
 
60
    {WM_LBUTTONUP,  MsgDrawQuitMagL  },
 
61
    {WM_MBUTTONDOWN,MsgDrawEnterMagM },
 
62
    {WM_MBUTTONUP,  MsgDrawQuitMagL  },
 
63
    {WM_RBUTTONDOWN,MsgDrawEnterMagR },
 
64
    {WM_RBUTTONUP,  MsgDrawQuitMagL  }
 
65
};
 
66
 
 
67
MSDI msdiDraw =
 
68
{
 
69
    sizeof(rgmsdDraw) / sizeof(MSD),
 
70
    rgmsdDraw,
 
71
    edwpWindow
 
72
};
 
73
 
 
74
/* Drawing window command table definition. */
 
75
CMD rgcmdDraw[] =
 
76
{
 
77
  {IDM_FILEOPEN, CmdStub}
 
78
};
 
79
 
 
80
CMDI cmdiDraw =
 
81
{
 
82
    sizeof(rgcmdDraw) / sizeof(CMD),
 
83
    rgcmdDraw,
 
84
    edwpNone
 
85
};
 
86
 
 
87
/*****************************************************************************
 
88
  Magnifying child window 
 
89
  ****************************************************************************/
 
90
HWND hWndMagnify;
 
91
HDC magDC, magMemDC;
 
92
BOOL bMagDisp = FALSE;          /* Mag. Glass is displayed */
 
93
BOOL bSetHome = FALSE;          /* User is setting home position */
 
94
BOOL bSrcSpecial = FALSE;   /* User wants to jump to the next src special */
 
95
 
 
96
int magWidth, magHeight;
 
97
 
 
98
LRESULT CALLBACK MagnifyProc(HWND, UINT, WPARAM, LPARAM);
 
99
 
 
100
/* Magnifying window message table definition. */
 
101
MSD rgmsdMagnify[] =
 
102
{
 
103
    {WM_CREATE,     MsgMagnifyCreate    },
 
104
    /*    {WM_SIZE,       MsgMagnifySize      },
 
105
    {WM_HSCROLL,    MsgMagnifyHScroll   },
 
106
    {WM_VSCROLL,    MsgMagnifyVScroll   },
 
107
    {WM_MOUSEMOVE,  MsgMagnifyMousemove },
 
108
    {WM_COMMAND,    MsgMagnifyCommand   }, */
 
109
    /* {WM_ERASEBKGND, MsgMagnifyEraseBkgnd}, */
 
110
    {WM_PAINT,      MsgMagnifyPaint     }
 
111
};
 
112
 
 
113
MSDI msdiMagnify =
 
114
{
 
115
    sizeof(rgmsdMagnify) / sizeof(MSD),
 
116
    rgmsdMagnify,
 
117
    edwpWindow
 
118
};
 
119
 
 
120
/* Magnifying window command table definition. */
 
121
CMD rgcmdMagnify[] =
 
122
{
 
123
  {IDM_FILEOPEN, CmdStub}
 
124
};
 
125
 
 
126
CMDI cmdiMagnify =
 
127
{
 
128
    sizeof(rgcmdMagnify) / sizeof(CMD),
 
129
    rgcmdMagnify,
 
130
    edwpNone
 
131
};
 
132
 
 
133
/*
 
134
 
 
135
  Magnifying glass
 
136
 
 
137
 */
 
138
BOOL CreateMagnify(HWND hwndParent)
 
139
{
 
140
  extern HBRUSH foreBrush, backBrush;
 
141
  extern HPEN forePen;
 
142
 
 
143
  hWndMagnify = CreateWindow("MagnifyGlass",
 
144
                             NULL,
 
145
                             WS_BORDER | WS_POPUP | WS_DISABLED,
 
146
                             /* | WS_CLIPSIBLINGS, */
 
147
                             0, 0, 50, 50,
 
148
                             hwndParent,
 
149
                             NULL,
 
150
                             hInst, 
 
151
                             NULL);
 
152
  if (hWndMagnify == NULL) {
 
153
    Win32Error("CreateWindow/Magnify");
 
154
    return FALSE;
 
155
  }
 
156
  alt.win = hWndMagnify;
 
157
  magDC = GetDC(hWndMagnify);
 
158
 
 
159
#if 1
 
160
#ifdef TRANSFORM
 
161
  if (IS_NT)
 
162
    SetGraphicsMode(magDC, GM_ADVANCED);
 
163
#endif
 
164
#endif
 
165
 
 
166
  if (resource.in_memory) {
 
167
    magMemDC = CreateCompatibleDC(magDC);
 
168
#ifdef TRANSFORM
 
169
  if (IS_NT)
 
170
    SetGraphicsMode(magDC, GM_ADVANCED);
 
171
#endif
 
172
  }
 
173
  else {
 
174
    magMemDC = magDC;
 
175
  }
 
176
 
 
177
  SetBkMode(magDC, OPAQUE);
 
178
  SetBkColor(magDC, back_Pixel);
 
179
 
 
180
  return TRUE;
 
181
}
 
182
 
 
183
 
 
184
LRESULT CALLBACK MagnifyProc(HWND hwnd, UINT uMessage, 
 
185
                          WPARAM wparam, LPARAM lparam)
 
186
{
 
187
    return DispMessage(&msdiMagnify, hwnd, uMessage, wparam, lparam);
 
188
}
 
189
 
 
190
LRESULT MsgMagnifyCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
191
{
 
192
  RECT r;
 
193
#if 0
 
194
  GetClientRect(hwnd, &r);
 
195
  if (wparam) FillRect((HDC)wparam, &r, backBrush);
 
196
#endif
 
197
  return 0;
 
198
}
 
199
 
 
200
LRESULT MsgMagnifyEraseBkgnd(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
201
{
 
202
  RECT r;
 
203
  GetClientRect(hwnd, &r);
 
204
  FillRect((HDC)wparam, &r, backBrush);
 
205
  return TRUE;
 
206
}
 
207
 
 
208
LRESULT MsgMagnifyPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
209
{
 
210
  PAINTSTRUCT ps;
 
211
  POINT ptOrg = { 0, 0};
 
212
 
 
213
  BeginPaint(hwnd, &ps);
 
214
 
 
215
  GetWindowOrgEx(maneDrawDC, &ptOrg);
 
216
 
 
217
  if (resource.in_memory) {
 
218
    HBRUSH oldBrush;
 
219
#if 0
 
220
    oldBrush = SelectObject(magDC, foreBrush);
 
221
#endif
 
222
    /* We have to paint in ps.rcPaint, from memory dib. */
 
223
    if (!BitBlt(magDC, 
 
224
                ps.rcPaint.left, ps.rcPaint.top,
 
225
                ps.rcPaint.right - ps.rcPaint.left, 
 
226
                ps.rcPaint.bottom - ps.rcPaint.top,
 
227
                magMemDC, 
 
228
                ps.rcPaint.left, 
 
229
                ps.rcPaint.top, SRCCOPY))
 
230
      Win32Error("Draw Magnify/BitBlt");
 
231
#if 0
 
232
    SelectObject(magDC, oldBrush);
 
233
#endif
 
234
  }
 
235
  else {
 
236
    /* We have to paint directly onto the screen */
 
237
    extern void redraw(struct WindowRec *);
 
238
    RECT altRect;
 
239
 
 
240
    /* swapping to mag. glass device contexts */
 
241
    foreGC =  ruleGC =  highGC = ps.hdc;
 
242
 
 
243
    alt.base_x = (xMousePos + xCurrentScroll + ptOrg.x)*mane.shrinkfactor - magWidth;
 
244
    alt.base_y = (yMousePos + yCurrentScroll + ptOrg.y)*mane.shrinkfactor - magHeight;
 
245
    alt.min_x = ps.rcPaint.left;
 
246
    alt.min_y = ps.rcPaint.top;
 
247
    alt.max_x = ps.rcPaint.right;
 
248
    alt.max_y = ps.rcPaint.bottom;
 
249
    alt.width = ps.rcPaint.right - ps.rcPaint.left;
 
250
    alt.height = ps.rcPaint.bottom - ps.rcPaint.bottom;
 
251
#if 0
 
252
    fprintf(stderr, "Painting in base (%d %d) (%d %d) - (%d %d)\n",
 
253
            alt.base_x, alt.base_y, alt.min_x, alt.min_y, alt.max_x, alt.max_y);
 
254
#endif
 
255
#if 1
 
256
    /* draw background */
 
257
    {
 
258
      RECT rectBg;
 
259
      rectBg.left = max(0, alt.min_x);
 
260
      rectBg.top = max(0, alt.min_y);
 
261
      rectBg.right = min(alt.max_x, unshrunk_paper_w - alt.base_x);
 
262
      rectBg.bottom = min(alt.max_y, unshrunk_paper_h - alt.base_y);
 
263
      FillRect(magDC, &rectBg, backBrush);
 
264
    }
 
265
#if 0
 
266
    draw_rulers(alt.width, alt.height, magDC);
 
267
#endif
 
268
#endif
 
269
    allowDrawingChars = TRUE;
 
270
    redraw(&alt);
 
271
 
 
272
    if (resource.reverse) {
 
273
      PatBlt(foreGC, alt.min_x, alt.min_y, alt.max_x, alt.max_y, DSTINVERT);
 
274
    }
 
275
    /* and back to drawing window dcs */
 
276
    foreGC =  ruleGC =  highGC = maneDrawDC;
 
277
  }
 
278
 
 
279
  EndPaint(hwnd, &ps);
 
280
  return 0;
 
281
}
 
282
 
 
283
/*
 
284
  Process messages for the about box.
 
285
  */
 
286
 
 
287
LRESULT CALLBACK DrawProc(HWND hwnd, UINT uMessage, 
 
288
                          WPARAM wparam, LPARAM lparam)
 
289
{
 
290
    return DispMessage(&msdiDraw, hwnd, uMessage, wparam, lparam);
 
291
}
 
292
 
 
293
/*
 
294
  CreateDraw(hWndParent) : creates the drawing window (child with 
 
295
  scrollbars).
 
296
  */
 
297
BOOL CreateDraw(HWND hwndParent)
 
298
{
 
299
  hWndDraw = CreateWindowEx(WS_EX_CLIENTEDGE, 
 
300
                            TEXT("ClientDrawClass"),
 
301
                            NULL,
 
302
                            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
 
303
                            | WS_HSCROLL | WS_VSCROLL,
 
304
                            -100, -100, 10, 10,
 
305
                            hwndParent,
 
306
                            NULL,
 
307
                            hInst, 
 
308
                            NULL);
 
309
  if (hWndDraw == NULL) {
 
310
    Win32Error("CreateWindowEx");
 
311
    return FALSE;
 
312
  }
 
313
 
 
314
  /* Initialize all graphic related variables */
 
315
 
 
316
  InitGlobalsDraw();
 
317
 
 
318
  SizeClientWindow(hWndDraw);
 
319
  SetScrollBars(hWndDraw);
 
320
  SetCursor(hCursArrow);
 
321
  ShowWindow(hWndDraw, SW_SHOW);
 
322
 
 
323
  make_temporary_dir(&temporary_dir); /* For storing temporary files... */
 
324
 
 
325
  if (dvi_name) {
 
326
    char            *title_name;
 
327
    char            *icon_name;
 
328
    
 
329
    /*
 
330
     *      Open the dvi file and set titles
 
331
     */
 
332
    set_directory_dvifile();
 
333
#ifdef HTEX
 
334
#ifndef WIN32
 
335
    {
 
336
      char *cp = getenv("WWWBROWSER"); 
 
337
      if (cp) browser = cp;
 
338
    }
 
339
    HTProfile_newPreemptiveClient(HTAppName, HTAppVersion); 
 
340
    HTCacheMode_setEnabled(NO);
 
341
    
 
342
#if 0   
 
343
    /* Optionally, turn on tracing of WWW library calls. */
 
344
    if (debug & DBG_HYPER) {
 
345
      WWWTRACE = SHOW_STREAM_TRACE; 
 
346
    }
 
347
#endif
 
348
#endif /* WIN32 */
 
349
    
 
350
#if T1
 
351
        /* At this point DISP, our_visual, our_depth and our_colormap must
 
352
           be defined, and they are */
 
353
        init_t1();
 
354
#endif
 
355
 
 
356
    /* Open the input file.  Turn filename into URL first if needed */
 
357
    URL_aware = TRUE;
 
358
 
 
359
    if (!(URLbase || htex_is_url(dvi_name))) {
 
360
      char *new_name;
 
361
      int n;
 
362
      
 
363
      n = strlen(dvi_name);
 
364
      new_name = dvi_name;
 
365
      /* Find the right filename */
 
366
      if (n < sizeof(".dvi")
 
367
          || strcmp(dvi_name + n - sizeof(".dvi") + 1, ".dvi") != 0) {
 
368
        dvi_name = xmalloc((unsigned) n + sizeof(".dvi"));
 
369
        Strcpy(dvi_name, new_name);
 
370
        Strcat(dvi_name, ".dvi");
 
371
        /* Atempt $dvi_name.dvi */
 
372
        dvi_file = xfopen(dvi_name, OPEN_MODE);
 
373
        if (dvi_file == NULL) {
 
374
          /* Didn't work, revert to original $dvi_name */
 
375
          free(dvi_name);
 
376
          dvi_name = new_name;
 
377
        }
 
378
      }
 
379
      
 
380
      /* Turn filename into URL */
 
381
      /* Escape dangers, esp. # from emacs */
 
382
#ifdef WIN32
 
383
      new_name = xmalloc((unsigned) strlen(dvi_name)+6);
 
384
      strcat(strcpy(new_name,"file:"),dvi_name);
 
385
      free(dvi_name);
 
386
      dvi_name = new_name;
 
387
#else
 
388
      new_name=HTEscape(dvi_name,URL_PATH);
 
389
      free(dvi_name);
 
390
      dvi_name = xmalloc((unsigned) strlen(new_name)+6);
 
391
      strcat(strcpy(dvi_name,"file:"),new_name);
 
392
#endif
 
393
      /* Now we have the right filename, in a URL */
 
394
    }
 
395
 
 
396
#if 0
 
397
    __asm int 3;
 
398
#endif
 
399
    detach_anchor();
 
400
    if (!open_www_file()) {
 
401
      fprintf(stderr,"Could not open dvi file. Exiting.\n");
 
402
      Exit(1);
 
403
    }
 
404
    htex_reinit();
 
405
    URL_aware = FALSE;
 
406
#else
 
407
    open_dvi_file();
 
408
#endif /* not HTEX */
 
409
 
 
410
#ifdef XFORM
 
411
        reset_xform_stack();
 
412
#endif
 
413
#ifdef SRC_SPECIALS
 
414
        src_delete_all_specials();
 
415
#endif
 
416
    if (curr_page) {
 
417
      current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
 
418
      if (current_page < 0 || current_page >= total_pages) usage();
 
419
    }
 
420
#if 1
 
421
    set_icon_and_title (dvi_name, &icon_name, &title_name, 1);
 
422
#endif
 
423
 
 
424
    {
 
425
      int new_shrink;
 
426
      if (resource.shrinkfactor <= 0)
 
427
        new_shrink = ChooseShrink();
 
428
      else
 
429
        new_shrink = resource.shrinkfactor;
 
430
      
 
431
      reconfig();
 
432
      ChangeZoom(new_shrink);
 
433
#if 0
 
434
      redraw_page();
 
435
      ChangePage(0);
 
436
      /* FIXME : why 2 calls ? */
 
437
      redraw_page();
 
438
#endif
 
439
      ChangePage(0);
 
440
    }
 
441
  }
 
442
 
 
443
  return TRUE;
 
444
}
 
445
 
 
446
#if 0
 
447
LRESULT MsgDrawCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
448
{
 
449
  return 0;
 
450
}
 
451
 
 
452
LRESULT MsgDrawNCPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
453
{
 
454
  fprintf(stderr, "NC Paint hwnd = %x, wparam = %x, lparam = %x\n", 
 
455
          hwnd, wparam, lparam);
 
456
  /*  return DefWindowProc(hwnd, uMessage, wparam, lparam); */
 
457
  return 0;
 
458
}
 
459
#endif
 
460
 
 
461
LRESULT MsgDrawMousemove(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
462
{
 
463
  char szBuf[80];               /* Array for formatting mouse coordinates */
 
464
  RECT altRect, oldRect;
 
465
  extern void redraw(struct WindowRec *);
 
466
  extern double p2u_factor;
 
467
  extern const char *pos_format;
 
468
#if 0
 
469
  HRGN hrgnMag;
 
470
  RECT clipRect;
 
471
#endif
 
472
  int xDelta, yDelta;
 
473
  POINT ptOrg = { 0, 0};
 
474
 
 
475
  GetWindowOrgEx(maneDrawDC, &ptOrg);
 
476
 
 
477
  xMousePos = LOWORD(lparam);
 
478
  yMousePos = HIWORD(lparam);
 
479
 
 
480
  if (bMagDisp && mask_mag(wparam)) {
 
481
    POINT absPos;
 
482
    /* redraw mag. glass content */
 
483
 
 
484
    /* adjust magnifying glass position */
 
485
    GetWindowRect(hWndMagnify, &oldRect);
 
486
    absPos.x = xMousePos - magWidth - 1; 
 
487
    absPos.y = yMousePos - magHeight - 1;
 
488
    ClientToScreen(hwnd, &absPos);
 
489
    if (SetWindowPos(hWndMagnify, HWND_TOPMOST, 
 
490
                     absPos.x, absPos.y, 
 
491
                     magWidth*2/* +2 */, magHeight*2 /* +2 */,
 
492
                     SWP_NOACTIVATE | SWP_NOSIZE /* |  SWP_SHOWWINDOW */
 
493
                     /* | SWP_NOCOPYBITS */
 
494
                     | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0)
 
495
      Win32Error("SetWindowPos");
 
496
    UpdateWindow(hwnd);
 
497
#if 1
 
498
    /* UpdateWindow(hWndMagnify); */
 
499
    /* Need to redisplay the toolbar too ! */
 
500
    UpdateWindow(hWndToolbar);
 
501
#endif
 
502
    /*
 
503
      Redraw the in-memory bitmap for the mag. glass
 
504
    */
 
505
    alt.base_x = (xMousePos + xCurrentScroll)*mane.shrinkfactor - magWidth;
 
506
    alt.base_y = (yMousePos + yCurrentScroll)*mane.shrinkfactor - magHeight;
 
507
    GetClientRect(alt.win, &altRect);
 
508
    alt.min_x = altRect.left;
 
509
    alt.min_y = altRect.top;
 
510
    alt.width = altRect.right - altRect.left;
 
511
    alt.height = altRect.bottom - altRect.top;
 
512
    alt.max_x = altRect.right;
 
513
    alt.max_y = altRect.bottom;
 
514
 
 
515
    /* Better than invalidating the whole rectangle, scroll the window */
 
516
    xDelta = (oldRect.left - absPos.x)*mane.shrinkfactor;
 
517
    yDelta = (oldRect.top - absPos.y)*mane.shrinkfactor;
 
518
 
 
519
#if 0
 
520
    /* FIXME : the whol mag glass is redrawn, not only the part invalidated 
 
521
       or is this because the laptop has no advanced graphic feature ? */
 
522
    fprintf(stderr, "scrolling by %d %d\n", xDelta, yDelta);
 
523
#endif
 
524
    if (xDelta || yDelta) {
 
525
      RECT prcUpdate;
 
526
      if (ScrollWindowEx(hWndMagnify, 
 
527
                         xDelta, yDelta,
 
528
                         NULL, NULL, NULL, &prcUpdate, 
 
529
                         SW_INVALIDATE | SW_ERASE ) == ERROR)
 
530
        Win32Error("ScrollWindowEx");
 
531
#if 0
 
532
      fprintf(stderr, "prcUpdate : (%d %d) - (%d %d) mag (%d %d)\n",
 
533
              prcUpdate.left, prcUpdate.top,
 
534
              prcUpdate.right, prcUpdate.bottom, magWidth, magHeight);
 
535
#endif
 
536
    }
 
537
 
 
538
    if (resource.in_memory) {
 
539
#if 0
 
540
      SelectObject(magMemDC, backBrush);
 
541
#endif
 
542
      if (!FillRect(magMemDC, &altRect, backBrush))
 
543
        Win32Error("FillRect Magnifying Glass");
 
544
#if 0
 
545
      /* FIXME : it would be nice to see the page's border in the mag. glass */
 
546
      PatBlt(magMemDC, 
 
547
             max(alt.min_x, -alt.base_x), 
 
548
             max(alt.min_y, -alt.base_y),
 
549
             min(alt.max_x, ),
 
550
             min(alt.max_y, ),
 
551
             WHITENESS);
 
552
#endif
 
553
      redraw(&alt);
 
554
      /* FIXME : how to put these rulers once for all and bitblt
 
555
         on top of them ? */
 
556
#if 0
 
557
      draw_rulers(alt.width, alt.height, magMemDC);
 
558
#endif
 
559
    }
 
560
    UpdateWindow(hWndMagnify);
 
561
  }
 
562
  sprintf(szBuf, pos_format, 
 
563
          (xMousePos + xCurrentScroll + ptOrg.x) * mane.shrinkfactor * p2u_factor,
 
564
          (yMousePos + yCurrentScroll + ptOrg.y) * mane.shrinkfactor * p2u_factor);
 
565
  UpdateStatusBar(szBuf, 6, 0);
 
566
  return 0;
 
567
}
 
568
 
 
569
void
 
570
EnterMag(HWND hwnd, int xMousePos, int yMousePos)
 
571
{
 
572
  RECT rcClient, rcPage, rcClip, rcMag;
 
573
  POINT ptClientUL, ptClientLR;
 
574
  POINT mousePos, absPos, wndOrg;
 
575
 
 
576
  extern int numColors;
 
577
  HWND hWndTop = GetTopWindow(NULL);
 
578
 
 
579
  /* Retrieve the page dimensions */
 
580
  rcPage.left = 0;
 
581
  rcPage.top = 0; 
 
582
  rcPage.right = page_w - 1;
 
583
  rcPage.bottom = page_h - 1;
 
584
 
 
585
  /* Get Window origin */
 
586
  GetWindowOrgEx(maneDrawDC, &wndOrg);
 
587
 
 
588
  mousePos.x = xMousePos + wndOrg.x;
 
589
  mousePos.y = yMousePos + wndOrg.y;
 
590
 
 
591
  if (!PtInRect(&rcPage, mousePos)) {
 
592
        return;
 
593
  }
 
594
 
 
595
  if (1 /* hWndTop == hWndMain */) {
 
596
        RECT rc;
 
597
#if 0
 
598
        fprintf(stderr, "Entering mag and saving main window\n");
 
599
#endif
 
600
        GetClientRect(hWndMain,&rc);
 
601
        BitBlt(hdcDrawSave, 0,0,rc.right,rc.bottom,
 
602
                   maneDC, 0,0,SRCCOPY);  
 
603
        bDrawKeep = TRUE; 
 
604
  }
 
605
 
 
606
  /* FIXME: this causes a redisplay bug if xdvi is not the topmost
 
607
     window */
 
608
  bMagDisp = TRUE;
 
609
 
 
610
  /* Capture mouse input */
 
611
  SetCapture(hwnd);
 
612
  /* Retrieve the screen coordinates of the client area, 
 
613
     and convert them into client coordinates.  */
 
614
  GetClientRect(hwnd, &rcClient);
 
615
  /* Intersect both rectangles. The mag. glass will be limited
 
616
     to the actual visible part of the page. */
 
617
  IntersectRect(&rcClip, &rcClient, &rcPage);
 
618
  ptClientUL.x = rcClip.left; 
 
619
  ptClientUL.y = rcClip.top;  
 
620
  /* Add one to the right and bottom sides, because the 
 
621
     coordinates retrieved by GetClientRect do not 
 
622
     include the far left and lowermost pixels.  */
 
623
  ptClientLR.x = rcClip.right; 
 
624
  ptClientLR.y = rcClip.bottom; 
 
625
 
 
626
  /* FIXME : GetWindowOrgEx() to translate the points */
 
627
  ClientToScreen(hwnd, &ptClientUL); 
 
628
  ClientToScreen(hwnd, &ptClientLR);  
 
629
  /* Copy the client coordinates of the client area 
 
630
     to the rcClip structure. Confine the mouse cursor 
 
631
     to the client area by passing the rcClip structure 
 
632
     to the ClipCursor function. */
 
633
#if 0
 
634
  fprintf(stderr, "Org %d %d\n", wndOrg.x, wndOrg.y);
 
635
#endif
 
636
  SetRect(&rcClip, 
 
637
          ptClientUL.x - wndOrg.x, 
 
638
          ptClientUL.y - wndOrg.y, 
 
639
          ptClientLR.x - wndOrg.x,
 
640
          ptClientLR.y - wndOrg.y);
 
641
  ClipCursor(&rcClip); 
 
642
  /* Calculates the new position and size of the magnifying glass */
 
643
  mousePos.x = xMousePos - magWidth - 1; 
 
644
  mousePos.y = yMousePos - magHeight - 1;
 
645
  /*  ClientToScreen(hwnd, &mousePos); */
 
646
  rcMag.left = mousePos.x + 1;
 
647
  rcMag.top = mousePos.y + 1;
 
648
  /* FIXME : +1 ? */
 
649
  rcMag.right = rcMag.left + 2*magWidth + 1;
 
650
  rcMag.bottom = rcMag.top + 2*magHeight + 1;
 
651
 
 
652
  if (resource.in_memory) {
 
653
    if (oldmagDIB) {
 
654
      /* There is an old magDIB, put it back in the DC
 
655
         and delete the current one */
 
656
      if ((magDIB = SelectObject(magMemDC, oldmagDIB)) == NULL)
 
657
        Win32Error("SelectObject/oldmagDIB");
 
658
      if (DeleteObject(magDIB) == FALSE)
 
659
        Win32Error("DeleteObject/magDIB");
 
660
    }
 
661
 
 
662
    magDIB = CreateDIB(magMemDC, 2*magWidth, 2*magHeight, 16, NULL, NULL);
 
663
    if ((oldmagDIB = SelectObject(magMemDC, magDIB)) == NULL)
 
664
      Win32Error("SelectObject/magDIB");
 
665
 
 
666
    if (!FillRect(magMemDC, &rcMag, backBrush))
 
667
      Win32Error("FillRect magMemDC background");
 
668
 
 
669
    foreGC = ruleGC = highGC = magMemDC;
 
670
  }
 
671
 
 
672
  /* redraw mag. glass content */
 
673
  absPos.x = xMousePos - magWidth - 1; 
 
674
  absPos.y = yMousePos - magHeight - 1;
 
675
  ClientToScreen(hwnd, &absPos);
 
676
  if (SetWindowPos(hWndMagnify, HWND_TOPMOST, 
 
677
                   absPos.x, 
 
678
                   absPos.y, magWidth*2/*+2*/, magHeight*2/*+2*/,
 
679
                   SWP_NOACTIVATE | SWP_SHOWWINDOW
 
680
                   | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0)
 
681
    Win32Error("SetWindowPos");
 
682
  /* ShowWindow(hWndMagnify, SW_SHOW); */
 
683
}
 
684
 
 
685
LRESULT MsgDrawEnterMagL(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
686
{
 
687
  if (bSkipFirstClick) {
 
688
        bSkipFirstClick = FALSE;
 
689
        return 0;
 
690
  }
 
691
 
 
692
  if (bMagDisp || bSetHome)
 
693
        return 0;
 
694
 
 
695
  if (mask_sethome(wparam)) {
 
696
    RECT rcClip, rcPage, rcClient;
 
697
    POINT ptClientUL, ptClientLR;
 
698
    bSetHome = TRUE;
 
699
    SetCursor(hCursCross);
 
700
    SetCapture(hwnd);
 
701
    /* Retrieve the screen coordinates of the client area, 
 
702
       and convert them into client coordinates.  */
 
703
    GetClientRect(hwnd, &rcClient);
 
704
    /* Retrieve the page dimensions */
 
705
    rcPage.top = rcPage.left = 0;
 
706
    rcPage.right = page_w - 1;
 
707
    rcPage.bottom = page_h - 1;
 
708
    /* Intersect both rectangles. The mag. glass will be limited
 
709
       to the actual visible part of the page. */
 
710
    IntersectRect(&rcClip, &rcClient, &rcPage);
 
711
    ptClientUL.x = rcClip.left; 
 
712
    ptClientUL.y = rcClip.top;  
 
713
    /* Add one to the right and bottom sides, because the 
 
714
       coordinates retrieved by GetClientRect do not 
 
715
       include the far left and lowermost pixels.  */
 
716
    ptClientLR.x = rcClip.right; 
 
717
    ptClientLR.y = rcClip.bottom; 
 
718
    ClientToScreen(hwnd, &ptClientUL); 
 
719
    ClientToScreen(hwnd, &ptClientLR);  
 
720
    /* Copy the client coordinates of the client area 
 
721
       to the rcClip structure. Confine the mouse cursor 
 
722
       to the client area by passing the rcClip structure 
 
723
       to the ClipCursor function. */
 
724
    SetRect(&rcClip, ptClientUL.x, ptClientUL.y, 
 
725
            ptClientLR.x, ptClientLR.y);             
 
726
    ClipCursor(&rcClip); 
 
727
    UpdateStatusBar("Setting home position...", 0, 0);
 
728
  }
 
729
  else {
 
730
#ifdef HTEX
 
731
    int x, y;
 
732
    if (mask_opennewframe(wparam)) {
 
733
      HTeXnext_extern = 1;
 
734
    }
 
735
    else {
 
736
      HTeXnext_extern = 0;
 
737
    }
 
738
    if (pointerlocate(&x, &y)) {
 
739
      /* Only do this if there's actually an href right there */
 
740
      int ret;
 
741
      /* screen_to_page(&mane,x,y,&page,&px,&py); */
 
742
      ret = htex_handleref(current_page, x, y);
 
743
      HTeXnext_extern = 0;
 
744
      if (ret == 1) return 0;
 
745
    }
 
746
#endif
 
747
    magWidth = mg_size[0].w / 2;
 
748
    magHeight = mg_size[0].h / 2;
 
749
    EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
 
750
  }
 
751
  return 0;
 
752
}
 
753
 
 
754
LRESULT MsgDrawEnterMagM(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
755
{
 
756
#if 0
 
757
  /* Allow to open a new frame only if not running in single
 
758
     instance mode ! */
 
759
  if (!resource.single_flag) {
 
760
    int x, y;
 
761
    if (pointerlocate(&x, &y)) {
 
762
      /* Only do this if there's actually an href right there */
 
763
      int ret;
 
764
      /* screen_to_page(&mane,x,y,&page,&px,&py); */
 
765
      HTeXnext_extern = 1;
 
766
      ret = htex_handleref(current_page, x, y);
 
767
      HTeXnext_extern = 0;
 
768
      if (ret == 1) return 0;
 
769
    }
 
770
  }
 
771
#endif
 
772
  if (bSkipFirstClick) {
 
773
    bSkipFirstClick = FALSE;
 
774
    return 0;
 
775
  }
 
776
 
 
777
  if (bMagDisp || bSetHome)
 
778
        return 0;
 
779
 
 
780
  magWidth = mg_size[1].w / 2;
 
781
  magHeight = mg_size[1].h / 2;
 
782
  EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
 
783
 
 
784
  return 0;
 
785
}
 
786
 
 
787
LRESULT MsgDrawEnterMagR(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
788
{
 
789
  if (bSkipFirstClick) {
 
790
    bSkipFirstClick = FALSE;
 
791
    return 0;
 
792
  }
 
793
  if (bMagDisp || bSetHome)
 
794
        return 0;
 
795
 
 
796
#ifdef SRC_SPECIALS
 
797
  if (mask_srcspecial(wparam)) {
 
798
        if (src_evalMode) {
 
799
          int x, y;
 
800
          POINT ptOrg = { 0, 0};
 
801
          GetWindowOrgEx(maneDrawDC, &ptOrg);
 
802
          x = min(xMousePos + xCurrentScroll + ptOrg.x, (unsigned)page_w)/* * mane.shrinkfactor */;
 
803
          y = min(yMousePos + yCurrentScroll + ptOrg.y, (unsigned)page_h)/* * mane.shrinkfactor */;
 
804
          src_find_special(1, x, y);
 
805
        }
 
806
  }
 
807
  else
 
808
#endif
 
809
        {
 
810
          magWidth = mg_size[2].w / 2;
 
811
          magHeight = mg_size[2].h / 2;
 
812
          EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
 
813
        }
 
814
  return 0;
 
815
}
 
816
 
 
817
LRESULT MsgDrawQuitMagL(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
818
{
 
819
  POINT ptOrg = { 0, 0};
 
820
 
 
821
  GetWindowOrgEx(maneDrawDC, &ptOrg);
 
822
 
 
823
  if (bSetHome) {
 
824
    char szBuf[128];
 
825
    /* Restore cursor */
 
826
    bSetHome = FALSE;
 
827
    ClipCursor(NULL);
 
828
    ReleaseCapture();
 
829
    SetCursor(hCursArrow);
 
830
    home_x = min(xMousePos + xCurrentScroll + ptOrg.x, (unsigned)page_w) * mane.shrinkfactor;
 
831
    home_y = min(yMousePos + yCurrentScroll + ptOrg.y, (unsigned)page_h) * mane.shrinkfactor;
 
832
    if (resource.sidemargin) free(resource.sidemargin);
 
833
    resource.sidemargin = pixtoa(home_x);
 
834
    if (resource.topmargin) free(resource.topmargin);
 
835
    resource.topmargin = pixtoa(home_y);
 
836
    
 
837
    wsprintf(szBuf, "Setting home to %5d, %5d", home_x, home_y);
 
838
    UpdateStatusBar(szBuf, 0, 0);
 
839
  }
 
840
  else if (bMagDisp) {
 
841
    /* removes the window */
 
842
    foreGC = ruleGC = highGC = maneDrawDC;
 
843
    ShowWindow(hWndMagnify, SW_HIDE);
 
844
    bMagDisp = FALSE;
 
845
    UpdateWindow(hWndDraw);
 
846
    /* restores the old shrink factor and redisplay page */
 
847
    ClipCursor(NULL);
 
848
    ReleaseCapture();
 
849
  }
 
850
  return 0;
 
851
}
 
852
 
 
853
LRESULT MsgDrawCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam) 
 
854
{
 
855
  HDC hDC = GetDC(hwnd);
 
856
  HBITMAP hBitmap;
 
857
  int width, height;
 
858
 
 
859
  /* Scroll Bars */
 
860
  xMinScroll = 0;
 
861
  xMaxScroll = page_w;
 
862
  /* mane.base_x =  */xCurrentScroll = 0;
 
863
  
 
864
  yMinScroll = 0;
 
865
  yMaxScroll = page_h;
 
866
  /* mane.base_y =  */yCurrentScroll = yMinScroll;
 
867
 
 
868
  fScroll = FALSE;
 
869
  fSize = FALSE;
 
870
 
 
871
  /* When the main window is created, allocate a memory context */
 
872
  /*   of the appropriate size */
 
873
  hdcDrawSave = CreateCompatibleDC(hDC);
 
874
  /* Create a bitmap buffer for hdcMemSave that is */
 
875
  /*   the same size as the physical screen */
 
876
  width = GetDeviceCaps(hDC, HORZRES);
 
877
  height = GetDeviceCaps(hDC, VERTRES);
 
878
  hBitmap = CreateCompatibleBitmap(hDC, width, height);
 
879
  SelectObject(hdcDrawSave, hBitmap);  
 
880
  DeleteObject(hBitmap);
 
881
  ReleaseDC(hwnd,hDC);
 
882
 
 
883
#if 0
 
884
  /* Scrolled Region */
 
885
  if (hrgnScroll ==0)
 
886
      hrgnScroll = CreateRectRgn(0, 0, 10, 10);
 
887
#endif
 
888
  return 0;
 
889
}
 
890
 
 
891
LRESULT MsgDrawHScroll(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
892
{
 
893
  RECT r;
 
894
  int xDelta;
 
895
  int xNewPos;
 
896
  int yDelta = 0;
 
897
 
 
898
  bDrawKeep = FALSE;
 
899
 
 
900
  GetClientRect(hwnd, &r);
 
901
  
 
902
  switch (LOWORD(wparam)) {
 
903
  case SB_TOP:
 
904
    xNewPos = xMinScroll;
 
905
    break;
 
906
  case SB_BOTTOM:
 
907
    xNewPos = xMaxScroll;
 
908
    break;
 
909
  case SB_PAGEUP:
 
910
    xNewPos = xCurrentScroll - (((r.right - r.left) * 2) / 3);
 
911
    break;
 
912
  case SB_PAGEDOWN:
 
913
    xNewPos = xCurrentScroll + (((r.right - r.left) * 2) / 3);
 
914
    break;
 
915
  case SB_LINEUP:
 
916
    xNewPos = xCurrentScroll - 5;
 
917
    break;
 
918
  case SB_LINEDOWN:
 
919
    xNewPos = xCurrentScroll + 5;
 
920
    break;
 
921
  case SB_THUMBPOSITION:
 
922
    xNewPos = HIWORD(wparam);
 
923
    break;
 
924
  default:
 
925
    xNewPos = xCurrentScroll;
 
926
  }
 
927
 
 
928
 
 
929
  xNewPos = max(xMinScroll, xNewPos);
 
930
  xNewPos = min(xMaxScroll - max(r.right - 1, 0), xNewPos);
 
931
 
 
932
#if 0
 
933
  fprintf(stderr, "r.right = %d [%d %d %d]\n",
 
934
          r.right, xMinScroll, xCurrentScroll, xMaxScroll);
 
935
  fprintf(stderr, "xNewPos = %d\n", xNewPos);
 
936
#endif
 
937
 
 
938
  if (xNewPos == xCurrentScroll)
 
939
    return 0;
 
940
      
 
941
  fScroll = TRUE;
 
942
      
 
943
  xDelta = xNewPos - xCurrentScroll;
 
944
  /* mane.base_x =  */xCurrentScroll = xNewPos;
 
945
  ScrollWindowEx(hwnd, -xDelta, -yDelta, NULL, NULL,
 
946
                 (HRGN)NULL, (LPRECT)NULL,
 
947
                 SW_INVALIDATE | SW_ERASE);
 
948
#if 1
 
949
  UpdateWindow(hwnd);
 
950
#endif      
 
951
  si.cbSize = sizeof(si);
 
952
  si.fMask = SIF_POS;
 
953
  si.nPos = xCurrentScroll;
 
954
  SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
 
955
  return 0;
 
956
}
 
957
 
 
958
LRESULT MsgDrawVScroll(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
959
{
 
960
  RECT r;
 
961
 
 
962
  int xDelta = 0;
 
963
  int yNewPos;
 
964
  int yDelta;
 
965
 
 
966
  bDrawKeep = FALSE;
 
967
 
 
968
  GetClientRect(hwnd, &r);
 
969
  if (yCurrentScroll == yMinScroll
 
970
      && current_page > 0
 
971
      && (LOWORD(wparam) == SB_TOP 
 
972
          || LOWORD(wparam) == SB_PAGEUP
 
973
          /* || LOWORD(wparam) == SB_LINEUP */)) {
 
974
    ChangePage(-1);
 
975
    wparam = MAKEWORD(SB_BOTTOM, HIWORD(wparam));
 
976
  }
 
977
  else if (yCurrentScroll == yMaxScroll - max(r.bottom - 1, 0)
 
978
           && current_page < total_pages - 1
 
979
           && (LOWORD(wparam) == SB_BOTTOM 
 
980
               || LOWORD(wparam) == SB_PAGEDOWN
 
981
               /* || LOWORD(wparam) == SB_LINEDOWN */)) {
 
982
    ChangePage(+1);
 
983
    wparam = MAKEWORD(SB_TOP, HIWORD(wparam));
 
984
  }
 
985
  switch (LOWORD(wparam)) {
 
986
  case SB_TOP:
 
987
    yNewPos = yMinScroll;
 
988
    break;
 
989
  case SB_BOTTOM:
 
990
    yNewPos = yMaxScroll;
 
991
    break;
 
992
  case SB_PAGEUP:
 
993
    yNewPos = yCurrentScroll - (((r.bottom - r.top) * 2) / 3);
 
994
    break;
 
995
  case SB_PAGEDOWN:
 
996
    yNewPos = yCurrentScroll + (((r.bottom - r.top) * 2) / 3);
 
997
    break;
 
998
  case SB_LINEUP:
 
999
    yNewPos = yCurrentScroll - 5;
 
1000
    break;
 
1001
  case SB_LINEDOWN:
 
1002
    yNewPos = yCurrentScroll + 5;
 
1003
    break;
 
1004
  case SB_THUMBPOSITION:
 
1005
    yNewPos = HIWORD(wparam);
 
1006
    break;
 
1007
  default:
 
1008
    yNewPos = yCurrentScroll;
 
1009
  }
 
1010
  yNewPos = max(yMinScroll, yNewPos);
 
1011
  yNewPos = min(yMaxScroll - max(r.bottom - 1, 0), yNewPos);
 
1012
      
 
1013
  if (yNewPos == yCurrentScroll)
 
1014
    return 0;
 
1015
      
 
1016
  fScroll = TRUE;
 
1017
       
 
1018
  yDelta = yNewPos - yCurrentScroll;
 
1019
  /* mane.base_y =  */yCurrentScroll = yNewPos;
 
1020
  ScrollWindowEx(hwnd, -xDelta, -yDelta, NULL, NULL,
 
1021
                 (HRGN)NULL, (LPRECT)NULL,
 
1022
                 SW_INVALIDATE | SW_ERASE);
 
1023
#if 0
 
1024
  UpdateWindow(hwnd);
 
1025
#endif
 
1026
      
 
1027
  si.cbSize = sizeof(si);
 
1028
  si.fMask = SIF_POS;
 
1029
  si.nPos = yCurrentScroll;
 
1030
  SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
 
1031
  return 0;
 
1032
}
 
1033
 
 
1034
LRESULT MsgDrawEraseBkgnd(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
1035
{
 
1036
  RECT r;
 
1037
  HDC hdc = (HDC)wparam;
 
1038
 
 
1039
  if (isPrinting) return TRUE;
 
1040
 
 
1041
  GetClientRect(hwnd, &r);
 
1042
  
 
1043
  if (resource.in_memory) {
 
1044
    FillRect(hdc, &r, GetStockObject (LTGRAY_BRUSH));
 
1045
  }
 
1046
  else {
 
1047
 
 
1048
  if (debug & DBG_EVENT)
 
1049
    fprintf(stderr, "Erasing background with colors %x\n", back_Pixel);
 
1050
 
 
1051
    FillRect(hdc, &r, GetStockObject (LTGRAY_BRUSH));
 
1052
    if (dvi_file) {
 
1053
      r.bottom = min(page_h - yCurrentScroll, r.bottom);
 
1054
      r.right = min(page_w - xCurrentScroll, r.right);
 
1055
 
 
1056
  if (debug & DBG_EVENT)
 
1057
      fprintf(stderr, "Erasing background, Page is in (%d x %d)\n",
 
1058
              r.right, r.bottom);
 
1059
 
 
1060
      FillRect(hdc, &r, backBrush);
 
1061
      
 
1062
    }
 
1063
  }
 
1064
  return TRUE;
 
1065
}
 
1066
 
 
1067
/*
 
1068
  We have 2 alternatives :
 
1069
 
 
1070
  - using a page for the text and BitBlt'ing this page onto the screen
 
1071
  But there is a serious drawback : at scale 1 and 600dpi, a color
 
1072
  page is about 34Mb... Not anybody can afford this easily. At least
 
1073
  not W9x users. So we have to do banding. Anyway, this is needed for
 
1074
  printing. This is the only way to guarantee that the file will be
 
1075
  printed on any printer.
 
1076
 
 
1077
  - directly drawing on the screen. This is rather efficient for the display.
 
1078
 
 
1079
  We choose among these 2 methods thanks to the resource.in_memory flag.
 
1080
*/
 
1081
 
 
1082
void DrawInMemory(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
 
1083
{
 
1084
  unsigned int rop;
 
1085
  RECT rcGSPaint;
 
1086
  extern void reset_xfrm_stack(void);
 
1087
 
 
1088
  /* If no file open, just return */
 
1089
  if (!dvi_name || !*dvi_name)
 
1090
    return;
 
1091
 
 
1092
  if (!bMagDisp) {
 
1093
    mane.base_x = xCurrentScroll;
 
1094
    mane.base_y = yCurrentScroll;
 
1095
    mane.min_x = lprcPaint->left;
 
1096
    mane.min_y = lprcPaint->top;
 
1097
    mane.max_x = lprcPaint->right;
 
1098
    mane.max_y = lprcPaint->bottom;
 
1099
    mane.width = lprcPaint->right - lprcPaint->left;
 
1100
    mane.height = lprcPaint->bottom - lprcPaint->top;
 
1101
    
 
1102
    /*
 
1103
      We have the page in memory. This page consist of all the pk chars
 
1104
      and rules/boxes.
 
1105
      
 
1106
      As pictures are drawn one onto the other, we need some kind of
 
1107
      transparent blt.  AFAIK, the special rop code used here does the
 
1108
      trick. But it is slow.  
 
1109
      
 
1110
    */
 
1111
    
 
1112
#ifdef TRANSFORM
 
1113
    /* FIXME : there should be a global stack in case
 
1114
       such transformations would span over several pages. */
 
1115
    if (resource.use_xform)
 
1116
      reset_xfrm_stack();
 
1117
#endif
 
1118
    
 
1119
    /* Erasing background */
 
1120
    {
 
1121
      RECT r;
 
1122
      r.left = mane.min_x;
 
1123
      r.top = mane.min_y;
 
1124
      r.right = min(page_w - xCurrentScroll, mane.max_x);
 
1125
      r.bottom = min(page_h - yCurrentScroll, mane.max_y);
 
1126
      FillRect(hdcFrom, &r, backBrush);
 
1127
    }
 
1128
    
 
1129
    /* First pass for specials */
 
1130
    allowDrawingChars = FALSE;
 
1131
    
 
1132
    redraw(&mane);
 
1133
    
 
1134
#if PS
 
1135
    if (resource._postscript && psToDisplay) {
 
1136
      rop = /* 0x008E1D7C */ SRCCOPY;
 
1137
    
 
1138
      /* if gs is active, try to make it paint its picture */
 
1139
      if (gs_device) {
 
1140
        rcGSPaint.left = lprcPaint->left+xCurrentScroll;
 
1141
        rcGSPaint.right = lprcPaint->right+xCurrentScroll;
 
1142
        rcGSPaint.top = lprcPaint->top+yCurrentScroll;
 
1143
        rcGSPaint.bottom = lprcPaint->bottom+yCurrentScroll;
 
1144
#if 0
 
1145
        fprintf(stderr, "gs: redrawing\n");
 
1146
#endif
 
1147
        (*pgsdll_draw)(gs_device, hdcFrom, lprcPaint, &rcGSPaint);
 
1148
      }
 
1149
    }
 
1150
    else
 
1151
#endif
 
1152
      rop = SRCCOPY;
 
1153
    
 
1154
    allowDrawingChars = TRUE;
 
1155
    
 
1156
    redraw(&mane);
 
1157
  }
 
1158
 
 
1159
  /* We have to paint in lprcPaint. */
 
1160
  if (!BitBlt(hdcDest, 
 
1161
              lprcPaint->left, lprcPaint->top,
 
1162
              lprcPaint->right - lprcPaint->left,
 
1163
              lprcPaint->bottom - lprcPaint->top,
 
1164
              hdcFrom, 
 
1165
              lprcPaint->left+xCurrentScroll, 
 
1166
              lprcPaint->top+yCurrentScroll, SRCCOPY)) {
 
1167
    Win32Error("Draw Page/BitBlt");
 
1168
    fprintf(stderr, "BitBlt page failed\nRectangle to be painted : l = %d t = %d r = %d b = %d\n",
 
1169
            lprcPaint->left, lprcPaint->top,
 
1170
            lprcPaint->right, lprcPaint->bottom);
 
1171
    fprintf(stderr, "Rectangle to be updated : l = %d t = %d r = %d b = %d\n",
 
1172
            lprcPaint->left, lprcPaint->top, 
 
1173
            lprcPaint->right, lprcPaint->bottom);
 
1174
    fprintf(stderr, "Rectangle for page : l = %d t = %d r = %d b = %d\n",
 
1175
            0, 0, page_w - xCurrentScroll, page_h - yCurrentScroll); 
 
1176
    fprintf(stderr, "Page width = %d\nPage height = %d\nScroll %d %d\n",
 
1177
            page_w, page_h, xCurrentScroll, yCurrentScroll);
 
1178
  }
 
1179
}
 
1180
 
 
1181
 
 
1182
void DrawOnScreen(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
 
1183
{
 
1184
  extern void reset_xfrm_stack(void);
 
1185
  /*
 
1186
    We want to draw directly onto the screen.
 
1187
    */
 
1188
 
 
1189
  mane.base_x = xCurrentScroll;
 
1190
  mane.base_y = yCurrentScroll;
 
1191
  mane.min_x = lprcPaint->left;
 
1192
  mane.min_y = lprcPaint->top;
 
1193
  mane.max_x = lprcPaint->right;
 
1194
  mane.max_y = lprcPaint->bottom;
 
1195
  mane.width = lprcPaint->right - lprcPaint->left;
 
1196
  mane.height = lprcPaint->bottom - lprcPaint->top;
 
1197
  
 
1198
  /* If no file open, just return */
 
1199
  if (!dvi_name || !*dvi_name)
 
1200
    return;
 
1201
 
 
1202
#ifdef TRANSFORM
 
1203
  /* FIXME : there should be a global stack in case
 
1204
     such transformations would span over several pages. */
 
1205
  if (resource.use_xform)
 
1206
    reset_xfrm_stack();
 
1207
#endif
 
1208
 
 
1209
  /*
 
1210
    FIXME : remove this and process directly.
 
1211
  */
 
1212
 
 
1213
  /* First pass for specials */
 
1214
  allowDrawingChars = FALSE;
 
1215
 
 
1216
  redraw(&mane);
 
1217
 
 
1218
#if PS
 
1219
  if (resource._postscript && psToDisplay) {
 
1220
    /* if gs is active, try to make it paint its picture */
 
1221
    if (gs_device) {
 
1222
#if 0
 
1223
      fprintf(stderr, "gs: redrawing\n");
 
1224
      fprintf(stderr, "repaint : %d %d %d %d\n",
 
1225
              lprcPaint->left, lprcPaint->top,
 
1226
              lprcPaint->right, lprcPaint->bottom);
 
1227
#endif
 
1228
      (*pgsdll_lock_device)(gs_device, 1);
 
1229
      (*pgsdll_draw)(gs_device, hdcDest, lprcPaint, lprcPaint);
 
1230
      (*pgsdll_lock_device)(gs_device, 0);
 
1231
    }
 
1232
  }
 
1233
 
 
1234
  allowDrawingChars = TRUE;
 
1235
 
 
1236
#if 0
 
1237
  fprintf(stderr, "repaint : %d %d %d %d ps = %d\n",
 
1238
          lprcPaint->left, lprcPaint->top,
 
1239
          lprcPaint->right, lprcPaint->bottom, psToDisplay);
 
1240
#endif
 
1241
  redraw(&mane);
 
1242
#endif
 
1243
 
 
1244
  if (resource.reverse) {
 
1245
    PatBlt(hdcDest, lprcPaint->left, lprcPaint->top, lprcPaint->right, lprcPaint->bottom, DSTINVERT);
 
1246
  }
 
1247
 
 
1248
}
 
1249
 
 
1250
void DoDrawPaint(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
 
1251
{
 
1252
  RECT rcToPaint, rcPage;
 
1253
 
 
1254
  rcPage.left = 0;
 
1255
  rcPage.right = page_w - xCurrentScroll;
 
1256
  rcPage.top = 0;
 
1257
  rcPage.bottom = page_h - yCurrentScroll;
 
1258
 
 
1259
  IntersectRect(&rcToPaint, lprcPaint, &rcPage);
 
1260
 
 
1261
  if (resource.in_memory) 
 
1262
    DrawInMemory(hdcDest, hdcFrom, &rcToPaint);
 
1263
  else
 
1264
    DrawOnScreen(hdcDest, hdcFrom, &rcToPaint);
 
1265
}
 
1266
 
 
1267
LRESULT MsgDrawPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
 
1268
{
 
1269
  PAINTSTRUCT ps;
 
1270
  
 
1271
  /* No redrawing while printing. Should not happen, but who knows ? */
 
1272
  HDC hDC = BeginPaint(hwnd, &ps);
 
1273
 
 
1274
  if (!isPrinting) {
 
1275
 
 
1276
        /* FIXME : Is there anyway to optimize this
 
1277
           wrt to the mag. glass moving ? */
 
1278
    if (bDrawKeep || bMagDisp) {
 
1279
      /* Repaint from the memory context */
 
1280
      BitBlt(ps.hdc,  ps.rcPaint.left, ps.rcPaint.top,
 
1281
             (ps.rcPaint.right - ps.rcPaint.left),
 
1282
             (ps.rcPaint.bottom - ps.rcPaint.top),
 
1283
             hdcDrawSave, ps.rcPaint.left,ps.rcPaint.top, SRCCOPY); 
 
1284
    }
 
1285
    else {
 
1286
      /* New data, so need to do some work */
 
1287
      RECT rc;  
 
1288
          HWND hWndTop = GetTopWindow(NULL);
 
1289
#if 0
 
1290
          fprintf(stderr, "Redrawing (%d, %d) - (%d x %d)\n",
 
1291
                          ps.rcPaint.left, ps.rcPaint.top,
 
1292
                          ps.rcPaint.right - ps.rcPaint.left,
 
1293
                          ps.rcPaint.bottom - ps.rcPaint.top);
 
1294
#endif
 
1295
      DoDrawPaint(maneDC, maneDrawDC, &(ps.rcPaint));
 
1296
      /* The screen has been redrawn manually; now update */
 
1297
      /*   the memory context and set fKeep=TRUE. */
 
1298
          if (hWndTop == hWndMain /* || hWndTop == hWndDraw || hWndTop == hWndMagnify */) {
 
1299
                GetClientRect(hwnd,&rc);
 
1300
                BitBlt(hdcDrawSave, 0,0,rc.right,rc.bottom,
 
1301
                           hDC, 0,0,SRCCOPY);  
 
1302
                bDrawKeep = TRUE; 
 
1303
          }
 
1304
          else {
 
1305
#if 0
 
1306
                fprintf(stderr, "Active window is *not* draw window\n");
 
1307
#endif
 
1308
          }
 
1309
    }
 
1310
  }
 
1311
  EndPaint(hwnd, &ps);
 
1312
  return 0;
 
1313
}
 
1314
 
 
1315
/*
 
1316
  FUNCTION: InitGlobalsDraw()
 
1317
  PURPOSE : Initialize all graphic-relative variables needed.
 
1318
            Can be done only after hWndDraw has been created.
 
1319
            Must be done before trying to open a dvi file.
 
1320
*/
 
1321
 
 
1322
void InitGlobalsDraw()
 
1323
{
 
1324
  extern void initcolor(void);
 
1325
  extern void init_xfrm_stack(void);
 
1326
 
 
1327
  currwin.win = mane.win = hWndDraw;
 
1328
 
 
1329
  /* It has its own_dc */
 
1330
  maneDC = GetDC(hWndDraw);
 
1331
 
 
1332
  maneHorzRes = GetDeviceCaps(maneDC, HORZRES);
 
1333
  maneVertRes = GetDeviceCaps(maneDC, VERTRES);
 
1334
  maneLogPixelsX = GetDeviceCaps(maneDC, LOGPIXELSX);
 
1335
  maneLogPixelsY = GetDeviceCaps(maneDC, LOGPIXELSY);
 
1336
  maneBitsPixel = GetDeviceCaps(maneDC, BITSPIXEL);
 
1337
  maneSizePalette = GetDeviceCaps(maneDC, SIZEPALETTE);
 
1338
  maneColorRes = GetDeviceCaps(maneDC, COLORRES);
 
1339
  maneRasterCaps = GetDeviceCaps(maneDC, RASTERCAPS);
 
1340
 
 
1341
#ifdef GREY
 
1342
  if (maneBitsPixel >= 8 && use_grey) {
 
1343
    numColors = 16;
 
1344
  }
 
1345
  else {
 
1346
    numColors = 1;
 
1347
  }
 
1348
#else
 
1349
  numColors = 1;
 
1350
#endif
 
1351
 
 
1352
  if (!(maneRasterCaps & RC_BITBLT)) {
 
1353
    MessageBox(hWndMain, 
 
1354
               "Can't use the BitBlt() function\r\non your display. Exiting...",
 
1355
               NULL, MB_OK | MB_ICONERROR | MB_APPLMODAL);
 
1356
    CleanExit(1);
 
1357
  }
 
1358
  if (!(maneRasterCaps & RC_STRETCHDIB)) {
 
1359
    MessageBox(hWndMain, 
 
1360
               "Can't use the StretchDIBits() function\r\non your display. Exiting...",
 
1361
               NULL, MB_OK | MB_ICONERROR | MB_APPLMODAL);
 
1362
    CleanExit(1);
 
1363
  }
 
1364
  if (!(maneRasterCaps & RC_BITMAP64)) {
 
1365
    MessageBox(hWndMain, 
 
1366
               "Device does not support >64k bitmaps. Exiting...",
 
1367
               NULL, MB_OK | MB_ICONERROR | MB_APPLMODAL);
 
1368
    CleanExit(1);
 
1369
  }
 
1370
#if 0
 
1371
  fprintf(stderr, "Caps = %x\n", maneRasterCaps);
 
1372
  fprintf(stderr, "Hres = %d, Yres = %d, lpx = %d, lpy = %d\n",
 
1373
          maneHorzRes, maneVertRes, maneLogPixelsX, maneLogPixelsY);
 
1374
  fprintf(stderr, "bits/pix = %d, size palette = %d, colorres = %d\n",
 
1375
          maneBitsPixel, maneSizePalette, maneColorRes);
 
1376
#endif
 
1377
 
 
1378
#if 0
 
1379
  /* Device context for drawing and the associated bitmap. */
 
1380
  if ((imageDC = CreateCompatibleDC(maneDC)) == NULL)
 
1381
    Win32Error("CreateCompatibleDC imageDC");
 
1382
#endif
 
1383
  
 
1384
  if (resource.in_memory) {
 
1385
    maneDrawMemDC = CreateCompatibleDC(maneDC);
 
1386
    if (maneDrawMemDC == NULL)
 
1387
      Win32Error("CreateCompatibleDC maneDrawMemDC");
 
1388
 
 
1389
    foreGC = ruleGC = highGC = maneDrawDC = maneDrawMemDC;
 
1390
 
 
1391
    grid1GC = grid2GC = grid3GC = maneDrawDC;
 
1392
    foreGC2 = NULL;             /* not used under Win32 */
 
1393
  }
 
1394
  else {
 
1395
    foreGC = ruleGC = highGC = maneDrawDC = GetDC(hWndDraw);
 
1396
    grid1GC = grid2GC = grid3GC = foreGC;
 
1397
    magMemDC = foreGC2 = NULL;          /* not used under Win32 */
 
1398
  }
 
1399
 
 
1400
#ifdef TRANSFORM
 
1401
  if (IS_NT)
 
1402
    SetGraphicsMode(maneDrawDC, GM_ADVANCED);
 
1403
 
 
1404
  if (resource.use_xform) {
 
1405
    if (IS_WIN95) {
 
1406
      fprintf(stderr, "The xform feature is not available under Win95.\n");
 
1407
      fprintf(stderr, "Use the View -> Options dialog box to configure\n");
 
1408
      fprintf(stderr, "or run `windvi +xform' to reset the option.\n");
 
1409
    }
 
1410
    else {
 
1411
      init_xfrm_stack();
 
1412
    }
 
1413
  }
 
1414
#endif
 
1415
 
 
1416
  SetStretchBltMode(foreGC, COLORONCOLOR); 
 
1417
  SetStretchBltMode(maneDC, COLORONCOLOR); 
 
1418
 
 
1419
  initcolor();
 
1420
 
 
1421
 
 
1422
  /* This little image is not used anymore. We are doing 
 
1423
     everything straight in bitmaps */
 
1424
  image = XCreateImage(DISP, maneDrawDC, numColors, XYBitmap, 0,
 
1425
                       (char *)NULL, 0, 0, BMBITS, 0);
 
1426
 
 
1427
 
 
1428
  bmi1.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
 
1429
  bmi1.bmiHeader.biPlanes   = 1;
 
1430
  bmi1.bmiHeader.biBitCount = 1;
 
1431
  bmi1.bmiHeader.biCompression        = BI_RGB;
 
1432
  bmi1.bmiHeader.biXPelsPerMeter      = 0;
 
1433
  bmi1.bmiHeader.biYPelsPerMeter      = 0;
 
1434
  bmi1.bmiHeader.biClrUsed            = 0;
 
1435
  bmi1.bmiHeader.biClrImportant       = 0;
 
1436
 
 
1437
  bmi4.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
 
1438
  bmi4.bmiHeader.biPlanes   = 1;
 
1439
  bmi4.bmiHeader.biBitCount = 4;
 
1440
  bmi4.bmiHeader.biCompression        = BI_RGB;
 
1441
  bmi4.bmiHeader.biXPelsPerMeter      = 0;
 
1442
  bmi4.bmiHeader.biYPelsPerMeter      = 0;
 
1443
  bmi4.bmiHeader.biClrUsed            = 0;
 
1444
  bmi4.bmiHeader.biClrImportant       = 0;
 
1445
 
 
1446
  bmi8.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
 
1447
  bmi8.bmiHeader.biPlanes   = 1;
 
1448
  bmi8.bmiHeader.biBitCount = 8;
 
1449
  bmi8.bmiHeader.biCompression        = BI_RGB;
 
1450
  bmi8.bmiHeader.biXPelsPerMeter      = 0;
 
1451
  bmi8.bmiHeader.biYPelsPerMeter      = 0;
 
1452
  bmi8.bmiHeader.biClrUsed            = 0;
 
1453
  bmi8.bmiHeader.biClrImportant       = 0;
 
1454
 
 
1455
  bmi24.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
 
1456
  bmi24.bmiHeader.biPlanes   = 1;
 
1457
  bmi24.bmiHeader.biBitCount = 24;
 
1458
  bmi24.bmiHeader.biCompression        = BI_RGB;
 
1459
  bmi24.bmiHeader.biXPelsPerMeter      = 0;
 
1460
  bmi24.bmiHeader.biYPelsPerMeter      = 0;
 
1461
  bmi24.bmiHeader.biClrUsed            = 0;
 
1462
  bmi24.bmiHeader.biClrImportant       = 0;
 
1463
 
 
1464
 
 
1465
  /*
 
1466
    Setting geometry
 
1467
    */
 
1468
  /* Where to create the window ?
 
1469
     Thanks to suggestions by Stanley A. Sawyer <sawyer@math.wustl.edu>
 
1470
     this code has been improved.
 
1471
     -------------------------------------------------------------------------
 
1472
     The main window will be loaded at (xval,yval) (the upper-left (UL)
 
1473
     corner of the window) with widths (xsize,ysize).
 
1474
     The physical screen size is stored in global variables (maxx,maxy).
 
1475
     The code below first checks if there is an instance of a program of
 
1476
     type ``window class=vshowclass'' already running. If so, the new window
 
1477
     is cascaded off the old by v4size pixels at the UL corner.
 
1478
     ``FindWindow()'' seems to find the last-run instance, so that the
 
1479
     result can be a nice cascade of windows.
 
1480
     If there are no pre-existing instances, the code then checks for a
 
1481
     Taskbar on either the left-hand-side or the top of the screen. If the
 
1482
     Taskbar is in either position, (xval,yval) is set to avoid overlaying
 
1483
     them. If not, the default xval=yval=10 is used.
 
1484
     The code can be improved by checking the Taskbar position if the
 
1485
     previous instance window is too far from the UL corner of the screen,
 
1486
     but the following should work fine in most cases.
 
1487
     -------------------------------------------------------------------------
 
1488
  */
 
1489
  /*
 
1490
    FIXME : should we implement several policies 
 
1491
    - user might want to open the new window exactly
 
1492
    on top of the previous one,
 
1493
    - or cascade windows,
 
1494
    - or ...
 
1495
  */
 
1496
  {
 
1497
    int off_x, off_y, width, height;
 
1498
    int v4size = 25; /* cascading by this number of pixels */
 
1499
    RECT rectDesktop, r;
 
1500
    extern BOOL bPrevInstance;
 
1501
    extern RECT rectWndPrev;
 
1502
    APPBARDATA abd = { sizeof(APPBARDATA), NULL };
 
1503
    int abd_width = 0, abd_height = 0;
 
1504
 
 
1505
    GetWindowRect(hWndMain, &r);
 
1506
    off_x = r.left;
 
1507
    off_y = r.top;
 
1508
    width = r.right - r.left;
 
1509
    height = r.bottom - r.top;
 
1510
      
 
1511
    /* Get APPBAR information */
 
1512
    abd.cbSize = sizeof(APPBARDATA);
 
1513
    if (SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) {
 
1514
      /* The Taskbar is at positions    */
 
1515
      /*   abd.rc.left, abd.rc.right, abd.rc.top, abd.rc.bottom */
 
1516
      /* The variable at the long screen boundary is negative, */
 
1517
      /*   which locates the Taskbar.  */
 
1518
#if 0
 
1519
      fprintf(stderr, "Appbar : (%d %d) -- (%d %d)\n",
 
1520
              abd.rc.left, abd.rc.top,
 
1521
              abd.rc.right, abd.rc.bottom);
 
1522
#endif
 
1523
      if (abd.rc.left<0 && abd.rc.right < maneHorzRes/2) {
 
1524
        abd_width = abd.rc.right;  
 
1525
      }
 
1526
      else if (abd.rc.top<0 && abd.rc.bottom < maneVertRes/2) {
 
1527
        abd_height = abd.rc.bottom; 
 
1528
      }
 
1529
    }
 
1530
 
 
1531
    if (bPrevInstance && !resource.single_flag) {
 
1532
      /* if there is a previous instance, rely on it. */
 
1533
      off_x = (rectWndPrev.left> maneHorzRes / 3) 
 
1534
        ? 10 + v4size 
 
1535
        : rectWndPrev.left+v4size;
 
1536
      off_y = (rectWndPrev.top > maneVertRes / 3)  
 
1537
        ? 10 + v4size 
 
1538
        : rectWndPrev.top+v4size; 
 
1539
      width = rectWndPrev.right - rectWndPrev.left;
 
1540
      height = rectWndPrev.bottom - rectWndPrev.top;
 
1541
#if 0
 
1542
      fprintf(stderr, "Prev inst : @(%d,%d) (%d x %d)\n",
 
1543
              off_x, off_y, width, height);
 
1544
#endif
 
1545
    }
 
1546
 
 
1547
    else if (geometry) {
 
1548
      RECT r;
 
1549
      int flag = XParseGeometry(geometry, &off_x, &off_y,
 
1550
                                &width, &height);
 
1551
#ifndef WIN32
 
1552
      if (flag & (XValue | YValue))
 
1553
        size_hints.flags |= USPosition;
 
1554
      if (flag & (WidthValue | HeightValue))
 
1555
        size_hints.flags |= USSize;
 
1556
#endif
 
1557
      if (flag & XNegative) off_x += maneHorzRes - width;
 
1558
      if (flag & YNegative) off_y += maneVertRes - height;
 
1559
        }
 
1560
    else {
 
1561
      /*
 
1562
        if no geometry has been given, make the main window big enough.
 
1563
      */
 
1564
      width = (int)(maneVertRes - abd_height * 0.618);
 
1565
      height = maneVertRes - abd_height;
 
1566
#if 0
 
1567
      fprintf(stderr, "Nothing : @(%d,%d) (%d x %d)\n",
 
1568
              off_x, off_y, width, height);
 
1569
#endif
 
1570
    }
 
1571
    if (!(MoveWindow(hWndMain, 
 
1572
                     off_x, off_y, 
 
1573
                     width, height,
 
1574
                     TRUE)))
 
1575
      Win32Error("no Geometry/MoveWindow");
 
1576
  }
 
1577
  
 
1578
}