2
#include "xdvi-config.h"
12
/* Application name and version for w3c-libwww routines.
13
This is what will show up in httpd's agent_log files.
16
char *HTAppName = "owindvi";
18
char *HTAppName = "windvi";
20
char *HTAppVersion = XDVERSION;
22
/* Create the anchor information stuff at the bottom of the page */
24
/* Anchor search: a dialog box */
25
/* anchorinfo = Ascii text widget */
27
char anchorsearchstring[1024];
28
char anchorask[] = "Access new URL:";
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))
37
/*****************************************************************************
39
****************************************************************************/
41
BOOL bDrawKeep = FALSE;
43
static HRGN hrgnScroll = 0;
45
LRESULT CALLBACK DrawProc(HWND, UINT, WPARAM, LPARAM);
47
/* Drawing window message table definition. */
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 }
69
sizeof(rgmsdDraw) / sizeof(MSD),
74
/* Drawing window command table definition. */
77
{IDM_FILEOPEN, CmdStub}
82
sizeof(rgcmdDraw) / sizeof(CMD),
87
/*****************************************************************************
88
Magnifying child window
89
****************************************************************************/
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 */
96
int magWidth, magHeight;
98
LRESULT CALLBACK MagnifyProc(HWND, UINT, WPARAM, LPARAM);
100
/* Magnifying window message table definition. */
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 }
115
sizeof(rgmsdMagnify) / sizeof(MSD),
120
/* Magnifying window command table definition. */
123
{IDM_FILEOPEN, CmdStub}
128
sizeof(rgcmdMagnify) / sizeof(CMD),
138
BOOL CreateMagnify(HWND hwndParent)
140
extern HBRUSH foreBrush, backBrush;
143
hWndMagnify = CreateWindow("MagnifyGlass",
145
WS_BORDER | WS_POPUP | WS_DISABLED,
146
/* | WS_CLIPSIBLINGS, */
152
if (hWndMagnify == NULL) {
153
Win32Error("CreateWindow/Magnify");
156
alt.win = hWndMagnify;
157
magDC = GetDC(hWndMagnify);
162
SetGraphicsMode(magDC, GM_ADVANCED);
166
if (resource.in_memory) {
167
magMemDC = CreateCompatibleDC(magDC);
170
SetGraphicsMode(magDC, GM_ADVANCED);
177
SetBkMode(magDC, OPAQUE);
178
SetBkColor(magDC, back_Pixel);
184
LRESULT CALLBACK MagnifyProc(HWND hwnd, UINT uMessage,
185
WPARAM wparam, LPARAM lparam)
187
return DispMessage(&msdiMagnify, hwnd, uMessage, wparam, lparam);
190
LRESULT MsgMagnifyCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
194
GetClientRect(hwnd, &r);
195
if (wparam) FillRect((HDC)wparam, &r, backBrush);
200
LRESULT MsgMagnifyEraseBkgnd(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
203
GetClientRect(hwnd, &r);
204
FillRect((HDC)wparam, &r, backBrush);
208
LRESULT MsgMagnifyPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
211
POINT ptOrg = { 0, 0};
213
BeginPaint(hwnd, &ps);
215
GetWindowOrgEx(maneDrawDC, &ptOrg);
217
if (resource.in_memory) {
220
oldBrush = SelectObject(magDC, foreBrush);
222
/* We have to paint in ps.rcPaint, from memory dib. */
224
ps.rcPaint.left, ps.rcPaint.top,
225
ps.rcPaint.right - ps.rcPaint.left,
226
ps.rcPaint.bottom - ps.rcPaint.top,
229
ps.rcPaint.top, SRCCOPY))
230
Win32Error("Draw Magnify/BitBlt");
232
SelectObject(magDC, oldBrush);
236
/* We have to paint directly onto the screen */
237
extern void redraw(struct WindowRec *);
240
/* swapping to mag. glass device contexts */
241
foreGC = ruleGC = highGC = ps.hdc;
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;
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);
256
/* draw background */
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);
266
draw_rulers(alt.width, alt.height, magDC);
269
allowDrawingChars = TRUE;
272
if (resource.reverse) {
273
PatBlt(foreGC, alt.min_x, alt.min_y, alt.max_x, alt.max_y, DSTINVERT);
275
/* and back to drawing window dcs */
276
foreGC = ruleGC = highGC = maneDrawDC;
284
Process messages for the about box.
287
LRESULT CALLBACK DrawProc(HWND hwnd, UINT uMessage,
288
WPARAM wparam, LPARAM lparam)
290
return DispMessage(&msdiDraw, hwnd, uMessage, wparam, lparam);
294
CreateDraw(hWndParent) : creates the drawing window (child with
297
BOOL CreateDraw(HWND hwndParent)
299
hWndDraw = CreateWindowEx(WS_EX_CLIENTEDGE,
300
TEXT("ClientDrawClass"),
302
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
303
| WS_HSCROLL | WS_VSCROLL,
309
if (hWndDraw == NULL) {
310
Win32Error("CreateWindowEx");
314
/* Initialize all graphic related variables */
318
SizeClientWindow(hWndDraw);
319
SetScrollBars(hWndDraw);
320
SetCursor(hCursArrow);
321
ShowWindow(hWndDraw, SW_SHOW);
323
make_temporary_dir(&temporary_dir); /* For storing temporary files... */
330
* Open the dvi file and set titles
332
set_directory_dvifile();
336
char *cp = getenv("WWWBROWSER");
337
if (cp) browser = cp;
339
HTProfile_newPreemptiveClient(HTAppName, HTAppVersion);
340
HTCacheMode_setEnabled(NO);
343
/* Optionally, turn on tracing of WWW library calls. */
344
if (debug & DBG_HYPER) {
345
WWWTRACE = SHOW_STREAM_TRACE;
351
/* At this point DISP, our_visual, our_depth and our_colormap must
352
be defined, and they are */
356
/* Open the input file. Turn filename into URL first if needed */
359
if (!(URLbase || htex_is_url(dvi_name))) {
363
n = strlen(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 */
380
/* Turn filename into URL */
381
/* Escape dangers, esp. # from emacs */
383
new_name = xmalloc((unsigned) strlen(dvi_name)+6);
384
strcat(strcpy(new_name,"file:"),dvi_name);
388
new_name=HTEscape(dvi_name,URL_PATH);
390
dvi_name = xmalloc((unsigned) strlen(new_name)+6);
391
strcat(strcpy(dvi_name,"file:"),new_name);
393
/* Now we have the right filename, in a URL */
400
if (!open_www_file()) {
401
fprintf(stderr,"Could not open dvi file. Exiting.\n");
408
#endif /* not HTEX */
414
src_delete_all_specials();
417
current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
418
if (current_page < 0 || current_page >= total_pages) usage();
421
set_icon_and_title (dvi_name, &icon_name, &title_name, 1);
426
if (resource.shrinkfactor <= 0)
427
new_shrink = ChooseShrink();
429
new_shrink = resource.shrinkfactor;
432
ChangeZoom(new_shrink);
436
/* FIXME : why 2 calls ? */
447
LRESULT MsgDrawCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
452
LRESULT MsgDrawNCPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
454
fprintf(stderr, "NC Paint hwnd = %x, wparam = %x, lparam = %x\n",
455
hwnd, wparam, lparam);
456
/* return DefWindowProc(hwnd, uMessage, wparam, lparam); */
461
LRESULT MsgDrawMousemove(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
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;
473
POINT ptOrg = { 0, 0};
475
GetWindowOrgEx(maneDrawDC, &ptOrg);
477
xMousePos = LOWORD(lparam);
478
yMousePos = HIWORD(lparam);
480
if (bMagDisp && mask_mag(wparam)) {
482
/* redraw mag. glass content */
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,
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");
498
/* UpdateWindow(hWndMagnify); */
499
/* Need to redisplay the toolbar too ! */
500
UpdateWindow(hWndToolbar);
503
Redraw the in-memory bitmap for the mag. glass
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;
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;
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);
524
if (xDelta || yDelta) {
526
if (ScrollWindowEx(hWndMagnify,
528
NULL, NULL, NULL, &prcUpdate,
529
SW_INVALIDATE | SW_ERASE ) == ERROR)
530
Win32Error("ScrollWindowEx");
532
fprintf(stderr, "prcUpdate : (%d %d) - (%d %d) mag (%d %d)\n",
533
prcUpdate.left, prcUpdate.top,
534
prcUpdate.right, prcUpdate.bottom, magWidth, magHeight);
538
if (resource.in_memory) {
540
SelectObject(magMemDC, backBrush);
542
if (!FillRect(magMemDC, &altRect, backBrush))
543
Win32Error("FillRect Magnifying Glass");
545
/* FIXME : it would be nice to see the page's border in the mag. glass */
547
max(alt.min_x, -alt.base_x),
548
max(alt.min_y, -alt.base_y),
554
/* FIXME : how to put these rulers once for all and bitblt
557
draw_rulers(alt.width, alt.height, magMemDC);
560
UpdateWindow(hWndMagnify);
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);
570
EnterMag(HWND hwnd, int xMousePos, int yMousePos)
572
RECT rcClient, rcPage, rcClip, rcMag;
573
POINT ptClientUL, ptClientLR;
574
POINT mousePos, absPos, wndOrg;
576
extern int numColors;
577
HWND hWndTop = GetTopWindow(NULL);
579
/* Retrieve the page dimensions */
582
rcPage.right = page_w - 1;
583
rcPage.bottom = page_h - 1;
585
/* Get Window origin */
586
GetWindowOrgEx(maneDrawDC, &wndOrg);
588
mousePos.x = xMousePos + wndOrg.x;
589
mousePos.y = yMousePos + wndOrg.y;
591
if (!PtInRect(&rcPage, mousePos)) {
595
if (1 /* hWndTop == hWndMain */) {
598
fprintf(stderr, "Entering mag and saving main window\n");
600
GetClientRect(hWndMain,&rc);
601
BitBlt(hdcDrawSave, 0,0,rc.right,rc.bottom,
602
maneDC, 0,0,SRCCOPY);
606
/* FIXME: this causes a redisplay bug if xdvi is not the topmost
610
/* Capture mouse input */
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;
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. */
634
fprintf(stderr, "Org %d %d\n", wndOrg.x, wndOrg.y);
637
ptClientUL.x - wndOrg.x,
638
ptClientUL.y - wndOrg.y,
639
ptClientLR.x - wndOrg.x,
640
ptClientLR.y - wndOrg.y);
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;
649
rcMag.right = rcMag.left + 2*magWidth + 1;
650
rcMag.bottom = rcMag.top + 2*magHeight + 1;
652
if (resource.in_memory) {
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");
662
magDIB = CreateDIB(magMemDC, 2*magWidth, 2*magHeight, 16, NULL, NULL);
663
if ((oldmagDIB = SelectObject(magMemDC, magDIB)) == NULL)
664
Win32Error("SelectObject/magDIB");
666
if (!FillRect(magMemDC, &rcMag, backBrush))
667
Win32Error("FillRect magMemDC background");
669
foreGC = ruleGC = highGC = magMemDC;
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,
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); */
685
LRESULT MsgDrawEnterMagL(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
687
if (bSkipFirstClick) {
688
bSkipFirstClick = FALSE;
692
if (bMagDisp || bSetHome)
695
if (mask_sethome(wparam)) {
696
RECT rcClip, rcPage, rcClient;
697
POINT ptClientUL, ptClientLR;
699
SetCursor(hCursCross);
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);
727
UpdateStatusBar("Setting home position...", 0, 0);
732
if (mask_opennewframe(wparam)) {
738
if (pointerlocate(&x, &y)) {
739
/* Only do this if there's actually an href right there */
741
/* screen_to_page(&mane,x,y,&page,&px,&py); */
742
ret = htex_handleref(current_page, x, y);
744
if (ret == 1) return 0;
747
magWidth = mg_size[0].w / 2;
748
magHeight = mg_size[0].h / 2;
749
EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
754
LRESULT MsgDrawEnterMagM(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
757
/* Allow to open a new frame only if not running in single
759
if (!resource.single_flag) {
761
if (pointerlocate(&x, &y)) {
762
/* Only do this if there's actually an href right there */
764
/* screen_to_page(&mane,x,y,&page,&px,&py); */
766
ret = htex_handleref(current_page, x, y);
768
if (ret == 1) return 0;
772
if (bSkipFirstClick) {
773
bSkipFirstClick = FALSE;
777
if (bMagDisp || bSetHome)
780
magWidth = mg_size[1].w / 2;
781
magHeight = mg_size[1].h / 2;
782
EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
787
LRESULT MsgDrawEnterMagR(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
789
if (bSkipFirstClick) {
790
bSkipFirstClick = FALSE;
793
if (bMagDisp || bSetHome)
797
if (mask_srcspecial(wparam)) {
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);
810
magWidth = mg_size[2].w / 2;
811
magHeight = mg_size[2].h / 2;
812
EnterMag(hwnd, LOWORD(lparam), HIWORD(lparam));
817
LRESULT MsgDrawQuitMagL(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
819
POINT ptOrg = { 0, 0};
821
GetWindowOrgEx(maneDrawDC, &ptOrg);
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);
837
wsprintf(szBuf, "Setting home to %5d, %5d", home_x, home_y);
838
UpdateStatusBar(szBuf, 0, 0);
841
/* removes the window */
842
foreGC = ruleGC = highGC = maneDrawDC;
843
ShowWindow(hWndMagnify, SW_HIDE);
845
UpdateWindow(hWndDraw);
846
/* restores the old shrink factor and redisplay page */
853
LRESULT MsgDrawCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
855
HDC hDC = GetDC(hwnd);
862
/* mane.base_x = */xCurrentScroll = 0;
866
/* mane.base_y = */yCurrentScroll = yMinScroll;
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);
884
/* Scrolled Region */
886
hrgnScroll = CreateRectRgn(0, 0, 10, 10);
891
LRESULT MsgDrawHScroll(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
900
GetClientRect(hwnd, &r);
902
switch (LOWORD(wparam)) {
904
xNewPos = xMinScroll;
907
xNewPos = xMaxScroll;
910
xNewPos = xCurrentScroll - (((r.right - r.left) * 2) / 3);
913
xNewPos = xCurrentScroll + (((r.right - r.left) * 2) / 3);
916
xNewPos = xCurrentScroll - 5;
919
xNewPos = xCurrentScroll + 5;
921
case SB_THUMBPOSITION:
922
xNewPos = HIWORD(wparam);
925
xNewPos = xCurrentScroll;
929
xNewPos = max(xMinScroll, xNewPos);
930
xNewPos = min(xMaxScroll - max(r.right - 1, 0), xNewPos);
933
fprintf(stderr, "r.right = %d [%d %d %d]\n",
934
r.right, xMinScroll, xCurrentScroll, xMaxScroll);
935
fprintf(stderr, "xNewPos = %d\n", xNewPos);
938
if (xNewPos == xCurrentScroll)
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);
951
si.cbSize = sizeof(si);
953
si.nPos = xCurrentScroll;
954
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
958
LRESULT MsgDrawVScroll(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
968
GetClientRect(hwnd, &r);
969
if (yCurrentScroll == yMinScroll
971
&& (LOWORD(wparam) == SB_TOP
972
|| LOWORD(wparam) == SB_PAGEUP
973
/* || LOWORD(wparam) == SB_LINEUP */)) {
975
wparam = MAKEWORD(SB_BOTTOM, HIWORD(wparam));
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 */)) {
983
wparam = MAKEWORD(SB_TOP, HIWORD(wparam));
985
switch (LOWORD(wparam)) {
987
yNewPos = yMinScroll;
990
yNewPos = yMaxScroll;
993
yNewPos = yCurrentScroll - (((r.bottom - r.top) * 2) / 3);
996
yNewPos = yCurrentScroll + (((r.bottom - r.top) * 2) / 3);
999
yNewPos = yCurrentScroll - 5;
1002
yNewPos = yCurrentScroll + 5;
1004
case SB_THUMBPOSITION:
1005
yNewPos = HIWORD(wparam);
1008
yNewPos = yCurrentScroll;
1010
yNewPos = max(yMinScroll, yNewPos);
1011
yNewPos = min(yMaxScroll - max(r.bottom - 1, 0), yNewPos);
1013
if (yNewPos == yCurrentScroll)
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);
1027
si.cbSize = sizeof(si);
1029
si.nPos = yCurrentScroll;
1030
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
1034
LRESULT MsgDrawEraseBkgnd(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
1037
HDC hdc = (HDC)wparam;
1039
if (isPrinting) return TRUE;
1041
GetClientRect(hwnd, &r);
1043
if (resource.in_memory) {
1044
FillRect(hdc, &r, GetStockObject (LTGRAY_BRUSH));
1048
if (debug & DBG_EVENT)
1049
fprintf(stderr, "Erasing background with colors %x\n", back_Pixel);
1051
FillRect(hdc, &r, GetStockObject (LTGRAY_BRUSH));
1053
r.bottom = min(page_h - yCurrentScroll, r.bottom);
1054
r.right = min(page_w - xCurrentScroll, r.right);
1056
if (debug & DBG_EVENT)
1057
fprintf(stderr, "Erasing background, Page is in (%d x %d)\n",
1060
FillRect(hdc, &r, backBrush);
1068
We have 2 alternatives :
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.
1077
- directly drawing on the screen. This is rather efficient for the display.
1079
We choose among these 2 methods thanks to the resource.in_memory flag.
1082
void DrawInMemory(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
1086
extern void reset_xfrm_stack(void);
1088
/* If no file open, just return */
1089
if (!dvi_name || !*dvi_name)
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;
1103
We have the page in memory. This page consist of all the pk chars
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.
1113
/* FIXME : there should be a global stack in case
1114
such transformations would span over several pages. */
1115
if (resource.use_xform)
1119
/* Erasing background */
1122
r.left = mane.min_x;
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);
1129
/* First pass for specials */
1130
allowDrawingChars = FALSE;
1135
if (resource._postscript && psToDisplay) {
1136
rop = /* 0x008E1D7C */ SRCCOPY;
1138
/* if gs is active, try to make it paint its picture */
1140
rcGSPaint.left = lprcPaint->left+xCurrentScroll;
1141
rcGSPaint.right = lprcPaint->right+xCurrentScroll;
1142
rcGSPaint.top = lprcPaint->top+yCurrentScroll;
1143
rcGSPaint.bottom = lprcPaint->bottom+yCurrentScroll;
1145
fprintf(stderr, "gs: redrawing\n");
1147
(*pgsdll_draw)(gs_device, hdcFrom, lprcPaint, &rcGSPaint);
1154
allowDrawingChars = TRUE;
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,
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);
1182
void DrawOnScreen(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
1184
extern void reset_xfrm_stack(void);
1186
We want to draw directly onto the screen.
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;
1198
/* If no file open, just return */
1199
if (!dvi_name || !*dvi_name)
1203
/* FIXME : there should be a global stack in case
1204
such transformations would span over several pages. */
1205
if (resource.use_xform)
1210
FIXME : remove this and process directly.
1213
/* First pass for specials */
1214
allowDrawingChars = FALSE;
1219
if (resource._postscript && psToDisplay) {
1220
/* if gs is active, try to make it paint its picture */
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);
1228
(*pgsdll_lock_device)(gs_device, 1);
1229
(*pgsdll_draw)(gs_device, hdcDest, lprcPaint, lprcPaint);
1230
(*pgsdll_lock_device)(gs_device, 0);
1234
allowDrawingChars = TRUE;
1237
fprintf(stderr, "repaint : %d %d %d %d ps = %d\n",
1238
lprcPaint->left, lprcPaint->top,
1239
lprcPaint->right, lprcPaint->bottom, psToDisplay);
1244
if (resource.reverse) {
1245
PatBlt(hdcDest, lprcPaint->left, lprcPaint->top, lprcPaint->right, lprcPaint->bottom, DSTINVERT);
1250
void DoDrawPaint(HDC hdcDest, HDC hdcFrom, LPRECT lprcPaint)
1252
RECT rcToPaint, rcPage;
1255
rcPage.right = page_w - xCurrentScroll;
1257
rcPage.bottom = page_h - yCurrentScroll;
1259
IntersectRect(&rcToPaint, lprcPaint, &rcPage);
1261
if (resource.in_memory)
1262
DrawInMemory(hdcDest, hdcFrom, &rcToPaint);
1264
DrawOnScreen(hdcDest, hdcFrom, &rcToPaint);
1267
LRESULT MsgDrawPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
1271
/* No redrawing while printing. Should not happen, but who knows ? */
1272
HDC hDC = BeginPaint(hwnd, &ps);
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);
1286
/* New data, so need to do some work */
1288
HWND hWndTop = GetTopWindow(NULL);
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);
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,
1306
fprintf(stderr, "Active window is *not* draw window\n");
1311
EndPaint(hwnd, &ps);
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.
1322
void InitGlobalsDraw()
1324
extern void initcolor(void);
1325
extern void init_xfrm_stack(void);
1327
currwin.win = mane.win = hWndDraw;
1329
/* It has its own_dc */
1330
maneDC = GetDC(hWndDraw);
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);
1342
if (maneBitsPixel >= 8 && use_grey) {
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);
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);
1364
if (!(maneRasterCaps & RC_BITMAP64)) {
1365
MessageBox(hWndMain,
1366
"Device does not support >64k bitmaps. Exiting...",
1367
NULL, MB_OK | MB_ICONERROR | MB_APPLMODAL);
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);
1379
/* Device context for drawing and the associated bitmap. */
1380
if ((imageDC = CreateCompatibleDC(maneDC)) == NULL)
1381
Win32Error("CreateCompatibleDC imageDC");
1384
if (resource.in_memory) {
1385
maneDrawMemDC = CreateCompatibleDC(maneDC);
1386
if (maneDrawMemDC == NULL)
1387
Win32Error("CreateCompatibleDC maneDrawMemDC");
1389
foreGC = ruleGC = highGC = maneDrawDC = maneDrawMemDC;
1391
grid1GC = grid2GC = grid3GC = maneDrawDC;
1392
foreGC2 = NULL; /* not used under Win32 */
1395
foreGC = ruleGC = highGC = maneDrawDC = GetDC(hWndDraw);
1396
grid1GC = grid2GC = grid3GC = foreGC;
1397
magMemDC = foreGC2 = NULL; /* not used under Win32 */
1402
SetGraphicsMode(maneDrawDC, GM_ADVANCED);
1404
if (resource.use_xform) {
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");
1416
SetStretchBltMode(foreGC, COLORONCOLOR);
1417
SetStretchBltMode(maneDC, COLORONCOLOR);
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);
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;
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;
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;
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;
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
-------------------------------------------------------------------------
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,
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;
1505
GetWindowRect(hWndMain, &r);
1508
width = r.right - r.left;
1509
height = r.bottom - r.top;
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. */
1519
fprintf(stderr, "Appbar : (%d %d) -- (%d %d)\n",
1520
abd.rc.left, abd.rc.top,
1521
abd.rc.right, abd.rc.bottom);
1523
if (abd.rc.left<0 && abd.rc.right < maneHorzRes/2) {
1524
abd_width = abd.rc.right;
1526
else if (abd.rc.top<0 && abd.rc.bottom < maneVertRes/2) {
1527
abd_height = abd.rc.bottom;
1531
if (bPrevInstance && !resource.single_flag) {
1532
/* if there is a previous instance, rely on it. */
1533
off_x = (rectWndPrev.left> maneHorzRes / 3)
1535
: rectWndPrev.left+v4size;
1536
off_y = (rectWndPrev.top > maneVertRes / 3)
1538
: rectWndPrev.top+v4size;
1539
width = rectWndPrev.right - rectWndPrev.left;
1540
height = rectWndPrev.bottom - rectWndPrev.top;
1542
fprintf(stderr, "Prev inst : @(%d,%d) (%d x %d)\n",
1543
off_x, off_y, width, height);
1547
else if (geometry) {
1549
int flag = XParseGeometry(geometry, &off_x, &off_y,
1552
if (flag & (XValue | YValue))
1553
size_hints.flags |= USPosition;
1554
if (flag & (WidthValue | HeightValue))
1555
size_hints.flags |= USSize;
1557
if (flag & XNegative) off_x += maneHorzRes - width;
1558
if (flag & YNegative) off_y += maneVertRes - height;
1562
if no geometry has been given, make the main window big enough.
1564
width = (int)(maneVertRes - abd_height * 0.618);
1565
height = maneVertRes - abd_height;
1567
fprintf(stderr, "Nothing : @(%d,%d) (%d x %d)\n",
1568
off_x, off_y, width, height);
1571
if (!(MoveWindow(hWndMain,
1575
Win32Error("no Geometry/MoveWindow");