File: cAcceleratorTable_121.c

package info (click to toggle)
ghc-cvs 20040725-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 68,484 kB
  • ctags: 19,658
  • sloc: haskell: 251,945; ansic: 109,709; asm: 24,961; sh: 12,825; perl: 5,786; makefile: 5,334; xml: 3,884; python: 682; yacc: 650; lisp: 477; cpp: 337; ml: 76; fortran: 24; csh: 18
file content (215 lines) | stat: -rw-r--r-- 6,513 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/********************************************************************************************
	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;
}