Release 951226
[wine] / windows / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <string.h>
8 #include "win.h"
9 #include "user.h"
10 #include "callback.h"
11 #include "stddebug.h"
12 /* #define DEBUG_PROP */
13 #include "debug.h"
14
15
16 typedef struct
17 {
18     HANDLE next;       /* Next property in window list */
19     ATOM   atom;       /* Atom (or 0 if string) */
20     HANDLE hData;      /* User's data */
21     char   string[1];  /* Property string */
22 } PROPERTY;
23
24
25 /***********************************************************************
26  *           SetProp   (USER.26)
27  */
28 BOOL SetProp( HWND hwnd, SEGPTR str, HANDLE hData )
29 {
30     HANDLE hProp;
31     PROPERTY *prop;
32     WND *wndPtr;
33
34     dprintf_prop( stddeb, "SetProp: "NPFMT" "SPFMT" "NPFMT"\n", hwnd, str, hData );
35     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
36     hProp = USER_HEAP_ALLOC( sizeof(PROPERTY) + 
37                              (HIWORD(str) ? strlen(PTR_SEG_TO_LIN(str)) : 0 ));
38     if (!hProp) return FALSE;
39     prop = (PROPERTY *) USER_HEAP_LIN_ADDR( hProp );
40     if (HIWORD(str))  /* string */
41     {
42         prop->atom = 0;
43         strcpy( prop->string, PTR_SEG_TO_LIN(str) );
44     }
45     else  /* atom */
46     {
47         prop->atom = LOWORD(str);
48         prop->string[0] = '\0';
49     }
50     prop->hData = hData;
51     prop->next = wndPtr->hProp;
52     wndPtr->hProp = hProp;
53     return TRUE;
54 }
55
56
57 /***********************************************************************
58  *           GetProp   (USER.25)
59  */
60 HANDLE GetProp( HWND hwnd, SEGPTR str )
61 {
62     HANDLE hProp;
63     WND *wndPtr;
64
65     dprintf_prop( stddeb, "GetProp: "NPFMT" "SPFMT"\n", hwnd, str );
66     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
67     hProp = wndPtr->hProp;
68     while (hProp)
69     {
70         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
71         if (HIWORD(str))
72         {
73             if (!prop->atom && !strcasecmp( prop->string, PTR_SEG_TO_LIN(str)))
74                 return prop->hData;
75         }
76         else if (prop->atom && (prop->atom == LOWORD(str))) return prop->hData;
77         hProp = prop->next;
78     }
79     return 0;
80 }
81
82
83 /***********************************************************************
84  *           RemoveProp   (USER.24)
85  */
86 HANDLE RemoveProp( HWND hwnd, SEGPTR str )
87 {
88     HANDLE *hProp;
89     WND *wndPtr;
90
91     dprintf_prop( stddeb, "RemoveProp: "NPFMT" "SPFMT"\n", hwnd, str );
92     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
93     hProp = &wndPtr->hProp;
94     while (*hProp)
95     {
96         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR( *hProp );
97         if ((HIWORD(str) && !prop->atom &&
98              !strcasecmp( prop->string, PTR_SEG_TO_LIN(str))) ||
99             (!HIWORD(str) && prop->atom && (prop->atom == LOWORD(str))))
100         {
101             HANDLE hNext = prop->next;
102             HANDLE hData = prop->hData;
103             USER_HEAP_FREE( *hProp );
104             *hProp = hNext;
105             return hData;
106         }
107         hProp = &prop->next;
108     }
109     return 0;
110 }
111
112
113 /***********************************************************************
114  *           EnumProps   (USER.27)
115  */
116 int EnumProps( HWND hwnd, FARPROC func )
117 {
118     int ret = -1;
119     HANDLE hProp;
120     WND *wndPtr;
121
122     dprintf_prop( stddeb, "EnumProps: "NPFMT" %08lx\n", hwnd, (LONG)func );
123     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
124     hProp = wndPtr->hProp;
125     while (hProp)
126     {
127         PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
128         
129         dprintf_prop( stddeb, "  Callback: atom=%04x data="NPFMT" str='%s'\n",
130                       prop->atom, prop->hData, prop->string );
131
132           /* Already get the next in case the callback */
133           /* function removes the current property.    */
134         hProp = prop->next;
135         ret = CallEnumPropProc( func, hwnd,
136                                 prop->atom ? 
137                                   (LONG)MAKELONG( prop->atom, 0 )
138                                 :
139                                   (LONG)(USER_HEAP_SEG_ADDR(hProp) +
140                                          ((int)prop->string - (int)prop)),
141                                 prop->hData );
142         if (!ret) break;
143     }
144     return ret;
145 }