Commit 353a4868 authored by Martin Wierich's avatar Martin Wierich
Browse files

integrating tcp and printing. Changes are commented with "MW11"

parent 8f022d36
......@@ -3,4 +3,6 @@ DragAcceptFiles@8
DragFinish@4
DragQueryFileA@16
SHGetPathFromIDList@8
SHGetPathFromIDListA@8
SHBrowseForFolder@4
SHBrowseForFolderA@4
......@@ -6,7 +6,9 @@
/* ...Mike */
// MW...
#include "cprinter_12.c"
#include "cprinter_12.h"
#include "cTCP.h"
#include "winsock.h"
#ifdef HILT
#include <htmlhelp.h>
......@@ -14,13 +16,11 @@ int htmlHelpInitialized = FALSE;
DWORD htmlHelpCookie;
#endif
// MW: Since currently cCrosscall.o, cDebug.o, cPicture.o and util.o are the ONLY object files,
// which can be linked automatically, I include all routines for printing here.
// CPrinter.c could also be compiled separately.
#include <commctrl.h>
extern BOOL bUserAbort;
extern HWND hDlgPrint; /* MW: hDlgPrint is the handle of the "Cancel Printing" dialog. */
extern HWND hwndText; /* MW: hwndText is the handle of the page count text in the dialog. */
DNSInfo *DNSInfoList=NULL;
// ...MW
CrossCallInfo gCci;
static BOOL gEventsInited = FALSE;
......@@ -81,6 +81,7 @@ static CrossCallInfo *MakeReturn2Cci (CrossCallInfo * pcci, int v1, int v2);
static CrossCallInfo *MakeReturn3Cci (CrossCallInfo * pcci, int v1, int v2, int v3);
static CrossCallInfo *MakeReturn4Cci (CrossCallInfo * pcci, int v1, int v2, int v3, int v4);
static CrossCallInfo *MakeReturn5Cci (CrossCallInfo * pcci, int v1, int v2, int v3, int v4, int v5);
static CrossCallInfo *MakeReturn6Cci (CrossCallInfo * pcci, int v1, int v2, int v3, int v4, int v5, int v6);
/* Menu(item)IDs are not allowed to exceed OSMenuIDEnd.
This is because window ids start at (OSMenuIDEnd+5), and need to be distinct from menu ids
......@@ -1610,6 +1611,22 @@ DialogProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
*/
// MW...
void lookUpAndRemove(WPARAM dnsHdl,DNSInfo **listPtr,DNSInfo **elPtr)
// This function is used to look up an element with a matching dnsHdl-field in
// the DNSInfoList. This element will then be removed from the list.
{
if ((WPARAM)(*listPtr)->dnsHdl==dnsHdl)
{ // the object to look up has been found, so remove it from the list
// and give it back via elPtr.
*elPtr = *listPtr;
*listPtr = (*listPtr)->next;
}
else
lookUpAndRemove(dnsHdl, &(*listPtr)->next, elPtr);
}
// ... MW
/* The callback routine for the main window.
*/
static LRESULT CALLBACK
......@@ -1680,6 +1697,77 @@ MainWindowProcedure (HWND hWin, UINT uMess, WPARAM wPara, LPARAM lPara)
}
}
break;
// MW...
case PM_SOCKET_EVENT:
{
// wPara is the socket handle
// LOWORD(lPara) is the message
// HIWORD(lPara) is an error code
switch (LOWORD(lPara))
{ case FD_OOB:
case FD_READ: SendMessage3ToClean(CcWmINETEVENT,IE_RECEIVED, wPara,
RChanReceiver);
break;
case FD_WRITE: SendMessage3ToClean(CcWmINETEVENT,IE_SENDABLE, wPara,
SChanReceiver);
break;
case FD_ACCEPT: SendMessage3ToClean(CcWmINETEVENT,IE_CONNECTREQUEST, wPara,
ListenerReceiver);
break;
case FD_CONNECT:SendMessage3ToClean(
CcWmINETEVENT,
HIWORD(lPara)==0 ? IE_ASYNCCONNECTCOMPLETE :
IE_ASYNCCONNECTFAILED,
wPara,
ConnectReceiver);
break;
case FD_CLOSE: {
dictitem *pDictitem;
pDictitem = lookup(wPara);
if (pDictitem) {
if (pDictitem->hasReceiveNotifier)
SendMessage3ToClean(CcWmINETEVENT,IE_EOM, wPara,
RChanReceiver);
if (pDictitem->hasSendableNotifier && HIWORD(lPara)!=0)
SendMessage3ToClean(CcWmINETEVENT,IE_DISCONNECTED, wPara,
SChanReceiver);
};
};
break;
};
};
break;
case PM_DNS_EVENT:
{ // wPara contains the DNS handle (the handle created by WSAAsyncGetHostByName
// The IP-adress of the looked up host will have been written into the
// corresponding element of the DNSInfoList. Look it up:
struct DNSInfo *elPtr;
int errCode;
errCode = HIWORD(lPara);
lookUpAndRemove(wPara,&DNSInfoList,&elPtr);
// *elPtr contains the info
SendMessage4ToClean( CcWmINETEVENT,
errCode ? IE_IPADDRESSNOTFOUND :
IE_IPADDRESSFOUND, ,
elPtr->dnsHdl,
DNSReceiver,
errCode ?
0 :
ntohl(((int*)(*(elPtr->junion.Hostent.h_addr_list)))[0])
);
// deallocate unused memory
LocalFree(elPtr);
};
break;
// ... MW
case WM_DDE_INITIATE:
{
static char apptext[256], topictext[256];
......@@ -6478,25 +6566,36 @@ HandleCleanRequest (CrossCallInfo * pcci)
}
break;
// MW...
case CcRqDO_PRINT_SETUP:
{ int ok;
PRINTDLG *pdPtr;
printSetup(0, pcci->p1,
(char*) pcci->p2, (char*) pcci->p3, (char*) pcci->p4, (char*) pcci->p5,
&ok, &pdPtr);
MakeReturn2Cci (pcci, ok, (int) pdPtr);
} break;
case CcRqGET_PRINTER_DC:
{ int doDialog,emulateScreen,ok,first,last,copies,deviceContext,dummy;
{ int doDialog,emulateScreenRes,
err,first,last,copies,pPrintDlg,deviceContext;
//rprintf("GET_PRINTER_DC\n");
doDialog = pcci->p1;
emulateScreen = pcci->p2;
getDC(doDialog,emulateScreen,0,42,&ok,&first,&last,&copies,&deviceContext,&dummy);
MakeReturn5Cci (pcci,ok,first,last,copies,deviceContext);
// unpack doDialog and emulateScreenRes
doDialog = (pcci->p1) & 1;
emulateScreenRes = (pcci->p1) & 2;
getDC( doDialog,emulateScreenRes,FALSE,pcci->p2,
(char*) pcci->p3,(char*) pcci->p4,(char*) pcci->p5,(char*) pcci->p6,
&err,&first,&last,&copies,(PRINTDLG**)&pPrintDlg,&deviceContext);
MakeReturn6Cci (pcci,err,first,last,copies,pPrintDlg,deviceContext);
} break;
case CcRqSTARTDOC:
{ HDC hdc = (HDC) pcci->p1;
int err,dummy1,dummy2;
//rprintf("1 Before EnableWindow ghMainWindow:%i\n",ghMainWindow);
{
HDC hdc = (HDC) pcci->p1;
int err;
EnableWindow (ghMainWindow, FALSE) ;
//rprintf("1 Before CreateCancelDialog\n");
hDlgPrint = CreateCancelDialog ();
hDlgPrint = CreateCancelDialog ();
SetAbortProc (hdc, AbortProc) ;
startDoc((int) hdc,0,&err,&dummy1,&dummy2);
err = startDoc((int) hdc);
if (err<=0 && ghMainWindow!=NULL && !bUserAbort)
{
EnableWindow (ghMainWindow, TRUE) ;
......@@ -6507,9 +6606,8 @@ HandleCleanRequest (CrossCallInfo * pcci)
case CcRqENDDOC:
{
HDC hdc = (HDC) pcci->p1;
int dummy1,dummy2;
endDoc((int) hdc,0,&dummy1,&dummy2);
endDoc((int) hdc);
if (ghMainWindow!=NULL && !bUserAbort)
{
EnableWindow (ghMainWindow, TRUE) ;
......@@ -6523,9 +6621,7 @@ HandleCleanRequest (CrossCallInfo * pcci)
char *pageMessage= (char*) (pcci->p1);
SetWindowText(hwndText,pageMessage);
//rprintf("CcRqDISPATCH_MESSAGES_WHILE_PRINTING\n");
while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))
......@@ -6702,9 +6798,9 @@ WinKillOsThread (OS os)
rprintf (" DeleteObject(gWinFont);\n");
DeleteObject (gControlFont); // The global logical font must be deleted.
}
};
// MW...
ghMainWindow = NULL; // XXX still don't know whether this is OK
ghMainWindow = NULL;
// ... MW
return os;
......@@ -7098,6 +7194,19 @@ MakeReturn5Cci (CrossCallInfo * pcci, int v1, int v2, int v3, int v4, int v5)
return pcci;
}
CrossCallInfo *
MakeReturn6Cci (CrossCallInfo * pcci, int v1, int v2, int v3, int v4, int v5, int v6)
{
pcci->mess = CcRETURN6;
pcci->p1 = v1;
pcci->p2 = v2;
pcci->p3 = v3;
pcci->p4 = v4;
pcci->p5 = v5;
pcci->p6 = v6;
return pcci;
}
BOOL
IsReturnCci (CrossCallInfo * pcci)
{
......
This diff is collapsed.
#ifndef __CTCP__
#define __CTCP__
#include <winsock.h>
typedef int DNSHdl;
struct DNSInfo
{ struct DNSInfo *next;
HANDLE dnsHdl;
union { struct hostent Hostent;
char freeSpace[MAXGETHOSTSTRUCT];
}
junion;
};
typedef struct DNSInfo DNSInfo;
// the dictionary items
struct dictitem
{ SOCKET endpointRef;
struct dictitem *next;
char availByte;
unsigned availByteValid : 1;
unsigned referenceCount : 2;
unsigned hasReceiveNotifier : 1;
// three kinds of receivers: receivers for established connections,
// receivers for dns requests, receivers for asynchronous connect
unsigned hasSendableNotifier : 1;
unsigned aborted : 1;
unsigned disconnected : 1;
};
typedef struct dictitem dictitem;
#define IE_CONNECTREQUEST 0x0001
#define IE_RECEIVED 0x0004
#define IE_EOM 0x0010
#define IE_SENDABLE 0x0100
#define IE_DISCONNECTED 0x0011
#define IE_IPADDRESSFOUND 0x2000000F
#define IE_IPADDRESSNOTFOUND 0x20000010
#define IE_ASYNCCONNECTCOMPLETE 0x0002
#define IE_ASYNCCONNECTFAILED 0x0003
#define ListenerReceiver 0
#define RChanReceiver 1
#define SChanReceiver 2
#define DNSReceiver 3
#define ConnectReceiver 4
void InitSockets();
dictitem* lookup(SOCKET endpointRef);
#endif
\ No newline at end of file
......@@ -1398,55 +1398,6 @@ WinDestroyScreenHDC (HDC ihdc, OS os)
return os;
}
/* PA: new routine to draw bitmap images (by courtesy of Arjan van IJzendoorn).
*/
/* Arjan's original
extern EXPORT_TO_CLEAN void
WinDrawBitmap (int x, int y, int bx1, int by1, int bx2, int by2,
char *ptr, HDC hdc, int os,
HDC *hdcReturn, int *osReturn)
{
char *startOfFile = ptr + 4;
int dataOffset = *((int*)(startOfFile + 10));
char *startOfData = startOfFile + dataOffset;
char *startOfHeader = startOfFile + 14;
int width = *((int*)(startOfHeader + 4));
int height = *((int*)(startOfHeader + 8));
int cx1, cy1, cx2, cy2;
*hdcReturn = hdc;
*osReturn = os;
cx1 = (bx1 > bx2) ? bx2 : bx1;
cx2 = (bx1 > bx2) ? bx1 : bx2;
cy1 = (by1 > by2) ? by2 : by1;
cy2 = (by1 > by2) ? by1 : by2;
if (cx1 == cx2 || cy1 == cy2) return;
SetDIBitsToDevice ( hdc
, x // xdest
, y // ydest
, cx2 - cx1 // dwWidth
, cy2 - cy1 // dwHeight
, cx1 // xsrc
, height - cy2 // ysrc
, 0 // uStartScan
, height // cScanLines
, startOfData // lpvBits
, (struct tagBITMAPINFO *) startOfHeader // lpbmi
, DIB_RGB_COLORS // fuColorUse
);
}
*/
// MW: The drawing of bitmaps could be speeded up. The SetDIBitsToDevice function
// translates each time a bitmap is drawn a device independent bitmap (DIB)
// into the device dependent form. This process invloves finding the right
// coulours for the given device. This translation could be done only once,
// resulting in a higher output speed for bitmaps. The disadvantage is:
// Saving the bitmap info in a device dependent manner involves handles,
// so that this information can not be garbage collected. The (DIB) data
// is stored in the Clean heap !!!
static void getBitmapData(/*input:*/ char *ptr, // points to beginning of bitmap
/*output*/ char **startOfData,char **startOfHeader, int *height)
{
......@@ -1540,51 +1491,6 @@ WinDrawResizedBitmap ( int sourcew, int sourceh, int destx, int desty, int destw
*osReturn = os;
}
/* WinPrintBitmap must be used for printing bitmaps.
*/
extern EXPORT_TO_CLEAN void
WinPrintBitmap (int sx2, int sy2, int dx1, int dy1,
char *ptr, HDC hdc, int os,
HDC *hdcReturn, int *osReturn)
{
// if (GetMapMode(hdc)==MM_ISOTROPIC) // bitmap has to be streched (currently only
// WinPrintResizedBitmap // for printing with emulation of screen resolution)
// ( sx2,sy2,
// dx1,dy1,sx2,sy2,
// ptr,hdc,os,
// hdcReturn,osReturn);
// else // no zooming or streching: copy it 1:1
// {
char *startOfData, *startOfHeader;
int height;
int error; // PA+++
DWORD errorcode;// PA+++
*hdcReturn = hdc;
*osReturn = os;
getBitmapData(ptr,&startOfData,&startOfHeader,&height);
error = SetDIBitsToDevice (
hdc
, dx1 // xdest
, dy1 // ydest
, sx2 // Width
, sy2 // Height
, 0 // xsrc
, height - sy2 // ysrc
, 0 // uStartScan
, height // cScanLines
, startOfData // lpvBits
, (struct tagBITMAPINFO *) startOfHeader // lpbmi
, DIB_RGB_COLORS // fuColorUse
);
if (error==0)
{
errorcode = GetLastError ();
rMessageBox (NULL,MB_APPLMODAL,"WinPrintBitmap","SetDIBitsToDevice failed: %i",errorcode);
}
// };
}
// ... MW
......
// CPrinter.c -- for printing in Clean (0.8 I/O library and Object I/O library)
#include <windows.h>
#include <limits.h>
#include "cpicture_12.h"
......@@ -13,51 +14,318 @@ int semaphor=0;
extern HWND ghMainWindow;
extern HINSTANCE ghInst;
void startPage(int hdc, int os, int *ok, int *hdcReturn, int *osReturn)
typedef struct pass_object *PassObject;
/* with a PassObject one can pass strings back to Clean. It's first DWORD
contains the size of the object -8, the second DWORD contains the length
of the string, and the rest contains the string itself. In
PassObject pObj;
the following expression points to a Clean string:
((char*)passObj)[4]
*/
PassObject passObj1 = NULL, passObj2 = NULL, passObj3 = NULL, passObj4 = NULL;
void mwStrcpy(char* dest, char *src)
{
*osReturn = os;
*hdcReturn = hdc;
*ok = StartPage((HDC) hdc) > 0;
int i=0;
while (src[i]!='\0')
{
dest[i] = src[i];
i++;
};
dest[i] = '\0';
}
void endPage(int hdc, int os, int *ok, int *hdcReturn, int *osReturn)
void mwMemcpy(char* dest, char *src, int count)
{
*osReturn = os;
*hdcReturn = hdc;
*ok = EndPage((HDC) hdc) > 0;
int i;
for(i=0; i<count; i++)
dest[i] = src[i];
}
void startDoc(int hdc, int os, int *err, int *hdcReturn, int *osReturn)
// err code: >0:no error, <=0: user cancelled file dialog
int CStringLength(char* string)
// returns length of C string INCLUDING the '\0'
{
int i=0;
while(string[i]!='\0')
i++;
i++;
return i;
}
CleanString PassCleanString(PassObject *pPassObj, char* data,unsigned int size)
{
unsigned int passObjSize,i;
PassObject passObj;
if (*pPassObj==NULL)
{
*pPassObj = (PassObject) LocalAlloc(LMEM_FIXED, size+8);
((unsigned int*)*pPassObj)[0] = size;
};
passObjSize = ((unsigned int*)*pPassObj)[0];
if (passObjSize<size)
{
LocalFree(LocalHandle(*pPassObj));
*pPassObj = (PassObject) LocalAlloc(LMEM_FIXED, size+8);
((unsigned int*)*pPassObj)[0] = size;
};
// now the pass object is big enough, so fill it with data
passObj = *pPassObj;
((unsigned int*)passObj)[1] = size;
for(i=0; i<size; i++)
((char*)passObj)[i+8] = data[i];
return (CleanString) (((unsigned int*)passObj)+1);
}
#define tachtig 80
void getDevmodeSizeC(int *size, HANDLE *phPrinter,
CleanString *device, CleanString *driver, CleanString *output)
{
char szPrinterSpace[80];
char *szPrinter = szPrinterSpace;
char *szDevice, *szDriver, *szOutput;
GetProfileString("windows", "device", ",,,", szPrinter, 80);
szDevice = strtokMW(&szPrinter,',',',');
szDriver = strtokMW(&szPrinter,',',' ');
szOutput = strtokMW(&szPrinter,',',' ');
if (*szDevice=='\0' || szDriver=='\0' || *szOutput=='\0')
{
*size = 0;
return;
};
*device = PassCleanString(&passObj1,szDevice,CStringLength(szDevice)+1); // add 1 so '\0' will be passed too
*driver = PassCleanString(&passObj2,szDriver,CStringLength(szDriver)+1);
*output = PassCleanString(&passObj3,szOutput,CStringLength(szOutput)+1);
OpenPrinter(szDevice,phPrinter,NULL);
*size = DocumentProperties(NULL,*phPrinter,szDevice,NULL,NULL,0);
}
void getDefaultDevmodeC(char *printSetup, LPHANDLE phPrinter, CleanString *device)
{
int size,r1;
size = ((int*)printSetup)[0];
printSetup +=4;
r1 = DocumentProperties(NULL,phPrinter,((char*)device)+4,
(DEVMODE*)printSetup,NULL,DM_OUT_BUFFER);
ClosePrinter(phPrinter);
}
void os_getpagedimensionsC( CleanString devmode,
CleanString device, CleanString driver,
int emulateScreenRes,
int *maxX, int *maxY,
int *leftPaper, int *topPaper,
int *rightPaper, int *bottomPaper,
int *xRes, int *yRes
)
{
HDC icPrint;
int horPaperPixels, verPaperPixels,
xResolution,yResolution,
scNX, scNY, scDX, scDY;
icPrint = CreateIC( CleanStringCharacters(driver),CleanStringCharacters(device),NULL,
(DEVMODE*) CleanStringCharacters(devmode));
xResolution = GetDeviceCaps(icPrint, LOGPIXELSX);
yResolution = GetDeviceCaps(icPrint, LOGPIXELSY);
if (emulateScreenRes) // for emulation of the screen resolution
{ scNX = WinGetHorzResolution(); // all the deviceCaps will be scaled
scNY = WinGetVertResolution();
scDX = xResolution;
scDY = yResolution;
}
else
{ scNX = 1; scNY = 1; scDX = 1; scDY = 1; };
horPaperPixels = (GetDeviceCaps(icPrint, PHYSICALWIDTH)*scNX)/scDX;
verPaperPixels = (GetDeviceCaps(icPrint, PHYSICALHEIGHT)*scNY)/scDY;
*maxX = (GetDeviceCaps(icPrint, HORZRES)*scNX)/scDX;
*maxY = (GetDeviceCaps(icPrint, VERTRES)*scNY)/scDY;
*leftPaper = (-GetDeviceCaps(icPrint, PHYSICALOFFSETX)*scNX