/* silo.c: Conversions between SCSI and IDE disk names
 *	   and OpenPROM fully qualified paths.
 *
 * Modified for DrakX light integration.
 * Copyright (C) 1999, 2000 Jakub Jelinek <jakub@redhat.com>
 * 
 * This software may be freely redistributed under the terms of the GNU
 * public license.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef __sparc__

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <asm/openpromio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/utsname.h>

#ifndef OPROMSETCUR
#define OPROMSETCUR	0x20004FF0
#define OPROMPCI2NODE	0x20004FF1
#define OPROMPATH2NODE	0x20004FF2
#endif

static int hasaliases;
static char *promdev = "/dev/openprom";
static int promfd;
static char sd_targets[10] = "31204567";
static int p1275 = 0;
static int prom_root_node, prom_current_node;
static int promvers;
static void (*prom_walk_callback)(int node);
static char prom_path[1024];
#define MAX_PROP	128
#define MAX_VAL		(4096-128-4)
static char buf[4096];
static char regstr[40];
#define DECL_OP(size) struct openpromio *op = (struct openpromio *)buf; op->oprom_size = (size)

static int
prom_setcur(int node) {
    DECL_OP(sizeof(int));
    
    if (node == -1) return 0;
    *(int *)op->oprom_array = node;
    if (ioctl (promfd, OPROMSETCUR, op) < 0)
        return 0;
    prom_current_node = *(int *)op->oprom_array;
    return *(int *)op->oprom_array;
}

static int
prom_getsibling(int node) {
    DECL_OP(sizeof(int));
    
    if (node == -1) return 0;
    *(int *)op->oprom_array = node;
    if (ioctl (promfd, OPROMNEXT, op) < 0)
        return 0;
    prom_current_node = *(int *)op->oprom_array;
    return *(int *)op->oprom_array;
}

static int
prom_getchild(int node) {
    DECL_OP(sizeof(int));
    
    if (!node || node == -1) return 0;
    *(int *)op->oprom_array = node;
    if (ioctl (promfd, OPROMCHILD, op) < 0)
        return 0;
    prom_current_node = *(int *)op->oprom_array;
    return *(int *)op->oprom_array;
}

static char *
prom_getproperty(char *prop, int *lenp) {
    DECL_OP(MAX_VAL);
    
    strcpy (op->oprom_array, prop);
    if (ioctl (promfd, OPROMGETPROP, op) < 0)
        return 0;
    if (lenp) *lenp = op->oprom_size;
    return op->oprom_array;
}

static char *
prom_getopt(char *var, int *lenp) {
    DECL_OP(MAX_VAL);

    strcpy (op->oprom_array, var);
    if (ioctl (promfd, OPROMGETOPT, op) < 0)
        return 0;
    if (lenp) *lenp = op->oprom_size;
    return op->oprom_array;
}

static void
prom_setopt(char *var, char *value) {
    DECL_OP(MAX_VAL);

    strcpy (op->oprom_array, var);
    strcpy (op->oprom_array + strlen (var) + 1, value);
    ioctl (promfd, OPROMSETOPT, op);
}

static int
prom_getbool(char *prop) {
    DECL_OP(0);

    *(int *)op->oprom_array = 0;
    for (;;) {
        op->oprom_size = MAX_PROP;
            if (ioctl(promfd, OPROMNXTPROP, op) < 0)
                return 0;
            if (!op->oprom_size)
                return 0;
            if (!strcmp (op->oprom_array, prop))
                return 1;
    }
}

static int
prom_pci2node(int bus, int devfn) {
    DECL_OP(2*sizeof(int));
    
    ((int *)op->oprom_array)[0] = bus;
    ((int *)op->oprom_array)[1] = devfn;
    if (ioctl (promfd, OPROMPCI2NODE, op) < 0)
        return 0;
    prom_current_node = *(int *)op->oprom_array;
    return *(int *)op->oprom_array;
}

static int
prom_path2node(char *path) {
    DECL_OP(MAX_VAL);
    
    strcpy (op->oprom_array, path);
    if (ioctl (promfd, OPROMPATH2NODE, op) < 0)
        return 0;
    prom_current_node = *(int *)op->oprom_array;
    return *(int *)op->oprom_array;
}

#define PW_TYPE_SBUS	1
#define PW_TYPE_PCI	2
#define PW_TYPE_EBUS	3

static void
prom_walk(char *path, int parent, int node, int type) {
    int nextnode;
    int len, ntype = type;
    char *prop;
    
    prop = prom_getproperty("name", &len);
    if (prop && len > 0) {
        if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
            ntype = PW_TYPE_SBUS;
        else if (!strcmp(prop, "ebus") && type == PW_TYPE_PCI)
            ntype = PW_TYPE_EBUS;
        else if (!strcmp(prop, "pci") && !type)
            ntype = PW_TYPE_PCI;
    }
    *path = '/';
    strcpy (path + 1, prop);
    prop = prom_getproperty("reg", &len);
    if (prop && len >= 4) {
        unsigned int *reg = (unsigned int *)prop;
        int cnt = 0;
        if (!p1275 || (type == PW_TYPE_SBUS))
	    sprintf (regstr, "@%x,%x", reg[0], reg[1]);
        else if (type == PW_TYPE_PCI) {
	    if ((reg[0] >> 8) & 7)
		sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
	    else
		sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
        } else if (len == 4)
	    sprintf (regstr, "@%x", reg[0]);
        else {
	    unsigned int regs[2];

	    /* Things get more complicated on UPA. If upa-portid exists,
	       then address is @upa-portid,second-int-in-reg, otherwise
	       it is @first-int-in-reg/16,second-int-in-reg (well, probably
	       upa-portid always exists, but just to be safe). */
	    memcpy (regs, reg, sizeof(regs));
	    prop = prom_getproperty("upa-portid", &len);
	    if (prop && len == 4) {
		reg = (unsigned int *)prop;
		sprintf (regstr, "@%x,%x", reg[0], regs[1]); 
	    } else
	        sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]);
	}
        for (nextnode = prom_getchild(parent); nextnode; nextnode = prom_getsibling(nextnode)) {
	    prop = prom_getproperty("name", &len);
	    if (prop && len > 0 && !strcmp (path + 1, prop))
		cnt++;
	}
        if (cnt > 1)
	    strcat (path, regstr);
    }

    prom_walk_callback(node);

    nextnode = prom_getchild(node);
    if (nextnode)
        prom_walk(strchr (path, 0), node, nextnode, ntype);
    nextnode = prom_getsibling(node);
    if (nextnode)
        prom_walk(path, parent, nextnode, type);
}

static int
prom_init(int mode) {    
    struct utsname u;

    promfd = open(promdev, mode);
    if (promfd == -1)
	return -1;
    prom_root_node = prom_getsibling(0);
    if (!prom_root_node)
	return -1;

    if (!uname (&u) && !strcmp (u.machine, "sparc64"))
	p1275 = 1;
    return 0;
}

#define SDSK_TYPE_IDE	1
#define SDSK_TYPE_SD	2
#define SDSK_TYPE_PLN	3
#define SDSK_TYPE_FC	4

static struct sdsk_disk {
    unsigned int prom_node;
    unsigned int type, host, hi, mid, lo;
    unsigned char *prom_name;
} *hd = NULL, *sd = NULL;
static int hdlen, sdlen;

static void
scan_walk_callback(int node) {
    int nextnode;
    char *prop;
    int len, disk;
    static int v0ctrl = 0;

    for (disk = 0; disk < hdlen + sdlen; disk++) {
	if (hd[disk].prom_node == node) {
	    switch (hd[disk].type) {
	    case SDSK_TYPE_IDE:
		for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) {
		    prop = prom_getproperty("name", &len);
		    if (prop && len > 0 && (!strcmp (prop, "ata") || !strcmp (prop, "disk")))
			break;
		}
		if (!nextnode)
		    continue;
		if (prop[0] == 'a')
		    sprintf (prop, "/ata@%x,0/cmdk@%x,0", hd[disk].hi, hd[disk].lo);
		else
		    sprintf (prop, "/disk@%x,0", hd[disk].hi * 2 + hd[disk].lo);
		break;
	    case SDSK_TYPE_SD:
		for (nextnode = prom_getchild(node); nextnode; nextnode = prom_getsibling(nextnode)) {
		    prop = prom_getproperty("compatible", &len);
		    if (prop && len > 0 && !strcmp (prop, "sd"))
			break;
		    prop = prom_getproperty("name", &len);
		    if (prop && len > 0 && (!strcmp (prop, "sd") || !strcmp (prop, "disk")))
			break;
		}
		if (!nextnode || hd[disk].hi)
		    continue;
		if (promvers) {
		    char name[1024];
		    prop = prom_getproperty("name", &len);
		    if (prop && len > 0)
			strcpy (name, prop);
		    else
			strcpy (name, "sd");
		    if (!prop)
			prop = ((struct openpromio *)buf)->oprom_array;
		    sprintf (prop, "/%s@%x,%x", name, hd[disk].mid, hd[disk].lo);
		} else {
		    int i;
		    for (i = 0; sd_targets[i]; i++)
			if (sd_targets[i] == '0' + hd[disk].mid)
			    break;
		    if (!sd_targets[i])
			i = hd[disk].mid;
		    sprintf (prop, "sd(%d,%d,", v0ctrl, i);
		}
		break;
	    case SDSK_TYPE_PLN:
		prop = ((struct openpromio *)buf)->oprom_array;
		sprintf (prop, "/SUNW,pln@%x,%x/SUNW,ssd@%x,%x",
			 hd[disk].lo & 0xf0000000, hd[disk].lo & 0xffffff,
			 hd[disk].hi, hd[disk].mid);
		break;
	    case SDSK_TYPE_FC:
		prop = ((struct openpromio *)buf)->oprom_array;
		sprintf (prop, "/sf@0,0/ssd@w%08x%08x,%x", hd[disk].hi, hd[disk].mid, hd[disk].lo);
		break;
	    default:
		continue;
	    }
	    hd[disk].prom_name = malloc (strlen (prom_path) + strlen(prop) + 3);
	    if (!hd[disk].prom_name)
		continue;
	    if (promvers)
		strcpy (hd[disk].prom_name, prom_path);
	    else
		hd[disk].prom_name[0] = '\0';
	    strcat (hd[disk].prom_name, prop);
	}
    }
    v0ctrl++;
}

static int
scan_ide(void) {
    DIR * dir;
    char path[80];
    char buffer[512];
    int fd, i, disk;
    struct dirent * ent;
    int pci_bus, pci_devfn;

    if (access("/proc/ide", R_OK)) return 0;

    if (!(dir = opendir("/proc/ide"))) {
	return 1;
    }

    while ((ent = readdir(dir))) {
	if (ent->d_name[0] == 'h' && ent->d_name[1] == 'd' &&
	    ent->d_name[2] >= 'a' && ent->d_name[2] <= 'z' &&
	    ent->d_name[3] == '\0') {
	    disk = ent->d_name[2] - 'a';
	    if (disk >= hdlen) {
		hd = (struct sdsk_disk *)realloc(hd, ((disk&~3)+4)*sizeof(struct sdsk_disk));
		memset (hd + hdlen, 0, ((disk&~3)+4-hdlen)*sizeof(struct sdsk_disk));
		hdlen = (disk&~3)+4;
	    }
	    for (i = (disk & ~3); i <= (disk | 3); i++) {
		if (hd[i].type)
		    break;
	    }
	    if (i > (disk | 3)) {
		sprintf(path, "/proc/ide/%s", ent->d_name);
		if (readlink(path, buffer, 512) < 5)
		    continue;
		if (strncmp(buffer, "ide", 3) ||
		    !isdigit(buffer[3]) ||
		    buffer[4] != '/')
		    continue;
		buffer[4] = 0;
		sprintf(path, "/proc/ide/%s/config", buffer);
		if ((fd = open(path, O_RDONLY)) < 0)
		    continue;
		i = read(fd, buffer, 50);
		close(fd);
		if (i < 50) continue;
		if (sscanf (buffer, "pci bus %x device %x ",
			    &pci_bus, &pci_devfn) != 2)
			continue;
		hd[disk].prom_node = prom_pci2node (pci_bus, pci_devfn);
	    } else
	    	hd[disk].prom_node = hd[i].prom_node;
	    hd[disk].type = SDSK_TYPE_IDE;
	    hd[disk].hi = (disk & 2) >> 1;
	    hd[disk].lo = (disk & 1);
	}
    }

    closedir(dir);

    return 0;
}

static int
scan_scsi(void) {
    FILE *f;
    DIR * dir, *dirhba;
    struct dirent * ent, *enthba;
    struct stat st;
    char * p, * q;
    char buf[512];
    char path[128];
    int disk = 0;
    int host, channel, id, lun;
    int prom_node, pci_bus, pci_devfn;

    if (access("/proc/scsi/scsi", R_OK)) {
	return 0;
    }

    f = fopen("/proc/scsi/scsi", "r");
    if (f == NULL) return 1;

    if (fgets(buf, sizeof(buf), f) == NULL) {
	fclose(f);
	return 1;
    }
    if (!strcmp(buf, "Attached devices: none\n")) {
	fclose(f);
	return 0;
    }

    while (fgets(buf, sizeof(buf), f) != NULL) {
	if (sscanf(buf, "Host: scsi%d Channel: %d Id: %d Lun: %d\n",
		   &host, &channel, &id, &lun) != 4)
	    break;
	if (fgets(buf, sizeof(buf), f) == NULL)
	    break;
	if (strncmp(buf, "  Vendor:", 9))
	    break;
	if (fgets(buf, sizeof(buf), f) == NULL)
	    break;
	if (strncmp(buf, "  Type:   ", 10))
	    break;
	if (!strncmp(buf+10, "Direct-Access", 13)) {
	    if (disk >= sdlen) {
		hd = (struct sdsk_disk *)
		     realloc(hd, (hdlen+(disk&~3)+4)*sizeof(struct sdsk_disk));
		sd = hd + hdlen;
		memset (sd + sdlen, 0,
			((disk&~3)+4-sdlen)*sizeof(struct sdsk_disk));
		sdlen = (disk&~3)+4;
	    }
	    sd[disk].type = SDSK_TYPE_SD;
	    sd[disk].host = host;
	    sd[disk].hi = channel;
	    sd[disk].mid = id;
	    sd[disk].lo = lun;
	    disk++;
	}
    }
    fclose (f);

    if (!(dir = opendir("/proc/scsi"))) {
	if (!hdlen && hd) {
	    free(hd);
	    hd = NULL;
	}
	sd = NULL;
	sdlen = 0;
	return 1;
    }

    while ((ent = readdir(dir))) {
	if (!strcmp (ent->d_name, "scsi") || ent->d_name[0] == '.')
	    continue;
	sprintf (path, "/proc/scsi/%s", ent->d_name);
	if (stat (path, &st) < 0 || !S_ISDIR (st.st_mode))
	    continue;
	if (!(dirhba = opendir(path)))
	    continue;

	while ((enthba = readdir(dirhba))) {
	    if (enthba->d_name[0] == '.')
		continue;
	    host = atoi(enthba->d_name);
	    sprintf (path, "/proc/scsi/%s/%s", ent->d_name, enthba->d_name);
	    f = fopen (path, "r");
	    if (f == NULL) continue;

	    if (!strcmp (ent->d_name, "esp") ||
		!strcmp (ent->d_name, "qlogicpti") ||
		!strcmp (ent->d_name, "fcal"))
		p = "PROM node";
	    else if (!strcmp (ent->d_name, "pluto"))
		p = "serial ";
	    else
		p = "PCI bus";
	    while (fgets (buf, sizeof(buf), f) != NULL) {
		q = strstr (buf, p);
		if (q == NULL) continue;
		prom_node = 0;
		switch (p[1]) {
		case 'R':
		    if (sscanf (q, "PROM node %x", &prom_node) == 1)
			q = NULL;
		    break;
		case 'e':
		    if (sscanf (q, "serial 000000%x %*dx%*d on soc%*d port %x PROM node %x",
				&id, &lun, &prom_node) == 3 &&
			lun >= 10 && lun <= 11) {
			q = NULL;
		    }
		    break;
		case 'C':
		    if (sscanf (q, "PCI bus %x device %x", &pci_bus, &pci_devfn) == 2) {
			q = NULL;
			prom_node = prom_pci2node (pci_bus, pci_devfn);
		    }
		    break;
		}
		if (q == NULL) {
		    for (disk = 0; disk < sdlen; disk++)
			if (sd[disk].host == host && sd[disk].type) {
			    sd[disk].prom_node = prom_node;
			    if (p[1] == 'e') {
				sd[disk].type = SDSK_TYPE_PLN;
				sd[disk].lo = (lun << 28) | id;
			    } else if (!strcmp (ent->d_name, "fcal"))
				sd[disk].type = SDSK_TYPE_FC;
			}
		}
	    }
	    if (!strcmp (ent->d_name, "fcal")) {
		while (fgets (buf, sizeof(buf), f) != NULL) {
		    unsigned long long ll;
		    if (sscanf (buf, " [AL-PA: %*x, Id: %d, Port WWN: %Lx, Node WWN: ", &id, &ll) == 2) {
			for (disk = 0; disk < sdlen; disk++)
			if (sd[disk].host == host && sd[disk].mid == id) {
			    sd[disk].hi = ll >> 32;
			    sd[disk].mid = ll;
			}
		    }
		}
	    }
	    fclose(f);
	}
	closedir(dirhba);
    }
    closedir(dir);
    return 0;
}

