1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2009 Martin Pitt <martin.pitt@ubuntu.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see
17  * <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <config.h>
21 #include "gvfsgphoto2utils.h"
22 #include <string.h>
23 #include <glib/gi18n-lib.h>
24 
hexdigit(char c)25 static int hexdigit (char c)
26 {
27   if (c >= 'a')
28     return c - 'a' + 10;
29   if (c >= 'A')
30    return c - 'A' + 10;
31   g_return_val_if_fail (c >= '0' && c <= '9', 0);
32   return c - '0';
33 }
34 
35 /* Do not free result, it's a static buffer */
36 static const char*
udev_decode_string(const char * encoded)37 udev_decode_string (const char* encoded)
38 {
39   int len;
40   const char* s;
41   static char decoded[4096];
42 
43   if (encoded == NULL)
44     return NULL;
45 
46   for (len = 0, s = encoded; *s && len < sizeof (decoded) - 1; ++len, ++s) {
47     /* need to check for NUL terminator in advance */
48     if (s[0] == '\\' && s[1] == 'x' && s[2] >= '0' && s[3] >= '0') {
49       decoded[len] = (hexdigit (s[2]) << 4) | hexdigit (s[3]);
50       s += 3;
51     } else if (s[0] == '_' || s[0] == '-') {
52       decoded[len] = ' ';
53     } else {
54       decoded[len] = *s;
55     }
56   }
57   decoded[len] = '\0';
58 
59   return decoded;
60 }
61 
62 char *
g_vfs_get_volume_name(GUdevDevice * device,const char * device_id)63 g_vfs_get_volume_name (GUdevDevice *device, const char *device_id)
64 {
65   const char *gphoto_name;
66   const char *product = NULL;
67   const char *vendor;
68   const char *model;
69 
70   /* our preference: device_id > ID_MEDIA_PLAYER_{VENDOR,PRODUCT} > product >
71    * ID_{VENDOR,MODEL} */
72 
73   gphoto_name = g_udev_device_get_property (device, device_id);
74   if (gphoto_name != NULL && strcmp (gphoto_name, "1") != 0)
75     return g_strdup (gphoto_name);
76 
77   vendor = g_udev_device_get_property (device, "ID_MEDIA_PLAYER_VENDOR");
78   if (vendor == NULL)
79     vendor = g_udev_device_get_property (device, "ID_VENDOR_ENC");
80   model = g_udev_device_get_property (device, "ID_MEDIA_PLAYER_MODEL");
81   if (model == NULL) {
82     model = g_udev_device_get_property (device, "ID_MODEL_ENC");
83     product = g_udev_device_get_sysfs_attr (device, "product");
84   }
85 
86   if (product != NULL && strlen (product) > 0)
87     return g_strdup (udev_decode_string (product));
88   else if (vendor == NULL)
89     {
90       if (model != NULL)
91         return g_strdup (udev_decode_string (model));
92     }
93   else
94     {
95       if (model != NULL)
96         {
97           /* we can't call udev_decode_string() twice in one g_strdup_printf(),
98            * it returns a static buffer */
99           gchar *temp = g_strconcat (vendor, " ", model, NULL);
100           gchar *name = g_strdup (udev_decode_string (temp));
101           g_free (temp);
102           return name;
103         }
104       else
105         {
106           if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER"))
107             {
108               /* Translators: %s is the device vendor */
109               return g_strdup_printf (_("%s Audio Player"), udev_decode_string (vendor));
110             }
111           else
112             {
113               /* Translators: %s is the device vendor */
114               return g_strdup_printf (_("%s Camera"), udev_decode_string (vendor));
115             }
116         }
117     }
118 
119   return g_strdup (_("Camera"));
120 }
121 
122 char *
g_vfs_get_volume_icon(GUdevDevice * device)123 g_vfs_get_volume_icon (GUdevDevice *device)
124 {
125   if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER_ICON_NAME"))
126     return g_strdup (g_udev_device_get_property (device, "ID_MEDIA_PLAYER_ICON_NAME"));
127   else if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER"))
128     return g_strdup ("phone");
129   else
130     return g_strdup ("camera-photo");
131 }
132 
133 char *
g_vfs_get_volume_symbolic_icon(GUdevDevice * device)134 g_vfs_get_volume_symbolic_icon (GUdevDevice *device)
135 {
136   if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER_ICON_NAME"))
137     return g_strconcat (g_udev_device_get_property (device, "ID_MEDIA_PLAYER_ICON_NAME"), "-symbolic", NULL);
138   else if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER"))
139     return g_strdup ("phone-symbolic");
140   else
141     return g_strdup ("camera-photo-symbolic");
142 }
143 
144 char **
g_vfs_get_x_content_types(GUdevDevice * device)145 g_vfs_get_x_content_types (GUdevDevice *device)
146 {
147   char *camera_x_content_types[] = {"x-content/image-dcf", NULL};
148   char *media_player_x_content_types[] = {"x-content/audio-player", NULL};
149 
150   if (g_udev_device_has_property (device, "ID_MEDIA_PLAYER"))
151     return g_strdupv (media_player_x_content_types);
152   else
153     return g_strdupv (camera_x_content_types);
154 }
155