home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 17
/
CD_ASCQ_17_101194.iso
/
vrac_os2
/
blankr42.zip
/
BSSDEV.ZIP
/
bssdev.doc
< prev
next >
Wrap
Text File
|
1994-08-17
|
9KB
|
310 lines
Instructions for writing External Screen Blanker Modules
Screen Blanker modules are the 32-Bit counterpart of Deskpic
modules.
What do you need to write an external Screen Blanker module?
Well, a pretty good working knowledge of Presentation Manager
wouldn't hurt. These instructions will attempt to tell you how
to write a module, but they won't tell you how to program
in PM. To help, an example extension is provided and is a good place
to start. When I write a new extension, I usually use 'BOUNCE' as a
framework and go from there.
An external Screen Blanker module is a Dynamic Link Library that contains
three functions and has the file extension of '.BBS' instead of '.DLL'.
The three functions must be exported with the following ordinals:
pchStatus @1
dpBlanker @2
vdBlankerThread @3
The three functions are specified by the following function prototypes:
PCHAR pchStatus(PBLANKERBLOCK, PBOOL);
MRESULT EXPENTRY dpBlanker(HWND, ULONG, MPARAM, MPARAM);
VOID vdBlankerThread(VOID);
And the structure BLANKERBLOCK is defined as follows:
typedef struct {
HAB habBlanker;
HWND hwndScreen;
RECTL rclScreen;
BOOL fClose;
HMODULE hmodBlanker;
} BLANKERBLOCK;
typedef BLANKERBLOCK *PBLANKERBLOCK;
The BLANKERBLOCK structure is how Screen Blanker provides the module with
information about its environment. The fields have the following meaning:
'habBlanker' is the handle of the Screen Blanker program's Anchor Block. This may
be needed by some OS/2 functions.
'hwndScreen' is the handle of the screen saver window. This will be needed
by 'vdBlankerThread' to get a Presentation Space to draw into.
'rclScreen' is the coordinates of the screen saver window.
'fClose' is a flag that is used by 'vdBlankerThread' to
determine when to stop.
'hModBlanker' is the module handle of the Screen Blanker module.
This will be needed to access any local resources.
The values of 'habBlanker' and 'hModBlanker' are always valid, but the values
of 'hwndScreen', 'rclScreen', and 'fClose' are only valid during
the execution of 'vdBlankerThread'.
pchStatus
This function is called by Screen Blanker to get the name of the screen saver.
Screen Blanker passes a pointer to a BLANKERBLOCK structure, and a pointer to a
BOOL. The function should save the pointer to the BLANKERBLOCK structure in
global memory so that it can be accessed by the other two functions. The
function should also indicate whether the screen saver is enabled by setting
the BOOL to TRUE if enabled, and FALSE if disabled. When finished, the
function should return a pointer to a zero terminated string which is the
name of the Screen Blanker module, or NULL if the screen saver has
no name. Note that while Screen Blanker will call this function before calling the
other two, it may call this function multiple times.
dpBlanker
This is a dialog procedure for the dialog that Screen Blanker will invoke when
the user chooses this screen saver module from the list of External modules.
The dialog should allow the user to modify any parameters that
the screen saver may have. The dialog template should be part of the
resources of the screen saver module and should have a dialog
template ID of 42. If 'pchStatus' returns NULL instead of a screen saver
name, the dialog will never be invoked.
vdBlankerThread
This procedure will be started as a separate thread when Screen Blanker invokes
the screen saver. The procedure should clear the screen and then display
whatever graphics the screen saver employs until 'fClose' in the
BLANKERBLOCK structure becomes non-zero. When 'fClose' becomes
non-zero, the procedure should release any resources it might have, enter
a critical section using 'DosEnterCritSec', set 'fClose' to FALSE,
and exit (in that order). It is important that the procedure
respond quickly to 'fClose' becoming TRUE so that users will
not be delayed by the screen saver. The procedure should also get its own
Anchor Block, since threads shouldn't make calls to the PM API without one.
Note that stack space is limited, so any sizeable memory needed should be
allocated at run time.
That completes the explanation. Where the instructions are a little sketchy,
use the example source code to see at least one way of doing it.
Please avoid statically linking the C library where possible to reduce the
size of the .BSS file. Whenever possible use the following function replacements
(like in BOUNCE.C):
/*
minirtl.c
mini run time library for use with
ScreenSaver modules with Borland C++
*/
#define INCL_DOS
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <malloc.h>
#include <memory.h>
#include <process.h>
/*
this part of the file was taken from emx 0.8g
-- Copyright (c) 1990-1993 by Eberhard Mattes
*/
void *memcpy (void *s1, const void *s2, size_t n)
{
size_t i;
for (i = 0; i < n; ++i)
((char *)s1)[i] = ((char *)s2)[i];
return (s1);
}
void *memset (void *s, int c, size_t n)
{
size_t i;
for (i = 0; i < n; ++i)
((char *)s)[i] = (char)c;
return (s);
}
char *strcat (char *string1, const char *string2)
{
char *dst;
dst = string1;
while (*dst != 0)
++dst;
while ((*dst = *string2) != 0)
++dst, ++string2;
return (string1);
}
char *strcpy (char *string1, const char *string2)
{
char *dst;
dst = string1;
while ((*dst = *string2) != 0)
++dst, ++string2;
return (string1);
}
size_t strlen (const char *string)
{
size_t i;
i = 0;
while (string[i] != 0) ++i;
return (i);
}
static unsigned int __rand = 1;
int rand()
{
__rand = __rand * 69069 + 5;
return ((__rand >> 16) & 0x7fff);
}
void srand(unsigned int seed)
{
__rand = seed;
}
/*
the remainder of the file is
(C) 1993-94 Siegfried Hanisch
*/
// if 1MB is not enough, increase this value
// the memory is not commited, so it does not use physical memory
// until it is accessed
#define MEMPOOLSIZE (1024L*1024L)
static void *mempool = NULL;
void *calloc(size_t elements, size_t size)
{
return malloc(elements*size);
}
void *malloc(size_t size)
{
APIRET rc;
size_t *mem;
rc = DosSubAllocMem(mempool, (PVOID *)&mem, size+sizeof(size_t));
if(rc){
WinAlarm(HWND_DESKTOP, WA_ERROR);
return NULL;
}
mem[0] = size;
return (void *)(&mem[1]);
}
void free(void *mem)
{
APIRET rc;
size_t *m;
m = (size_t *)mem;
rc = DosSubFreeMem(mempool, &m[-1], m[-1]+sizeof(size_t));
if(rc){
WinAlarm(HWND_DESKTOP, WA_ERROR);
}
}
void *realloc(void *mem, size_t size)
{
void *new_mem;
size_t *m;
size_t old_size;
m = (size_t *)mem;
old_size = m[-1];
new_mem = malloc(size);
memcpy(new_mem, mem, old_size);
memset(((char *)new_mem)+old_size, 0 , size-old_size);
free(mem);
return new_mem;
}
char *strdup(const char *string)
{
return strcpy(malloc(strlen(string)+1), string);
}
BOOL alloc_heap()
{
APIRET rc;
rc = DosAllocMem((PVOID *)&mempool, MEMPOOLSIZE, PAG_READ|PAG_WRITE);
if(rc){
WinAlarm(HWND_DESKTOP, WA_ERROR);
mempool = NULL;
return FALSE;
}
rc = DosSubSetMem(mempool, DOSSUB_INIT|DOSSUB_SPARSE_OBJ, MEMPOOLSIZE);
if(rc){
DosFreeMem(mempool);
WinAlarm(HWND_DESKTOP, WA_ERROR);
return FALSE;
}
return TRUE;
}
void free_heap()
{
APIRET rc;
rc = DosSubUnsetMem(mempool);
if(rc){
WinAlarm(HWND_DESKTOP, WA_ERROR);
}
rc = DosFreeMem(mempool);
if(rc){
WinAlarm(HWND_DESKTOP, WA_ERROR);
}
}
#if defined(__BORLANDC__)
int _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg)
{
TID tid;
if(DosCreateThread(&tid, (PFNTHREAD)__start, (ULONG)__arg, 2L, __stksize) != 0)
return -1;
return tid;
}
void _endthread(void)
{
DosExit(EXIT_THREAD, 0);
}
#elif defined(__IBMC__)
int _Optlink beginthread( void(* _Optlink __thread)(void *),
void *stack, unsigned stack_size, void *arg_list);
{
TID tid;
if(DosCreateThread(&tid, (PFNTHREAD)__thread, (ULONG)arg_list, 2L, stack_size) != 0)
return -1;
return tid;
}
void _endthread()
{
DosExit(EXIT_THREAD, 0);
}
#elif defined(__EMX__)
int _beginthread(void (*start)(void *arg), void *stack,
unsigned stack_size, void *arg_list)
{
TID tid;
if(DosCreateThread(&tid, (PFNTHREAD)start, (ULONG)arg_list, 2L, stack_size) != 0)
return -1;
return tid;
}
void _endthread()
{
DosExit(EXIT_THREAD, 0);
}
#endif