static int get_prom_ver(void)
{
    FILE *f = fopen ("/proc/cpuinfo","r");
    int ver = 0;
    char buffer[1024];
    char *p;
                    
    if (f) {
	while (fgets (buffer, 1024, f)) {
	    if (!strncmp (buffer, "promlib", 7)) {
		p = strstr (buffer, "Version ");
		if (p) {
		    p += 8;
		    if (*p == '0' || (*p >= '2' && *p <= '3')) {
			ver = *p - '0';
		    }
		}
		break;
	    }
	}
	fclose(f);
    }
    if (!ver) {
	int len;
        p = prom_getopt("sd-targets", &len);
        if (p && len > 0 && len <= 8)
	    strcpy(sd_targets, p);
    }
    return ver;
}

static void check_aliases(void) {
    int nextnode, len;
    char *prop;
    hasaliases = 0;
    for (nextnode = prom_getchild(prom_root_node); nextnode; nextnode = prom_getsibling(nextnode)) {
	prop = prom_getproperty("name", &len);
	if (prop && len > 0 && !strcmp (prop, "aliases"))
	    hasaliases = 1;
    }
}

char *prom_root_name = NULL;

static void get_root_name(void) {
    int len;
    char *prop;
    
    prom_getsibling(0);
    prop = prom_getproperty("name", &len);
    if (prop && len > 0)
	prom_root_name = strdup(prop);
}

int init_sbusdisk(void) {
    if (prom_init(O_RDONLY))
	return -1;
    promvers = get_prom_ver();
    check_aliases();
    get_root_name();
    scan_ide();
    scan_scsi();
    prom_walk_callback = scan_walk_callback;
    prom_walk(prom_path, prom_root_node, prom_getchild (prom_root_node), 0);
    close(promfd);
    return 0;
}

void set_prom_vars(char *linuxAlias, char *bootDevice) {
    int len;
    int aliasDone = 0;
    if (prom_init(O_RDWR))
	return;
    if (linuxAlias && hasaliases) {
	char *use_nvramrc;
	char nvramrc[2048];
	char *p, *q, *r, *s;
	int enabled = -1;
	int count;

	use_nvramrc = prom_getopt ("use-nvramrc?", &len);
	if (len > 0) {
	    if (!strcasecmp (use_nvramrc, "false"))
		enabled = 0;
	    else if (!strcasecmp (use_nvramrc, "true"))
		enabled = 1;
	}
	if (enabled != -1) {
	    p = prom_getopt ("nvramrc", &len);
	    if (p) {
		memcpy (nvramrc, p, len);
		nvramrc [len] = 0;
		q = nvramrc;
		for (;;) {
		    /* If there is already `devalias linux /some/ugly/prom/path'
		       make sure we fully understand that and remove it. */
		    if (!strncmp (q, "devalias", 8) && (q[8] == ' ' || q[8] == '\t')) {
			for (r = q + 9; *r == ' ' || *r == '\t'; r++);
			if (!strncmp (r, "linux", 5)) {
			    for (s = r + 5; *s && *s != ' ' && *s != '\t'; s++);
			    if (!*s) break;
			    if (s == r + 5 ||
				(r[5] == '#' && r[6] >= '0' && r[6] <= '9' &&
				 (s == r + 7 ||
				  (r[7] >= '0' && r[7] <= '9' && s == r + 8)))) {
				for (r = s + 1; *r == ' ' || *r == '\t'; r++);
				for (; *r && *r != ' ' && *r != '\t' && *r != '\n'; r++);
				for (; *r == ' ' || *r == '\t'; r++);
				if (*r == '\n') {
				    r++;
				    memmove (q, r, strlen(r) + 1);
				    continue;
				}
			    }
			}
		    }
		    q = strchr (q, '\n');
		    if (!q) break;
		    q++;
		}
		len = strlen (nvramrc);
		if (len && nvramrc [len-1] != '\n')
		    nvramrc [len++] = '\n';
		p = nvramrc + len;
		p = stpcpy (p, "devalias linux ");
		r = linuxAlias;
		q = strchr (r, ';');
		count = 1;
		while (q) {
		    memcpy (p, r, q - r);
		    p += q - r;
		    sprintf (p, "\ndevalias linux#%d ", count++);
		    p = strchr (p, 0);
		    r = q + 1;
		    q = strchr (r, ';');
		}
		p = stpcpy (p, r);
		*p++ = '\n';
		*p = 0;
		prom_setopt ("nvramrc", nvramrc);
		if (!enabled)
		    prom_setopt ("use-nvramrc?", "true");
		aliasDone = 1;
	    }
	}
    }
    if (bootDevice) {
	char *p;
	if (aliasDone)
	    bootDevice = "linux";
	p = prom_getopt ("boot-device", &len);
	if (p) {
	    prom_setopt ("boot-device", bootDevice);
	    prom_setopt ("boot-file", "");
	} else {
	    p = prom_getopt ("boot-from", &len);
	    if (p)
		prom_setopt ("boot-from", bootDevice);
	}
    }
    close(promfd);
}

#ifdef STANDALONE_SILO

int main(void) {
    int i;

    init_sbusdisk();
    set_prom_vars ("/sbus@1f,0/espdma/esp/sd@1,0:c;/sbus@1f,0/espdma/esp/sd@1,0:g;/sbus@1f,0/espdma/esp/sd@1,0:h", "linux");
    printf ("prom root name `%s'\n", prom_root_name);
    for (i = 0; i < hdlen; i++) {
	if (hd[i].type)
		printf ("hd%c %x %d %d %d\n", i + 'a', hd[i].prom_node,
						    hd[i].hi, hd[i].mid, hd[i].lo);
	if (hd[i].prom_name) printf ("%s\n", hd[i].prom_name);
    }
    for (i = 0; i < sdlen; i++) {
	if (sd[i].type) {
	    if (i < 26)
		printf ("sd%c %x %d %d %d\n", i + 'a', sd[i].prom_node,
						    sd[i].hi, sd[i].mid, sd[i].lo);
	    else
		printf ("sd%c%c %x %d %d %d\n", (i / 26) + 'a' - 1, (i % 26) + 'a', sd[i].prom_node,
						    sd[i].hi, sd[i].mid, sd[i].lo);
	}
	if (sd[i].prom_name) printf ("%s\n", sd[i].prom_name);
    }
    exit(0);
}

#else

void
initSilo ()
{
    return init_sbusdisk();
}

char *
disk2PromPath (unsigned char *disk)
{
    static unsigned char prompath[1024];
    int diskno = -1, part;

    if (disk[0] == 'h' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') {
	diskno = disk[2] - 'a';
	disk += 3;
    } else if (disk[0] == 's' && disk[1] == 'd' && disk[2] >= 'a' && disk[2] <= 'z') {
	if (disk[3] >= 'a' && disk[3] <= 'z') {
	    diskno = (disk[2] - 'a' + 1) * 26 + (disk[3] - 'a');
	    disk += 4;
	} else {
	    diskno = disk[2] - 'a';
	    disk += 3;
	}
	if (diskno >= 128)
	    diskno = -1;
	else
	    diskno += hdlen;
    }
    if (diskno == -1)
	part = -1;
    else if (!disk[0])
	part = 3;
    else {
	part = atoi (disk);
	if (part <= 0 || part > 8) part = -1;
    }
    if (diskno < 0 || part == -1 ||
	diskno >= hdlen + sdlen || !hd[diskno].prom_name) {
	return NULL;
    }
    if (!promvers)
	sprintf (prompath, "%s%d)", hd[diskno].prom_name, part ? part - 1 : 2);
    else {
	if (part)
	    sprintf (prompath, "%s:%c", hd[diskno].prom_name, part + 'a' - 1);
	else
	    strcpy (prompath, hd[diskno].prom_name);
    }
    return prompath;
}

int
hasAliases (void)
{
    return hasaliases;
}

char *
promRootName (void)
{
    return prom_root_name ? prom_root_name : "";
}

void
setPromVars (char *linuxAlias, char *bootDevice)
{
    if (linuxAlias && !*linuxAlias) linuxAlias = NULL;
    if (bootDevice && !*bootDevice) bootDevice = NULL;
    set_prom_vars (linuxAlias, bootDevice);
}

#endif

#else
void initSilo() {}
char *disk2PromPath(unsigned char *disk) { return 0; /* NULL */ }
int hasAliases(void) { return 0; }
char *promRootName(void) { return 0; /* NULL */ }
void setPromVars(char *linuxAlias, char *bootDevice) {}
#endif /* __sparc__ */
a>
<a id='n429' href='#n429'>429</a>
<a id='n430' href='#n430'>430</a>
<a id='n431' href='#n431'>431</a>
<a id='n432' href='#n432'>432</a>
<a id='n433' href='#n433'>433</a>
<a id='n434' href='#n434'>434</a>
<a id='n435' href='#n435'>435</a>
<a id='n436' href='#n436'>436</a>
<a id='n437' href='#n437'>437</a>
<a id='n438' href='#n438'>438</a>
<a id='n439' href='#n439'>439</a>
<a id='n440' href='#n440'>440</a>
<a id='n441' href='#n441'>441</a>
<a id='n442' href='#n442'>442</a>
<a id='n443' href='#n443'>443</a>
<a id='n444' href='#n444'>444</a>
<a id='n445' href='#n445'>445</a>
<a id='n446' href='#n446'>446</a>
<a id='n447' href='#n447'>447</a>
<a id='n448' href='#n448'>448</a>
<a id='n449' href='#n449'>449</a>
<a id='n450' href='#n450'>450</a>
<a id='n451' href='#n451'>451</a>
<a id='n452' href='#n452'>452</a>
<a id='n453' href='#n453'>453</a>
<a id='n454' href='#n454'>454</a>
<a id='n455' href='#n455'>455</a>
<a id='n456' href='#n456'>456</a>
<a id='n457' href='#n457'>457</a>
<a id='n458' href='#n458'>458</a>
<a id='n459' href='#n459'>459</a>
<a id='n460' href='#n460'>460</a>
<a id='n461' href='#n461'>461</a>
<a id='n462' href='#n462'>462</a>
<a id='n463' href='#n463'>463</a>
<a id='n464' href='#n464'>464</a>
<a id='n465' href='#n465'>465</a>
<a id='n466' href='#n466'>466</a>
<a id='n467' href='#n467'>467</a>
<a id='n468' href='#n468'>468</a>
<a id='n469' href='#n469'>469</a>
<a id='n470' href='#n470'>470</a>
<a id='n471' href='#n471'>471</a>
<a id='n472' href='#n472'>472</a>
<a id='n473' href='#n473'>473</a>
<a id='n474' href='#n474'>474</a>
<a id='n475' href='#n475'>475</a>
<a id='n476' href='#n476'>476</a>
<a id='n477' href='#n477'>477</a>
<a id='n478' href='#n478'>478</a>
<a id='n479' href='#n479'>479</a>
<a id='n480' href='#n480'>480</a>
<a id='n481' href='#n481'>481</a>
<a id='n482' href='#n482'>482</a>
<a id='n483' href='#n483'>483</a>
<a id='n484' href='#n484'>484</a>
<a id='n485' href='#n485'>485</a>
<a id='n486' href='#n486'>486</a>
<a id='n487' href='#n487'>487</a>
<a id='n488' href='#n488'>488</a>
<a id='n489' href='#n489'>489</a>
<a id='n490' href='#n490'>490</a>
<a id='n491' href='#n491'>491</a>
<a id='n492' href='#n492'>492</a>
<a id='n493' href='#n493'>493</a>
<a id='n494' href='#n494'>494</a>
<a id='n495' href='#n495'>495</a>
<a id='n496' href='#n496'>496</a>
<a id='n497' href='#n497'>497</a>
<a id='n498' href='#n498'>498</a>
<a id='n499' href='#n499'>499</a>
<a id='n500' href='#n500'>500</a>
<a id='n501' href='#n501'>501</a>
<a id='n502' href='#n502'>502</a>
<a id='n503' href='#n503'>503</a>
<a id='n504' href='#n504'>504</a>
<a id='n505' href='#n505'>505</a>
<a id='n506' href='#n506'>506</a>
<a id='n507' href='#n507'>507</a>
<a id='n508' href='#n508'>508</a>
<a id='n509' href='#n509'>509</a>
<a id='n510' href='#n510'>510</a>
<a id='n511' href='#n511'>511</a>
<a id='n512' href='#n512'>512</a>
<a id='n513' href='#n513'>513</a>
<a id='n514' href='#n514'>514</a>
<a id='n515' href='#n515'>515</a>
<a id='n516' href='#n516'>516</a>
<a id='n517' href='#n517'>517</a>
<a id='n518' href='#n518'>518</a>
<a id='n519' href='#n519'>519</a>
<a id='n520' href='#n520'>520</a>
<a id='n521' href='#n521'>521</a>
<a id='n522' href='#n522'>522</a>
<a id='n523' href='#n523'>523</a>
<a id='n524' href='#n524'>524</a>
<a id='n525' href='#n525'>525</a>
<a id='n526' href='#n526'>526</a>
<a id='n527' href='#n527'>527</a>
<a id='n528' href='#n528'>528</a>
<a id='n529' href='#n529'>529</a>
<a id='n530' href='#n530'>530</a>
<a id='n531' href='#n531'>531</a>
<a id='n532' href='#n532'>532</a>
<a id='n533' href='#n533'>533</a>
<a id='n534' href='#n534'>534</a>
<a id='n535' href='#n535'>535</a>
<a id='n536' href='#n536'>536</a>
<a id='n537' href='#n537'>537</a>
<a id='n538' href='#n538'>538</a>
<a id='n539' href='#n539'>539</a>
<a id='n540' href='#n540'>540</a>
<a id='n541' href='#n541'>541</a>
<a id='n542' href='#n542'>542</a>
<a id='n543' href='#n543'>543</a>
<a id='n544' href='#n544'>544</a>
<a id='n545' href='#n545'>545</a>
<a id='n546' href='#n546'>546</a>
<a id='n547' href='#n547'>547</a>
<a id='n548' href='#n548'>548</a>
<a id='n549' href='#n549'>549</a>
<a id='n550' href='#n550'>550</a>
<a id='n551' href='#n551'>551</a>
<a id='n552' href='#n552'>552</a>
<a id='n553' href='#n553'>553</a>
<a id='n554' href='#n554'>554</a>
<a id='n555' href='#n555'>555</a>
<a id='n556' href='#n556'>556</a>
<a id='n557' href='#n557'>557</a>
<a id='n558' href='#n558'>558</a>
<a id='n559' href='#n559'>559</a>
<a id='n560' href='#n560'>560</a>
<a id='n561' href='#n561'>561</a>
<a id='n562' href='#n562'>562</a>
<a id='n563' href='#n563'>563</a>
<a id='n564' href='#n564'>564</a>
<a id='n565' href='#n565'>565</a>
<a id='n566' href='#n566'>566</a>
<a id='n567' href='#n567'>567</a>
<a id='n568' href='#n568'>568</a>
<a id='n569' href='#n569'>569</a>
<a id='n570' href='#n570'>570</a>
<a id='n571' href='#n571'>571</a>
<a id='n572' href='#n572'>572</a>
<a id='n573' href='#n573'>573</a>
<a id='n574' href='#n574'>574</a>
<a id='n575' href='#n575'>575</a>
<a id='n576' href='#n576'>576</a>
<a id='n577' href='#n577'>577</a>
<a id='n578' href='#n578'>578</a>
<a id='n579' href='#n579'>579</a>
<a id='n580' href='#n580'>580</a>
<a id='n581' href='#n581'>581</a>
<a id='n582' href='#n582'>582</a>
<a id='n583' href='#n583'>583</a>
<a id='n584' href='#n584'>584</a>
<a id='n585' href='#n585'>585</a>
<a id='n586' href='#n586'>586</a>
<a id='n587' href='#n587'>587</a>
<a id='n588' href='#n588'>588</a>
<a id='n589' href='#n589'>589</a>
<a id='n590' href='#n590'>590</a>
<a id='n591' href='#n591'>591</a>
<a id='n592' href='#n592'>592</a>
<a id='n593' href='#n593'>593</a>
<a id='n594' href='#n594'>594</a>
<a id='n595' href='#n595'>595</a>
<a id='n596' href='#n596'>596</a>
<a id='n597' href='#n597'>597</a>
<a id='n598' href='#n598'>598</a>
<a id='n599' href='#n599'>599</a>
<a id='n600' href='#n600'>600</a>
<a id='n601' href='#n601'>601</a>
<a id='n602' href='#n602'>602</a>
<a id='n603' href='#n603'>603</a>
<a id='n604' href='#n604'>604</a>
<a id='n605' href='#n605'>605</a>
<a id='n606' href='#n606'>606</a>
<a id='n607' href='#n607'>607</a>
<a id='n608' href='#n608'>608</a>
<a id='n609' href='#n609'>609</a>
<a id='n610' href='#n610'>610</a>
<a id='n611' href='#n611'>611</a>
<a id='n612' href='#n612'>612</a>
<a id='n613' href='#n613'>613</a>
<a id='n614' href='#n614'>614</a>
<a id='n615' href='#n615'>615</a>
<a id='n616' href='#n616'>616</a>
<a id='n617' href='#n617'>617</a>
<a id='n618' href='#n618'>618</a>
<a id='n619' href='#n619'>619</a>
<a id='n620' href='#n620'>620</a>
<a id='n621' href='#n621'>621</a>
<a id='n622' href='#n622'>622</a>
<a id='n623' href='#n623'>623</a>
<a id='n624' href='#n624'>624</a>
<a id='n625' href='#n625'>625</a>
<a id='n626' href='#n626'>626</a>
<a id='n627' href='#n627'>627</a>
<a id='n628' href='#n628'>628</a>
<a id='n629' href='#n629'>629</a>
<a id='n630' href='#n630'>630</a>
<a id='n631' href='#n631'>631</a>
<a id='n632' href='#n632'>632</a>
<a id='n633' href='#n633'>633</a>
<a id='n634' href='#n634'>634</a>
<a id='n635' href='#n635'>635</a>
<a id='n636' href='#n636'>636</a>
<a id='n637' href='#n637'>637</a>
<a id='n638' href='#n638'>638</a>
<a id='n639' href='#n639'>639</a>
<a id='n640' href='#n640'>640</a>
<a id='n641' href='#n641'>641</a>
<a id='n642' href='#n642'>642</a>
</pre></td>
<td class='lines'><pre><code>
<span class="hl kwa">package</span> install_steps_gtk<span class="hl opt">;</span> <span class="hl slc"># $Id$</span>

