This patch gives IShellLink::SetPath the ability to create a kde and gnome link to the program based on its windows directory. This works definitely in RH 6.2, not sure under other systems. It provides an icon interface under a subdirectory named winefiles in the application section of the kde/gnome start menus. There are two seperate files attached, one is the program file itself, which belongs in the wine/dlls/shell32/. directory and the xpm which I put into wine/linuxIshell/. directory (and needs to be there for a proper reference to be made to it from the linking function. -Brian files: kdelinkmaker.c directory: wine/dlls/shell32/. wine.xpm wine/linuxIshell/.
#include<stdio.h> #include<string.h> #include "file.h" int kdelinkmaker(char*linkloc,char * pathandfile,char * typelnk,int termrun,char * namelnk) { char * ld_lib,executa[100],*ptrexec,buffer[400]; FILE *fpout; int count=0; ld_lib =(char *) getenv("LD_LIBRARY_PATH"); /*use the environment variable to get wine directory path*/ strcpy(executa,ld_lib); ptrexec = executa; /*just build the file*/ ptrexec = strtok(ptrexec,":"); if((fpout = fopen(linkloc, "w")) == NULL) { printf("\ncan't open file for write\n"); return 1; } for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"# KDE Config File\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"[KDE Desktop Entry]\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"SwallowExec=\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"BinaryPattern=\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Name=%s\n",namelnk); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Comment[]=Wine executable\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"MimeType=wine;\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Exec=%s/wine \"%s\"\n",ptrexec,pathandfile); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Icon=%s/linuxIshell/wine.xpm\n",ptrexec); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"TerminalOptions=\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Path=\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Type=%s\n",typelnk); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Terminal=%d\n",termrun); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Name[]=%s\n",namelnk); fprintf(fpout,"%s",buffer); fclose(fpout); return 0; } int gnomelinkmaker(char*linkloc,char * pathandfile,char * typelnk,int termrun,char * namelnk) { char * ld_lib,executa[100],*ptrexec,buffer[400]; FILE *fpout; int count=0; ld_lib =(char *) getenv("LD_LIBRARY_PATH"); /*get the wine directory path from the environment*/ strcpy(executa,ld_lib); /*build the file*/ ptrexec = executa; ptrexec = strtok(ptrexec,":"); if((fpout = fopen(linkloc, "w")) == NULL) { printf("\ncan't open file for write\n"); return 1; } for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"[Desktop Entry]\n"); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Name=%s\n",namelnk); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Comment=%s\n",typelnk); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Exec=%s/wine \"%s\"\n",ptrexec,pathandfile); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Icon=%s/linuxIshell/wine.xpm\n",ptrexec); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Terminal=%d\n",termrun); fprintf(fpout,"%s",buffer); for(count = 0;count < 400;count++) buffer[count] = '\0'; sprintf(buffer,"Type=Application\n"); fprintf(fpout,"%s",buffer); fclose(fpout); return 0; } void linuxlinker(char * pszFile) { char* linkloc, *pathandfile,*typelnk,*namelnk,name[256],tester[500],path[500],* test2,holdingpath[500]; int i,j,termrun; char lnklocbase[500],pathandfilebase[500],typelnkbase[500],namelnkbase[50], tester2[50],* test3,cmd[1000]; char *getwd(char*); int chdir(char * ); char basealpha[500],basealpha3[500],* alpha1, * alpha3, alpha4[500]; char *alphab1,basealphab1[500],*alphab2,basealphab2[500]; DOS_FULL_NAME fulle; linkloc=lnklocbase; /*match up pointers with buffers*/ pathandfile = pathandfilebase; typelnk = typelnkbase; namelnk = namelnkbase; alpha1 = basealpha; alpha3 = basealpha3; alphab1 = basealphab1; alphab2 = basealphab2; test3 = tester2; strcpy(alpha1, "/usr/share/applnk/Applications"); /*set base dir's for kde and gnome menus*/ strcpy(alphab1,"/usr/share/gnome/apps/Applications"); for (i = 0; i< 500; i++) path[i] = '\0'; /*null out the path to work with*/ i = strlen(pszFile); /*make sure the file is concluded with a null*/ *(pszFile + i) = '\0'; strcpy(path , pszFile); /*make a copy of the file path to work with*/ for(i=0;i<=50;i++) /*null out 2 working buffers*/ { tester2[i] = '\0'; name[i] = '\0'; } test2 = strrchr(path,'\\'); /*point to the last occurence of / in the file, before the filename*/ for(i=0;*(test2 + i) != '\0';i++) /*copy the file name into the name buffer*/ name[i] = *(test2 + i); strcat(name,"\0"); /*end it with a null*/ test2 = strstr(path,name); /*get the first position of the name and cut it off of the path*/ *(test2) = '\0'; test2 = strrchr(name,'.'); /*point to the extension off of the name*/ if ((*test2) != '\0') /*make sure that it is a file*/ { for(i=1;*(test2 + i) != '\0';i++) tester2[i-1] = *(test2 + i); /*get a copy of the extension*/ if((!strcmp("exe",tester2)) || (!strcmp("EXE",tester2)) || (!strcmp("Exe",tester2))) { DOSFS_GetFullName( pszFile, 1, &fulle ); /*get the full unix path*/ strcpy(path,fulle.long_name); /*put a copy of the long path into 2 holders*/ strcpy(holdingpath,fulle.long_name); i = 1; while(path[i] != '\0') /*copy over the path after the first slash*/ { tester[i-1] = path[i]; i++; } tester[i] = '\0'; strcpy(path,tester); /*copy the path after the first slash back into the holder*/ test2 = strchr(path,'/'); /*just retrieve the first directory name*/ *test2 = '\0'; i = test2 - path; /*get the length of the directory name, make a copy*/ j = i; while(path[i+1] != '\0') /*copy the next directory name into a holder*/ { tester[i-j] = path[i+1]; i++; } strcpy(path,tester); /*put the directory name back into the holder*/ test2 = strchr(path,'/'); *test2 = '\0'; strcat(alpha1, "/winefiles"); /*set the head directory under the start menu dir's*/ strcat(alphab1,"/winefiles"); if(!strcmp(path,"Program Files")) /*just get a straight directory listing, no Program Files group*/ { /*winefiles is a good substitute*/ i = test2 - path; /*get the length of the directory name*/ j = i; while(path[i+1] != '\0') /*copy the next directory into the holder*/ { tester[i-j] = path[i+1]; i++; } strcpy(path,tester); /*put it back into the original holder*/ test2 = strchr(path,'/'); *test2 = '\0'; } while(test2 != NULL) { /*while there are still directories left in the path, we need*/ i = chdir(alpha1); /*to either recreate the directory structure under winefiles*/ j = chdir(alphab1); /*or at least make sure it exists*/ if(i == (-1)) /*if the directory doesn't exist in KDE, create it*/ { sprintf(cmd,"mkdir \"%s\"",alpha1); system(cmd); i = chdir(alpha1); } if(j == (-1)) /*do the same for the gnome directory*/ { sprintf(cmd,"mkdir \"%s\"",alphab1); system(cmd); j = chdir(alphab1); } strcat(alpha1,"/"); /*add a slash and the next directory name to each path*/ strcat(alphab1,"/"); strcat(alpha1,path); strcat(alphab1,path); i = chdir(alpha1); /*check to see if the new directory exists*/ j = chdir(alphab1); if(i == (-1)){ /*create if it doesn't*/ sprintf(cmd,"mkdir \"%s\"",alpha1); system(cmd); i=chdir(alpha1); } if(j == (-1)) { sprintf(cmd,"mkdir \"%s\"",alphab1); system(cmd); j=chdir(alphab1); } strcpy(alpha3,alpha1); /*put the path into holders for later operations*/ strcpy(alphab2,alphab1); i = test2 - path; j = i; while(path[i+1] != '\0') /*skip over the directory just worked with and get the next one*/ { tester[i-j] = path[i+1]; i++; } strcpy(path,tester); /*copy the next dir back into path*/ test2 = strchr(path,'/'); if(test2 != NULL) *test2 = '\0'; } for(i=1;(i<=50) && (name[i] != '\0');i++) /*copy the name, post slash into a holder*/ alpha4[i-1] = name[i]; strcat(alpha3,"/"); /*add a slash to both paths*/ strcat(alphab2,"/"); strtok(alpha4,"."); /*delete the .exe and add the .kdelnk for kde directory structure*/ strcat(alpha4,".kdelnk"); strcat(alpha3,alpha4); /*add the .kdelnk filename to the path*/ strcpy(linkloc,alpha3); /*fill in the appropriate var's to be sent to the kdelinkmaker function*/ strcpy(pathandfile,fulle.long_name); strcpy(typelnk,"Application"); termrun = 0; strtok(alpha4,"."); strcpy(namelnk,alpha4); kdelinkmaker(linkloc,pathandfile,typelnk,termrun,namelnk); strtok(alpha4,"."); /*change what needs to be for gnome and send to the gnomelindmaker fn*/ strcat(alpha4,".desktop"); strcat(alphab2,alpha4); strcpy(linkloc,alphab2); gnomelinkmaker(linkloc,pathandfile,typelnk,termrun,namelnk); } } }
? linuxIshell/wine.xpm ? dlls/shell32/kdelinkmaker.c Index: dlls/shell32/shelllink.c =================================================================== RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v retrieving revision 1.24 diff -u -r1.24 shelllink.c --- dlls/shell32/shelllink.c 2000/01/18 05:09:50 1.24 +++ dlls/shell32/shelllink.c 2000/07/21 22:26:18 @@ -4,16 +4,16 @@ * Copyright 1998 Juergen Schmied * */ - +#include<stdio.h> #include <string.h> #include "debugtools.h" #include "winerror.h" - +#include "kdelinkmaker.c" #include "wine/obj_base.h" #include "wine/obj_storage.h" #include "wine/obj_shelllink.h" #include "wine/undocshell.h" - +#include "file.h" #include "heap.h" #include "winnls.h" #include "pidl.h" @@ -23,7 +23,7 @@ DEFAULT_DEBUG_CHANNEL(shell) /* link file formats */ - +#include <windows.h> #include "pshpack1.h" /* flag1: lnk elements: simple link has 0x0B */ @@ -441,8 +441,7 @@ { *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream); } - - if(*ppvObj) + if(*ppvObj) { IUnknown_AddRef((IUnknown*)(*ppvObj)); TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); @@ -496,7 +495,6 @@ ICOM_THIS(IShellLinkImpl, iface); TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",This, pszFile, cchMaxPath, pfd, fFlags, debugstr_a(This->sPath)); - if (This->sPath) lstrcpynA(pszFile,This->sPath, cchMaxPath); else @@ -567,7 +565,6 @@ ICOM_THIS(IShellLinkImpl, iface); FIXME("(%p)->(args=%s)\n",This, pszArgs); - return NOERROR; } static HRESULT WINAPI IShellLink_fnGetHotkey(IShellLink * iface, WORD *pwHotkey) @@ -577,7 +574,6 @@ TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey); *pwHotkey = This->wHotKey; - return NOERROR; } static HRESULT WINAPI IShellLink_fnSetHotkey(IShellLink * iface, WORD wHotkey) @@ -587,7 +583,6 @@ TRACE("(%p)->(hotkey=%x)\n",This, wHotkey); This->wHotKey = wHotkey; - return NOERROR; } static HRESULT WINAPI IShellLink_fnGetShowCmd(IShellLink * iface, INT *piShowCmd) @@ -640,6 +635,7 @@ ICOM_THIS(IShellLinkImpl, iface); FIXME("(%p)->(path=%s)\n",This, pszFile); + linuxlinker(pszFile); return NOERROR; } @@ -681,7 +677,6 @@ IShellLinkW * iface, REFIID riid, LPVOID *ppvObj) { _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); - return IShellLink_QueryInterface((IShellLink*)This, riid, ppvObj); } @@ -693,7 +688,6 @@ _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); TRACE("(%p)->(count=%lu)\n",This,This->ref); - return IShellLink_AddRef((IShellLink*)This); } /****************************************************************************** @@ -705,7 +699,6 @@ _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); TRACE("(%p)->(count=%lu)\n",This,This->ref); - return IShellLink_Release((IShellLink*)This); }