summaryrefslogtreecommitdiffstats
path: root/kio
diff options
context:
space:
mode:
Diffstat (limited to 'kio')
-rw-r--r--kio/CMakeLists.txt3
-rw-r--r--kio/kio/CMakeLists.txt1
-rw-r--r--kio/kio/kfileitem.cpp169
3 files changed, 172 insertions, 1 deletions
diff --git a/kio/CMakeLists.txt b/kio/CMakeLists.txt
index b18bfef33..73c2c9dba 100644
--- a/kio/CMakeLists.txt
+++ b/kio/CMakeLists.txt
@@ -30,6 +30,7 @@ include_directories(
link_directories(
${TQT_LIBRARY_DIRS}
+ ${LIBR_LIBDIR}
)
@@ -60,6 +61,6 @@ tde_add_library( ${target} SHARED
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
VERSION 4.2.0
EMBED kssl-static kiocore-static ksycoca-static kbookmarks-static kfile-static
- LINK tdeui-shared tdesu-shared kwalletclient-shared
+ LINK tdeui-shared tdesu-shared kwalletclient-shared ${LIBR_LIBRARIES}
DESTINATION ${LIB_INSTALL_DIR}
)
diff --git a/kio/kio/CMakeLists.txt b/kio/kio/CMakeLists.txt
index f9976a6d2..479814f15 100644
--- a/kio/kio/CMakeLists.txt
+++ b/kio/kio/CMakeLists.txt
@@ -24,6 +24,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/kio
${CMAKE_SOURCE_DIR}/kio/kssl
${CMAKE_SOURCE_DIR}/interfaces
+ ${LIBR_INCLUDEDIR}
)
diff --git a/kio/kio/kfileitem.cpp b/kio/kio/kfileitem.cpp
index 010832573..eaedf0a2d 100644
--- a/kio/kio/kfileitem.cpp
+++ b/kio/kio/kfileitem.cpp
@@ -19,6 +19,8 @@
*/
// $Id$
+#include <config.h>
+
#include <sys/time.h>
#include <pwd.h>
#include <grp.h>
@@ -46,6 +48,115 @@
#include <kmimetype.h>
#include <krun.h>
+#ifdef HAVE_ELFICON
+#include <alloca.h>
+#include <stdint.h>
+#include <cstdlib>
+
+extern "C" {
+ #include <libr-icons.h>
+
+ // BEGIN HACK
+ // libr does not export these structures and defines,
+ // but we need access to them to make the UI behave sanely
+ // Keep them in sync with libr and all should be OK
+
+ // Valid for libr version 0.6.0
+ // See libr detection code in ConfigureChecks.cmake
+
+ typedef uint32_t ID8;
+ typedef uint16_t ID4;
+ typedef struct {uint64_t p:48;} __attribute__((__packed__)) ID12;
+
+ typedef struct {
+ ID8 g1;
+ ID4 g2;
+ ID4 g3;
+ ID4 g4;
+ ID12 g5;
+ } __attribute__((__packed__)) UUID;
+
+ typedef struct {
+ char *name;
+ size_t offset;
+ size_t entry_size;
+ libr_icontype_t type;
+ unsigned int icon_size;
+ } iconentry;
+
+ typedef struct{
+ size_t size;
+ char *buffer;
+ iconentry entry;
+ } iconlist;
+
+ #define ICON_SECTION ".icon"
+ // END HACK
+
+// int get_iconlist(libr_file *file_handle, iconlist *icons);
+// iconentry *get_nexticon(iconlist *icons, iconentry *last_entry);
+}
+
+/*
+ * Obtain an existing icon resource list
+ */
+int get_iconlist(libr_file *file_handle, iconlist *icons)
+{
+ if(icons == NULL)
+ {
+ /* Need to be able to return SOMETHING */
+ return false;
+ }
+ /* Obtain the icon resource list */
+ icons->buffer = libr_malloc(file_handle, ICON_SECTION, &(icons->size));
+ if(icons->buffer == NULL)
+ return false;
+ return true;
+}
+
+/*
+ * Get the next entry in an icon resource list
+ */
+iconentry *get_nexticon(iconlist *icons, iconentry *last_entry)
+{
+ size_t i;
+
+ /* The icon list is needed both for the data buffer and for a call-specific iconentry instance */
+ if(icons == NULL)
+ return NULL;
+ /* If this is the first call (last_entry == NULL) then return the first entry */
+ if(last_entry == NULL)
+ icons->entry.offset = sizeof(uint32_t)+sizeof(UUID);
+ else
+ icons->entry.offset += icons->entry.entry_size;
+ /* Check to see if we've run out of entries */
+ if(icons->entry.offset >= icons->size)
+ return NULL;
+ i = icons->entry.offset;
+ memcpy(&(icons->entry.entry_size), &(icons->buffer[i]), sizeof(uint32_t));
+ i += sizeof(uint32_t);
+ icons->entry.type = (libr_icontype_t)icons->buffer[i];
+ i += sizeof(unsigned char);
+ switch(icons->entry.type)
+ {
+ case LIBR_SVG:
+ icons->entry.icon_size = 0;
+ icons->entry.name = &(icons->buffer[i]);
+ break;
+ case LIBR_PNG:
+ memcpy(&(icons->entry.icon_size), &(icons->buffer[i]), sizeof(uint32_t));
+ i += sizeof(uint32_t);
+ icons->entry.name = &(icons->buffer[i]);
+ break;
+ default:
+ /* Invalid entry type */
+ return NULL;
+ }
+ return &(icons->entry);
+}
+
+#endif // HAVE_ELFICON
+
class KFileItem::KFileItemPrivate {
public:
TQString iconName;
@@ -630,6 +741,64 @@ TQPixmap KFileItem::pixmap( int _size, int _state ) const
if (p.isNull())
kdWarning() << "Pixmap not found for mimetype " << m_pMimeType->name() << endl;
+ if ( mime->name() == "application/x-executable" ) {
+ // FIXME
+ // Look for .desktop files for this executable
+ // before resorting to the embedded icon
+ // (look at how the minicli does it)
+#ifdef HAVE_ELFICON
+ // Check for an embedded icon
+ unsigned int icon_size;
+ libr_icon *icon = NULL;
+ libr_file *handle = NULL;
+ libr_access_t access = LIBR_READ;
+
+ if((handle = libr_open(const_cast<char*>(url.path().ascii()), access)) == NULL)
+ {
+ kdWarning() << "failed to open file" << url.path() << endl;
+ return p;
+ }
+
+ icon_size = _size;
+ icon = libr_icon_geticon_bysize(handle, icon_size);
+ if(icon == NULL)
+ {
+ kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl;
+ libr_close(handle);
+ return p;
+ }
+
+ // See if the embedded icon name matches any icon file names already on the system
+ // If it does, use the system icon instead of the embedded one
+ int iconresnamefound = 0;
+ iconentry *entry = NULL;
+ iconlist icons;
+ if(!get_iconlist(handle, &icons))
+ {
+ // Failed to obtain a list of ELF icons
+ }
+ while((entry = get_nexticon(&icons, entry)) != NULL)
+ {
+ if (KGlobal::iconLoader()->iconPath(entry->name, _size, true) != "") {
+ iconresnamefound = 1;
+ p = DesktopIcon( entry->name, _size, _state );
+ break;
+ }
+ }
+
+ if (iconresnamefound == 0) {
+ // Extract the embedded icon
+ size_t icon_data_length;
+ char* icondata = libr_icon_malloc(icon, &icon_data_length);
+ p.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST
+ free(icondata);
+ libr_icon_close(icon);
+ }
+
+ libr_close(handle);
+#endif // HAVE_ELFICON
+ }
+
return p;
}