wine/ipc/dde_atom.c
Alexandre Julliard ac9c9b07cf Release 960728
Sun Jul 28 17:57:19 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/task.c] [include/task.h]
	Implemented SwitchStackTo()/SwitchStackBack().

	* [include/wintypes.h] [loader/main.c]
	Added __winelib variable to distinguish between emulator and
 	library at run-time. Later on, this should avoid some
 	recompilations when building Winelib.

	* [windows/property.c]
	Implemented Win32 functions for window properties.

Fri Jul 26 18:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [controls/listbox.c]
	Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
	messages.

	* [controls/menu.c]
	Call TranslateMessage() to enable shortcuts (on WM_CHAR).

	* [include/cursoricon.h]
	Moved #pragma pack(1) back to where it belongs.

	* [objects/palette.c]
	RealizeDefaultPalette() maps to system colors only.
	Do not broadcast palette notifications when in TrueColor.

	* [objects/color.c] [include/palette.h]
	Miscellaneous optimizations. Had to fix several
	"improvements" made to my patch for previous release.

	* [objects/dib.c]
	Reverse dib bits order for 24-bit SetDIBits().

	* [objects/dc.c]
	GetDeviceCaps() does not return RC_PALETTE when in TrueColor.

	* [windows/scroll.c]
	Scroll update region too.

	* [windows/message.c]
	Include QS_MOUSE into the event mask for nonclient mouse
	message filter. Fixes problems with Word 6 freezing when
	mouse hits nonclient area.

	* [windows/win.c] 
	Allow top-level windows to be linked as HWND_TOP in CreateWindow().

	* [windows/winpos.c] [windows/mdi.c]
	Attempt to fix control menu duplication.

