2 * Copyright 2002-2008, Haiku Inc.
3 * Distributed under the terms of the MIT License.
7 * Ingo Weinhold, bonefish@users.sf.net
8 * Axel Dörfler, axeld@pinc-software.de
16 #include <sys/ioctl.h>
19 #include <AutoDeleter.h>
24 #include <FindDirectory.h>
27 #include <IconUtils.h>
32 #include <RegistrarDefs.h>
34 #include <RosterPrivate.h>
37 using namespace BPrivate
;
40 NOT_IMPLEMENTED
= B_ERROR
,
44 // Helper function that contacts the registrar for mime update calls
46 do_mime_update(int32 what
, const char* path
, int recursive
,
47 int synchronous
, int force
)
52 status_t err
= root
.SetTo(path
? path
: "/");
54 err
= root
.GetRef(&ref
);
60 // Build and send the message, read the reply
62 err
= msg
.AddRef("entry", &ref
);
64 err
= msg
.AddBool("recursive", recursive
);
66 err
= msg
.AddBool("synchronous", synchronous
);
68 err
= msg
.AddInt32("force", force
);
70 err
= BRoster::Private().SendTo(&msg
, &reply
, true);
72 err
= reply
.what
== B_REG_RESULT
? B_OK
: B_BAD_VALUE
;
74 err
= reply
.FindInt32("result", &result
);
82 // Updates the MIME information (i.e MIME type) for one or more files.
84 update_mime_info(const char* path
, int recursive
, int synchronous
, int force
)
86 // Force recursion when given a NULL path
90 return do_mime_update(B_REG_MIME_UPDATE_MIME_INFO
, path
, recursive
,
95 // Creates a MIME database entry for one or more applications.
97 create_app_meta_mime(const char* path
, int recursive
, int synchronous
,
100 // Force recursion when given a NULL path
104 return do_mime_update(B_REG_MIME_CREATE_APP_META_MIME
, path
, recursive
,
109 // Retrieves an icon associated with a given device.
111 get_device_icon(const char* device
, void* icon
, int32 size
)
113 if (device
== NULL
|| icon
== NULL
114 || (size
!= B_LARGE_ICON
&& size
!= B_MINI_ICON
))
117 int fd
= open(device
, O_RDONLY
);
121 // ToDo: The mounted directories for volumes can also have META:X:STD_ICON
122 // attributes. Should those attributes override the icon returned by
123 // ioctl(,B_GET_ICON,)?
124 device_icon iconData
= {size
, icon
};
125 if (ioctl(fd
, B_GET_ICON
, &iconData
) != 0) {
126 // legacy icon was not available, try vector icon
132 status_t status
= get_device_icon(device
, &data
, &dataSize
, &type
);
133 if (status
== B_OK
) {
134 BBitmap
* icon32
= new(std::nothrow
) BBitmap(
135 BRect(0, 0, size
- 1, size
- 1), B_BITMAP_NO_SERVER_LINK
,
137 BBitmap
* icon8
= new(std::nothrow
) BBitmap(
138 BRect(0, 0, size
- 1, size
- 1), B_BITMAP_NO_SERVER_LINK
,
141 ArrayDeleter
<uint8
> dataDeleter(data
);
142 ObjectDeleter
<BBitmap
> icon32Deleter(icon32
);
143 ObjectDeleter
<BBitmap
> icon8Deleter(icon8
);
145 if (icon32
== NULL
|| icon32
->InitCheck() != B_OK
|| icon8
== NULL
146 || icon8
->InitCheck() != B_OK
) {
150 status
= BIconUtils::GetVectorIcon(data
, dataSize
, icon32
);
152 status
= BIconUtils::ConvertToCMAP8(icon32
, icon8
);
154 memcpy(icon
, icon8
->Bits(), icon8
->BitsLength());
166 // Retrieves an icon associated with a given device.
168 get_device_icon(const char* device
, BBitmap
* icon
, icon_size which
)
171 if (device
== NULL
|| icon
== NULL
)
177 status_t status
= get_device_icon(device
, &data
, &size
, &type
);
178 if (status
== B_OK
) {
179 status
= BIconUtils::GetVectorIcon(data
, size
, icon
);
184 // Vector icon was not available, try old one
187 if (which
== B_MINI_ICON
)
188 rect
.Set(0, 0, 15, 15);
189 else if (which
== B_LARGE_ICON
)
190 rect
.Set(0, 0, 31, 31);
192 BBitmap
* bitmap
= icon
;
193 int32 iconSize
= which
;
195 if (icon
->ColorSpace() != B_CMAP8
196 || (which
!= B_MINI_ICON
&& which
!= B_LARGE_ICON
)) {
197 if (which
< B_LARGE_ICON
)
198 iconSize
= B_MINI_ICON
;
200 iconSize
= B_LARGE_ICON
;
202 bitmap
= new(std::nothrow
) BBitmap(
203 BRect(0, 0, iconSize
- 1, iconSize
-1), B_BITMAP_NO_SERVER_LINK
,
205 if (bitmap
== NULL
|| bitmap
->InitCheck() != B_OK
) {
211 // get the icon, convert temporary data into bitmap if necessary
212 status
= get_device_icon(device
, bitmap
->Bits(), iconSize
);
213 if (status
== B_OK
&& icon
!= bitmap
)
214 status
= BIconUtils::ConvertFromCMAP8(bitmap
, icon
);
224 get_device_icon(const char* device
, uint8
** _data
, size_t* _size
,
227 if (device
== NULL
|| _data
== NULL
|| _size
== NULL
|| _type
== NULL
)
230 int fd
= open(device
, O_RDONLY
);
234 // Try to get the icon by name first
236 char name
[B_FILE_NAME_LENGTH
];
237 if (ioctl(fd
, B_GET_ICON_NAME
, name
) >= 0) {
238 status_t status
= get_named_icon(name
, _data
, _size
, _type
);
239 if (status
== B_OK
) {
245 // Getting the named icon failed, try vector icon next
247 // NOTE: The actual icon size is unknown as of yet. After the first call
248 // to B_GET_VECTOR_ICON, the actual size is known and the final buffer
249 // is allocated with the correct size. If the buffer needed to be
250 // larger, then the temporary buffer above will not yet contain the
251 // valid icon data. In that case, a second call to B_GET_VECTOR_ICON
252 // retrieves it into the final buffer.
254 device_icon iconData
= {sizeof(data
), data
};
255 status_t status
= ioctl(fd
, B_GET_VECTOR_ICON
, &iconData
,
256 sizeof(device_icon
));
260 if (status
== B_OK
) {
261 *_data
= new(std::nothrow
) uint8
[iconData
.icon_size
];
263 status
= B_NO_MEMORY
;
266 if (status
== B_OK
) {
267 if (iconData
.icon_size
> (int32
)sizeof(data
)) {
268 // the stack buffer does not contain the data, see NOTE above
269 iconData
.icon_data
= *_data
;
270 status
= ioctl(fd
, B_GET_VECTOR_ICON
, &iconData
,
271 sizeof(device_icon
));
275 memcpy(*_data
, data
, iconData
.icon_size
);
277 *_size
= iconData
.icon_size
;
278 *_type
= B_VECTOR_ICON_TYPE
;
281 // TODO: also support getting the old icon?
288 get_named_icon(const char* name
, BBitmap
* icon
, icon_size which
)
291 if (name
== NULL
|| icon
== NULL
)
295 if (which
== B_MINI_ICON
)
296 rect
.Set(0, 0, 15, 15);
297 else if (which
== B_LARGE_ICON
)
298 rect
.Set(0, 0, 31, 31);
302 if (icon
->Bounds() != rect
)
308 status_t status
= get_named_icon(name
, &data
, &size
, &type
);
309 if (status
== B_OK
) {
310 status
= BIconUtils::GetVectorIcon(data
, size
, icon
);
319 get_named_icon(const char* name
, uint8
** _data
, size_t* _size
, type_code
* _type
)
321 if (name
== NULL
|| _data
== NULL
|| _size
== NULL
|| _type
== NULL
)
324 directory_which kWhich
[] = {
325 B_USER_NONPACKAGED_DATA_DIRECTORY
,
326 B_USER_DATA_DIRECTORY
,
327 B_SYSTEM_NONPACKAGED_DATA_DIRECTORY
,
328 B_SYSTEM_DATA_DIRECTORY
,
331 status_t status
= B_ENTRY_NOT_FOUND
;
335 for (uint32 i
= 0; i
< sizeof(kWhich
) / sizeof(kWhich
[0]); i
++) {
337 if (find_directory(kWhich
[i
], &path
) != B_OK
)
340 path
.Append("icons");
343 status
= file
.SetTo(path
.Path(), B_READ_ONLY
);
344 if (status
== B_OK
) {
345 status
= file
.GetSize(&size
);
346 if (size
> 1024 * 1024)
356 *_data
= new(std::nothrow
) uint8
[size
];
360 if (file
.Read(*_data
, size
) != size
) {
366 *_type
= B_VECTOR_ICON_TYPE
;