<span class="hl kwa">use</span> diagnostics<span class="hl opt">;</span>
<span class="hl kwa">use</span> strict<span class="hl opt">;</span>
<span class="hl kwa">use</span> vars <span class="hl str">qw(</span><span class="hl ipl">&#64;ISA</span><span class="hl str">)</span><span class="hl opt">;</span>

<span class="hl kwb">&#64;ISA</span> <span class="hl opt">=</span> <span class="hl str">qw(install_steps_interactive interactive_gtk)</span><span class="hl opt">;</span>

<span class="hl slc">#-######################################################################################</span>
<span class="hl slc">#- misc imports</span>
<span class="hl slc">#-######################################################################################</span>
<span class="hl kwa">use</span> install_steps_interactive<span class="hl opt">;</span>
<span class="hl kwa">use</span> interactive_gtk<span class="hl opt">;</span>
<span class="hl kwa">use</span> common <span class="hl str">qw(:common :file :functional :system)</span><span class="hl opt">;</span>
<span class="hl kwa">use</span> my_gtk <span class="hl str">qw(:helpers :wrappers)</span><span class="hl opt">;</span>
<span class="hl kwa">use</span> Gtk<span class="hl opt">;</span>
<span class="hl kwa">use</span> devices<span class="hl opt">;</span>
<span class="hl kwa">use</span> modules<span class="hl opt">;</span>
<span class="hl kwa">use</span> install_gtk<span class="hl opt">;</span>
<span class="hl kwa">use</span> install_any<span class="hl opt">;</span>
<span class="hl kwa">use</span> mouse<span class="hl opt">;</span>
<span class="hl kwa">use</span> help<span class="hl opt">;</span>
<span class="hl kwa">use</span> <span class="hl kwc">log</span><span class="hl opt">;</span>

<span class="hl slc">#-######################################################################################</span>
<span class="hl slc">#- In/Out Steps Functions</span>
<span class="hl slc">#-######################################################################################</span>
<span class="hl kwa">sub</span> new<span class="hl opt">(</span><span class="hl kwb">$$</span><span class="hl opt">) {</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$type, $o</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$old</span> <span class="hl opt">=</span> <span class="hl kwb">$SIG</span><span class="hl opt">{</span>__DIE__<span class="hl opt">};</span>
    <span class="hl kwb">$SIG</span><span class="hl opt">{</span>__DIE__<span class="hl opt">} =</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">] !~</span> <span class="hl kwd">/my_gtk\.pm/</span> <span class="hl kwc">and</span> <span class="hl kwa">goto</span> <span class="hl kwb">$old</span> <span class="hl opt">};</span>

    <span class="hl kwb">$ENV</span><span class="hl opt">{</span>DISPLAY<span class="hl opt">} ||=</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>display<span class="hl opt">} ||</span> <span class="hl str">&quot;:0&quot;</span><span class="hl opt">;</span>
    <span class="hl kwa">unless</span> <span class="hl opt">($::</span>testing<span class="hl opt">) {</span>
	<span class="hl kwb">$my_gtk</span><span class="hl opt">::</span>force_focus <span class="hl opt">=</span> <span class="hl kwb">$ENV</span><span class="hl opt">{</span>DISPLAY<span class="hl opt">}</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;:0&quot;</span><span class="hl opt">;</span>

	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">$ENV</span><span class="hl opt">{</span>DISPLAY<span class="hl opt">}</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;:0&quot;</span> <span class="hl opt">&amp;&amp; !$::</span>live<span class="hl opt">) {</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$f</span> <span class="hl opt">=</span> <span class="hl str">&quot;/tmp/Xconf&quot;</span><span class="hl opt">;</span>
	    install_gtk<span class="hl opt">::</span>createXconf<span class="hl opt">(</span><span class="hl kwb">$f,</span> <span class="hl opt">&#64;{</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>mouse<span class="hl opt">}}{</span><span class="hl str">&quot;XMOUSETYPE&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;device&quot;</span><span class="hl opt">},</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>wacom<span class="hl opt">});</span>
	    devices<span class="hl opt">::</span>make<span class="hl opt">(</span><span class="hl str">&quot;/dev/kbd&quot;</span><span class="hl opt">);</span>

	    <span class="hl kwc">local</span> <span class="hl opt">(*</span>T1<span class="hl opt">, *</span>T2<span class="hl opt">);</span>
	    <span class="hl kwc">open</span> T1<span class="hl opt">,</span> <span class="hl str">&quot;&gt;/dev/tty5&quot;</span><span class="hl opt">;</span>
	    <span class="hl kwc">open</span> T2<span class="hl opt">,</span> <span class="hl str">&quot;&gt;/dev/tty6&quot;</span><span class="hl opt">;</span>

	    <span class="hl kwc">my</span> <span class="hl kwb">$launchX</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$ok</span> <span class="hl opt">=</span> <span class="hl num">1</span><span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$xpmac_opts</span> <span class="hl opt">=</span> cat_<span class="hl opt">(</span><span class="hl str">&quot;/proc/cmdline&quot;</span><span class="hl opt">);</span>        		
		<span class="hl kwc">local</span> <span class="hl kwb">$SIG</span><span class="hl opt">{</span>CHLD<span class="hl opt">} =</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$ok</span> <span class="hl opt">=</span> <span class="hl num">0</span> <span class="hl kwa">if</span> <span class="hl kwc">waitpid</span><span class="hl opt">(-</span><span class="hl num">1</span><span class="hl opt">,</span> c<span class="hl opt">::</span>WNOHANG<span class="hl opt">()) &gt;</span> <span class="hl num">0</span> <span class="hl opt">};</span>
		<span class="hl kwa">unless</span> <span class="hl opt">(</span><span class="hl kwc">fork</span><span class="hl opt">) {</span>
		    <span class="hl kwc">exec</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">], (</span>arch<span class="hl opt">() =~</span> <span class="hl kwd">/^sparc/</span> <span class="hl opt">||</span> arch<span class="hl opt">()</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;ppc&quot;</span> ? <span class="hl opt">() : (</span><span class="hl str">&quot;-kb&quot;</span><span class="hl opt">)),</span> <span class="hl str">&quot;-dpms&quot;</span><span class="hl opt">,</span><span class="hl str">&quot;-s&quot;</span> <span class="hl opt">,</span><span class="hl str">&quot;240&quot;</span><span class="hl opt">,</span>
		      <span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">] =~</span> <span class="hl kwd">/Xpmac/</span> ? <span class="hl kwb">$xpmac_opts</span> <span class="hl opt">!~</span> <span class="hl kwd">/ofonly/</span> ? <span class="hl opt">(</span><span class="hl str">&quot;-mode&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;17&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;-depth&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;32&quot;</span><span class="hl opt">) : (</span><span class="hl str">&quot;-mach64&quot;</span><span class="hl opt">):()),</span>
		      <span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">] =~</span> <span class="hl kwd">/Xsun/</span> <span class="hl opt">||</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">] =~</span> <span class="hl kwd">/Xpmac/</span> ? <span class="hl opt">(</span><span class="hl str">&quot;-fp&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;/usr/X11R6/lib/X11/fonts:unscaled&quot;</span><span class="hl opt">) :</span>
		       <span class="hl opt">(</span><span class="hl str">&quot;-allowMouseOpenFail&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;-xf86config&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$f</span><span class="hl opt">))</span> <span class="hl kwc">or</span> <span class="hl kwa">exit</span> <span class="hl num">1</span><span class="hl opt">;</span>
		<span class="hl opt">}</span>
		<span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl num">1</span><span class="hl opt">.</span><span class="hl num">.60</span><span class="hl opt">) {</span>
		    <span class="hl kwc">sleep</span> <span class="hl num">1</span><span class="hl opt">;</span>
		    <span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;Server died&quot;</span><span class="hl opt">),</span> <span class="hl kwa">return</span> <span class="hl num">0</span> <span class="hl kwa">if</span> <span class="hl opt">!</span><span class="hl kwb">$ok</span><span class="hl opt">;</span>
		    <span class="hl kwa">return</span> <span class="hl num">1</span> <span class="hl kwa">if</span> c<span class="hl opt">::</span>Xtest<span class="hl opt">(</span><span class="hl kwb">$ENV</span><span class="hl opt">{</span>DISPLAY<span class="hl opt">});</span>
		<span class="hl opt">}</span>
		<span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;Timeout!!&quot;</span><span class="hl opt">);</span>
		<span class="hl num">0</span><span class="hl opt">;</span>
	    <span class="hl opt">};</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl str">qw(FBDev VGA16)</span><span class="hl opt">;</span> <span class="hl slc">#-)</span>
	    <span class="hl kwa">if</span> <span class="hl opt">(</span>arch<span class="hl opt">()</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;alpha&quot;</span><span class="hl opt">) {</span>
		<span class="hl kwa">require</span> Xconfigurator<span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$card</span> <span class="hl opt">=</span> Xconfigurator<span class="hl opt">::</span>cardConfigurationAuto<span class="hl opt">();</span>
		Xconfigurator<span class="hl opt">::</span>updateCardAccordingName<span class="hl opt">(</span><span class="hl kwb">$card, $card</span><span class="hl opt">-&gt;{</span>type<span class="hl opt">})</span> <span class="hl kwa">if</span> <span class="hl kwb">$card</span> <span class="hl opt">&amp;&amp;</span> <span class="hl kwb">$card</span><span class="hl opt">-&gt;{</span>type<span class="hl opt">};</span>
		<span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl kwb">$card</span><span class="hl opt">-&gt;{</span>server<span class="hl opt">} ||</span> <span class="hl str">&quot;TGA&quot;</span><span class="hl opt">;</span>
		<span class="hl slc">#-&#64;servers = qw(SVGA 3DLabs TGA) </span>
	    <span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span>arch<span class="hl opt">() =~</span> <span class="hl kwd">/^sparc/</span><span class="hl opt">) {</span>
		<span class="hl kwc">local</span> <span class="hl kwb">$_</span> <span class="hl opt">=</span> cat_<span class="hl opt">(</span><span class="hl str">&quot;/proc/fb&quot;</span><span class="hl opt">);</span>
		<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwd">/Mach64/</span><span class="hl opt">) {</span> <span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl str">qw(Mach64)</span> <span class="hl opt">}</span>
		<span class="hl kwa">elsif</span> <span class="hl opt">(</span><span class="hl kwd">/Permedia2/</span><span class="hl opt">) {</span> <span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl str">qw(3DLabs)</span> <span class="hl opt">}</span>
		<span class="hl kwa">else</span> <span class="hl opt">{</span> <span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl str">qw(Xsun24)</span> <span class="hl opt">}</span>
	    <span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span>arch<span class="hl opt">()</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;ppc&quot;</span><span class="hl opt">) {</span>
	    	<span class="hl kwb">&#64;servers</span> <span class="hl opt">=</span> <span class="hl str">qw(Xpmac)</span><span class="hl opt">;</span>
            <span class="hl opt">}</span>

	    <span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl kwb">&#64;servers</span><span class="hl opt">) {</span>
		<span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;Trying with server</span> <span class="hl ipl">$_</span><span class="hl str">&quot;</span><span class="hl opt">);</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$dir</span> <span class="hl opt">=</span> <span class="hl str">&quot;/usr/X11R6/bin&quot;</span><span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$prog</span> <span class="hl opt">=</span> <span class="hl kwd">/Xsun|Xpmac/</span> ? <span class="hl kwb">$_</span> <span class="hl opt">:</span> <span class="hl str">&quot;XF86_</span><span class="hl ipl">$_</span><span class="hl str">&quot;</span><span class="hl opt">;</span>
		<span class="hl kwa">unless</span> <span class="hl opt">(-</span>x <span class="hl str">&quot;</span><span class="hl ipl">$dir/$prog</span><span class="hl str">&quot;</span><span class="hl opt">) {</span>
		    <span class="hl kwc">unlink</span> <span class="hl kwb">$_</span> <span class="hl kwa">foreach</span> glob_<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$dir/X*</span><span class="hl str">&quot;</span><span class="hl opt">);</span>
		    install_any<span class="hl opt">::</span>getAndSaveFile<span class="hl opt">(</span><span class="hl str">&quot;Mandrake/mdkinst</span><span class="hl ipl">$dir/$prog</span><span class="hl str">&quot;</span><span class="hl opt">,</span> <span class="hl str">&quot;</span><span class="hl ipl">$dir/$prog</span><span class="hl str">&quot;</span><span class="hl opt">)</span> <span class="hl kwc">or die</span> <span class="hl str">&quot;failed to get server</span> <span class="hl ipl">$prog</span><span class="hl str">:</span> <span class="hl ipl">$!</span><span class="hl str">&quot;</span><span class="hl opt">;</span>
		    <span class="hl kwc">chmod</span> <span class="hl num">0755</span><span class="hl opt">,</span> <span class="hl str">&quot;</span><span class="hl ipl">$dir/$prog</span><span class="hl str">&quot;</span><span class="hl opt">;</span>
		<span class="hl opt">}</span>
		<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwd">/FB/</span><span class="hl opt">) {</span>
		    <span class="hl opt">!</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>vga16<span class="hl opt">} &amp;&amp;</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>allowFB<span class="hl opt">}</span> <span class="hl kwc">or</span> <span class="hl kwa">next</span><span class="hl opt">;</span>

		    <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>allowFB<span class="hl opt">} = &amp;</span><span class="hl kwb">$launchX</span><span class="hl opt">(</span><span class="hl kwb">$prog</span><span class="hl opt">)</span> <span class="hl slc">#- keep in mind FB is used.</span>
		      <span class="hl kwc">and</span> <span class="hl kwa">goto</span> OK<span class="hl opt">;</span>
		<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
		    <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>vga16<span class="hl opt">} =</span> <span class="hl num">1</span> <span class="hl kwa">if</span> <span class="hl kwd">/VGA16/</span><span class="hl opt">;</span>
		    <span class="hl opt">&amp;</span><span class="hl kwb">$launchX</span><span class="hl opt">(</span><span class="hl kwb">$prog</span><span class="hl opt">)</span> <span class="hl kwc">and</span> <span class="hl kwa">goto</span> OK<span class="hl opt">;</span>
		<span class="hl opt">}</span>
	    <span class="hl opt">}</span>
	    <span class="hl kwa">return</span> <span class="hl kwc">undef</span><span class="hl opt">;</span>
	<span class="hl opt">}</span>
    <span class="hl opt">}</span>
  OK<span class="hl opt">:</span>
    install_gtk<span class="hl opt">::</span>init_sizes<span class="hl opt">();</span>
    install_gtk<span class="hl opt">::</span>default_theme<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
    install_gtk<span class="hl opt">::</span>create_logo_window<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>

    <span class="hl kwb">$my_gtk</span><span class="hl opt">::</span>force_center <span class="hl opt">= [ $::</span>rootwidth <span class="hl opt">- $::</span>windowwidth<span class="hl opt">, $::</span>logoheight<span class="hl opt">, $::</span>windowwidth<span class="hl opt">, $::</span>windowheight <span class="hl opt">];</span>

    <span class="hl opt">(</span><span class="hl kwc">bless</span> <span class="hl opt">{},</span> <span class="hl kwc">ref</span> <span class="hl kwb">$type</span> <span class="hl opt">||</span> <span class="hl kwb">$type</span><span class="hl opt">)-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>new<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
