feat: First working Windows build
This commit is contained in:
@@ -79,4 +79,4 @@ int ProbeCacheLineSize()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* TODO MINGW: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-cache_descriptor */
|
||||
|
||||
13
dvdisaster.c
13
dvdisaster.c
@@ -22,6 +22,19 @@
|
||||
|
||||
#include "dvdisaster.h"
|
||||
|
||||
|
||||
/*
|
||||
* Those are now declared as extern in dvdisaster.h,
|
||||
* and as such are accessible from everywhere.
|
||||
* MinGW didn't link these being declared directly
|
||||
* in dvdisaster.h (ended up having one copy of each
|
||||
* struct for every .c including dvdisaster.h)
|
||||
*/
|
||||
struct _RawBuffer *rawbuffer_forward;
|
||||
struct _DefectiveSectorHeader *dsh_forward;
|
||||
struct _DeviceHandle *dh_forward;
|
||||
struct _Image *dh_image;
|
||||
|
||||
/*
|
||||
* The all-famous main() loop
|
||||
*/
|
||||
|
||||
14
dvdisaster.h
14
dvdisaster.h
@@ -77,7 +77,11 @@
|
||||
|
||||
/* File permissions for images */
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
#define IMG_PERMS (S_IRUSR | S_IWUSR)
|
||||
#else
|
||||
#define IMG_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
||||
#endif
|
||||
|
||||
/* Using round() is preferred over rint() on systems which have it */
|
||||
|
||||
@@ -452,13 +456,13 @@ typedef struct _CrcBlock
|
||||
} CrcBlock;
|
||||
|
||||
/***
|
||||
*** forward declarations
|
||||
*** dvdisaster.c
|
||||
***/
|
||||
|
||||
struct _RawBuffer *rawbuffer_forward;
|
||||
struct _DefectiveSectorHeader *dsh_forward;
|
||||
struct _DeviceHandle *dh_forward;
|
||||
struct _Image *dh_image;
|
||||
extern struct _RawBuffer *rawbuffer_forward;
|
||||
extern struct _DefectiveSectorHeader *dsh_forward;
|
||||
extern struct _DeviceHandle *dh_forward;
|
||||
extern struct _Image *dh_image;
|
||||
|
||||
/***
|
||||
*** bitmap.c
|
||||
|
||||
@@ -109,6 +109,9 @@ LargeFile* LargeOpen(char *name, int flags, mode_t mode)
|
||||
#ifdef HAVE_O_LARGEFILE
|
||||
flags |= O_LARGEFILE;
|
||||
#endif
|
||||
#ifdef SYS_MINGW
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
|
||||
cp_path = os_path(name);
|
||||
if(!cp_path)
|
||||
|
||||
891
locale/cs.po
891
locale/cs.po
File diff suppressed because it is too large
Load Diff
893
locale/de.po
893
locale/de.po
File diff suppressed because it is too large
Load Diff
860
locale/it.po
860
locale/it.po
File diff suppressed because it is too large
Load Diff
882
locale/pt_BR.po
882
locale/pt_BR.po
File diff suppressed because it is too large
Load Diff
882
locale/ru.po
882
locale/ru.po
File diff suppressed because it is too large
Load Diff
858
locale/sv.po
858
locale/sv.po
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,6 @@ static void action_cb(GtkWidget *widget, gpointer data)
|
||||
if(action != ACTION_STOP)
|
||||
{
|
||||
/* Clear the log buffer, request new log file time stamp */
|
||||
|
||||
if(action != ACTION_CREATE_CONT)
|
||||
{ g_mutex_lock(Closure->logLock);
|
||||
g_string_truncate(Closure->logString, 0);
|
||||
@@ -69,7 +68,6 @@ static void action_cb(GtkWidget *widget, gpointer data)
|
||||
g_mutex_unlock(Closure->logLock);
|
||||
Closure->logFileStamped = FALSE;
|
||||
}
|
||||
|
||||
/* Make sure we're using the current file selections */
|
||||
|
||||
g_free(Closure->imageName);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* along with dvdisaster. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYS_MINGW /* completely untested under Windows, and we don't need it for releases anyway */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#if !defined(SYS_FREEBSD) /* FreeBSD declares malloc() in stdlib.h */
|
||||
@@ -85,7 +87,7 @@ void remember(void *ptr, int size, char *file, int line)
|
||||
|
||||
g_mutex_lock(&phMutex);
|
||||
|
||||
hash_idx = (((long)ptr)>>3)&63;
|
||||
hash_idx = (((long long)ptr)>>3)&63;
|
||||
if(phCnt[hash_idx] >= phMax[hash_idx])
|
||||
{ if(!phMax[hash_idx]) phMax[hash_idx] = 16;
|
||||
else phMax[hash_idx] *= 2;
|
||||
@@ -348,3 +350,4 @@ void check_memleaks(void)
|
||||
else g_printf("dvdisaster: No memory leaks found.\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -353,7 +353,7 @@ void RS01ScanImage(Method *method, Image* image, struct MD5Context *ecc_ctxt, in
|
||||
}
|
||||
|
||||
if(crc != crcbuf[crcidx++] && !current_missing)
|
||||
{ PrintCLI(_("* CRC error, sector: %lld\n"), s);
|
||||
{ PrintCLI(_("* CRC error, sector: %lld, found %08x instead of %08x\n"), crc, crcbuf[crcidx], s);
|
||||
image->crcErrors++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
#include "rs03-includes.h"
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* Needed version must be consistent between CRC blocks and ECC headers
|
||||
since ECC headers may be reconstructed from CRC blocks. */
|
||||
|
||||
@@ -1220,7 +1224,15 @@ static void create_reed_solomon(ecc_closure *ec)
|
||||
ec->chunkBytes = 2048*Closure->prefetchSectors;
|
||||
ec->chunkSize = Closure->prefetchSectors;
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
ec->pageSize = si.dwPageSize;
|
||||
}
|
||||
#else
|
||||
ec->pageSize = sysconf(_SC_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
/*** Allocate stuff shared by all threads */
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
# along with Bash based configure. If not, see <http://www.gnu.org/licenses/>.
|
||||
#/
|
||||
|
||||
|
||||
# Command overview:
|
||||
#
|
||||
# PACKAGE Define package name and version
|
||||
|
||||
11
scsi-layer.h
11
scsi-layer.h
@@ -28,6 +28,11 @@
|
||||
#include <linux/cdrom.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(SYS_FREEBSD) || defined(SYS_KFREEBSD)
|
||||
#include <camlib.h>
|
||||
#endif
|
||||
@@ -106,6 +111,8 @@ typedef struct _DeviceHandle
|
||||
#elif defined(SYS_FREEBSD) || defined(SYS_KFREEBSD)
|
||||
struct cam_device *camdev; /* camlib device handle */
|
||||
union ccb *ccb;
|
||||
#elif defined(SYS_MINGW)
|
||||
HANDLE fd; /* Windows SPTI file handle for the device */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -226,6 +233,10 @@ typedef struct _DeviceHandle
|
||||
|
||||
DeviceHandle* OpenDevice(char*);
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
DeviceHandle* open_spti_device(char*);
|
||||
#endif
|
||||
|
||||
int SendPacket(DeviceHandle*, unsigned char*, int, unsigned char*, int, Sense*, int);
|
||||
int SimulateSendPacket(DeviceHandle*, unsigned char*, int, unsigned char*, int, Sense*, int);
|
||||
|
||||
|
||||
286
scsi-win32.c
Normal file
286
scsi-win32.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/* dvdisaster: Additional error correction for optical media.
|
||||
* Copyright (C) 2004-2010 Carsten Gnoerlich.
|
||||
* Project home page: http://www.dvdisaster.com
|
||||
* Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
|
||||
* or direct your browser at http://www.gnu.org.
|
||||
*/
|
||||
|
||||
#include "dvdisaster.h"
|
||||
|
||||
#include "scsi-layer.h"
|
||||
#include "udf.h"
|
||||
|
||||
/**
|
||||
** Windows wrapper.
|
||||
**
|
||||
* As of dvdisaster 0.73.1, Windows 2000 SP4 is the minimum
|
||||
* system requirement and thus only SPTI is supported.
|
||||
*/
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
|
||||
/*
|
||||
* The drive letter ordering is remembered for
|
||||
* historical reasons (it was once useful for ASPI mapping)
|
||||
*/
|
||||
|
||||
static int drive_letters[26];
|
||||
static int cd_dvd_drives = 0;
|
||||
|
||||
char* DefaultDevice()
|
||||
{
|
||||
char drive_letter;
|
||||
char device_path[16],buf[80];
|
||||
DeviceHandle *dh;
|
||||
|
||||
/* As a convenience, add the simulated drive first. */
|
||||
|
||||
InitSimulatedCD();
|
||||
|
||||
/* Now probe the physical drives. */
|
||||
|
||||
for(drive_letter='C'; drive_letter<='Z'; drive_letter++)
|
||||
{ UINT drive_type;
|
||||
|
||||
g_sprintf(device_path, "%c:\\", drive_letter);
|
||||
drive_type = GetDriveType(device_path);
|
||||
|
||||
if(drive_type == DRIVE_CDROM)
|
||||
{ drive_letters[cd_dvd_drives] = drive_letter;
|
||||
cd_dvd_drives++;
|
||||
|
||||
/* Collect drives accessible via SPTI */
|
||||
|
||||
sprintf(buf, "%c:", drive_letter);
|
||||
|
||||
if((dh = open_spti_device(buf)))
|
||||
{ InquireDevice(dh, 1);
|
||||
|
||||
g_ptr_array_add(Closure->deviceNodes, g_strdup(buf));
|
||||
sprintf(buf, "%c: %s", drive_letter, dh->devinfo);
|
||||
g_ptr_array_add(Closure->deviceNames, g_strdup(buf));
|
||||
CloseDevice(dh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Closure->deviceNodes->len)
|
||||
return g_strdup(g_ptr_array_index(Closure->deviceNodes, 0));
|
||||
else
|
||||
{ PrintLog(_("No optical drives found in /dev.\n"
|
||||
"No drives will be pre-selected.\n"));
|
||||
|
||||
|
||||
return g_strdup("No_Drive_found");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the SPTI device.
|
||||
*/
|
||||
|
||||
void CloseDevice(DeviceHandle *dh)
|
||||
{
|
||||
if(dh->simImage)
|
||||
LargeClose(dh->simImage);
|
||||
|
||||
if(dh->canReadDefective)
|
||||
SetRawMode(dh, MODE_PAGE_UNSET);
|
||||
|
||||
if(dh->rawBuffer)
|
||||
FreeRawBuffer(dh->rawBuffer);
|
||||
|
||||
if(dh->fd) /* SPTI cleanup */
|
||||
CloseHandle(dh->fd);
|
||||
|
||||
if(dh->typeDescr)
|
||||
g_free(dh->typeDescr);
|
||||
if(dh->mediumDescr)
|
||||
g_free(dh->mediumDescr);
|
||||
if(dh->defects)
|
||||
FreeBitmap(dh->defects);
|
||||
|
||||
g_free(dh->device);
|
||||
g_free(dh);
|
||||
}
|
||||
|
||||
/**
|
||||
** The SPTI wrapper.
|
||||
**/
|
||||
|
||||
/*
|
||||
* The Mingw includes are missing the following structs
|
||||
* for sending SCSI packets via SPTI.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{ USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
PVOID DataBuffer;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
} SCSI_PASS_THROUGH_DIRECT;
|
||||
|
||||
typedef struct
|
||||
{ SCSI_PASS_THROUGH_DIRECT spt;
|
||||
ULONG Filler;
|
||||
UCHAR SenseBuf[32];
|
||||
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
||||
|
||||
#define IOCTL_SCSI_BASE 0x00000004
|
||||
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
||||
|
||||
/*
|
||||
* Open the device using SPTI.
|
||||
*/
|
||||
|
||||
DeviceHandle* open_spti_device(char *device)
|
||||
{ DeviceHandle *dh;
|
||||
char device_path[16];
|
||||
|
||||
if( strlen(device) != 2
|
||||
|| toupper(*device) < 'C'
|
||||
|| toupper(*device) > 'Z'
|
||||
|| device[1] != ':')
|
||||
{
|
||||
Stop(_("\nIllegal device name \"%s\" (use devices \"C:\" ... \"Z:\")"),device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dh = g_malloc0(sizeof(DeviceHandle));
|
||||
dh->device = g_strdup(device);
|
||||
|
||||
g_sprintf(device_path, "\\\\.\\%c:", toupper(*device));
|
||||
|
||||
dh->fd = CreateFile(device_path,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL );
|
||||
|
||||
if(dh->fd == INVALID_HANDLE_VALUE) /* Might be Win9x or missing priviledges */
|
||||
{ g_free(dh->device);
|
||||
g_free(dh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the SCSI command through SPTI.
|
||||
* At least W2K seems to have problems with SCSI commands timing out;
|
||||
* it even manages to do a spontaneous reboot because of that occasionally.
|
||||
* So we set the time out value to a conservative 120 secs.
|
||||
*/
|
||||
|
||||
static int send_spti_packet(HANDLE fd, unsigned char *cmd, int cdb_size, char *buf, int size, Sense *sense, int data_mode)
|
||||
{ SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER ss;
|
||||
BOOL success;
|
||||
ULONG returned;
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
|
||||
ss.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
||||
ss.spt.CdbLength = cdb_size;
|
||||
ss.spt.SenseInfoLength = 24;
|
||||
ss.spt.TargetId = 1;
|
||||
switch(data_mode)
|
||||
{ case DATA_WRITE:
|
||||
ss.spt.DataIn = 0; /* SCSI_IOCTL_DATA_OUT */
|
||||
break;
|
||||
case DATA_READ:
|
||||
ss.spt.DataIn = 1; /* SCSI_IOCTL_DATA_IN */
|
||||
break;
|
||||
case DATA_NONE:
|
||||
ss.spt.DataIn = 2; /* SCSI_IOCTL_DATA_UNSPECIFIED */
|
||||
break;
|
||||
default:
|
||||
Stop("illegal data_mode: %d",data_mode);
|
||||
return -1;
|
||||
}
|
||||
ss.spt.DataTransferLength = size;
|
||||
ss.spt.TimeOutValue = 120; /* see comment above */
|
||||
ss.spt.DataBuffer = buf;
|
||||
ss.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf);
|
||||
memcpy(ss.spt.Cdb, cmd, cdb_size);
|
||||
|
||||
success = DeviceIoControl(fd, IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
||||
&ss, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
|
||||
&ss, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
|
||||
&returned, FALSE);
|
||||
|
||||
memcpy(sense, ss.SenseBuf, 24); /* Hmm. What a kludge. */
|
||||
|
||||
if(!success || ss.spt.ScsiStatus) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the device
|
||||
*/
|
||||
|
||||
DeviceHandle* OpenDevice(char *device)
|
||||
{ DeviceHandle *dh = NULL;
|
||||
|
||||
if(!strcmp(device, "sim-cd"))
|
||||
{ if(!Closure->simulateCD) /* can happen via resource file / last-device */
|
||||
return NULL;
|
||||
dh = g_malloc0(sizeof(DeviceHandle));
|
||||
dh->senseSize = sizeof(Sense);
|
||||
dh->simImage = LargeOpen(Closure->simulateCD, O_RDONLY, IMG_PERMS);
|
||||
if(!dh->simImage)
|
||||
{ g_free(dh);
|
||||
|
||||
Stop(_("Could not open %s: %s"), Closure->simulateCD, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( (*device >= 'c' && *device <= 'z')
|
||||
|| (*device >= 'C' && *device <= 'Z'))
|
||||
dh = open_spti_device(Closure->device);
|
||||
|
||||
if(!dh)
|
||||
{ Stop(_("\nCould not open device %s."), device);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate Scsi wrapper into SPTI call
|
||||
*/
|
||||
|
||||
int SendPacket(DeviceHandle *dh, unsigned char *cmd, int cdb_size, unsigned char *buf, int size, Sense *sense, int data_mode)
|
||||
{
|
||||
if(dh->simImage)
|
||||
return SimulateSendPacket(dh, cmd, cdb_size, buf, size, sense, data_mode);
|
||||
|
||||
return send_spti_packet(dh->fd, cmd, cdb_size, (char *)buf, size, sense, data_mode);
|
||||
}
|
||||
|
||||
#endif /* SYS_MINGW */
|
||||
@@ -23,12 +23,23 @@
|
||||
|
||||
#include "dvdisaster.h"
|
||||
|
||||
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
|
||||
defined(SYS_NETBSD) || defined(SYS_HURD)
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
#include "windows.h"
|
||||
#include "shellapi.h"
|
||||
#endif
|
||||
|
||||
/***
|
||||
*** Ask user to specify his viewer
|
||||
***/
|
||||
|
||||
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
|
||||
defined(SYS_NETBSD) || defined(SYS_HURD)
|
||||
|
||||
#define SEARCH_BUTTON 1
|
||||
|
||||
typedef struct
|
||||
@@ -141,6 +152,7 @@ static void viewer_dialog(char *path)
|
||||
|
||||
gtk_widget_show_all(dialog);
|
||||
}
|
||||
#endif /* SYS_ unix-like */
|
||||
|
||||
/***
|
||||
*** Show the manual in an external viewer
|
||||
@@ -165,6 +177,9 @@ static void msg_destroy_cb(GtkWidget *widget, gpointer data)
|
||||
bi->msg = NULL;
|
||||
}
|
||||
|
||||
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
|
||||
defined(SYS_NETBSD) || defined(SYS_HURD)
|
||||
|
||||
/*
|
||||
* The following list of viewers
|
||||
* will be tried one at a time until one entry succeeds by:
|
||||
@@ -234,11 +249,34 @@ static gboolean viewer_timeout_func(gpointer data)
|
||||
|
||||
return bi->seconds > 60 ? FALSE : TRUE;
|
||||
}
|
||||
#endif /* SYS_ unix-like */
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
static gboolean viewer_timeout_func(gpointer data)
|
||||
{ viewer_info *bi = (viewer_info*)data;
|
||||
|
||||
bi->seconds++;
|
||||
|
||||
if(bi->seconds >= 10)
|
||||
{ if(bi->msg)
|
||||
{ gtk_widget_destroy(bi->msg);
|
||||
bi->msg = NULL;
|
||||
}
|
||||
//if(bi->url) g_free(bi->url);
|
||||
g_free(bi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* SYS_MINGW */
|
||||
|
||||
/*
|
||||
* Invoke the viewer
|
||||
*/
|
||||
|
||||
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
|
||||
defined(SYS_NETBSD) || defined(SYS_HURD)
|
||||
static void try_viewer(viewer_info *bi)
|
||||
{ pid_t pid;
|
||||
|
||||
@@ -274,6 +312,8 @@ static void try_viewer(viewer_info *bi)
|
||||
_exit(110); /* couldn't execute */
|
||||
}
|
||||
}
|
||||
#endif /* SYS_ unix-like */
|
||||
|
||||
|
||||
void ShowPDF(char *target)
|
||||
{ viewer_info *bi = g_malloc0(sizeof(viewer_info));
|
||||
@@ -311,6 +351,15 @@ void ShowPDF(char *target)
|
||||
|
||||
/* Try the first viwer */
|
||||
|
||||
#ifdef SYS_MINGW
|
||||
/* Okay, Billy wins big time here ;-) */
|
||||
|
||||
ShellExecute(NULL, "open", bi->path, NULL, NULL, SW_SHOWNORMAL);
|
||||
g_timeout_add(1000, viewer_timeout_func, (gpointer)bi);
|
||||
#endif
|
||||
|
||||
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_DARWIN) || defined(SYS_NETBSD)
|
||||
viewer_index = 0;
|
||||
try_viewer(bi);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user