wined3d: Introduce a wined3d_state_get_ffp_texture() helper.
[wine.git] / dlls / hlink / browse_ctx.c
blob88ee3ea29af40bc9b0e2488a9c4074bdc388b000
1 /*
2 * Implementation of hyperlinking (hlink.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "hlink_private.h"
23 #include "wine/debug.h"
24 #include "wine/list.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(hlink);
28 struct link_entry
30 struct list entry;
31 IHlink *link;
34 typedef struct
36 IHlinkBrowseContext IHlinkBrowseContext_iface;
37 LONG ref;
38 HLBWINFO* BrowseWindowInfo;
39 struct link_entry *current;
40 struct list links;
41 } HlinkBCImpl;
43 static inline HlinkBCImpl *impl_from_IHlinkBrowseContext(IHlinkBrowseContext *iface)
45 return CONTAINING_RECORD(iface, HlinkBCImpl, IHlinkBrowseContext_iface);
48 static HRESULT WINAPI IHlinkBC_fnQueryInterface( IHlinkBrowseContext *iface,
49 REFIID riid, LPVOID* ppvObj)
51 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
52 TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj);
54 if (IsEqualIID(riid, &IID_IUnknown) ||
55 IsEqualIID(riid, &IID_IHlinkBrowseContext))
57 *ppvObj = &This->IHlinkBrowseContext_iface;
59 else
61 *ppvObj = NULL;
62 return E_NOINTERFACE;
65 IUnknown_AddRef((IUnknown *)*ppvObj);
66 return S_OK;
69 static ULONG WINAPI IHlinkBC_fnAddRef (IHlinkBrowseContext* iface)
71 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
72 ULONG refCount = InterlockedIncrement(&This->ref);
74 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
76 return refCount;
79 static ULONG WINAPI IHlinkBC_fnRelease (IHlinkBrowseContext* iface)
81 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
82 ULONG ref = InterlockedDecrement(&This->ref);
84 TRACE("(%p)->(count=%lu)\n", This, ref + 1);
86 if (!ref)
88 struct link_entry *link, *link2;
90 LIST_FOR_EACH_ENTRY_SAFE(link, link2, &This->links, struct link_entry, entry)
92 list_remove(&link->entry);
93 IHlink_Release(link->link);
94 free(link);
97 free(This->BrowseWindowInfo);
98 free(This);
101 return ref;
104 static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface,
105 DWORD dwReserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
107 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
108 IMoniker *mon;
109 IMoniker *composite;
110 IRunningObjectTable *ROT;
111 HRESULT hr;
113 FIXME("(%p)->(%li %p %p %p)\n", This, dwReserved, piunk, pimk, pdwRegister);
115 hr = CreateItemMoniker(NULL, L"WINEHLINK", &mon);
116 if (FAILED(hr))
117 return hr;
118 CreateGenericComposite(mon, pimk, &composite);
120 GetRunningObjectTable(0, &ROT);
121 IRunningObjectTable_Register(ROT, 0, piunk, composite, pdwRegister);
123 IRunningObjectTable_Release(ROT);
124 IMoniker_Release(composite);
125 IMoniker_Release(mon);
127 return S_OK;
130 static HRESULT WINAPI IHlinkBC_GetObject(IHlinkBrowseContext* iface,
131 IMoniker *pimk, BOOL fBindifRootRegistered, IUnknown **ppiunk)
133 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
134 IMoniker *mon;
135 IMoniker *composite;
136 IRunningObjectTable *ROT;
137 HRESULT hr;
139 TRACE("(%p)->(%p, %d, %p)\n", This, pimk, fBindifRootRegistered, ppiunk);
141 hr = CreateItemMoniker(NULL, L"WINEHLINK", &mon);
142 if (FAILED(hr)) return hr;
143 CreateGenericComposite(mon, pimk, &composite);
145 GetRunningObjectTable(0, &ROT);
146 hr = IRunningObjectTable_GetObject(ROT, composite, ppiunk);
148 IRunningObjectTable_Release(ROT);
149 IMoniker_Release(composite);
150 IMoniker_Release(mon);
152 return hr;
155 static HRESULT WINAPI IHlinkBC_Revoke(IHlinkBrowseContext* iface,
156 DWORD dwRegister)
158 HRESULT r;
159 IRunningObjectTable *ROT;
160 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
162 FIXME("(%p)->(%li)\n", This, dwRegister);
164 GetRunningObjectTable(0, &ROT);
165 r = IRunningObjectTable_Revoke(ROT, dwRegister);
166 IRunningObjectTable_Release(ROT);
168 return r;
171 static HRESULT WINAPI IHlinkBC_SetBrowseWindowInfo(IHlinkBrowseContext* iface,
172 HLBWINFO *phlbwi)
174 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
175 TRACE("(%p)->(%p)\n", This, phlbwi);
177 if(!phlbwi)
178 return E_INVALIDARG;
180 free(This->BrowseWindowInfo);
181 This->BrowseWindowInfo = malloc(phlbwi->cbSize);
182 memcpy(This->BrowseWindowInfo, phlbwi, phlbwi->cbSize);
184 return S_OK;
187 static HRESULT WINAPI IHlinkBC_GetBrowseWindowInfo(IHlinkBrowseContext* iface,
188 HLBWINFO *phlbwi)
190 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
191 TRACE("(%p)->(%p)\n", This, phlbwi);
193 if(!phlbwi)
194 return E_INVALIDARG;
196 if(!This->BrowseWindowInfo)
197 phlbwi->cbSize = 0;
198 else
199 memcpy(phlbwi, This->BrowseWindowInfo, This->BrowseWindowInfo->cbSize);
201 return S_OK;
204 static HRESULT WINAPI IHlinkBC_SetInitialHlink(IHlinkBrowseContext* iface,
205 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
207 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
208 struct link_entry *link;
210 TRACE("(%p)->(%p %s %s)\n", This, pimkTarget, debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName));
212 if (!list_empty(&This->links))
213 return CO_E_ALREADYINITIALIZED;
215 link = malloc(sizeof(struct link_entry));
216 if (!link) return E_OUTOFMEMORY;
218 HlinkCreateFromMoniker(pimkTarget, pwzLocation, pwzFriendlyName, NULL,
219 0, NULL, &IID_IHlink, (void**)&link->link);
221 list_add_head(&This->links, &link->entry);
222 This->current = LIST_ENTRY(list_head(&This->links), struct link_entry, entry);
223 return S_OK;
226 static HRESULT WINAPI IHlinkBC_OnNavigateHlink(IHlinkBrowseContext *iface,
227 DWORD grfHLNF, IMoniker* pmkTarget, LPCWSTR pwzLocation, LPCWSTR
228 pwzFriendlyName, ULONG *puHLID)
230 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
232 FIXME("(%p)->(%li %p %s %s %p)\n", This, grfHLNF, pmkTarget,
233 debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName), puHLID);
235 return S_OK;
238 static struct link_entry *context_get_entry(HlinkBCImpl *ctxt, ULONG hlid)
240 struct list *entry;
242 switch (hlid)
244 case HLID_PREVIOUS:
245 entry = list_prev(&ctxt->links, &ctxt->current->entry);
246 break;
247 case HLID_NEXT:
248 entry = list_next(&ctxt->links, &ctxt->current->entry);
249 break;
250 case HLID_CURRENT:
251 entry = &ctxt->current->entry;
252 break;
253 case HLID_STACKBOTTOM:
254 entry = list_tail(&ctxt->links);
255 break;
256 case HLID_STACKTOP:
257 entry = list_head(&ctxt->links);
258 break;
259 default:
260 WARN("unknown id 0x%lx\n", hlid);
261 entry = NULL;
264 return entry ? LIST_ENTRY(entry, struct link_entry, entry) : NULL;
267 static HRESULT WINAPI IHlinkBC_UpdateHlink(IHlinkBrowseContext* iface,
268 ULONG hlid, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name)
270 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
271 struct link_entry *entry = context_get_entry(This, hlid);
272 IHlink *link;
273 HRESULT hr;
275 TRACE("(%p)->(0x%lx %p %s %s)\n", This, hlid, target, debugstr_w(location), debugstr_w(friendly_name));
277 if (!entry)
278 return E_INVALIDARG;
280 hr = HlinkCreateFromMoniker(target, location, friendly_name, NULL, 0, NULL, &IID_IHlink, (void**)&link);
281 if (FAILED(hr))
282 return hr;
284 IHlink_Release(entry->link);
285 entry->link = link;
287 return S_OK;
290 static HRESULT WINAPI IHlinkBC_EnumNavigationStack( IHlinkBrowseContext *iface,
291 DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM** ppienumhlitem)
293 FIXME("\n");
294 return E_NOTIMPL;
297 static HRESULT WINAPI IHlinkBC_QueryHlink( IHlinkBrowseContext* iface,
298 DWORD grfHLONG, ULONG uHLID)
300 FIXME("\n");
301 return E_NOTIMPL;
304 static HRESULT WINAPI IHlinkBC_GetHlink(IHlinkBrowseContext* iface, ULONG hlid, IHlink **ret)
306 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
307 struct link_entry *link;
309 TRACE("(%p)->(0x%lx %p)\n", This, hlid, ret);
311 link = context_get_entry(This, hlid);
312 if (!link)
313 return E_FAIL;
315 *ret = link->link;
316 IHlink_AddRef(*ret);
318 return S_OK;
321 static HRESULT WINAPI IHlinkBC_SetCurrentHlink(IHlinkBrowseContext* iface, ULONG hlid)
323 HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
324 struct link_entry *link;
326 TRACE("(%p)->(0x%08lx)\n", This, hlid);
328 link = context_get_entry(This, hlid);
329 if (!link)
330 return E_FAIL;
332 This->current = link;
333 return S_OK;
336 static HRESULT WINAPI IHlinkBC_Clone( IHlinkBrowseContext* iface,
337 IUnknown* piunkOuter, REFIID riid, IUnknown** ppiunkOjb)
339 FIXME("\n");
340 return E_NOTIMPL;
343 static HRESULT WINAPI IHlinkBC_Close(IHlinkBrowseContext* iface,
344 DWORD reserved)
346 FIXME("\n");
347 return E_NOTIMPL;
350 static const IHlinkBrowseContextVtbl hlvt =
352 IHlinkBC_fnQueryInterface,
353 IHlinkBC_fnAddRef,
354 IHlinkBC_fnRelease,
355 IHlinkBC_Register,
356 IHlinkBC_GetObject,
357 IHlinkBC_Revoke,
358 IHlinkBC_SetBrowseWindowInfo,
359 IHlinkBC_GetBrowseWindowInfo,
360 IHlinkBC_SetInitialHlink,
361 IHlinkBC_OnNavigateHlink,
362 IHlinkBC_UpdateHlink,
363 IHlinkBC_EnumNavigationStack,
364 IHlinkBC_QueryHlink,
365 IHlinkBC_GetHlink,
366 IHlinkBC_SetCurrentHlink,
367 IHlinkBC_Clone,
368 IHlinkBC_Close
371 HRESULT HLinkBrowseContext_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
373 HlinkBCImpl * hl;
374 HRESULT hr;
376 TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid));
377 *ppv = NULL;
379 if (pUnkOuter)
380 return CLASS_E_NOAGGREGATION;
382 hl = calloc(1, sizeof(*hl));
383 if (!hl)
384 return E_OUTOFMEMORY;
386 hl->ref = 1;
387 hl->IHlinkBrowseContext_iface.lpVtbl = &hlvt;
388 list_init(&hl->links);
390 hr = IHlinkBrowseContext_QueryInterface(&hl->IHlinkBrowseContext_iface, riid, ppv);
391 IHlinkBrowseContext_Release(&hl->IHlinkBrowseContext_iface);
393 return hr;