|
|
/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/
/* insert2.c - MW insertion routines */
#define NOGDICAPMASKS
#define NOCLIPBOARD
#define NOCTLMGR
#define NOWINSTYLES
#ifndef KOREA
#define NOSYSMETRICS
#endif
#define NOMENUS
#define NOICON
#define NOKEYSTATE
#define NOSYSCOMMANDS
#define NOSHOWWINDOW
#define NOATOM
#define NOBRUSH
#define NOCREATESTRUCT
#define NOFONT
#define NOCLIPBOARD
#define NODRAWTEXT
#define NOPEN
#define NOREGION
#define NOSCROLL
#define NOMB
#define NOOPENFILE
#define NOSOUND
#define NOCOMM
#define NOWH
#define NOWINOFFSETS
#define NOWNDCLASS
#include <windows.h>
#include "mw.h"
#include "doslib.h"
#include "propdefs.h"
#include "dispdefs.h"
#include "fmtdefs.h"
#include "cmddefs.h"
#include "wwdefs.h"
#include "docdefs.h"
#define NOKCCODES
#include "ch.h"
#include "winddefs.h"
#include "fontdefs.h"
#include "debug.h"
#ifdef DEBUG
extern int vTune; #endif
#ifdef KOREA /* Use in KcInputNext..., 90.12.27 sangl */
extern int IsInterim; #endif
extern int vdlIns; extern int vxpIns; extern int vfTextBltValid; extern int vdypCursLineIns; extern struct FLI vfli; extern struct SEL selCur; extern int vdypBase; extern int vypBaseIns; extern int vxpMacIns; extern int vdypAfter; extern typeCP cpInsert; /* Beginning cp of insert block */ extern int ichInsert; /* Number of chars used in rgchInsert */ extern typeCP cpMinCur; extern typeCP cpMacCur; extern int docCur; extern struct CHP vchpInsert; extern struct WWD rgwwd[]; extern struct WWD *pwwdCur; extern int wwCur; extern int wwMac; extern int vfSeeSel; extern int vfFocus; #ifdef DBCS
extern int donteat; /* see disp.c */ #endif
unsigned WHsecGetTime() { /* Get the time (in hundredths of seconds) into a normalized word */ /* Ignore current hour, just minutes/seconds/hundredths */ struct TIM tim;
OsTime( &tim ); return ( (unsigned)tim.minutes * 6000 + (unsigned)tim.sec * 100 + (unsigned)tim.hsec ); }
/* V A L I D A T E T E X T B L T */ ValidateTextBlt() { /* Validate info sufficient for TextOut and ScrollCurWw calls in Insert */ /* In particular: vdlIns, vxpIns, vdypBase, vdypFont */
int NEAR FCpInsertInDl( typeCP, struct EDL * ); extern int vfInsFontTooTall; extern struct FMI vfmiScreen; extern int ferror; extern int vfInsEnd;
int dypFontAscent; int dypFontDescent; register struct EDL *pedl; int yp; typeCP cpBegin;
/* Routine assumes ww == wwDocument */
Assert( pwwdCur == &wwdCurrentDoc );
{ /* Look for a valid dl containing selCur.cpFirst */ /* We should usually be able to find one */ int dlGuess = vdlIns; struct EDL *dndl=&(**wwdCurrentDoc.hdndl)[0];
if ( (dlGuess < wwdCurrentDoc.dlMac) && FCpInsertInDl( selCur.cpFirst, pedl = &dndl[ dlGuess ] )) { /* vdlIns is already correct */ cpBegin = pedl->cpMin; } else { /* Search for valid dl containing insertion point */ /* Use linear search, all dl's may not be valid */ int dl;
for ( pedl = dndl, dl = 0; dl < wwdCurrentDoc.dlMac; dl++, pedl++ ) { if ( FCpInsertInDl( selCur.cpFirst, pedl ) ) { /* Found it */ vdlIns = dl; cpBegin = pedl->cpMin; break; } } if (dl >= wwdCurrentDoc.dlMac) { /* No valid dl contains the cp -- must update whole screen */ cpBegin = CpBeginLine( &vdlIns, selCur.cpFirst ); } } }
/* Special case for splat: locate insert point at end of previous line */
pedl = &(**wwdCurrentDoc.hdndl) [vdlIns]; if (pedl->fSplat && (vdlIns > 0) && selCur.cpFirst == pedl->cpMin) { /* Splat on current line */ /* Check for pedl->cpMin above is necessary for the special case */ /* in which the QD buffer is at the beginning of the splat line */ pedl--; if (pedl->fValid && !pedl->fSplat) { /* Locate cursor at end of previous line */ vdlIns--; cpBegin = pedl->cpMin;
ClearInsertLine(); selCur.fEndOfLine = TRUE; vfInsEnd = TRUE; ToggleSel( selCur.cpFirst, selCur.cpLim, TRUE ); } else { pedl++; goto CheckEnd; } } else { /* Eliminate end of line cursor if not before a splat */ CheckEnd: if (selCur.fEndOfLine) { ClearInsertLine(); selCur.fEndOfLine = FALSE; vfInsEnd = FALSE; ToggleSel( selCur.cpFirst, selCur.cpLim, TRUE ); } }
/* Assure we obtained a good vdlIns */
Assert( vdlIns < wwdCurrentDoc.dlMac ); Assert( ((selCur.cpFirst >= pedl->cpMin) && (selCur.cpFirst <= pedl->cpMin + pedl->dcpMac)));
FormatLine(docCur, cpBegin, 0, cpMacCur, flmSandMode); vxpIns = DxpDiff(0, (int) (selCur.cpFirst - cpBegin), &vxpIns) + vfli.xpLeft + xpSelBar - wwdCurrentDoc.xpMin; vdypBase = vfli.dypBase; vdypAfter = vfli.dypAfter; vdypCursLineIns = min(vfli.dypFont, vfli.dypLine - vdypAfter);
vxpMacIns = vfli.xpMarg;
LoadFont(docCur, &vchpInsert, mdFontChk); ferror = FALSE; // running out of memory here is OK. Must clear this
// or important calls will needlessly fail.
// (8.6.91) D. Kent
#ifdef KOREA // jinwoo: 92, 9, 28
/* For y position of display, 920604 KDLEE */ #ifdef NODESC
{ extern HDC vhMDC; TEXTMETRIC tm;
GetTextMetrics (vhMDC, (LPTEXTMETRIC)&tm); if (tm.tmCharSet==HANGEUL_CHARSET) vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp; else vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase; } #else /* NODESC */
vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase; #endif /* NODESC */
#else /* KOREA */
vypBaseIns = (**wwdCurrentDoc.hdndl) [vdlIns].yp - vdypBase; #endif // KOREA: jinwoo: 92, 9, 28
dypFontAscent = vfmiScreen.dypAscent + vfmiScreen.dypLeading; dypFontDescent = vfmiScreen.dypDescent;
if (vchpInsert.hpsPos) { if (vchpInsert.hpsPos < hpsNegMin) { vypBaseIns -= ypSubSuper; /* Superscript */ dypFontAscent += ypSubSuper; } else { vypBaseIns += ypSubSuper; /* Subscript */ dypFontDescent += ypSubSuper; } }
/* Set if current font is too tall to display on insert line */ vfInsFontTooTall = (imax( dypFontAscent, vfli.dypLine - vfli.dypBase ) + imax( dypFontDescent, vfli.dypBase )) > vfli.dypLine;
vfTextBltValid = true; }
int NEAR FCpInsertInDl( cp, pedl ) typeCP cp; register struct EDL *pedl; { /* Return TRUE if insert point cp is in dl & dl is valid, FALSE otherwise */
if ( (pedl->fValid) && (cp >= pedl->cpMin) ) { /* dl is valid & cp is at or below starting cp of dl */ if ( (cp < pedl->cpMin + pedl->dcpMac) || ((cp == cpMacCur) && (cp == pedl->cpMin + pedl->dcpMac)) ) { /* cp is on line dl */ if (pedl->yp <= wwdCurrentDoc.ypMac) { /* dl is complete, i.e. not cut off at bottom of window */ return TRUE; } } } return FALSE; }
#ifdef FOOTNOTES
/* F E D I T F T N */ int FEditFtn(cpFirst, cpLim) typeCP cpFirst, cpLim; { /* Return true if edit includes an end of footnote mark */ struct FNTB **hfntb; typeCP cp;
if ((hfntb = HfntbGet(docCur)) == 0 || cpLim < (cp = (*hfntb)->rgfnd[0].cpFtn)) return false;
if (cpFirst < cp || CpRefFromFtn(docCur, cpFirst) != CpRefFromFtn(docCur, cpLim)) { Error(IDPMTFtnLoad); return fTrue; } return fFalse; } #endif /* FOOTNOTES */
/* U P D A T E O T H E R W W S */ #ifdef CASHMERE
UpdateOtherWws(fInval) BOOL fInval; { int ww = 0; struct WWD *pwwd = rgwwd; {{ while (ww < wwMac) { if (ww != wwCur && (pwwd++)->doc == docCur) {{ typeCP cpI = cpInsert + ichInsert; typeCP cpH = CpMax(cpI, cpInsLastInval); typeCP cpL = CpMin(cpInsLastInval, cpI); typeCP dcp; if ((dcp = cpH - cpL) != cp0 || fInval) AdjustCp(docCur, cpL, dcp, dcp); cpInsLastInval = cpI; return; }} ww++; } }} } #endif /* CASHMERE */
/* K C I N P U T N E X T K E Y */ KcInputNextKey() { /* Get next available key/event from Windows */ /* Returns key code or kcNil if a non-key event */ /* Updates the screen if there is time before events arrive */ extern HWND vhWnd; /* WINDOWS: Handle of the current document display window*/ extern MSG vmsgLast; /* WINDOWS: last message gotten */ extern int vfInsLast; extern int vfCommandKey; extern int vfShiftKey; extern int vfAwfulNoise;
int i; int kc;
for ( ;; ) { if ( FImportantMsgPresent() ) goto GotMessage;
/* No events waiting -- if none show up for a while, update the screen */
#ifdef CASHMERE
UpdateOtherWws( FALSE ); #endif
{ /* Dawdle for a time, looking for keys, before updating the screen */ unsigned WHsecGetTime(); unsigned wHsec;
wHsec = WHsecGetTime(); do { if ( FImportantMsgPresent() ) goto GotMessage;
} while ( WHsecGetTime() - wHsec < dwHsecKeyDawdle ); }
#ifdef DEBUG
if (vTune) continue; /* Bag background update while debugging to see how we fare */ #endif
Scribble( 8, 'U' ); ClearInsertLine(); UpdateWw(wwCur, fTrue); ToggleSel(selCur.cpFirst, selCur.cpLim, fTrue); Scribble( 8, ' ' );
if ( FImportantMsgPresent() ) goto GotMessage;
vfAwfulNoise = FALSE; PutCpInWwHz( selCur.cpFirst );
EndLongOp( NULL );
if ( FImportantMsgPresent() ) goto GotMessage;
if ( !vfTextBltValid ) ValidateTextBlt();
/* Nothing has happened for a while, let's blink the cursor */
{ unsigned WHsecGetTime(); unsigned wHsecBlink = GetCaretBlinkTime() / 10; unsigned wHsecLastBlink=WHsecGetTime() + wHsecBlink/2;
for ( ;; ) { unsigned wHsecT;
if ( FImportantMsgPresent() ) goto GotMessage;
/* Another app may have stolen the focus away from us while we called
PeekMessage(), in which case we should end Alpha mode. */ if (!vfFocus) return kcNil;
UpdateDisplay( TRUE ); if ( (wHsecT = WHsecGetTime()) - wHsecLastBlink >= wHsecBlink ) { DrawInsertLine(); wHsecLastBlink = wHsecT; } } }
continue;
GotMessage: #ifdef DBCS
#ifdef KOREA /* Need to GetMessage for F-Key during Interim,90.12.27 sangl */
if ( ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil) || IsInterim) #else
if ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil) #endif
{ if (vmsgLast.wParam == VK_EXECUTE) return( kcNil ); if (vmsgLast.message == WM_KEYDOWN) { switch (kc) { default: break; case kcAlphaVirtual: /* This means we can't anticipate the key's meaning
before translation */ #ifdef KOREA /* Need GetMesssage for direc keys, etc during interim 90.12.26 sangl */
if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) && !IsInterim) #else
if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) ) #endif
/* This is a non-alpha key message */ return kcNil; if ( !donteat ) { GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 ); #ifdef DBCS
// kksuzuka #9193 NECAI95
// got message is WM_KEYDOWN by PeekMessage( )
// but got message is WM_IME_STARTCOMPOSITION by GetMessage()
// We need DispatchMessage( WM_IME_STARTCOMPOSITION )
if ( vmsgLast.message == 0x10d ) // WM_IME_STARTCOMPOSITION
DispatchMessage( (LPMSG)&vmsgLast ); #endif
} else { /* not eat message because FimportantMsgPresent has
** eaten KEY_DOWN message */ donteat = FALSE; } /*
** When KKAPP window open, this message is offten wrong. ** we must check it is really WM_KEYDOWN */ #ifdef KOREA /* for level 3, 90.12.26 sangl */
if ((vmsgLast.message == WM_CHAR) || (vmsgLast.message == WM_INTERIM)) { #else
if ( vmsgLast.message == WM_CHAR ) { #endif
return vmsgLast.wParam; } if ( vmsgLast.message != WM_KEYDOWN ) { return kcNil; } TranslateMessage( &vmsgLast ); continue; } /* switch kc */ } /* if keydown */ if ( !donteat ) { GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 ); #ifdef KOREA /* for level 3, 91.1.21 by Sangl */
if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) { #else
if ( vmsgLast.message == WM_CHAR ) { #endif
return vmsgLast.wParam; } } /* dont eat */ else { donteat = FALSE; } } /* if kc != kcNil */ #else
if ((kc=KcAlphaKeyMessage( &vmsgLast )) != kcNil) { if (vmsgLast.message == WM_KEYDOWN) { switch (kc) { default: break; case kcAlphaVirtual: /* This means we can't anticipate the key's meaning
before translation */ if ( FNonAlphaKeyMessage( &vmsgLast, FALSE ) ) /* This is a non-alpha key message */ return kcNil;
GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 ); TranslateMessage( &vmsgLast ); continue; } } GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 ); } #endif
return kc; } /* End of for ( ;; ) loop to process messages */ }
#ifdef KOREA /* 90.12.29 sangl */
KcInputNextHan() { /* Get next available key/event from Windows */ /* Returns key code or kcNil if a non-key event */ /* Updates the screen if there is time before events arrive */ extern HWND vhWnd; /* WINDOWS: Handle of the current document display window*/ extern MSG vmsgLast; /* WINDOWS: last message gotten */ extern int vfInsLast; extern int vfCommandKey; extern int vfShiftKey; extern int vfAwfulNoise;
int i; int kc; int tmp;
tmp = vfInsLast; tmp = vfCommandKey; tmp = vfShiftKey; tmp = vfAwfulNoise; tmp = vmsgLast.message; tmp = vmsgLast.wParam;
for ( ;; ) { if ( FImportantMsgPresent() ) goto GotMessage;
/* No events waiting -- if none show up for a while, update the screen */
{ /* Dawdle for a time, looking for keys, before updating the screen */ unsigned WHsecGetTime(); unsigned wHsec;
wHsec = WHsecGetTime(); do { if ( FImportantMsgPresent() ) goto GotMessage;
} while ( WHsecGetTime() - wHsec < dwHsecKeyDawdle ); }
#ifdef DEBUG
if (vTune) continue; /* Bag background update while debugging to see how we fare */ #endif
if ( FImportantMsgPresent() ) goto GotMessage;
/* vfAwfulNoise = FALSE;
PutCpInWwHz( selCur.cpFirst );
EndLongOp( NULL );*/
if ( FImportantMsgPresent() ) goto GotMessage;
/* Nothing has happened for a while, let's blink the cursor */
{ unsigned WHsecGetTime(); unsigned wHsecBlink = GetCaretBlinkTime() / 10; unsigned wHsecLastBlink=WHsecGetTime() + wHsecBlink/2; KillTimer( vhWnd, tidCaret ); for ( ;; ) { unsigned wHsecT;
if ( FImportantMsgPresent() ) { SetTimer( vhWnd, tidCaret, GetCaretBlinkTime(), (FARPROC)NULL ); goto GotMessage; }
/* Another app may have stolen the focus away from us while we called
PeekMessage(), in which case we should end Alpha mode. */ if (!vfFocus) { SetTimer( vhWnd, tidCaret, GetCaretBlinkTime(), (FARPROC)NULL ); return kcNil; }
if ( (wHsecT = WHsecGetTime()) - wHsecLastBlink >= wHsecBlink ) { DrawInsertLine(); wHsecLastBlink = wHsecT; } } }
continue;
GotMessage: { // MSCH bklee 12/22/94
#define VK_PROCESSKEY 0xE5 // New finalize message. bklee.
#include "ime.h"
MSG msg; extern BOOL fInterim;
if (fInterim) { if (PeekMessage ((LPMSG)&msg, vhWnd, WM_KEYDOWN, WM_SYSKEYUP, PM_NOYIELD | PM_NOREMOVE )) { if ( msg.wParam == VK_MENU || msg.wParam == VK_PROCESSKEY ) return VK_MENU; else if( msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT ) { HANDLE hIme; LPIMESTRUCT lpIme; DWORD dwConversionMode;
hIme = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE,(LONG)sizeof(IMESTRUCT)); if (hIme && (lpIme = (LPIMESTRUCT)GlobalLock(hIme))) { lpIme->fnc = IME_GETCONVERSIONMODE; GlobalUnlock(hIme);
dwConversionMode = SendIMEMessage (GetFocus(), MAKELONG(hIme,0)); GlobalFree(hIme); } if (dwConversionMode & IME_MODE_HANJACONVERT) // Hanja conversion mode
return VK_MENU; } } } }
if( vmsgLast.wParam == VK_EXECUTE ) vmsgLast.wParam = VK_RETURN;
/* To GetMessage for Func/Ctrl/direc keys, 90.4.4, Sang-Weon */ if ( ((kc=KcAlphaKeyMessage(&vmsgLast))!=kcNil) || IsInterim ) { if( vmsgLast.wParam == VK_EXECUTE ) return kcNil;
if (vmsgLast.message == WM_KEYDOWN) { switch (kc) { default: break; case kcAlphaVirtual: /* This means we can't anticipate the key's meaning
before translation */ if ( FNonAlphaKeyMessage(&vmsgLast, FALSE) && !IsInterim ) /* This is a non-alpha key message */ return kcNil; if ( !donteat ) { GetMessage( (LPMSG)&vmsgLast, NULL, 0, 0 ); } else { /* not eat message because FimportantMsgPresent has
** eaten KEY_DOWN message */ donteat = FALSE; } /*
** When KKAPP window open, this message is offten wrong. ** we must check it is really WM_KEYDOWN */ if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) { return vmsgLast.wParam; } if ( vmsgLast.message != WM_KEYDOWN ) { return kcNil; } TranslateMessage( &vmsgLast ); continue; } /* switch kc */ } /* if keydown */ if ( !donteat ) { GetMessage( (LPMSG) &vmsgLast, NULL, 0, 0 ); if ( (vmsgLast.message==WM_CHAR)||(vmsgLast.message==WM_INTERIM) ) { return vmsgLast.wParam; } } /* dont eat */ else { donteat = FALSE; } } /* if kc != kcNil */ return kc; } /* End of for ( ;; ) loop to process messages */ } #endif /* ifdef KOREA */
|