summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-12-31 04:24:59 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-12-31 04:24:59 -0600
commitbe3f8c175f534d88425b983a577e799c76202e38 (patch)
tree1024143f3894e273412ce44bd7530765664a4ea1
parent2e95a0338f40a820ea592802357e985cfcbdb388 (diff)
downloadtdelibs-be3f8c175f534d88425b983a577e799c76202e38.tar.gz
tdelibs-be3f8c175f534d88425b983a577e799c76202e38.zip
Fix up elficon support
-rw-r--r--kio/CMakeLists.txt7
-rw-r--r--kio/kio/CMakeLists.txt17
-rw-r--r--kio/kio/kfileitem.cpp115
-rw-r--r--kio/kio/kurifilter.cpp81
-rw-r--r--kio/kio/kurifilter.h13
5 files changed, 123 insertions, 110 deletions
diff --git a/kio/CMakeLists.txt b/kio/CMakeLists.txt
index 73c2c9dba..2c1d8ff0d 100644
--- a/kio/CMakeLists.txt
+++ b/kio/CMakeLists.txt
@@ -51,6 +51,11 @@ install( FILES kpasswdserver.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded )
install( FILES data.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
+if( HAVE_ELFICON )
+ set( ELFICON_STATIC_LIB tdelficon-static )
+endif( HAVE_ELFICON )
+
+
##### libkio ####################################
set( target kio )
@@ -60,7 +65,7 @@ configure_file( ${CMAKE_SOURCE_DIR}/cmake/modules/template_dummy_cpp.cmake dummy
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
+ EMBED kssl-static kiocore-static ksycoca-static kbookmarks-static kfile-static ${ELFICON_STATIC_LIB}
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 479814f15..9d8790f46 100644
--- a/kio/kio/CMakeLists.txt
+++ b/kio/kio/CMakeLists.txt
@@ -114,3 +114,20 @@ set( ${target}_SRCS
tde_add_library( ${target} STATIC_PIC AUTOMOC
SOURCES ${${target}_SRCS}
)
+
+
+##### tdelficon ###################################
+
+if( HAVE_ELFICON )
+
+ set( target tdelficon )
+
+ set( ${target}_SRCS
+ tdelficon.cpp
+ )
+
+ tde_add_library( ${target} STATIC_PIC AUTOMOC
+ SOURCES ${${target}_SRCS}
+ )
+
+endif( HAVE_ELFICON ) \ No newline at end of file
diff --git a/kio/kio/kfileitem.cpp b/kio/kio/kfileitem.cpp
index 839c38a68..e74b407be 100644
--- a/kio/kio/kfileitem.cpp
+++ b/kio/kio/kfileitem.cpp
@@ -35,6 +35,7 @@
#include <tqfile.h>
#include <tqmap.h>
#include <tqstylesheet.h>
+#include <tqimage.h>
#include <kdebug.h>
#include <kfilemetainfo.h>
@@ -49,112 +50,7 @@
#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);
-}
-
+#include "tdelficon.h"
#endif // HAVE_ELFICON
class KFileItem::KFileItemPrivate {
@@ -780,7 +676,7 @@ TQPixmap KFileItem::pixmap( int _size, int _state ) const
}
while((entry = get_nexticon(&icons, entry)) != NULL)
{
- if (KGlobal::iconLoader()->iconPath(entry->name, _size, true) != "") {
+ if (KGlobal::iconLoader()->iconPath(entry->name, 0, true) != "") {
iconresnamefound = 1;
p = DesktopIcon( entry->name, _size, _state );
break;
@@ -792,6 +688,11 @@ TQPixmap KFileItem::pixmap( int _size, int _state ) const
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
+ if (icon_size != 0) {
+ TQImage ip = p.convertToImage();
+ ip = ip.smoothScale(icon_size, icon_size);
+ p.convertFromImage(ip);
+ }
free(icondata);
libr_icon_close(icon);
}
diff --git a/kio/kio/kurifilter.cpp b/kio/kio/kurifilter.cpp
index 2c4c5b12e..f6910e6a1 100644
--- a/kio/kio/kurifilter.cpp
+++ b/kio/kio/kurifilter.cpp
@@ -28,6 +28,11 @@
#include <kstaticdeleter.h>
#include <kparts/componentfactory.h>
+#ifdef HAVE_ELFICON
+#include <tqimage.h>
+#include "tdelficon.h"
+#endif // HAVE_ELFICON
+
#include "kurifilter.h"
template class TQPtrList<KURIFilterPlugin>;
@@ -159,6 +164,7 @@ TQString KURIFilterData::iconName()
{
if( m_bChanged )
{
+ m_customIconPixmap = TQPixmap();
switch ( m_iType )
{
case KURIFilterData::LOCAL_FILE:
@@ -175,12 +181,78 @@ TQString KURIFilterData::iconName()
KService::Ptr service = KService::serviceByDesktopName( exeName );
if (service && service->icon() != TQString::fromLatin1( "unknown" ))
m_strIconName = service->icon();
- // Try to find an icon with the same name as the binary (useful for non-kde apps)
+ // Try to find an icon with the same name as the binary (useful for non-tde apps)
+ // FIXME: We should only do this if the binary is in the system path somewhere,
+ // otherwise TDE could end up showing system icons for user binaries
else if ( !KGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() )
m_strIconName = exeName;
- else
+ else {
+ // not found, try to load from elf file (if supported)
+#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;
+ char libr_can_continue = 1;
+
+ if((handle = libr_open(const_cast<char*>(m_pURI.path().ascii()), access)) == NULL)
+ {
+ kdWarning() << "failed to open file" << m_pURI.path() << endl;
+ libr_can_continue = 0;
+ }
+
+ if (libr_can_continue == 1) {
+ icon_size = 32; // FIXME: Is this a reasonable size request for all possible usages of kurifilter?
+ icon = libr_icon_geticon_bysize(handle, icon_size);
+ if(icon == NULL)
+ {
+ kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl;
+ libr_close(handle);
+ libr_can_continue = 0;
+ }
+
+ if (libr_can_continue == 1) {
+ // 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, 0, true) != "") {
+ iconresnamefound = 1;
+ m_strIconName = entry->name;
+ break;
+ }
+ }
+
+ if (iconresnamefound == 0) {
+ // Extract the embedded icon
+ size_t icon_data_length;
+ char* icondata = libr_icon_malloc(icon, &icon_data_length);
+ m_customIconPixmap.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST
+ if (icon_size != 0) {
+ TQImage ip = m_customIconPixmap.convertToImage();
+ ip = ip.smoothScale(icon_size, icon_size);
+ m_customIconPixmap.convertFromImage(ip);
+ }
+ free(icondata);
+ libr_icon_close(icon);
+ }
+
+ libr_close(handle);
+ }
+ }
+#endif // HAVE_ELFICON
+
// not found, use default
m_strIconName = TQString::fromLatin1("exec");
+ }
break;
}
case KURIFilterData::HELP:
@@ -208,6 +280,11 @@ TQString KURIFilterData::iconName()
return m_strIconName;
}
+TQPixmap KURIFilterData::customIconPixmap()
+{
+ return m_customIconPixmap;
+}
+
//******************************************** KURIFilterPlugin **********************************************
void KURIFilterPlugin::setArguments( KURIFilterData& data, const TQString& args ) const
{
diff --git a/kio/kio/kurifilter.h b/kio/kio/kurifilter.h
index 2cd999582..0887d8e4b 100644
--- a/kio/kio/kurifilter.h
+++ b/kio/kio/kurifilter.h
@@ -28,6 +28,7 @@
#include <tqptrlist.h>
#include <tqobject.h>
#include <tqstringlist.h>
+#include <tqpixmap.h>
#include <kurl.h>
@@ -257,6 +258,16 @@ public:
TQString iconName();
/**
+ * Returns the current custom icon
+ * The results are valid iff iconName() has
+ * returned TQString::null
+ *
+ * @return a pixmap with the current custom icon,
+ * or a null pixmap if no icon is available
+ */
+ TQPixmap customIconPixmap();
+
+ /**
* Check whether the provided uri is executable or not.
*
* Setting this to false ensures that typing the name of
@@ -332,6 +343,8 @@ private:
KURL m_pURI;
URITypes m_iType;
KURIFilterDataPrivate *d;
+
+ TQPixmap m_customIconPixmap;
};