1/*
2 * Copyright 2004-2008, Fran��ois Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "CamRoster.h"
7
8#include "AddOn.h"
9#include "CamDevice.h"
10#include "CamDebug.h"
11
12#include <OS.h>
13
14#undef B_WEBCAM_MKINTFUNC
15#define B_WEBCAM_MKINTFUNC(modname) \
16extern "C" status_t get_webcam_addon_##modname(WebCamMediaAddOn* webcam, CamDeviceAddon **addon);
17#include "CamInternalAddons.h"
18#undef B_WEBCAM_MKINTFUNC
19
20
21CamRoster::CamRoster(WebCamMediaAddOn* _addon)
22	: BUSBRoster(),
23	fLocker("WebcamRosterLock"),
24	fAddon(_addon)
25{
26	PRINT((CH "()" CT));
27	LoadInternalAddons();
28	LoadExternalAddons();
29}
30
31
32CamRoster::~CamRoster()
33{
34}
35
36
37status_t
38CamRoster::DeviceAdded(BUSBDevice* _device)
39{
40	PRINT((CH "()" CT));
41	status_t err;
42	for (int16 i = fCamerasAddons.CountItems() - 1; i >= 0; --i ) {
43		CamDeviceAddon *ao = (CamDeviceAddon *)fCamerasAddons.ItemAt(i);
44		PRINT((CH ": checking %s for support..." CT, ao->BrandName()));
45		err = ao->Sniff(_device);
46		if (err < B_OK)
47			continue;
48		CamDevice *cam = ao->Instantiate(*this, _device);
49		PRINT((CH ": found camera %s:%s!" CT, cam->BrandName(), cam->ModelName()));
50		err = cam->InitCheck();
51		if (err >= B_OK) {
52			fCameras.AddItem(cam);
53			fAddon->CameraAdded(cam);
54			return B_OK;
55		}
56		PRINT((CH " error 0x%08" B_PRIx32 CT, err));
57	}
58	return B_ERROR;
59}
60
61
62void
63CamRoster::DeviceRemoved(BUSBDevice* _device)
64{
65	PRINT((CH "()" CT));
66	for (int32 i = 0; i < fCameras.CountItems(); ++i) {
67		CamDevice* cam = (CamDevice *)fCameras.ItemAt(i);
68		if (cam->Matches(_device)) {
69			PRINT((CH ": camera %s:%s removed" CT, cam->BrandName(), cam->ModelName()));
70			fCameras.RemoveItem(i);
71			fAddon->CameraRemoved(cam);
72			// XXX: B_DONT_DO_THAT!
73			//delete cam;
74			cam->Unplugged();
75			return;
76		}
77	}
78}
79
80
81uint32
82CamRoster::CountCameras()
83{
84	int32 count;
85	fLocker.Lock();
86	PRINT((CH "(): %" B_PRId32 " cameras" CT, fCameras.CountItems()));
87	count = fCameras.CountItems();
88	fLocker.Unlock();
89	return count;
90}
91
92
93bool
94CamRoster::Lock()
95{
96	PRINT((CH "()" CT));
97	return fLocker.Lock();
98}
99
100
101void
102CamRoster::Unlock()
103{
104	PRINT((CH "()" CT));
105	fLocker.Unlock();
106	return;
107}
108
109
110CamDevice*
111CamRoster::CameraAt(int32 index)
112{
113	PRINT((CH "()" CT));
114	return (CamDevice *)fCameras.ItemAt(index);
115}
116
117
118status_t
119CamRoster::LoadInternalAddons()
120{
121	PRINT((CH "()" CT));
122	CamDeviceAddon *addon;
123	status_t err;
124
125#undef B_WEBCAM_MKINTFUNC
126#define B_WEBCAM_MKINTFUNC(modname) \
127	err = get_webcam_addon_##modname(fAddon, &addon); \
128	if (err >= B_OK) { \
129		fCamerasAddons.AddItem(addon); \
130		PRINT((CH ": registered %s addon" CT, addon->BrandName())); \
131	}
132
133#include "CamInternalAddons.h"
134#undef B_WEBCAM_MKINTFUNC
135
136
137	return B_OK;
138}
139
140
141status_t
142CamRoster::LoadExternalAddons()
143{
144	PRINT((CH "()" CT));
145	// FIXME
146	return B_ERROR;
147	int32 index;
148	int32 sclass;
149	status_t err;
150	CamDeviceAddon *addon;
151	status_t (*get_webcam_addon_func)(WebCamMediaAddOn* webcam, CamDeviceAddon **addon);
152	for (index = 0; get_nth_image_symbol(fAddon->ImageID(),
153										index, NULL, NULL,
154										&sclass,
155										(void **)&get_webcam_addon_func) == B_OK; index++) {
156		PRINT((CH ": got sym" CT));
157//		if (sclass != B_SYMBOL_TYPE_TEXT)
158//			continue;
159		err = (*get_webcam_addon_func)(fAddon, &addon);
160		PRINT((CH ": Loaded addon '%s' with error 0x%08" B_PRIx32 CT,
161			(err > 0) ? NULL : addon->BrandName(),
162			err));
163	}
164	return B_OK;
165}
166
167
168
169