Commit e98a4c17 authored by Peter Achten's avatar Peter Achten

(PA) improved OS Windows C implementation (modular structure)

parent 416102da
/********************************************************************************************
Clean OS Windows library module version 1.2.1.
This module is part of the Clean Object I/O library, version 1.2.1,
for the Windows platform.
********************************************************************************************/
/********************************************************************************************
About this module:
Implementation of accelerator tables.
For each accelerator key four entries are stored in the acceleratortable:
Ctrl +key
Ctrl+Shift +key
Ctrl +Alt+key
Ctrl+Shift+Alt+key
For this reason a minimum size of 4 (MINSIZEPROCESSSHORTCUTTABLE) has been set.
Deflating the table never decreases below this value.
********************************************************************************************/
#include "cAcceleratorTable_121.h"
#include "util_121.h"
void CopyACCEL (ACCEL *source, ACCEL *dest)
{
dest->fVirt = source->fVirt;
dest->key = source->key;
dest->cmd = source->cmd;
}
void SetACCELentry (ACCEL *entry, BYTE flags, int key, int id)
{
entry->fVirt = flags;
entry->key = (WORD) ((BYTE) VkKeyScan ((char) key));
entry->cmd = (WORD) id;
}
/* AllocateProcessShortcutTable (size) creates a shortcut table of the given size.
*/
ProcessShortcutTable AllocateProcessShortcutTable (int size)
{
ProcessShortcutTable table;
ACCEL *shortcuts;
table = (ProcessShortcutTable) rmalloc (sizeof (struct ProcessShortcutTable));
shortcuts = (ACCEL *) rmalloc (size * sizeof (ACCEL));
table->pst_size = size;
table->pst_used = 0;
table->pst_shortcuts = shortcuts;
return (table);
}
/* DestroyProcessShortcutTable (table) frees the memory used by the table.
*/
void DestroyProcessShortcutTable (ProcessShortcutTable table)
{
rfree (table->pst_shortcuts);
rfree (table);
}
/* InflateProcessShortcutTable (table) returns a new table double the size of the argument table.
*/
ProcessShortcutTable InflateProcessShortcutTable (ProcessShortcutTable oldTable)
{
int i, oldSize, newSize;
ProcessShortcutTable newTable;
oldSize = oldTable->pst_size;
newSize = oldSize*2;
newTable = (ProcessShortcutTable) AllocateProcessShortcutTable (newSize);
for (i=0; i<oldSize; i++)
CopyACCEL (&oldTable->pst_shortcuts[i], &newTable->pst_shortcuts[i]);
newTable->pst_used = oldTable->pst_used;
rfree (oldTable);
return (newTable);
}
/* DeflateProcessShortcutTable (table) returns a new table half the size of the argument table.
In case the table already is at its minimum size (MINSIZEPROCESSSHORTCUTTABLE) the argument
table is returned.
*/
ProcessShortcutTable DeflateProcessShortcutTable (ProcessShortcutTable oldTable)
{
int i, oldSize, newSize;
ProcessShortcutTable newTable;
oldSize = oldTable->pst_size;
newSize = oldSize/2;
if (newSize < MINSIZEPROCESSSHORTCUTTABLE)
{
return (oldTable);
}
else
{
newTable = (ProcessShortcutTable) AllocateProcessShortcutTable (newSize);
for (i=0; i<newSize; i++)
CopyACCEL (&oldTable->pst_shortcuts[i], &newTable->pst_shortcuts[i]);
newTable->pst_used = min (oldTable->pst_used, newSize);
rfree (oldTable);
return (newTable);
}
}
/* AddProcessShortcut (key,id,table) returns a new table in which the shortkey (id,key) has been added.
The new table may have been inflated to accomodate the new shortkey.
For each shortkey the following four accelerator flags are entered as separate entries:
FVIRTKEY | FCONTROL
FVIRTKEY | FCONTROL | FSHIFT
FVIRTKEY | FCONTROL | FALT
FVIRTKEY | FCONTROL | FSHIFT | FALT
*/
ProcessShortcutTable AddProcessShortcut (int key, int id, ProcessShortcutTable oldTable)
{
ACCEL *newentry;
ProcessShortcutTable newTable;
int used = oldTable->pst_used;
// first make sure that the table has the proper size.
if (used+4 >= oldTable->pst_size)
{
newTable = InflateProcessShortcutTable (oldTable);
}
else
{
newTable = oldTable;
}
// Add Ctrl+key:
newentry = &newTable->pst_shortcuts[used];
SetACCELentry (newentry, (BYTE) FCONTROL | FVIRTKEY, key, id);
// Add Ctrl+Shift+key:
newentry = &newTable->pst_shortcuts[used+1];
SetACCELentry (newentry, (BYTE) FCONTROL | FSHIFT | FVIRTKEY, key, id);
// Add Ctrl+Alt+key:
newentry = &newTable->pst_shortcuts[used+2];
SetACCELentry (newentry, (BYTE) FCONTROL | FALT | FVIRTKEY, key, id);
// Add Ctrl+Shift+Alt+key:
newentry = &newTable->pst_shortcuts[used+3];
SetACCELentry (newentry, (BYTE) FCONTROL |FSHIFT | FALT | FVIRTKEY, key, id);
newTable->pst_used = used+4;
return(newTable);
}
/* RemoveProcessShortcut (id,table) returns a new table in which the shortkey (id,_) has been removed.
The new table may have been deflated to use up less memory space.
In case the entry (id,_) has been located, the consecutive 3 entries are also removed as these
encode the accelerator flag versions.
*/
ProcessShortcutTable RemoveProcessShortcut (int id, ProcessShortcutTable oldTable)
{
int i;
int foundat = 0;
int used = oldTable->pst_used;
// search for the element to be deleted.
while (foundat<used && oldTable->pst_shortcuts[foundat].cmd != id)
{
foundat++;
}
if (foundat>=used)
{
return (oldTable); // the element was not found, so return argument table
}
used -= 4;
for (i=foundat; i<used; i++) // otherwise shift remaining entries to the left
CopyACCEL (&oldTable->pst_shortcuts[i+4], &oldTable->pst_shortcuts[i]);
oldTable->pst_used = used;
if (used < oldTable->pst_size/2 && used > MINSIZEPROCESSSHORTCUTTABLE) // check if table needs to be deflated
{
return (DeflateProcessShortcutTable (oldTable));
}
else
{
return (oldTable);
}
}
/* UpdateAcceleratorTable (table,frame) returns a new table that corresponds with the shortkeys
administered in frame. It is assumed that frame contains a pointer to a shortcut table.
The argument table should not be used anymore, because it might have been destroyed.
*/
HACCEL UpdateAcceleratorTable (HACCEL gAcceleratorTable,HWND ghActiveFrameWindow)
{
ProcessShortcutTable table;
if (gAcceleratorTable!=NULL) // Destroy the previous version if exists
{
DestroyAcceleratorTable (gAcceleratorTable);
}
gAcceleratorTable = NULL;
if (ghActiveFrameWindow!=NULL) // The current frame is an (MDI/SDI) frame
{
table = (ProcessShortcutTable) GetWindowLong (ghActiveFrameWindow, 0);
if (table!=NULL)
{
gAcceleratorTable = CreateAcceleratorTable (table->pst_shortcuts,table->pst_used);
}
}
return gAcceleratorTable;
}
/* Implementation of accelerator tables.
Now for each MDI and SDI frame window a private accelerator table is stored.
NDI processes have no frame window, and also don't need an accelerator table.
For each accelerator key four entries are stored in the acceleratortable:
Ctrl +key
Ctrl+Shift +key
Ctrl +Alt+key
Ctrl+Shift+Alt+key
For this reason a minimum size of 4 (MINSIZEPROCESSSHORTCUTTABLE) has been set.
Deflating the table never decreases below this value.
*/
#include <windows.h>
struct ProcessShortcutTable
{
int pst_size; // The current size of the table
int pst_used; // The current number of filled items
ACCEL *pst_shortcuts; // The current table, implemented as a pointer to ACCELs
};
typedef struct ProcessShortcutTable *ProcessShortcutTable;
#define MINSIZEPROCESSSHORTCUTTABLE 4 // The minimum size of an accelerator table is 4
/* AllocateProcessShortcutTable (size) creates a shortcut table of the given size.
*/
extern ProcessShortcutTable AllocateProcessShortcutTable (int size);
/* DestroyProcessShortcutTable (table) frees the memory used by the table.
*/
extern void DestroyProcessShortcutTable (ProcessShortcutTable table);
/* InflateProcessShortcutTable (table) returns a new table double the size of the argument table.
*/
extern ProcessShortcutTable InflateProcessShortcutTable (ProcessShortcutTable oldTable);
/* DeflateProcessShortcutTable (table) returns a new table half the size of the argument table.
In case the table already is at its minimum size (MINSIZEPROCESSSHORTCUTTABLE) the argument
table is returned.
*/
extern ProcessShortcutTable DeflateProcessShortcutTable (ProcessShortcutTable oldTable);
/* AddProcessShortcut (key,id,table) returns a new table in which the shortkey (id,key) has been added.
The new table may have been inflated to accomodate the new shortkey.
For each shortkey the following four accelerator flags are entered as separate entries:
FVIRTKEY | FCONTROL
FVIRTKEY | FCONTROL | FSHIFT
FVIRTKEY | FCONTROL | FALT
FVIRTKEY | FCONTROL | FSHIFT | FALT
*/
extern ProcessShortcutTable AddProcessShortcut (int key, int id, ProcessShortcutTable oldTable);
/* RemoveProcessShortcut (id,table) returns a new table in which the shortkey (id,_) has been removed.
The new table may have been deflated to use up less memory space.
In case the entry (id,_) has been located, the consecutive 3 entries are also removed as these
encode the accelerator flag versions.
*/
extern ProcessShortcutTable RemoveProcessShortcut (int id, ProcessShortcutTable oldTable);
/* UpdateAcceleratorTable (table,frame) returns a new table that corresponds with the shortkeys
administered in frame. It is assumed that frame contains a pointer to a shortcut table.
The argument table should not be used anymore, because it might have been destroyed.
*/
extern HACCEL UpdateAcceleratorTable (HACCEL gAcceleratorTable,HWND ghActiveFrameWindow);
/********************************************************************************************
Clean OS Windows library module version 1.2.1.
This module is part of the Clean Object I/O library, version 1.2.1,
for the Windows platform.
********************************************************************************************/
/********************************************************************************************
About this module:
Routines related to system handling that is not part of standard cross call handling.
********************************************************************************************/
#include "cCCallSystem_121.h"
int WinBeep (int ios)
{
MessageBeep (MB_ICONASTERISK);
return ios;
}
void WinGetTime (int ios, int * hour, int * minute, int * second, int * oos)
{
SYSTEMTIME time;
GetLocalTime (&time);
*hour = time.wHour;
*minute = time.wMinute;
*second = time.wSecond;
*oos = ios;
}
void WinGetDate (int ios, int * year, int * month, int * day, int * weekday, int * oos)
{
SYSTEMTIME time;
GetLocalTime (&time);
*year = time.wYear;
*month = time.wMonth;
*day = time.wDay;
*weekday = time.wDayOfWeek + 1;
*oos = ios;
}
int WinWait (int delay, int ios)
{
Sleep (delay);
return ios;
}
void WinGetBlinkTime (int ios, int* blinktime, int* oos)
{
*blinktime = (int) GetCaretBlinkTime ();
*oos = ios;
}
void WinGetTickCount (OS ios, int *tickCount, OS * oos)
{
*tickCount = GetTickCount ();
*oos = ios;
}
char * toCstring (CLEAN_STRING s)
{
char *cstr = (char *) NULL;
cstr = (char *) rmalloc ((s->length) + 1);
rsncopy (cstr, s->characters, s->length);
cstr[s->length] = 0;
return cstr;
}
void WinPlaySound (CLEAN_STRING clfilename, OS ios, Bool * ook, OS * oos)
{ char * cfilename;
cfilename = toCstring (clfilename);
if (PlaySound (cfilename, NULL, SND_FILENAME | SND_SYNC))
{
*ook = TRUE;
}
else
{
*ook = FALSE;
}
rfree (cfilename);
*oos = ios;
}
#include "intrface_121.h"
extern int WinBeep (int);
extern void WinGetTime (int,int*,int*,int*,int*);
extern void WinGetDate (int,int*,int*,int*,int*,int*);
extern int WinWait (int,int);
extern void WinGetBlinkTime (int,int*,int*);
extern void WinGetTickCount (OS ios, int *tickCount, OS * oos);
extern void WinPlaySound (CLEAN_STRING clfilename, OS ios, Bool * ook, OS * oos);
/********************************************************************************************
Clean OS Windows library module version 1.2.1.
This module is part of the Clean Object I/O library, version 1.2.1,
for the Windows platform.
********************************************************************************************/
/********************************************************************************************
About this module:
Routines related to window/dialog handling.
********************************************************************************************/
#include "cCCallWindows_121.h"
int WinInvalidateWindow (int hwnd, int ios)
{
InvalidateRect ((HWND) hwnd, NULL, FALSE);
return ios;
}
int WinInvalidateRect (int hwnd, int left, int top, int right, int bottom, int ios)
{
RECT rect;
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
InvalidateRect ((HWND) hwnd, &rect, FALSE);
return ios;
}
int WinValidateRect (int hwnd, int left, int top, int right, int bottom, int ios)
{
RECT rect;
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
ValidateRect ((HWND) hwnd, &rect);
return ios;
}
int WinValidateRgn (int hwnd, int rgn, int ios)
{
ValidateRgn ((HWND) hwnd, (HRGN) rgn);
return ios;
}
/* Win(M/S)DIClientToOuterSizeDims returns the width and height needed to add/subtract
from the client/outer size to obtain the outer/client size.
These values must be the same as used by W95AdjustClean(M/S)DIWindowDimensions!
*/
void WinMDIClientToOuterSizeDims (int styleFlags, OS ios, int *dw, int *dh, OS *oos)
{
if ((styleFlags&WS_THICKFRAME) != 0)
{ /* resizable window */
*dw = 2 * GetSystemMetrics (SM_CXSIZEFRAME);
*dh = 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
} else
{ /* fixed size window */
*dw = 2 * GetSystemMetrics (SM_CXFIXEDFRAME);
*dh = 2 * GetSystemMetrics (SM_CYFIXEDFRAME) + GetSystemMetrics (SM_CYCAPTION);
}
*oos = ios;
}
void WinSDIClientToOuterSizeDims (int styleFlags, OS ios, int *dw, int *dh, OS *oos)
{
*dw = 2 * GetSystemMetrics (SM_CXSIZEFRAME);
*dh = 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
*oos = ios;
}
/* Adjust the dimensions of a Clean MDI document window with W95 frame dimensions.
These values must be the same as returned by WinMDIClientToOuterSizeDims!
*/
void W95AdjustCleanMDIWindowDimensions (DWORD styleFlags, POINT * dim)
{
if ((styleFlags&WS_THICKFRAME) != 0)
{ /* resizable window */
dim->x += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
dim->y += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
} else
{ /* fixed size window */
dim->x += 2 * GetSystemMetrics (SM_CXFIXEDFRAME);
dim->y += 2 * GetSystemMetrics (SM_CYFIXEDFRAME) + GetSystemMetrics (SM_CYCAPTION);
}
}
/* Adjust the dimensions of a Clean SDI frame window with W95 frame and menu dimensions.
These values must be the same as returned by WinSDIClientToOuterSizeDims!
*/
void W95AdjustCleanSDIWindowDimensions (DWORD styleFlags, POINT * dim)
{
dim->x += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
dim->y += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
}
/* Set and get the GWL_USERDATA of a windowhandle.
*/
void SetGWL_USERDATA (LONG data, HWND hwnd)
{
SetWindowLong (hwnd, GWL_USERDATA, data);
}
LONG GetGWL_USERDATA (HWND hwnd)