Fri Jul 26 09:49:35 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/drive.c]
	GetDriveType32A(): return value for CDROM fixed.

	* [files/file.c]
	SearchPath* added.

	* [if1632/gdi32.spec] [objects/brush.c]
	SetBrushOrgEx() added.

	* [loader/pe_resource.c]
	If even loading the default entry fails, we just use the first
	entry from the resource directory.

	[loader/task.c]
	SetSigHandler() stub added, Paradox 4.5 now starts up.

	* [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
	COMM functions updated to win32, not complete.

	* [misc/lstr.c]
	FormatMessageA partially implemented.

	* [include/miscemu.h] [memory/selector.c]
	  [memory/global.c] [miscemu/dosmem.c]
	DOS memory handling changed: 1MB preallocated block, real-mode
	segment handling possible, SetSelectorBase into lower physical 1MB
	possible.

	* [miscemu/dpmi.c]
	Real-mode segments changed, real-mode int 21,ax=6506 added.
	AX=0x0303 added.

	* [multimedia/time.c]
	Fixed bug in killTimer.

	* [objects/bitmap.c]
	LoadImageA partially implemented.

Wed Jul 24 18:20:24 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [include/dde_mem.h][include/dde_proc.h]
	  [ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
	  [ipc/generic_hash.h][library/miscstubs.c]
	Changes for error free compilation using "--with-ipc":
	replaced some names with *16-equivalent (e.g. MSG to MSG16),
	modified prototype of function DDE_GlobalFree() .

	* [objects/palette.c]
	Added check for metafile-DC in GDISelectPalette(),
	GDIRealizePalette(),RealizeDefaultPalette() and
	IsDCCurrentPalette().

Tue Jul 23 22:46:53 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>

	* [controls/edit.c]
	EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
	fixes Winhelp.

	* [windows/dialog.c]
	DIALOG_CreateIndirect: Initialise dlgProc before creating children.
1996-07-28 18:50:11 +00:00

288 lines
7.5 KiB
C

/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_atom.c
* Purpose : atom functionality for DDE
*/
#ifdef CONFIG_IPC
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "dde_atom.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"
typedef struct
{
WORD count;
BYTE str[1];
} AtomData, *AtomData_ptr;
#define EMPTY 0 /* empty hash entry */
#define DELETED -1 /* deleted hash entry */
#define MIN_STR_ATOM 0xfc00
/* OFS2AtomData_ptr: extract AtomData_ptr from ofs */
#define OFS2AtomData_ptr(ofs) ((AtomData*)((int)&main_block->block+(ofs)))
/* OFS2AtomStr: find the string of the atom */
#define OFS2AtomStr(ofs) (OFS2AtomData_ptr(atom_ofs)->str)
/* offset of an atom according to index */
#define ATOM_OFS(idx) (main_block->atoms[idx])
/* rot_left: rotate (with wrap-around) */
static __inline__ int rot_left(unsigned var,int count)
{
return (var<<count) | (var>> (sizeof(var)-count));
}
/* find the entry in the atom table for this string */
static int FindHash(LPCSTR str) /* ignore str case */
{
int i,j;
unsigned hash1,hash2;
int deleted=-1; /* hash for deleted entry */
int atom_ofs;
/* get basic hash parameters */
for (i= hash1= hash2= 0; str[i] ; i++) {
hash1= rot_left(hash1,5) ^ toupper(str[i]);
hash2= rot_left(hash2,4) ^ toupper(str[i]);
}
hash1%= DDE_ATOMS;
atom_ofs=ATOM_OFS(hash1);
switch (atom_ofs) {
case EMPTY: /* empty atom entry */
return hash1;
case DELETED: /* deleted atom entry */
deleted=hash1;
break;
default : /* non empty atom entry */
if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
return hash1; /* found string in atom table */
}
hash2%= DDE_ATOMS-1 ; /* hash2=0..(DDE_ATOMS-2) */
hash2++; /* hash2=1..(DDE_ATOMS-1) */
/* make jumps in the hash table by hash2 steps */
for (i=hash1+hash2 ; ; i+=hash2) {
/* i wraps around into j */
j=i-DDE_ATOMS;
if (j >= 0)
i=j; /* i wraps around */
if (i==hash1)
/* here if covered all hash locations, and got back to beginning */
return deleted; /* return first empty entry - if any */
atom_ofs=ATOM_OFS(i);
switch (atom_ofs) {
case EMPTY: /* empty atom entry */
return i;
case DELETED: /* deleted atom entry */
if (deleted < 0)
/* consider only the first deleted entry */
deleted= i;
break;
default : /* nonempty atom entry */
if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
return i; /* found string in atom table */
}
}
}
void ATOM_GlobalInit(void)
{
int i;
for (i=0 ; i < DDE_ATOMS ; i++)
ATOM_OFS(i)=EMPTY;
}
/***********************************************************************
* DDE_GlobalAddAtom
*/
/* important! don't forget to unlock semaphores before return */
ATOM DDE_GlobalAddAtom( SEGPTR name )
{
int atom_idx;
int atom_ofs;
AtomData_ptr ptr;
ATOM atom;
char *str;
/* First check for integer atom */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
str = (char *)PTR_SEG_TO_LIN( name );
if (str[0] == '#')
{
ATOM atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);
DDE_IPC_init(); /* will initialize only if needed */
shm_write_wait(main_block->sem);
atom_idx=FindHash(str);
atom=(ATOM)0;
/* use "return" only at the end so semaphore handling is done only once */
if (atom_idx>=0) {
/* unless table full and item not found */
switch (atom_ofs= ATOM_OFS(atom_idx)) {
case DELETED:
case EMPTY: /* need to allocate new atom */
atom_ofs= shm_FragmentAlloc(&main_block->block,
strlen(str)+sizeof(AtomData));
if (atom_ofs==NIL)
break; /* no more memory (atom==0) */
ATOM_OFS(atom_idx)=atom_ofs;
ptr=OFS2AtomData_ptr(atom_ofs);
strcpy(ptr->str,str);
ptr->count=1;
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
break;
default : /* has to update existing atom */
OFS2AtomData_ptr(atom_ofs)->count++;
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
} /* end of switch */
} /* end of if */
shm_write_signal(main_block->sem);
return atom;
}
/***********************************************************************
* DDE_GlobalDeleteAtom
*/
ATOM DDE_GlobalDeleteAtom( ATOM atom )
{
int atom_idx;
int atom_ofs;
AtomData_ptr atom_ptr;
ATOM retval=(ATOM) 0;
dprintf_atom(stddeb,"GlobalDeleteAtom(\"%d\")\n",(int)atom);
atom_idx=(int)atom - MIN_STR_ATOM;
if (atom_idx < 0 )
return 0;
DDE_IPC_init(); /* will initialize only if needed */
shm_write_wait(main_block->sem);
/* return used only once from here on -- for semaphore simplicity */
switch (atom_ofs=ATOM_OFS(atom_idx)) {
case DELETED:
case EMPTY:
fprintf(stderr,"trying to free unallocated atom %d\n", atom);
retval=atom;
break;
default :
atom_ptr=OFS2AtomData_ptr(atom_ofs);
if ( --atom_ptr->count == 0) {
shm_FragmentFree(&main_block->block,atom_ofs);
ATOM_OFS(atom_idx)=DELETED;
}
}
shm_write_signal(main_block->sem);
return retval;
}
/***********************************************************************
* DDE_GlobalFindAtom
*/
ATOM DDE_GlobalFindAtom( SEGPTR name )
{
int atom_idx;
int atom_ofs;
char *str;
dprintf_atom(stddeb,"GlobalFindAtom(%08lx)\n", name );
/* First check for integer atom */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
str = (char *)PTR_SEG_TO_LIN( name );
if (str[0] == '#')
{
ATOM atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
dprintf_atom(stddeb,"GlobalFindAtom(\"%s\")\n",str);
DDE_IPC_init(); /* will initialize only if needed */
shm_read_wait(main_block->sem);
atom_idx=FindHash(str);
if (atom_idx>=0)
atom_ofs=ATOM_OFS(atom_idx); /* is it free ? */
else
atom_ofs=EMPTY;
shm_read_signal(main_block->sem);
if (atom_ofs==EMPTY || atom_ofs==DELETED)
return 0;
else
return (ATOM)(atom_idx+MIN_STR_ATOM);
}
/***********************************************************************
* DDE_GlobalGetAtomName
*/
WORD DDE_GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
{
int atom_idx, atom_ofs;
int size;
/* temporary buffer to hold maximum "#65535\0" */
char str_num[7];
if (count<2) /* no sense to go on */
return 0;
atom_idx=(int)atom - MIN_STR_ATOM;
if (atom_idx < 0) { /* word atom */
/* use wine convention... */
sprintf(str_num,"#%d%n",(int)atom,&size);
if (size+1>count) { /* overflow ? */
/* truncate the string */
size=count-1;
str_num[size]='\0';
}
strcpy(buffer,str_num);
return size;
}
DDE_IPC_init(); /* will initialize only if needed */
/* string atom */
shm_read_wait(main_block->sem);
atom_ofs=ATOM_OFS(atom_idx);
if (atom_ofs==EMPTY || atom_ofs==DELETED) {
fprintf(stderr,"GlobalGetAtomName: illegal atom=%d\n",(int)atom);
size=0;
} else { /* non empty entry */
/* string length will be at most count-1, find actual size */
sprintf(buffer,"%.*s%n",count-1, OFS2AtomStr(atom_ofs), &size);
}
shm_read_signal(main_block->sem);
return size;
}
#endif /* CONFIG_IPC */