Fix up elficon support

pull/16/head
Timothy Pearson 13 years ago
parent 2e95a0338f
commit be3f8c175f

@ -51,6 +51,11 @@ install( FILES kpasswdserver.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded )
install( FILES data.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) install( FILES data.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
if( HAVE_ELFICON )
set( ELFICON_STATIC_LIB tdelficon-static )
endif( HAVE_ELFICON )
##### libkio #################################### ##### libkio ####################################
set( target kio ) set( target kio )
@ -60,7 +65,7 @@ configure_file( ${CMAKE_SOURCE_DIR}/cmake/modules/template_dummy_cpp.cmake dummy
tde_add_library( ${target} SHARED tde_add_library( ${target} SHARED
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
VERSION 4.2.0 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} LINK tdeui-shared tdesu-shared kwalletclient-shared ${LIBR_LIBRARIES}
DESTINATION ${LIB_INSTALL_DIR} DESTINATION ${LIB_INSTALL_DIR}
) )

@ -114,3 +114,20 @@ set( ${target}_SRCS
tde_add_library( ${target} STATIC_PIC AUTOMOC tde_add_library( ${target} STATIC_PIC AUTOMOC
SOURCES ${${target}_SRCS} 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 )

@ -35,6 +35,7 @@
#include <tqfile.h> #include <tqfile.h>
#include <tqmap.h> #include <tqmap.h>
#include <tqstylesheet.h> #include <tqstylesheet.h>
#include <tqimage.h>
#include <kdebug.h> #include <kdebug.h>
#include <kfilemetainfo.h> #include <kfilemetainfo.h>
@ -49,112 +50,7 @@
#include <krun.h> #include <krun.h>
#ifdef HAVE_ELFICON #ifdef HAVE_ELFICON
#include <alloca.h> #include "tdelficon.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 #endif // HAVE_ELFICON
class KFileItem::KFileItemPrivate { class KFileItem::KFileItemPrivate {
@ -780,7 +676,7 @@ TQPixmap KFileItem::pixmap( int _size, int _state ) const
} }
while((entry = get_nexticon(&icons, entry)) != NULL) 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; iconresnamefound = 1;
p = DesktopIcon( entry->name, _size, _state ); p = DesktopIcon( entry->name, _size, _state );
break; break;
@ -792,6 +688,11 @@ TQPixmap KFileItem::pixmap( int _size, int _state ) const
size_t icon_data_length; size_t icon_data_length;
char* icondata = libr_icon_malloc(icon, &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 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); free(icondata);
libr_icon_close(icon); libr_icon_close(icon);
} }

@ -28,6 +28,11 @@
#include <kstaticdeleter.h> #include <kstaticdeleter.h>
#include <kparts/componentfactory.h> #include <kparts/componentfactory.h>
#ifdef HAVE_ELFICON
#include <tqimage.h>
#include "tdelficon.h"
#endif // HAVE_ELFICON
#include "kurifilter.h" #include "kurifilter.h"
template class TQPtrList<KURIFilterPlugin>; template class TQPtrList<KURIFilterPlugin>;
@ -159,6 +164,7 @@ TQString KURIFilterData::iconName()
{ {
if( m_bChanged ) if( m_bChanged )
{ {
m_customIconPixmap = TQPixmap();
switch ( m_iType ) switch ( m_iType )
{ {
case KURIFilterData::LOCAL_FILE: case KURIFilterData::LOCAL_FILE:
@ -175,12 +181,78 @@ TQString KURIFilterData::iconName()
KService::Ptr service = KService::serviceByDesktopName( exeName ); KService::Ptr service = KService::serviceByDesktopName( exeName );
if (service && service->icon() != TQString::fromLatin1( "unknown" )) if (service && service->icon() != TQString::fromLatin1( "unknown" ))
m_strIconName = service->icon(); 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() ) else if ( !KGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() )
m_strIconName = exeName; 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 // not found, use default
m_strIconName = TQString::fromLatin1("exec"); m_strIconName = TQString::fromLatin1("exec");
}
break; break;
} }
case KURIFilterData::HELP: case KURIFilterData::HELP:
@ -208,6 +280,11 @@ TQString KURIFilterData::iconName()
return m_strIconName; return m_strIconName;
} }
TQPixmap KURIFilterData::customIconPixmap()
{
return m_customIconPixmap;
}
//******************************************** KURIFilterPlugin ********************************************** //******************************************** KURIFilterPlugin **********************************************
void KURIFilterPlugin::setArguments( KURIFilterData& data, const TQString& args ) const void KURIFilterPlugin::setArguments( KURIFilterData& data, const TQString& args ) const
{ {

@ -28,6 +28,7 @@
#include <tqptrlist.h> #include <tqptrlist.h>
#include <tqobject.h> #include <tqobject.h>
#include <tqstringlist.h> #include <tqstringlist.h>
#include <tqpixmap.h>
#include <kurl.h> #include <kurl.h>
@ -256,6 +257,16 @@ public:
*/ */
TQString iconName(); 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. * Check whether the provided uri is executable or not.
* *
@ -332,6 +343,8 @@ private:
KURL m_pURI; KURL m_pURI;
URITypes m_iType; URITypes m_iType;
KURIFilterDataPrivate *d; KURIFilterDataPrivate *d;
TQPixmap m_customIconPixmap;
}; };

Loading…
Cancel
Save