<span class="hl opt">}</span>

<span class="hl kwa">sub</span> enteringStep <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $step</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>

    <span class="hl kwc">printf</span> <span class="hl str">&quot;Entering step `</span><span class="hl ipl">%s</span><span class="hl str">&apos;</span><span class="hl esc">\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>steps<span class="hl opt">}{</span><span class="hl kwb">$step</span><span class="hl opt">}{</span>text<span class="hl opt">};</span>
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>enteringStep<span class="hl opt">(</span><span class="hl kwb">$step</span><span class="hl opt">);</span>
    install_gtk<span class="hl opt">::</span>create_steps_window<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
    install_gtk<span class="hl opt">::</span>create_help_window<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
<span class="hl opt">}</span>
<span class="hl kwa">sub</span> leavingStep <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $step</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>leavingStep<span class="hl opt">(</span><span class="hl kwb">$step</span><span class="hl opt">);</span>
<span class="hl opt">}</span>


<span class="hl kwa">sub</span> charsetChanged <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">set_locale</span><span class="hl opt">;</span>
    install_gtk<span class="hl opt">::</span>install_theme<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
    install_gtk<span class="hl opt">::</span>create_steps_window<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
<span class="hl opt">}</span>

<span class="hl slc">#-######################################################################################</span>
<span class="hl slc">#- Steps Functions</span>
<span class="hl slc">#-######################################################################################</span>
<span class="hl kwa">sub</span> selectLanguage <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $first_time</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>selectLanguage<span class="hl opt">;</span>
  
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span>
_<span class="hl opt">(</span><span class="hl str">&quot;Your system is low on resource. You may have some problem installing</span>
<span class="hl str">Linux-Mandrake. If that occurs, you can try a text install instead. For this,</span>
<span class="hl str">press `F1&apos; when booting on CDROM, then enter `text&apos;.&quot;</span><span class="hl opt">))</span> <span class="hl kwa">if</span> <span class="hl kwb">$first_time</span> <span class="hl opt">&amp;&amp;</span> availableRamMB<span class="hl opt">() &lt;</span> <span class="hl num">60</span><span class="hl opt">;</span> <span class="hl slc"># 60MB</span>

<span class="hl opt">}</span>

<span class="hl slc">#------------------------------------------------------------------------------</span>
<span class="hl kwa">sub</span> selectInstallClass1 <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $verif, $l, $def, $l2, $def2</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    <span class="hl opt">$::</span>live <span class="hl opt">||</span> <span class="hl kwb">&#64;$l</span> <span class="hl opt">==</span> <span class="hl num">1</span> <span class="hl kwc">and</span> <span class="hl kwa">return</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>selectInstallClass1<span class="hl opt">(</span><span class="hl kwb">$verif, $l, $def, $l2, $def2</span><span class="hl opt">);</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$w</span> <span class="hl opt">=</span> my_gtk-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$focused</span><span class="hl opt">;</span>
    gtkadd<span class="hl opt">(</span><span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>window<span class="hl opt">},</span>
	   gtkpack<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">create_box_with_title</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Please, choose one of the following classes of installation:&quot;</span><span class="hl opt">)),</span>
		   <span class="hl opt">(</span><span class="hl kwc">my</span> <span class="hl kwb">&#64;radios</span> <span class="hl opt">=</span> gtkradio<span class="hl opt">(</span><span class="hl kwb">&#64;$l, $def</span><span class="hl opt">)),</span>
		   gtkadd<span class="hl opt">(</span>create_hbox<span class="hl opt">(),</span>
			  <span class="hl kwc">map</span> <span class="hl opt">{</span> <span class="hl kwc">my</span> <span class="hl kwb">$v</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">;</span> 
				<span class="hl kwc">my</span> <span class="hl kwb">$b</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Button<span class="hl opt">(</span>translate<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">));</span>
				<span class="hl kwb">$focused</span> <span class="hl opt">=</span> <span class="hl kwb">$b</span> <span class="hl kwa">if</span> <span class="hl kwb">$_</span> <span class="hl kwc">eq</span> <span class="hl kwb">$def2</span><span class="hl opt">;</span>
				gtksignal_connect<span class="hl opt">(</span><span class="hl kwb">$b,</span> <span class="hl str">&quot;clicked&quot;</span> <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>retval<span class="hl opt">} =</span> <span class="hl kwb">$v</span><span class="hl opt">;</span> Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">main_quit</span> <span class="hl opt">});</span>
			    <span class="hl opt">}</span> <span class="hl kwb">&#64;$l2</span><span class="hl opt">)</span>
		  <span class="hl opt">));</span>
    <span class="hl kwb">$focused</span><span class="hl opt">-&gt;</span><span class="hl kwd">grab_focus</span> <span class="hl kwa">if</span> <span class="hl kwb">$focused</span><span class="hl opt">;</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">main</span><span class="hl opt">;</span>

    mapn <span class="hl opt">{</span> <span class="hl kwb">$verif</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">])</span> <span class="hl kwa">if</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]-&gt;</span><span class="hl kwd">active</span> <span class="hl opt">}</span> \<span class="hl kwb">&#64;radios, $l</span><span class="hl opt">;</span>
    install_gtk<span class="hl opt">::</span>create_steps_window<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>

    <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>retval<span class="hl opt">};</span>
<span class="hl opt">}</span>

<span class="hl slc">#------------------------------------------------------------------------------</span>
<span class="hl kwa">sub</span> selectMouse <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $force</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl kwb">%old</span> <span class="hl opt">= %{</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>mouse<span class="hl opt">}};</span>
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>selectMouse<span class="hl opt">(</span><span class="hl kwb">$force</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$mouse</span> <span class="hl opt">=</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>mouse<span class="hl opt">};</span>
    <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>type<span class="hl opt">}</span> <span class="hl kwc">eq</span> <span class="hl str">&apos;none&apos;</span> <span class="hl opt">||</span>
      <span class="hl kwb">$old</span><span class="hl opt">{</span>type<span class="hl opt">}</span>   <span class="hl kwc">eq</span> <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>type<span class="hl opt">}   &amp;&amp;</span> 
      <span class="hl kwb">$old</span><span class="hl opt">{</span>name<span class="hl opt">}</span>   <span class="hl kwc">eq</span> <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>name<span class="hl opt">}   &amp;&amp;</span>
      <span class="hl kwb">$old</span><span class="hl opt">{</span>device<span class="hl opt">}</span> <span class="hl kwc">eq</span> <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>device<span class="hl opt">} &amp;&amp; !</span><span class="hl kwb">$force</span> <span class="hl kwc">and</span> <span class="hl kwa">return</span><span class="hl opt">;</span>

    <span class="hl kwc">local</span> <span class="hl kwb">$my_gtk</span><span class="hl opt">::</span>grab <span class="hl opt">=</span> <span class="hl num">1</span><span class="hl opt">;</span> <span class="hl slc">#- unsure a crazy mouse don&apos;t go wild clicking everywhere</span>

    <span class="hl kwa">while</span> <span class="hl opt">(</span><span class="hl num">1</span><span class="hl opt">) {</span>
	<span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;telling X server to use another mouse&quot;</span><span class="hl opt">);</span>
	<span class="hl kwc">eval</span> <span class="hl opt">{</span> modules<span class="hl opt">::</span>load<span class="hl opt">(</span><span class="hl str">&apos;serial&apos;</span><span class="hl opt">) }</span> <span class="hl kwa">if</span> <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>device<span class="hl opt">} =~</span> <span class="hl kwd">/ttyS/</span><span class="hl opt">;</span>

	<span class="hl kwa">if</span> <span class="hl opt">(!$::</span>testing<span class="hl opt">) {</span>
	    devices<span class="hl opt">::</span>make<span class="hl opt">(</span><span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>device<span class="hl opt">});</span>
	    symlinkf<span class="hl opt">(</span><span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>device<span class="hl opt">},</span> <span class="hl str">&quot;/dev/mouse&quot;</span><span class="hl opt">);</span>
	    c<span class="hl opt">::</span>setMouseLive<span class="hl opt">(</span><span class="hl kwb">$ENV</span><span class="hl opt">{</span>DISPLAY<span class="hl opt">},</span> mouse<span class="hl opt">::</span>xmouse2xId<span class="hl opt">(</span><span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>XMOUSETYPE<span class="hl opt">}),</span> <span class="hl kwb">$mouse</span><span class="hl opt">-&gt;{</span>nbuttons<span class="hl opt">} &lt;</span> <span class="hl num">3</span><span class="hl opt">);</span>
	<span class="hl opt">}</span>
	install_gtk<span class="hl opt">::</span>test_mouse<span class="hl opt">(</span><span class="hl kwb">$mouse</span><span class="hl opt">)</span> <span class="hl kwc">and</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
	<span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>selectMouse<span class="hl opt">(</span><span class="hl num">1</span><span class="hl opt">);</span>
	<span class="hl kwb">$mouse</span> <span class="hl opt">=</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>mouse<span class="hl opt">};</span>
    <span class="hl opt">}</span> 
<span class="hl opt">}</span>

<span class="hl slc">#------------------------------------------------------------------------------</span>
<span class="hl kwa">sub</span> chooseSizeToInstall <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $packages, $min_size, $def_size, $max_size_, $availableC, $individual</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$max_size</span> <span class="hl opt">=</span> min<span class="hl opt">(</span><span class="hl kwb">$max_size_, $availableC</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$enough</span> <span class="hl opt">=</span> <span class="hl kwb">$max_size</span> <span class="hl opt">==</span> <span class="hl kwb">$max_size_</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$percentage</span> <span class="hl opt">=</span> <span class="hl kwc">int</span> <span class="hl num">100</span> <span class="hl opt">*</span> <span class="hl kwb">$max_size</span> <span class="hl opt">/</span> <span class="hl kwb">$max_size_</span><span class="hl opt">;</span>

    <span class="hl slc">#- don&apos;t ask anything if the difference between min and max is too small</span>
    <span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;chooseSizeToInstall: min_size=</span><span class="hl ipl">$min_size,</span> <span class="hl str">def_size=</span><span class="hl ipl">$def_size,</span> <span class="hl str">max_size=</span><span class="hl ipl">$max_size_,</span> <span class="hl str">available=</span><span class="hl ipl">$availableC</span><span class="hl str">&quot;</span><span class="hl opt">);</span>
    <span class="hl kwa">return</span> <span class="hl kwb">$max_size</span> <span class="hl kwa">if</span> <span class="hl kwb">$min_size</span> <span class="hl opt">&amp;&amp;</span> <span class="hl kwb">$max_size</span> <span class="hl opt">/</span> <span class="hl kwb">$min_size</span> <span class="hl opt">&lt;</span> <span class="hl num">1.05</span><span class="hl opt">;</span>

    <span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;choosing size to install between</span> <span class="hl ipl">$min_size</span> <span class="hl str">and</span> <span class="hl ipl">$max_size</span><span class="hl str">&quot;</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$w</span> <span class="hl opt">=</span> my_gtk-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$adj</span> <span class="hl opt">=</span> create_adjustment<span class="hl opt">(</span><span class="hl kwc">int</span><span class="hl opt">(</span><span class="hl num">100</span> <span class="hl opt">*</span> <span class="hl kwb">$def_size</span> <span class="hl kwd">/ $max_size_), $min_size * 100 /</span> <span class="hl kwb">$max_size_, $percentage</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$spin</span> <span class="hl opt">=</span> gtkset_usize<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>SpinButton<span class="hl opt">(</span><span class="hl kwb">$adj,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">),</span> <span class="hl num">20</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$val</span><span class="hl opt">;</span>

    <span class="hl kwa">require</span> pkgs<span class="hl opt">;</span>
    gtkadd<span class="hl opt">(</span><span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>window<span class="hl opt">},</span>
	  gtkpack<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>VBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">20</span><span class="hl opt">),</span>
		  _<span class="hl opt">(</span><span class="hl str">&quot;The total size for the groups you have selected is approximately</span> <span class="hl ipl">%d</span> <span class="hl str">MB.</span><span class="hl esc">\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> pkgs<span class="hl opt">::</span>correctSize<span class="hl opt">(</span><span class="hl kwb">$max_size_</span> <span class="hl opt">/</span> sqr<span class="hl opt">(</span><span class="hl num">1024</span><span class="hl opt">))) .</span>
		  <span class="hl opt">(</span><span class="hl kwb">$enough</span> ?
_<span class="hl opt">(</span><span class="hl str">&quot;If you wish to install less than this size,</span>
<span class="hl str">select the percentage of packages that you want to install.</span>
<span class="hl str"></span>
<span class="hl str">A low percentage will install only the most important packages;</span>
<span class="hl str">a percentage of 100</span><span class="hl ipl">%%</span> <span class="hl str">will install all selected packages.&quot;</span><span class="hl opt">) :</span> 
_<span class="hl opt">(</span><span class="hl str">&quot;You have space on your disk for only</span> <span class="hl ipl">%d%%</span> <span class="hl str">of these packages.</span>
<span class="hl str"></span>
<span class="hl str">If you wish to install less than this,</span>
<span class="hl str">select the percentage of packages that you want to install.</span>
<span class="hl str">A low percentage will install only the most important packages;</span>
<span class="hl str">a percentage of</span> <span class="hl ipl">%d%%</span> <span class="hl str">will install as many packages as possible.&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$percentage, $percentage</span><span class="hl opt">))</span>
<span class="hl opt">. (</span><span class="hl kwb">$individual</span> ? <span class="hl str">&quot;</span><span class="hl esc">\n\n</span><span class="hl str">&quot;</span> <span class="hl opt">.</span> _<span class="hl opt">(</span><span class="hl str">&quot;You will be able to choose them more specifically in the next step.&quot;</span><span class="hl opt">) :</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">),</span>
		 create_packtable<span class="hl opt">({},</span>
				  <span class="hl opt">[</span> _<span class="hl opt">(</span><span class="hl str">&quot;Percentage of packages to install&quot;</span><span class="hl opt">) .</span> <span class="hl str">&apos;  &apos;</span><span class="hl opt">,</span> <span class="hl kwb">$spin,</span> <span class="hl str">&quot;%&quot;</span><span class="hl opt">,</span> <span class="hl kwc">my</span> <span class="hl kwb">$mb</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Label <span class="hl opt">],</span>
				  <span class="hl opt">[</span> <span class="hl kwc">undef</span><span class="hl opt">,</span> new Gtk<span class="hl opt">::</span>HScrollbar<span class="hl opt">(</span><span class="hl kwb">$adj</span><span class="hl opt">) ],</span>
			       <span class="hl opt">),</span>
		 create_okcancel<span class="hl opt">(</span><span class="hl kwb">$w</span><span class="hl opt">)</span>
		<span class="hl opt">)</span>
	 <span class="hl opt">);</span>
    <span class="hl kwb">$spin</span><span class="hl opt">-&gt;</span><span class="hl kwd">signal_connect</span><span class="hl opt">(</span>changed <span class="hl opt">=&gt;</span> <span class="hl kwc">my</span> <span class="hl kwb">$changed</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> 
	<span class="hl kwb">$val</span> <span class="hl opt">=</span> <span class="hl kwb">$spin</span><span class="hl opt">-&gt;</span><span class="hl kwd">get_value_as_int</span> <span class="hl opt">/</span> <span class="hl num">100</span> <span class="hl opt">*</span> <span class="hl kwb">$max_size_</span><span class="hl opt">;</span>
	<span class="hl kwb">$mb</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span><span class="hl kwc">sprintf</span><span class="hl opt">(</span><span class="hl str">&quot;(</span><span class="hl ipl">%dMB</span><span class="hl str">)&quot;</span><span class="hl opt">,</span> pkgs<span class="hl opt">::</span>correctSize<span class="hl opt">(</span><span class="hl kwb">$val</span> <span class="hl opt">/</span> sqr<span class="hl opt">(</span><span class="hl num">1024</span><span class="hl opt">))));</span> 
    <span class="hl opt">}); &amp;</span><span class="hl kwb">$changed</span><span class="hl opt">();</span>
    <span class="hl kwb">$spin</span><span class="hl opt">-&gt;</span><span class="hl kwd">signal_connect</span><span class="hl opt">(</span>activate <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>retval<span class="hl opt">} =</span> <span class="hl num">1</span><span class="hl opt">;</span> Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">main_quit</span> <span class="hl opt">});</span>
    <span class="hl kwb">$spin</span><span class="hl opt">-&gt;</span><span class="hl kwd">grab_focus</span><span class="hl opt">();</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">main</span> <span class="hl kwc">and</span> <span class="hl kwb">$val</span> <span class="hl opt">+</span> <span class="hl num">1</span><span class="hl opt">;</span> <span class="hl slc">#- add a single byte (hack?) to make selection of 0 bytes ok.</span>
<span class="hl opt">}</span>
<span class="hl kwa">sub</span> choosePackagesTree <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $packages</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>

    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_help</span><span class="hl opt">(</span><span class="hl str">&apos;choosePackagesTree&apos;</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$curr, $parent, $info_widget, $w_size, $go, $idle, $flat, $auto_deps</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">%wtree, %ptree</span><span class="hl opt">);</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$w</span> <span class="hl opt">=</span> my_gtk-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$details</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>VBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">0</span><span class="hl opt">);</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$tree</span> <span class="hl opt">=</span> Gtk<span class="hl opt">::</span>CTree-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">(</span><span class="hl num">3</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span>
    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_selection_mode</span><span class="hl opt">(</span><span class="hl str">&apos;browse&apos;</span><span class="hl opt">);</span>
    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_column_width</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">200</span><span class="hl opt">);</span>
    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_column_auto_resize</span><span class="hl opt">(</span><span class="hl kwb">$_,</span> <span class="hl num">1</span><span class="hl opt">)</span> <span class="hl kwa">foreach</span> <span class="hl num">1</span><span class="hl opt">.</span><span class="hl num">.2</span><span class="hl opt">;</span>

    gtkadd<span class="hl opt">(</span><span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>window<span class="hl opt">},</span> 
	   gtkpack_<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>VBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">5</span><span class="hl opt">),</span>
		    <span class="hl num">0</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;Choose the packages you want to install&quot;</span><span class="hl opt">),</span>
		    <span class="hl num">1</span><span class="hl opt">,</span> gtkpack<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>HBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">0</span><span class="hl opt">),</span>
			       createScrolledWindow<span class="hl opt">(</span><span class="hl kwb">$tree</span><span class="hl opt">),</span>
			       gtkadd<span class="hl opt">(</span>gtkset_usize<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>Frame<span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Info&quot;</span><span class="hl opt">)), $::</span>windowwidth <span class="hl opt">-</span> <span class="hl num">490</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">),</span>
				      createScrolledWindow<span class="hl opt">(</span><span class="hl kwb">$info_widget</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Text<span class="hl opt">),</span>
				     <span class="hl opt">)),</span>
		    <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl kwc">my</span> <span class="hl kwb">$l</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>HBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">15</span><span class="hl opt">),</span>
		    <span class="hl num">0</span><span class="hl opt">,</span> gtkpack<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>HBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">10</span><span class="hl opt">),</span>
			       <span class="hl kwb">$go</span> <span class="hl opt">=</span> gtksignal_connect<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>Button<span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Install&quot;</span><span class="hl opt">)),</span> <span class="hl str">&quot;clicked&quot;</span> <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>retval<span class="hl opt">} =</span> <span class="hl num">1</span><span class="hl opt">;</span> Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">main_quit</span> <span class="hl opt">}),</span>
			      <span class="hl opt">)</span>
    <span class="hl opt">));</span>
    gtkpack__<span class="hl opt">(</span><span class="hl kwb">$l,</span> <span class="hl kwc">my</span> <span class="hl kwb">$toolbar</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Toolbar<span class="hl opt">(</span><span class="hl str">&apos;horizontal&apos;</span><span class="hl opt">,</span> <span class="hl str">&apos;icons&apos;</span><span class="hl opt">));</span>
    gtkpack__<span class="hl opt">(</span><span class="hl kwb">$l,</span> gtksignal_connect<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>CheckButton<span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Automatic dependencies&quot;</span><span class="hl opt">)),</span> clicked <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> invbool \<span class="hl kwb">$auto_deps</span> <span class="hl opt">}));</span>
    <span class="hl kwb">$l</span><span class="hl opt">-&gt;</span><span class="hl kwd">pack_end</span><span class="hl opt">(</span><span class="hl kwb">$w_size</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Label<span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">),</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">20</span><span class="hl opt">);</span>

    <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>window<span class="hl opt">}-&gt;</span><span class="hl kwd">set_usize</span><span class="hl opt">(</span><span class="hl kwc">map</span> <span class="hl opt">{</span> <span class="hl kwb">$_</span> <span class="hl opt">-</span> <span class="hl num">2</span> <span class="hl opt">*</span> <span class="hl kwb">$my_gtk</span><span class="hl opt">::</span>border <span class="hl opt">-</span> <span class="hl num">4</span> <span class="hl opt">} $::</span>windowwidth<span class="hl opt">, $::</span>windowheight<span class="hl opt">);</span>
    <span class="hl kwb">$go</span><span class="hl opt">-&gt;</span><span class="hl kwd">grab_focus</span><span class="hl opt">;</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>rwindow<span class="hl opt">}-&gt;</span><span class="hl kwd">show_all</span><span class="hl opt">;</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$pix_base</span>     <span class="hl opt">= [</span> gtkcreate_png<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/rpm-base.png&quot;</span><span class="hl opt">) ];</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$pix_selected</span> <span class="hl opt">= [</span> gtkcreate_png<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/rpm-selected.png&quot;</span><span class="hl opt">) ];</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$pix_unselect</span> <span class="hl opt">= [</span> gtkcreate_png<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/rpm-unselected.png&quot;</span><span class="hl opt">) ];</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$pix_semisele</span> <span class="hl opt">= [</span> gtkcreate_png<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/rpm-semiselected.png&quot;</span><span class="hl opt">) ];</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$pix_installed</span><span class="hl opt">= [</span> gtkcreate_png<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/rpm-installed.png&quot;</span><span class="hl opt">) ];</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$add_parent</span><span class="hl opt">;</span> <span class="hl kwb">$add_parent</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span> <span class="hl kwc">undef</span><span class="hl opt">;</span>
	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwc">my</span> <span class="hl kwb">$w</span> <span class="hl opt">=</span> <span class="hl kwb">$wtree</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]}) {</span> <span class="hl kwa">return</span> <span class="hl kwb">$w</span> <span class="hl opt">}</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$s</span><span class="hl opt">;</span> <span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl kwc">split</span> <span class="hl str">&apos;\|&apos;</span><span class="hl opt">,</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]) {</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$s2</span> <span class="hl opt">=</span> <span class="hl kwb">$s</span> ? <span class="hl str">&quot;</span><span class="hl ipl">$s</span><span class="hl str">|</span><span class="hl ipl">$_</span><span class="hl str">&quot;</span> <span class="hl opt">:</span> <span class="hl kwb">$_</span><span class="hl opt">;</span>
	    <span class="hl kwb">$wtree</span><span class="hl opt">{</span><span class="hl kwb">$s2</span><span class="hl opt">} ||=</span> <span class="hl kwa">do</span> <span class="hl opt">{</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$n</span> <span class="hl opt">=</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">insert_node</span><span class="hl opt">(</span><span class="hl kwb">$s</span> ? <span class="hl kwb">$add_parent</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$s</span><span class="hl opt">) :</span> <span class="hl kwc">undef</span><span class="hl opt">,</span> <span class="hl kwc">undef</span><span class="hl opt">, [</span><span class="hl kwb">$_,</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">],</span> <span class="hl num">5</span><span class="hl opt">, (</span><span class="hl kwc">undef</span><span class="hl opt">)</span> x <span class="hl num">4</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span>
		<span class="hl kwb">$n</span><span class="hl opt">;</span>
	    <span class="hl opt">};</span>
	    <span class="hl kwb">$s</span> <span class="hl opt">=</span> <span class="hl kwb">$s2</span><span class="hl opt">;</span>
	<span class="hl opt">}</span>
	<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_set_pixmap</span><span class="hl opt">(</span><span class="hl kwb">$wtree</span><span class="hl opt">{</span><span class="hl kwb">$s</span><span class="hl opt">},</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl kwb">$pix_semisele</span><span class="hl opt">-&gt;[</span><span class="hl num">0</span><span class="hl opt">],</span> <span class="hl kwb">$pix_semisele</span><span class="hl opt">-&gt;[</span><span class="hl num">1</span><span class="hl opt">]);</span>
	<span class="hl kwb">$wtree</span><span class="hl opt">{</span><span class="hl kwb">$s</span><span class="hl opt">};</span>
    <span class="hl opt">};</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$add_node</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$leaf, $root</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageByName<span class="hl opt">(</span><span class="hl kwb">$packages,$leaf</span><span class="hl opt">)</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
	pkgs<span class="hl opt">::</span>packageMedium<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)-&gt;{</span>selected<span class="hl opt">}</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$node</span> <span class="hl opt">=</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">insert_node</span><span class="hl opt">(</span><span class="hl kwb">$add_parent</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$root</span><span class="hl opt">),</span> 
				      <span class="hl kwc">undef</span><span class="hl opt">, [</span><span class="hl kwb">$leaf,</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">],</span> <span class="hl num">5</span><span class="hl opt">, (</span><span class="hl kwc">undef</span><span class="hl opt">)</span> x <span class="hl num">4</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$pix</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageFlagBase<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> ? <span class="hl kwb">$pix_base</span> <span class="hl opt">:</span> pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> ? <span class="hl kwb">$pix_selected</span> <span class="hl opt">:</span> pkgs<span class="hl opt">::</span>packageFlagInstalled<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> ? <span class="hl kwb">$pix_installed</span> <span class="hl opt">:</span> <span class="hl kwb">$pix_unselect</span><span class="hl opt">;</span>
	<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_set_pixmap</span><span class="hl opt">(</span><span class="hl kwb">$node,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">0</span><span class="hl opt">],</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">1</span><span class="hl opt">]);</span>
	<span class="hl kwc">push</span> <span class="hl opt">&#64;{</span><span class="hl kwb">$ptree</span><span class="hl opt">{</span><span class="hl kwb">$leaf</span><span class="hl opt">}},</span> <span class="hl kwb">$node</span><span class="hl opt">;</span>
    <span class="hl opt">};</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$add_nodes</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwb">%ptree</span> <span class="hl opt">=</span> <span class="hl kwb">%wtree</span> <span class="hl opt">= ();</span>

	<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">freeze</span><span class="hl opt">;</span>
	<span class="hl kwa">while</span> <span class="hl opt">(</span><span class="hl num">1</span><span class="hl opt">) {</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">remove_node</span><span class="hl opt">(</span><span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_nth</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">) ||</span> <span class="hl kwa">last</span><span class="hl opt">) }</span>

	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">$flat</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]) {</span>
	    <span class="hl kwb">$add_node</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$_,</span> <span class="hl kwc">undef</span><span class="hl opt">)</span> <span class="hl kwa">foreach</span> <span class="hl kwc">sort grep</span> <span class="hl opt">{</span> <span class="hl kwc">my</span> <span class="hl kwb">$pkg</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageByName<span class="hl opt">(</span><span class="hl kwb">$packages, $_</span><span class="hl opt">);</span>
						       pkgs<span class="hl opt">::</span>packageMedium<span class="hl opt">(</span><span class="hl kwb">$pkg</span><span class="hl opt">)-&gt;{</span>selected<span class="hl opt">} }</span> <span class="hl kwc">keys</span> <span class="hl opt">%{</span><span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}};</span>
	<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
	    <span class="hl kwa">foreach</span> <span class="hl kwc">my</span> <span class="hl kwb">$root</span> <span class="hl opt">(&#64;{</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>compssUsersSorted<span class="hl opt">}}) {</span>
		<span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">%fl, &#64;firstchoice, &#64;others</span><span class="hl opt">);</span>
		<span class="hl kwb">$fl</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">} =</span> <span class="hl num">1</span> <span class="hl kwa">foreach</span> <span class="hl opt">&#64;{</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>compssUsers<span class="hl opt">}{</span><span class="hl kwb">$root</span><span class="hl opt">}{</span>flags<span class="hl opt">}};</span>
		<span class="hl kwa">foreach</span> <span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">(</span><span class="hl kwc">values</span> <span class="hl opt">%{</span><span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}}) {</span>
		    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$rate, &#64;flags</span><span class="hl opt">) =</span> pkgs<span class="hl opt">::</span>packageRateRFlags<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">);</span>
		    <span class="hl kwa">next if</span> <span class="hl opt">!(</span><span class="hl kwb">$rate</span> <span class="hl opt">&amp;&amp;</span> <span class="hl kwc">grep</span> <span class="hl opt">{</span> <span class="hl kwc">grep</span> <span class="hl opt">{ !</span><span class="hl kwd">/^!/</span> <span class="hl opt">&amp;&amp;</span> <span class="hl kwb">$fl</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">} }</span> <span class="hl kwc">split</span><span class="hl opt">(</span><span class="hl str">&apos;\|\|&apos;</span><span class="hl opt">) }</span> <span class="hl kwb">&#64;flags</span><span class="hl opt">);</span>
		    <span class="hl kwb">$rate</span> <span class="hl opt">&gt;=</span> <span class="hl num">3</span> ?
		      <span class="hl kwc">push</span><span class="hl opt">(</span><span class="hl kwb">&#64;firstchoice,</span> pkgs<span class="hl opt">::</span>packageName<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) :</span>
		      <span class="hl kwc">push</span><span class="hl opt">(</span><span class="hl kwb">&#64;others,</span>      pkgs<span class="hl opt">::</span>packageName<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">));</span>
		<span class="hl opt">}</span>
		<span class="hl kwb">$add_node</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$_, $root</span>                   <span class="hl opt">)</span> <span class="hl kwa">foreach</span> <span class="hl kwc">sort</span> <span class="hl kwb">&#64;firstchoice</span><span class="hl opt">;</span>
		<span class="hl kwb">$add_node</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$_, $root</span> <span class="hl opt">.</span> <span class="hl str">&apos;|&apos;</span> <span class="hl opt">.</span> _<span class="hl opt">(</span><span class="hl str">&quot;Other&quot;</span><span class="hl opt">))</span> <span class="hl kwa">foreach</span> <span class="hl kwc">sort</span> <span class="hl kwb">&#64;others</span><span class="hl opt">;</span>
	    <span class="hl opt">}</span>
	<span class="hl opt">}</span>
	<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">thaw</span><span class="hl opt">;</span>
    <span class="hl opt">};</span>
    <span class="hl kwb">$add_nodes</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$flat</span><span class="hl opt">);</span>

    <span class="hl kwc">my</span> <span class="hl kwb">%toolbar</span> <span class="hl opt">=</span> <span class="hl kwc">my</span> <span class="hl kwb">&#64;toolbar</span> <span class="hl opt">=</span> 
      <span class="hl opt">(</span>
       ftout <span class="hl opt">=&gt;  [</span> _<span class="hl opt">(</span><span class="hl str">&quot;Expand Tree&quot;</span><span class="hl opt">) ,</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">expand_recursive</span><span class="hl opt">(</span><span class="hl kwc">undef</span><span class="hl opt">) } ],</span>
       ftin  <span class="hl opt">=&gt;  [</span> _<span class="hl opt">(</span><span class="hl str">&quot;Collapse Tree&quot;</span><span class="hl opt">) ,</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">collapse_recursive</span><span class="hl opt">(</span><span class="hl kwc">undef</span><span class="hl opt">) } ],</span>
       reload<span class="hl opt">=&gt;  [</span> _<span class="hl opt">(</span><span class="hl str">&quot;Toggle between flat and group sorted&quot;</span><span class="hl opt">),</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$add_nodes</span><span class="hl opt">-&gt;(!</span><span class="hl kwb">$flat</span><span class="hl opt">) } ],</span>
      <span class="hl opt">);</span>
    <span class="hl kwb">$toolbar</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_button_relief</span><span class="hl opt">(</span><span class="hl str">&quot;none&quot;</span><span class="hl opt">);</span>
    <span class="hl kwa">foreach</span> <span class="hl opt">(</span>grep_index <span class="hl opt">{ $::</span>i <span class="hl opt">%</span> <span class="hl num">2</span> <span class="hl opt">==</span> <span class="hl num">0</span> <span class="hl opt">}</span> <span class="hl kwb">&#64;toolbar</span><span class="hl opt">) {</span>
	gtksignal_connect<span class="hl opt">(</span><span class="hl kwb">$toolbar</span><span class="hl opt">-&gt;</span><span class="hl kwd">append_item</span><span class="hl opt">(</span><span class="hl kwc">undef</span><span class="hl opt">,</span> <span class="hl kwb">$toolbar</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">}[</span><span class="hl num">0</span><span class="hl opt">],</span> <span class="hl kwc">undef</span><span class="hl opt">,</span> gtkpng<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">$ENV</span><span class="hl str">{SHARE_PATH}/</span><span class="hl ipl">$_</span><span class="hl str">.png&quot;</span><span class="hl opt">)),</span>
			  clicked <span class="hl opt">=&gt;</span> <span class="hl kwb">$toolbar</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">}[</span><span class="hl num">1</span><span class="hl opt">]);</span>
    <span class="hl opt">}</span>
    <span class="hl kwb">$toolbar</span><span class="hl opt">-&gt;</span><span class="hl kwd">set_style</span><span class="hl opt">(</span><span class="hl str">&quot;icons&quot;</span><span class="hl opt">);</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$display_info</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageByName<span class="hl opt">(</span><span class="hl kwb">$packages, $curr</span><span class="hl opt">)</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span> gtktext_insert<span class="hl opt">(</span><span class="hl kwb">$info_widget,</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">);</span>
	pkgs<span class="hl opt">::</span>extractHeaders<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>prefix<span class="hl opt">}, [</span><span class="hl kwb">$p</span><span class="hl opt">],</span> pkgs<span class="hl opt">::</span>packageMedium<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">));</span>
	pkgs<span class="hl opt">::</span>packageHeader<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> <span class="hl kwc">or die</span><span class="hl opt">;</span>

	<span class="hl kwc">my</span> <span class="hl kwb">$imp</span> <span class="hl opt">=</span> translate<span class="hl opt">(</span><span class="hl kwb">$pkgs</span><span class="hl opt">::</span>compssListDesc<span class="hl opt">{</span>pkgs<span class="hl opt">::</span>packageFlagBase<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> ?
						  <span class="hl num">5</span> <span class="hl opt">:</span> pkgs<span class="hl opt">::</span>packageRate<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)});</span>

	gtktext_insert<span class="hl opt">(</span><span class="hl kwb">$info_widget, $&#64;</span> ? _<span class="hl opt">(</span><span class="hl str">&quot;Bad package&quot;</span><span class="hl opt">) :</span>
		       _<span class="hl opt">(</span><span class="hl str">&quot;Name:</span> <span class="hl ipl">%s\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> pkgs<span class="hl opt">::</span>packageName<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) .</span>
		       _<span class="hl opt">(</span><span class="hl str">&quot;Version:</span> <span class="hl ipl">%s\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> pkgs<span class="hl opt">::</span>packageVersion<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">) .</span> <span class="hl str">&apos;-&apos;</span> <span class="hl opt">.</span> pkgs<span class="hl opt">::</span>packageRelease<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) .</span>
		       _<span class="hl opt">(</span><span class="hl str">&quot;Size:</span> <span class="hl ipl">%d</span> <span class="hl str">KB</span><span class="hl esc">\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> pkgs<span class="hl opt">::</span>packageSize<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">) /</span> <span class="hl num">1024</span><span class="hl opt">) .</span>
		       <span class="hl opt">(</span><span class="hl kwb">$imp</span> <span class="hl opt">&amp;&amp;</span> _<span class="hl opt">(</span><span class="hl str">&quot;Importance:</span> <span class="hl ipl">%s\n</span><span class="hl str">&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$imp</span><span class="hl opt">)) .</span> <span class="hl str">&quot;</span><span class="hl esc">\n</span><span class="hl str">&quot;</span> <span class="hl opt">.</span>
		       formatLines<span class="hl opt">(</span>c<span class="hl opt">::</span>headerGetEntry<span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageHeader<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">),</span> <span class="hl str">&apos;description&apos;</span><span class="hl opt">)));</span>
	pkgs<span class="hl opt">::</span>packageFreeHeader<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">);</span>
	<span class="hl slc">#c::headerFree(delete $p-&gt;[$HEADER]);</span>
	<span class="hl num">0</span><span class="hl opt">;</span>
    <span class="hl opt">};</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$update_size</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$size</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>selectedSize<span class="hl opt">(</span><span class="hl kwb">$packages</span><span class="hl opt">);</span>
	<span class="hl kwb">$w_size</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Total size:</span> <span class="hl ipl">%d</span> <span class="hl str">/</span> <span class="hl ipl">%d</span> <span class="hl str">MB&quot;</span><span class="hl opt">,</span> 
		       pkgs<span class="hl opt">::</span>correctSize<span class="hl opt">(</span><span class="hl kwb">$size</span> <span class="hl opt">/</span> sqr<span class="hl opt">(</span><span class="hl num">1024</span><span class="hl opt">)),</span>
		       install_any<span class="hl opt">::</span>getAvailableSpace<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">) /</span> sqr<span class="hl opt">(</span><span class="hl num">1024</span><span class="hl opt">)));</span>
    <span class="hl opt">};</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$select</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl kwb">%l</span><span class="hl opt">;</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$isSelection</span> <span class="hl opt">= !</span>pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]);</span>
	<span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl kwb">&#64;_</span><span class="hl opt">) {</span>
	    pkgs<span class="hl opt">::</span>togglePackageSelection<span class="hl opt">(</span><span class="hl kwb">$packages, $_,</span> <span class="hl kwc">my</span> <span class="hl kwb">$l</span> <span class="hl opt">= {});</span>
	    <span class="hl kwb">&#64;l</span><span class="hl opt">{</span><span class="hl kwc">grep</span> <span class="hl opt">{</span><span class="hl kwb">$l</span><span class="hl opt">-&gt;{</span><span class="hl kwb">$_</span><span class="hl opt">}}</span> <span class="hl kwc">keys</span> <span class="hl kwb">%$l</span><span class="hl opt">} = ();</span>
	<span class="hl opt">}</span>
	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwc">my</span> <span class="hl kwb">&#64;l</span> <span class="hl opt">=</span> <span class="hl kwc">keys</span> <span class="hl kwb">%l</span><span class="hl opt">) {</span>
	    <span class="hl slc">#- check for size before trying to select.</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$size</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>selectedSize<span class="hl opt">(</span><span class="hl kwb">$packages</span><span class="hl opt">);</span>
	    <span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl kwb">&#64;l</span><span class="hl opt">) {</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> <span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}{</span><span class="hl kwb">$_</span><span class="hl opt">};</span>
		pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> <span class="hl kwc">or</span> <span class="hl kwb">$size</span> <span class="hl opt">+=</span> pkgs<span class="hl opt">::</span>packageSize<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">);</span>
	    <span class="hl opt">}</span>
	    <span class="hl kwa">if</span> <span class="hl opt">(</span>pkgs<span class="hl opt">::</span>correctSize<span class="hl opt">(</span><span class="hl kwb">$size</span> <span class="hl kwd">/ sqr(1024)) &gt; install_any::getAvailableSpace($o) /</span> sqr<span class="hl opt">(</span><span class="hl num">1024</span><span class="hl opt">)) {</span>
		<span class="hl kwa">return</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;You can&apos;t select this package as there is not enough space left to install it&quot;</span><span class="hl opt">));</span>
	    <span class="hl opt">}</span>

	    <span class="hl kwb">&#64;l</span> <span class="hl opt">&gt;</span> <span class="hl kwb">&#64;_</span> <span class="hl opt">&amp;&amp; !</span><span class="hl kwb">$auto_deps</span> <span class="hl kwc">and</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_okcancel</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">, [</span> <span class="hl kwb">$isSelection</span> ? 
							      _<span class="hl opt">(</span><span class="hl str">&quot;The following packages are going to be installed&quot;</span><span class="hl opt">) :</span>
							      _<span class="hl opt">(</span><span class="hl str">&quot;The following packages are going to be removed&quot;</span><span class="hl opt">),</span>
							      <span class="hl kwc">join</span><span class="hl opt">(</span><span class="hl str">&quot;, &quot;</span><span class="hl opt">,</span> common<span class="hl opt">::</span>truncate_list<span class="hl opt">(</span><span class="hl num">20</span><span class="hl opt">,</span> <span class="hl kwc">sort</span> <span class="hl kwb">&#64;l</span><span class="hl opt">)) ],</span> <span class="hl num">1</span><span class="hl opt">) ||</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
	    <span class="hl kwb">$isSelection</span> ? pkgs<span class="hl opt">::</span>selectPackage<span class="hl opt">(</span><span class="hl kwb">$packages, $_</span><span class="hl opt">) :</span> pkgs<span class="hl opt">::</span>unselectPackage<span class="hl opt">(</span><span class="hl kwb">$packages, $_</span><span class="hl opt">)</span> <span class="hl kwa">foreach</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
	    <span class="hl kwa">foreach</span> <span class="hl opt">(</span><span class="hl kwb">&#64;l</span><span class="hl opt">) {</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> <span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}{</span><span class="hl kwb">$_</span><span class="hl opt">};</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$pix</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)</span> ? <span class="hl kwb">$pix_selected</span> <span class="hl opt">:</span> <span class="hl kwb">$pix_unselect</span><span class="hl opt">;</span>
		<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_set_pixmap</span><span class="hl opt">(</span><span class="hl kwb">$_,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">0</span><span class="hl opt">],</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">1</span><span class="hl opt">])</span> <span class="hl kwa">foreach</span> <span class="hl opt">&#64;{</span><span class="hl kwb">$ptree</span><span class="hl opt">{</span><span class="hl kwb">$_</span><span class="hl opt">}};</span>
	    <span class="hl opt">}</span>
	    <span class="hl opt">&amp;</span><span class="hl kwb">$update_size</span><span class="hl opt">;</span>
	<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
	    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;You can&apos;t select/unselect this package&quot;</span><span class="hl opt">));</span>
	<span class="hl opt">}</span>
    <span class="hl opt">};</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$children</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwc">map</span> <span class="hl opt">{</span> <span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}{(</span><span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_get_pixtext</span><span class="hl opt">(</span><span class="hl kwb">$_,</span> <span class="hl num">0</span><span class="hl opt">))[</span><span class="hl num">0</span><span class="hl opt">]} }</span> gtkctree_children<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]) };</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$toggle</span> <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwc">ref</span> <span class="hl kwb">$curr</span> <span class="hl opt">&amp;&amp; !</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]) {</span>
	    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">toggle_expansion</span><span class="hl opt">(</span><span class="hl kwb">$curr</span><span class="hl opt">);</span>
	<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
	    <span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwc">ref</span> <span class="hl kwb">$curr</span><span class="hl opt">) {</span>
		<span class="hl kwc">my</span> <span class="hl kwb">&#64;l</span> <span class="hl opt">=</span> <span class="hl kwc">grep</span> <span class="hl opt">{ !</span>pkgs<span class="hl opt">::</span>packageFlagBase<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">) }</span> <span class="hl kwb">$children</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$curr</span><span class="hl opt">)</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">&#64;unsel</span> <span class="hl opt">=</span> <span class="hl kwc">grep</span> <span class="hl opt">{ !</span>pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">) }</span> <span class="hl kwb">&#64;l</span><span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">&#64;p</span> <span class="hl opt">=</span> <span class="hl kwb">&#64;unsel</span> ?
		  <span class="hl kwb">&#64;unsel</span> <span class="hl opt">:</span> <span class="hl slc"># not all is selected, select all</span>
		    <span class="hl kwb">&#64;l</span><span class="hl opt">;</span>
		<span class="hl kwb">$select</span><span class="hl opt">-&gt;(</span><span class="hl kwb">&#64;p</span><span class="hl opt">);</span>
		<span class="hl kwb">$parent</span> <span class="hl opt">=</span> <span class="hl kwb">$curr</span><span class="hl opt">;</span>
	    <span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> <span class="hl kwb">$packages</span><span class="hl opt">-&gt;{</span>names<span class="hl opt">}{</span><span class="hl kwb">$curr</span><span class="hl opt">}</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
		<span class="hl kwa">if</span> <span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageFlagBase<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) {</span>
		    <span class="hl kwa">return</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;This is a mandatory package, it can&apos;t be unselected&quot;</span><span class="hl opt">));</span>
		<span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageFlagInstalled<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) {</span>
		    <span class="hl kwa">return</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;You can&apos;t unselect this package. It is already installed&quot;</span><span class="hl opt">));</span>
		<span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageFlagUpgrade<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) {</span>
		    <span class="hl kwa">if</span> <span class="hl opt">($::</span>expert<span class="hl opt">) {</span>
			<span class="hl kwa">if</span> <span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">)) {</span>
			    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_yesorno</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;This package must be upgraded</span><span class="hl esc">\n</span><span class="hl str">Are you sure you want to deselect it?&quot;</span><span class="hl opt">))</span> <span class="hl kwc">or</span> <span class="hl kwa">return</span><span class="hl opt">;</span>
			<span class="hl opt">}</span>
		    <span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
			<span class="hl kwa">return</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_warn</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;You can&apos;t unselect this package. It must be upgraded&quot;</span><span class="hl opt">));</span>
		    <span class="hl opt">}</span>
		<span class="hl opt">}</span>
		<span class="hl kwb">$select</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$p</span><span class="hl opt">);</span>
	    <span class="hl opt">}</span>
	    <span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwc">my</span> <span class="hl kwb">&#64;l</span> <span class="hl opt">=</span> <span class="hl kwb">$children</span><span class="hl opt">-&gt;(</span><span class="hl kwb">$parent</span><span class="hl opt">)) {</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$nb</span> <span class="hl opt">=</span> <span class="hl kwc">grep</span> <span class="hl opt">{</span> pkgs<span class="hl opt">::</span>packageFlagSelected<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">) }</span> <span class="hl kwb">&#64;l</span><span class="hl opt">;</span>
		<span class="hl kwc">my</span> <span class="hl kwb">$pix</span> <span class="hl opt">=</span> <span class="hl kwb">$nb</span><span class="hl opt">==</span><span class="hl num">0</span> ? <span class="hl kwb">$pix_unselect</span> <span class="hl opt">:</span> <span class="hl kwb">$nb</span><span class="hl opt">&lt;</span><span class="hl kwb">&#64;l</span> ? <span class="hl kwb">$pix_semisele</span> <span class="hl opt">:</span> <span class="hl kwb">$pix_selected</span><span class="hl opt">;</span>
		<span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_set_pixmap</span><span class="hl opt">(</span><span class="hl kwb">$parent,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">0</span><span class="hl opt">],</span> <span class="hl kwb">$pix</span><span class="hl opt">-&gt;[</span><span class="hl num">1</span><span class="hl opt">]);</span>
	    <span class="hl opt">}</span>
	<span class="hl opt">}</span>
    <span class="hl opt">};</span>

    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">signal_connect</span><span class="hl opt">(</span>key_press_event <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
        <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$w, $e</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$c</span> <span class="hl opt">=</span> <span class="hl kwc">chr</span><span class="hl opt">(</span><span class="hl kwb">$e</span><span class="hl opt">-&gt;{</span>keyval<span class="hl opt">} &amp;</span> <span class="hl num">0xff</span><span class="hl opt">);</span>
	<span class="hl kwb">$toggle</span><span class="hl opt">-&gt;(</span><span class="hl num">0</span><span class="hl opt">)</span> <span class="hl kwa">if</span> <span class="hl kwb">$e</span><span class="hl opt">-&gt;{</span>keyval<span class="hl opt">} &gt;=</span> <span class="hl num">0x100</span> ? <span class="hl kwb">$c</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;</span><span class="hl esc">\r</span><span class="hl str">&quot;</span> <span class="hl opt">||</span> <span class="hl kwb">$c</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;</span><span class="hl esc">\x8d</span><span class="hl str">&quot;</span> <span class="hl opt">:</span> <span class="hl kwb">$c</span> <span class="hl kwc">eq</span> <span class="hl str">&apos; &apos;</span><span class="hl opt">;</span>
	<span class="hl num">1</span><span class="hl opt">;</span>
    <span class="hl opt">});</span>
    <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">signal_connect</span><span class="hl opt">(</span>tree_select_row <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">timeout_remove</span><span class="hl opt">(</span><span class="hl kwb">$idle</span><span class="hl opt">)</span> <span class="hl kwa">if</span> <span class="hl kwb">$idle</span><span class="hl opt">;</span>

	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">]-&gt;</span><span class="hl kwd">row</span><span class="hl opt">-&gt;</span><span class="hl kwd">is_leaf</span><span class="hl opt">) {</span>
	    <span class="hl opt">(</span><span class="hl kwb">$curr</span><span class="hl opt">) =</span> <span class="hl kwb">$tree</span><span class="hl opt">-&gt;</span><span class="hl kwd">node_get_pixtext</span><span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">],</span> <span class="hl num">0</span><span class="hl opt">);</span>
	    <span class="hl kwb">$parent</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">]-&gt;</span><span class="hl kwd">row</span><span class="hl opt">-&gt;</span><span class="hl kwd">parent</span><span class="hl opt">;</span>
	    <span class="hl kwb">$idle</span> <span class="hl opt">=</span> Gtk-<span class="hl opt">&gt;</span><span class="hl kwd">timeout_add</span><span class="hl opt">(</span><span class="hl num">100</span><span class="hl opt">,</span> <span class="hl kwb">$display_info</span><span class="hl opt">);</span>
	<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span>
	    <span class="hl kwb">$curr</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">];</span>
	<span class="hl opt">}</span>
	<span class="hl kwb">$toggle</span><span class="hl opt">-&gt;(</span><span class="hl num">1</span><span class="hl opt">)</span> <span class="hl kwa">if</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">2</span><span class="hl opt">] ==</span> <span class="hl num">1</span><span class="hl opt">;</span>
    <span class="hl opt">});</span>
    <span class="hl opt">&amp;</span><span class="hl kwb">$update_size</span><span class="hl opt">;</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">main</span><span class="hl opt">;</span>
<span class="hl opt">}</span>

<span class="hl slc">#------------------------------------------------------------------------------</span>
<span class="hl kwa">sub</span> beforeInstallPackages <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>    
    <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">SUPER</span><span class="hl opt">::</span>beforeInstallPackages<span class="hl opt">;</span>
    install_any<span class="hl opt">::</span>copy_advertising<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">);</span>
<span class="hl opt">}</span>

<span class="hl slc">#------------------------------------------------------------------------------</span>
<span class="hl kwa">sub</span> installPackages <span class="hl opt">{</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$o, $packages</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>

    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$current_total_size, $last_size, $nb, $total_size, $start_time, $last_dtime, $trans_progress_total</span><span class="hl opt">);</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$w</span> <span class="hl opt">=</span> my_gtk-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Installing&quot;</span><span class="hl opt">));</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">sync</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$text</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Label<span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl kwb">$advertising</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$msg, $msg_time_remaining, $msg_time_total</span><span class="hl opt">) =</span> <span class="hl kwc">map</span> <span class="hl opt">{</span> new Gtk<span class="hl opt">::</span>Label<span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">) }</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">, (</span>_<span class="hl opt">(</span><span class="hl str">&quot;Estimating&quot;</span><span class="hl opt">))</span> x <span class="hl num">2</span><span class="hl opt">;</span>
    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$progress, $progress_total</span><span class="hl opt">) =</span> <span class="hl kwc">map</span> <span class="hl opt">{</span> new Gtk<span class="hl opt">::</span>ProgressBar <span class="hl opt">} (</span><span class="hl num">1</span><span class="hl opt">.</span><span class="hl num">.2</span><span class="hl opt">);</span>
    gtkadd<span class="hl opt">(</span><span class="hl kwb">$w</span><span class="hl opt">-&gt;{</span>window<span class="hl opt">},</span> <span class="hl kwc">my</span> <span class="hl kwb">$box</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>VBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">10</span><span class="hl opt">));</span>
    <span class="hl kwb">$box</span><span class="hl opt">-&gt;</span><span class="hl kwd">pack_end</span><span class="hl opt">(</span>gtkshow<span class="hl opt">(</span>gtkpack<span class="hl opt">(</span>gtkset_usize<span class="hl opt">(</span>new Gtk<span class="hl opt">::</span>VBox<span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span><span class="hl num">5</span><span class="hl opt">), $::</span>windowwidth <span class="hl opt">*</span> <span class="hl num">0.8</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">),</span>
			   <span class="hl kwb">$msg, $progress,</span>
			   create_packtable<span class="hl opt">({},</span>
					    <span class="hl opt">[</span>_<span class="hl opt">(</span><span class="hl str">&quot;Time remaining &quot;</span><span class="hl opt">),</span> <span class="hl kwb">$msg_time_remaining</span><span class="hl opt">],</span>
<span class="hl slc">#					    [_(&quot;Total time &quot;), $msg_time_total],</span>
					   <span class="hl opt">),</span>
			   <span class="hl kwb">$text,</span>
			   <span class="hl kwb">$progress_total,</span>
			   gtkadd<span class="hl opt">(</span>create_hbox<span class="hl opt">(),</span>
				  <span class="hl kwc">my</span> <span class="hl kwb">$cancel</span> <span class="hl opt">=</span> new Gtk<span class="hl opt">::</span>Button<span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Cancel&quot;</span><span class="hl opt">))),</span>
			  <span class="hl opt">)),</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span>
    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">sync</span><span class="hl opt">;</span>
    <span class="hl kwb">$msg</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Please wait, preparing installation&quot;</span><span class="hl opt">));</span>
    gtkset_mousecursor_normal<span class="hl opt">(</span><span class="hl kwb">$cancel</span><span class="hl opt">-&gt;</span><span class="hl kwd">window</span><span class="hl opt">);</span>
    <span class="hl kwb">$cancel</span><span class="hl opt">-&gt;</span><span class="hl kwd">signal_connect</span><span class="hl opt">(</span>clicked <span class="hl opt">=&gt;</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span> <span class="hl kwb">$pkgs</span><span class="hl opt">::</span>cancel_install <span class="hl opt">=</span> <span class="hl num">1</span> <span class="hl opt">});</span>

    <span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$change_time, $i</span><span class="hl opt">);</span>
    <span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">&#64;install_any</span><span class="hl opt">::</span>advertising_images<span class="hl opt">) {</span>
	<span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;hiding&quot;</span><span class="hl opt">);</span>
	<span class="hl kwb">$msg</span><span class="hl opt">-&gt;</span><span class="hl kwd">hide</span><span class="hl opt">;</span>
	<span class="hl kwb">$progress</span><span class="hl opt">-&gt;</span><span class="hl kwd">hide</span><span class="hl opt">;</span>
	<span class="hl kwb">$text</span><span class="hl opt">-&gt;</span><span class="hl kwd">hide</span><span class="hl opt">;</span>
    <span class="hl opt">}</span>

    <span class="hl kwc">my</span> <span class="hl kwb">$oldInstallCallback</span> <span class="hl opt">=</span> \<span class="hl opt">&amp;</span>pkgs<span class="hl opt">::</span>installCallback<span class="hl opt">;</span>
    <span class="hl kwc">local</span> <span class="hl opt">*</span>pkgs<span class="hl opt">::</span>installCallback <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl kwb">$m</span> <span class="hl opt">=</span> <span class="hl kwc">shift</span><span class="hl opt">;</span>
	<span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">$m</span> <span class="hl opt">=~</span> <span class="hl kwd">/^Starting installation/</span><span class="hl opt">) {</span>
	    <span class="hl kwb">$nb</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">];</span>
	    <span class="hl kwb">$total_size</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">];</span> <span class="hl kwb">$current_total_size</span> <span class="hl opt">=</span> <span class="hl num">0</span><span class="hl opt">;</span>
	    <span class="hl kwb">$start_time</span> <span class="hl opt">=</span> <span class="hl kwc">time</span><span class="hl opt">();</span>
	    <span class="hl kwb">$msg</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;</span><span class="hl ipl">%d</span> <span class="hl str">packages&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$nb</span><span class="hl opt">));</span>
	    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">flush</span><span class="hl opt">;</span>
	<span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span><span class="hl kwb">$m</span> <span class="hl opt">=~</span> <span class="hl kwd">/^Starting installing package/</span><span class="hl opt">) {</span>
	    <span class="hl kwb">$progress</span><span class="hl opt">-&gt;</span><span class="hl kwd">update</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">);</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$name</span> <span class="hl opt">=</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">];</span>
	    <span class="hl kwb">$msg</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;Installing package</span> <span class="hl ipl">%s</span><span class="hl str">&quot;</span><span class="hl opt">,</span> <span class="hl kwb">$name</span><span class="hl opt">));</span>
	    <span class="hl kwb">$current_total_size</span> <span class="hl opt">+=</span> <span class="hl kwb">$last_size</span><span class="hl opt">;</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$p</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>packageByName<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>packages<span class="hl opt">},</span> <span class="hl kwb">$name</span><span class="hl opt">);</span>
	    <span class="hl kwb">$last_size</span> <span class="hl opt">=</span> c<span class="hl opt">::</span>headerGetEntry<span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageHeader<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">),</span> <span class="hl str">&apos;size&apos;</span><span class="hl opt">);</span>
	    <span class="hl kwb">$text</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">((</span><span class="hl kwc">split</span> <span class="hl kwd">/\n/</span><span class="hl opt">,</span> c<span class="hl opt">::</span>headerGetEntry<span class="hl opt">(</span>pkgs<span class="hl opt">::</span>packageHeader<span class="hl opt">(</span><span class="hl kwb">$p</span><span class="hl opt">),</span> <span class="hl str">&apos;summary&apos;</span><span class="hl opt">))[</span><span class="hl num">0</span><span class="hl opt">] ||</span> <span class="hl str">&apos;&apos;</span><span class="hl opt">);</span>

	    <span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">&#64;install_any</span><span class="hl opt">::</span>advertising_images <span class="hl opt">&amp;&amp;</span> <span class="hl kwc">time</span><span class="hl opt">() -</span> <span class="hl kwb">$change_time</span> <span class="hl opt">&gt;</span> <span class="hl num">20</span><span class="hl opt">) {</span>
		<span class="hl kwb">$change_time</span> <span class="hl opt">=</span> <span class="hl kwc">time</span><span class="hl opt">();</span>
                <span class="hl kwc">my</span> <span class="hl kwb">$f</span> <span class="hl opt">=</span> <span class="hl kwb">$install_any</span><span class="hl opt">::</span>advertising_images<span class="hl opt">[</span><span class="hl kwb">$i++</span> <span class="hl opt">%</span> <span class="hl kwb">&#64;install_any</span><span class="hl opt">::</span>advertising_images<span class="hl opt">];</span>
		<span class="hl kwc">log</span><span class="hl opt">::</span>l<span class="hl opt">(</span><span class="hl str">&quot;advertising</span> <span class="hl ipl">$f</span><span class="hl str">&quot;</span><span class="hl opt">);</span>
		gtkdestroy<span class="hl opt">(</span><span class="hl kwb">$advertising</span><span class="hl opt">);</span>
		gtkpack<span class="hl opt">(</span><span class="hl kwb">$box, $advertising</span> <span class="hl opt">=</span> gtkpng<span class="hl opt">(</span><span class="hl kwb">$f</span><span class="hl opt">));</span>
	    <span class="hl opt">}</span>
	    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">flush</span><span class="hl opt">;</span>
	<span class="hl opt">}</span> <span class="hl kwa">elsif</span> <span class="hl opt">(</span><span class="hl kwb">$m</span> <span class="hl opt">=~</span> <span class="hl kwd">/^Progressing installing package/</span><span class="hl opt">) {</span>
	    <span class="hl kwb">$progress</span><span class="hl opt">-&gt;</span><span class="hl kwd">update</span><span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">2</span><span class="hl opt">]</span> ? <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">] /</span> <span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">2</span><span class="hl opt">] :</span> <span class="hl num">0</span><span class="hl opt">);</span>

	    <span class="hl kwc">my</span> <span class="hl kwb">$dtime</span> <span class="hl opt">=</span> <span class="hl kwc">time</span><span class="hl opt">() -</span> <span class="hl kwb">$start_time</span><span class="hl opt">;</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$ratio</span> <span class="hl opt">=</span> <span class="hl kwb">$total_size</span> ? <span class="hl opt">(</span><span class="hl kwb">$_</span><span class="hl opt">[</span><span class="hl num">1</span><span class="hl opt">] +</span> <span class="hl kwb">$current_total_size</span><span class="hl opt">) /</span> <span class="hl kwb">$total_size</span> <span class="hl opt">:</span> <span class="hl num">0</span><span class="hl opt">;</span> <span class="hl kwb">$ratio</span> <span class="hl opt">&gt;=</span> <span class="hl num">1</span> <span class="hl kwc">and</span> <span class="hl kwb">$ratio</span> <span class="hl opt">=</span> <span class="hl num">1</span><span class="hl opt">;</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$total_time</span> <span class="hl opt">=</span> <span class="hl kwb">$ratio</span> ? <span class="hl kwb">$dtime</span> <span class="hl opt">/</span> <span class="hl kwb">$ratio</span> <span class="hl opt">:</span> <span class="hl kwc">time</span><span class="hl opt">();</span>

	    <span class="hl kwb">$progress_total</span><span class="hl opt">-&gt;</span><span class="hl kwd">update</span><span class="hl opt">(</span><span class="hl kwb">$ratio</span><span class="hl opt">);</span>
	    <span class="hl kwa">if</span> <span class="hl opt">(</span><span class="hl kwb">$dtime</span> <span class="hl opt">!=</span> <span class="hl kwb">$last_dtime</span> <span class="hl opt">&amp;&amp;</span> <span class="hl kwb">$current_total_size</span> <span class="hl opt">&gt;</span> <span class="hl num">10</span> <span class="hl opt">*</span> <span class="hl num">1024</span> <span class="hl opt">*</span> <span class="hl num">1024</span><span class="hl opt">) {</span>
		<span class="hl kwb">$msg_time_total</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>formatTime<span class="hl opt">(</span><span class="hl num">10</span> <span class="hl opt">*</span> round<span class="hl opt">(</span><span class="hl kwb">$total_time</span> <span class="hl opt">/</span> <span class="hl num">10</span><span class="hl opt">) +</span> <span class="hl num">10</span><span class="hl opt">));</span>
		<span class="hl kwb">$msg_time_remaining</span><span class="hl opt">-&gt;</span><span class="hl kwd">set</span><span class="hl opt">(</span>formatTime<span class="hl opt">(</span><span class="hl num">10</span> <span class="hl opt">*</span> round<span class="hl opt">(</span>max<span class="hl opt">(</span><span class="hl kwb">$total_time</span> <span class="hl opt">-</span> <span class="hl kwb">$dtime,</span> <span class="hl num">0</span><span class="hl opt">) /</span> <span class="hl num">10</span><span class="hl opt">) +</span> <span class="hl num">10</span><span class="hl opt">));</span>
		<span class="hl kwb">$last_dtime</span> <span class="hl opt">=</span> <span class="hl kwb">$dtime</span><span class="hl opt">;</span>
	    <span class="hl opt">}</span>
	    <span class="hl kwb">$w</span><span class="hl opt">-&gt;</span><span class="hl kwd">flush</span><span class="hl opt">;</span>
	<span class="hl opt">}</span> <span class="hl kwa">else</span> <span class="hl opt">{</span> <span class="hl kwc">unshift</span> <span class="hl kwb">&#64;_, $m</span><span class="hl opt">;</span> <span class="hl kwa">goto</span> <span class="hl kwb">$oldInstallCallback</span> <span class="hl opt">}</span>
    <span class="hl opt">};</span>
    <span class="hl slc">#- the modification is not local as the box should be living for other package installation.</span>
    <span class="hl kwc">undef</span> <span class="hl opt">*</span>install_any<span class="hl opt">::</span>changeMedium<span class="hl opt">;</span>
    <span class="hl opt">*</span>install_any<span class="hl opt">::</span>changeMedium <span class="hl opt">=</span> <span class="hl kwa">sub</span> <span class="hl opt">{</span>
	<span class="hl kwc">my</span> <span class="hl opt">(</span><span class="hl kwb">$method, $medium</span><span class="hl opt">) =</span> <span class="hl kwb">&#64;_</span><span class="hl opt">;</span>

	<span class="hl slc">#- if not using a cdrom medium, always abort.</span>
	<span class="hl kwb">$method</span> <span class="hl kwc">eq</span> <span class="hl str">&apos;cdrom&apos;</span> <span class="hl kwc">and</span> <span class="hl kwa">do</span> <span class="hl opt">{</span>
	    <span class="hl kwc">local</span> <span class="hl kwb">$my_gtk</span><span class="hl opt">::</span>grab <span class="hl opt">=</span> <span class="hl num">1</span><span class="hl opt">;</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$name</span> <span class="hl opt">=</span> pkgs<span class="hl opt">::</span>mediumDescr<span class="hl opt">(</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>packages<span class="hl opt">},</span> <span class="hl kwb">$medium</span><span class="hl opt">);</span>
	    <span class="hl kwc">local</span> <span class="hl opt">$| =</span> <span class="hl num">1</span><span class="hl opt">;</span> <span class="hl kwc">print</span> <span class="hl str">&quot;</span><span class="hl esc">\a</span><span class="hl str">&quot;</span><span class="hl opt">;</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$time</span> <span class="hl opt">=</span> <span class="hl kwc">time</span><span class="hl opt">();</span>
	    <span class="hl kwc">my</span> <span class="hl kwb">$r</span> <span class="hl opt">=</span> <span class="hl kwb">$name</span> <span class="hl opt">!~</span> <span class="hl kwd">/Application/</span> <span class="hl opt">|| (</span><span class="hl kwb">$o</span><span class="hl opt">-&gt;{</span>useless_thing_accepted2<span class="hl opt">} ||=</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_from_list_</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> formatAlaTeX<span class="hl opt">(</span>_<span class="hl opt">(</span><span class="hl str">&quot;</span>
<span class="hl str">Warning</span>
<span class="hl str"></span>
<span class="hl str">Please read carefully the terms below. If you disagree with any</span>
<span class="hl str">portion, you are not allowed to install the next CD media. Press &apos;Refuse&apos; </span>
<span class="hl str">to continue the installation without using these media.</span>
<span class="hl str"></span>
<span class="hl str"></span>
<span class="hl str">Some components contained in the next CD media are not governed</span>
<span class="hl str">by the GPL License or similar agreements. Each such component is then</span>
<span class="hl str">governed by the terms and conditions of its own specific license. </span>
<span class="hl str">Please read carefully and comply with such specific licenses before </span>
<span class="hl str">you use or redistribute the said components. </span>
<span class="hl str">Such licenses will in general prevent the transfer,  duplication </span>
<span class="hl str">(except for backup purposes), redistribution, reverse engineering, </span>
<span class="hl str">de-assembly, de-compilation or modification of the component. </span>
<span class="hl str">Any breach of agreement will immediately terminate your rights under </span>
<span class="hl str">the specific license. Unless the specific license terms grant you such</span>
<span class="hl str">rights, you usually cannot install the programs on more than one</span>
<span class="hl str">system, or adapt it to be used on a network. In doubt, please contact </span>
<span class="hl str">directly the distributor or editor of the component. </span>
<span class="hl str">Transfer to third parties or copying of such components including the </span>
<span class="hl str">documentation is usually forbidden.</span>
<span class="hl str"></span>
<span class="hl str"></span>
<span class="hl str">All rights to the components of the next CD media belong to their </span>
<span class="hl str">respective authors and are protected by intellectual property and </span>
<span class="hl str">copyright laws applicable to software programs.</span>
<span class="hl str">&quot;</span><span class="hl opt">)), [</span> __<span class="hl opt">(</span><span class="hl str">&quot;Accept&quot;</span><span class="hl opt">),</span> __<span class="hl opt">(</span><span class="hl str">&quot;Refuse&quot;</span><span class="hl opt">) ],</span> <span class="hl str">&quot;Accept&quot;</span><span class="hl opt">)</span> <span class="hl kwc">eq</span> <span class="hl str">&quot;Accept&quot;</span><span class="hl opt">);</span>
            <span class="hl kwb">$r</span> <span class="hl opt">&amp;&amp;=</span> <span class="hl kwb">$o</span><span class="hl opt">-&gt;</span><span class="hl kwd">ask_okcancel</span><span class="hl opt">(</span><span class="hl str">&apos;&apos;</span><span class="hl opt">,</span> _<span class="hl opt">(</span><span class="hl str">&quot;Change your Cd-Rom!</span>
<span class="hl str"></span>
<span class="hl str">Please insert the Cd-Rom labelled</span> <span class="hl esc">\&quot;</span><span class="hl str"></span><span class="hl ipl">%s\</span><span class="hl str">&quot;</span> <span class="hl kwa">in</span> your drive <span class="hl kwc">and</span> press Ok <span class="hl kwa">when</span> done<span class="hl opt">.</span>
If you don<span class="hl str">&apos;t have it, press Cancel to avoid installation from this Cd-Rom.&quot;,</span> <span class="hl ipl">$name</span><span class="hl str">));</span>
<span class="hl str">            #- add the elapsed time (otherwise the predicted time will be rubbish)</span>
<span class="hl str"></span>            <span class="hl ipl">$start_time</span> <span class="hl str">+= time() -</span> <span class="hl ipl">$time</span><span class="hl str">;</span>
<span class="hl str"></span>            <span class="hl ipl">$r</span><span class="hl str">;</span>
<span class="hl str">	};</span>
<span class="hl str">    };</span>
<span class="hl str">    catch_cdie {</span> <span class="hl ipl">$o</span><span class="hl str">-&gt;install_steps::installPackages(</span><span class="hl ipl">$packages</span><span class="hl str">); }</span>
<span class="hl str">      sub {</span>
<span class="hl str">	  if (</span><span class="hl ipl">$&#64;</span> <span class="hl str">=~ /^error ordering package list: (.*)/) {</span>
<span class="hl str"></span>	      <span class="hl ipl">$o</span><span class="hl str">-&gt;ask_yesorno(&apos;</span><span class="hl str">&apos;, [</span>
<span class="hl str">_(&quot;There was an error ordering packages:&quot;),</span> <span class="hl ipl">$1,</span> <span class="hl str">_(&quot;Go on anyway?&quot;) ], 1) and return 1;</span>
<span class="hl str">	      ${</span><span class="hl ipl">$_</span><span class="hl str">[0]} = &quot;already displayed&quot;;</span>
<span class="hl str">	  } elsif (</span><span class="hl ipl">$&#64;</span> <span class="hl str">=~ /^error installing package list: (.*)/) {</span>
<span class="hl str"></span>	      <span class="hl ipl">$o</span><span class="hl str">-&gt;ask_yesorno(&apos;</span><span class="hl str">&apos;, [</span>
<span class="hl str">_(&quot;There was an error installing packages:&quot;),</span> <span class="hl ipl">$1,</span> <span class="hl str">_(&quot;Go on anyway?&quot;) ], 1) and return 1;</span>
<span class="hl str">	      ${</span><span class="hl ipl">$_</span><span class="hl str">[0]} = &quot;already displayed&quot;;</span>
<span class="hl str">	  }</span>
<span class="hl str">	  0;</span>
<span class="hl str">      };</span>
<span class="hl str">    if (</span><span class="hl ipl">$pkgs</span><span class="hl str">::cancel_install) {</span>
<span class="hl str"></span>	<span class="hl ipl">$pkgs</span><span class="hl str">::cancel_install = 0;</span>
<span class="hl str">	die &quot;setstep choosePackages</span><span class="hl esc">\n</span><span class="hl str">&quot;;</span>
<span class="hl str">    }</span>
<span class="hl str"></span>    <span class="hl ipl">$w</span><span class="hl str">-&gt;destroy;</span>
<span class="hl str">}</span>
<span class="hl str"></span>
<span class="hl str">sub set_help {</span>
<span class="hl str">    my (</span><span class="hl ipl">$o,</span> <span class="hl str"></span><span class="hl ipl">&#64;l</span><span class="hl str">) =</span> <span class="hl ipl">&#64;_</span><span class="hl str">;</span>
<span class="hl str"></span>
<span class="hl str"></span>    <span class="hl ipl">$o</span><span class="hl str">-&gt;{current_help} = formatAlaTeX(join &quot;</span><span class="hl esc">\n</span><span class="hl str">&quot;, map { _ deref(</span><span class="hl ipl">$help</span><span class="hl str">::steps{</span><span class="hl ipl">$_</span><span class="hl str">}) }</span> <span class="hl ipl">&#64;l</span><span class="hl str">);</span>
<span class="hl str">    gtktext_insert(</span><span class="hl ipl">$o</span><span class="hl str">-&gt;{help_window_text},</span> <span class="hl ipl">$o</span><span class="hl str">-&gt;{current_help});</span>
<span class="hl str">    1;</span>
<span class="hl str">}</span>
<span class="hl str"></span>
<span class="hl str">#-######################################################################################</span>
<span class="hl str">#- Wonderful perl :(</span>
<span class="hl str">#-######################################################################################</span>
<span class="hl str">1; #</span>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.1</a> (<a href='https://git-scm.com/'>git 2.21.0</a>) at 2025-03-03 21:23:11 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>