unsigned long XtcwpGetLastPixel (Display *dpy) /***************************************************************************** return last pixel in range of contiguous pixels in XA_RGB_DEFAULT_MAP ****************************************************************************** Input: dpy display ****************************************************************************** Notes: If it does not already exist, XA_RGB_DEFAULT_MAP will be created. If XA_RGB_DEFAULT_MAP does not exist and cannot be created, then this function returns 0. ****************************************************************************** Author: Dave Hale, Colorado School of Mines, 09/29/90 *****************************************************************************/ { Screen *scr=XDefaultScreenOfDisplay(dpy); Window root=XRootWindowOfScreen(scr); XStandardColormap scmap; /* if XA_RGB_DEFAULT_MAP does not exist, create it */ if (!XGetStandardColormap(dpy,root,&scmap,XA_RGB_DEFAULT_MAP)) if (!XtcwpCreateRGBDefaultMap(dpy,&scmap)) return 0; /* return last pixel in range of contiguous pixels */ return scmap.base_pixel+ scmap.red_max*scmap.red_mult+ scmap.green_max*scmap.green_mult+ scmap.blue_max*scmap.blue_mult; }
/* **************************************************************** * Programa principal * **************************************************************** */ int main (int argc, const char *argv[]) { XStandardColormap stdcmap, *cmp; Display *dpy = NULL; Window root, win; XGCValues gcv; int depth; FILE *fp; XImage *ximage = NULL; IMAGE *last_image, *ip, *old_ip; int nimages, times; const char *display = NOSTR; int time_interval = 0; int opt, exit_val = 0; int Nflag = 0; Atom map; KeySym key; save_argc = argc; save_argv = argv; /* * Analisa as opções de execução. */ while ((opt = getopt (argc, argv, "d:f:HMNRs:v")) != EOF) { switch (opt) { case 'd': display = optarg; break; case 'f': if (strchr (optarg, '/') != NOSTR) { int num, den; sscanf (optarg, "%d/%d", &num, &den); if (num != 1 || den <= 0 || den > 8) msg ("$Fator redutivo inválido"); default_factor = -den + 1; } else { sscanf (optarg, "%d", &default_factor); if (default_factor <= 0 || default_factor > 8) msg ("$Fator de ampliação inválido"); default_factor--; } break; case 'H': help (0); break; case 'M': return (0); case 'N': Nflag++; break; case 'R': Rflag++; break; case 's': time_interval = atol (optarg); if (time_interval < 1 || time_interval > 60) { msg ("Argumento inválido para opção '-s'"); help (1); } break; case 'v': vflag++; break; default: putc ('\n', stderr); help (2); } /* end switch (opt) */ } /* end while (analisando opções) */ argv += optind; argc -= optind; /* * Consistência final das Opções. */ if (Nflag) { if (argc > 0 || *argv != NOSTR) msg ("$Com a opção '-N' NÃO podem ser dados nomes de arquivos"); argv = read_args_from_stdin (&argc); } if (Rflag && time_interval > 0) msg ("$As opções '-R' e '-s' são incompatíveis"); /* * Constrói a Tabela de Imagens. */ for (/* acima */; *argv != NULL; argv++) { if (ftw (*argv, add_image_to_table) < 0) msg ("$*Erro em \"ftw (%s)\"", *argv); } if ((nimages = next_image - images) <= 0) msg ("$Não foram encontrados arquivos contendo imagens"); last_image = next_image - 1; if (Rflag && nimages > 1) { /* Escolhe aleatoriamente uma imagem */ images += (time (NULL) % nimages); last_image = images; msg ("Imagem a a janela-mãe: \"%s\"", images->i_name); } /* * Abre a conexão com o servidor. */ if ((dpy = XOpenDisplay (display)) == NULL) { msg ( "$Não consegui conectar-me ao servidor \"%s\"", XDisplayName (display) ); } screen = DefaultScreen (dpy); depth = DefaultDepth (dpy, screen); root = RootWindow (dpy, screen); /* * Obtém o mapa de cores de acordo com a profundidade. */ cmp = &stdcmap; map = (depth <= 8) ? XA_RGB_DEFAULT_MAP : XA_RGB_BEST_MAP; if (!XGetStandardColormap (dpy, root, cmp, map)) { cmp = NULL; msg ("Mapa de cores padrão para profundidade %d não disponível", depth); } /* * Decide se cria ou não uma janela para exibir as imagens. */ win = Rflag ? root : create_window (dpy); gcv.foreground = WhitePixel (dpy, screen); gcv.background = BlackPixel (dpy, screen); gc = XCreateGC (dpy, win, GCForeground|GCBackground, &gcv); /* * Mostra as imagens. */ for (times = 0, old_ip = NOIMAGE, ip = images; ip != NOIMAGE; times++) { if (vflag && (times & 15) == 0 && nimages > 0) { printf ("\n NUM FMT LARG x ALT FATOR CORES TAMANHO ARQUIVO\n"); printf ("--------------------------------------------------------------\n"); } if (old_ip != ip) { /* Abre o arquivo que contém a imagem */ if ((fp = fdopen (inopen (ip->i_dev, ip->i_ino), "r")) == NOFILE) { msg ("*Não consegui abrir o arquivo \"%s\"", ip->i_name); exit_val++; break; } /* Lê a imagem para a memória */ if ((ximage = (*ip->i_format->f_load) (fp, 1, dpy, cmp, ip)) == NULL) { msg ("Não consegui ler imagens do arquivo \"%s\"", ip->i_name); fclose (fp); exit_val++; break; } fclose (fp); /* Imprime, se necessário, algumas informações sobre a imagem */ if (vflag) { char factor[8]; if (ip->i_factor >= 0) snprintf (factor, sizeof (factor), "%d", ip->i_factor + 1); else snprintf (factor, sizeof (factor), "1/%d", -ip->i_factor + 1); printf ( "%4d %s %4d x %4d %4s %8d %8d %s\n", ip - images + 1, ip->i_format->f_extension, ip->i_width, ip->i_height, factor, ip->i_ncolors, ip->i_file_sz, ip->i_name ); } /* Mostra a imagem como fundo da janela */ if (draw_window (dpy, win, ximage, ip) < 0) break; } /* end if (nova imagem) */ /* Aguarda eventos e analisa o retorno */ key = wait_for_events (dpy, win, time_interval); old_ip = ip; switch (key) { case 'q': case 'Q': case XK_Escape: ip = NOIMAGE; /* Fim do programa */ break; case XK_Up: case XK_KP_Up: if (ip > images) ip--; /* Retrocede uma imagem */ break; case XK_Down: case XK_KP_Down: if (ip < last_image) ip++; /* Avança uma imagem */ elif (time_interval > 0) ip = images; /* Volta ao início */ break; case XK_Home: case XK_KP_Home: ip = images; /* Volta ao início */ break; case XK_End: case XK_KP_End: ip = last_image; /* Vai para a última imagem */ break; case XK_Right: case XK_KP_Right: ip->i_factor++; /* Aumenta o fator */ old_ip = NOIMAGE; break; case XK_Left: /* Diminui o fator */ case XK_KP_Left: ip->i_factor--; old_ip = NOIMAGE; break; default: break; } /* end switch (tecla retornada) */ if (ip != old_ip) XDestroyImage (ximage); } /* end for (percorrendo imagens) */ XFreeGC (dpy, gc); XCloseDisplay (dpy); return (exit_val); } /* end main */
Colormap XtcwpCreateRGBColormap (Display *dpy, Window win) /***************************************************************************** create a colormap with an RGB color scale in contiguous cells ****************************************************************************** Input: dpy display win window ****************************************************************************** Notes: The returned colormap is only created; the window's colormap attribute is not changed, and the colormap is not installed by this function. The returned colormap is a copy of the window's current colormap, but with an RGB color scale allocated in the range of contiguous cells determined by XA_RGB_DEFAULT_MAP. If it does not already exist, XA_RGB_DEFAULT_MAP will be created. ****************************************************************************** Author: Dave Hale, Colorado School of Mines, 09/29/90 *****************************************************************************/ { Screen *scr=XDefaultScreenOfDisplay(dpy); Window root=XRootWindowOfScreen(scr); Colormap cmap,wcmap; XStandardColormap scmap; XColor color; XWindowAttributes wa; unsigned long i,ncells,npixels; unsigned long bpixel,epixel,pixel[4096]; /* determine beginning and ending pixels in contiguous range */ bpixel = XtcwpGetFirstPixel(dpy); epixel = XtcwpGetLastPixel(dpy); if (epixel<=bpixel) return None; /* get standard colormap XA_RGB_DEFAULT_MAP */ if (!XGetStandardColormap(dpy,root,&scmap,XA_RGB_DEFAULT_MAP)) if (!XtcwpCreateRGBDefaultMap(dpy,&scmap)) return None; /* determine window's current colormap */ XGetWindowAttributes(dpy,win,&wa); wcmap = wa.colormap; /* create new colormap and allocate all cells read/write */ cmap = XCreateColormap(dpy,win,DefaultVisualOfScreen(scr),AllocNone); ncells = CellsOfScreen(scr); XAllocColorCells(dpy,cmap,True,NULL,0,pixel,(unsigned int)ncells); /* copy color cells from window's colormap to new colormap */ for (i=0; i<ncells; ++i) { if (i<bpixel || i>epixel) { color.pixel = i; XQueryColor(dpy,wcmap,&color); XFreeColors(dpy,cmap,&i,1,0); XAllocColor(dpy,cmap,&color); } } /* copy RGB color scale from XA_RGB_DEFAULT_MAP to new colormap */ npixels = epixel-bpixel+1; for (i=0; i<npixels; ++i) { color.pixel = bpixel+i; XQueryColor(dpy,scmap.colormap,&color); XStoreColor(dpy,cmap,&color); } /* return colormap */ return cmap; }
Status XtcwpCreateRGBDefaultMap (Display *dpy, XStandardColormap *scmap) /***************************************************************************** create XA_RGB_DEFAULT_MAP property of root window if it does not already exist ****************************************************************************** Input: dpy display Output: scmap the standard colormap structure ****************************************************************************** Notes: This function returns 0 if the XA_RGB_DEFAULT_MAP property does not exist and cannot be created. At least 8 contiguous color cells must be free in the default colormap to create the XA_RGB_DEFAULT_MAP. If created, the red_max, green_max, and blue_max values returned in scmap will be equal. ****************************************************************************** Author: Dave Hale, Colorado School of Mines, 09/29/90 *****************************************************************************/ { Screen *scr=XDefaultScreenOfDisplay(dpy); Window root=XRootWindowOfScreen(scr); Colormap cmap; XColor color; int i,ncells; unsigned long npixels; unsigned long bpixel,epixel,pixel1,pixel2,imax,rmult,gmult,bmult; unsigned long pixel[4096]; /* grab the server */ XGrabServer(dpy); /* if XA_RGB_DEFAULT_MAP does not exist, then */ if (!XGetStandardColormap(dpy,root,scmap,XA_RGB_DEFAULT_MAP)) { /* use default colormap */ cmap = DefaultColormapOfScreen(scr); /* determine largest number of contiguous free color cells */ ncells = CellsOfScreen(scr); while(ncells && !XAllocColorCells(dpy,cmap,True,NULL,0,pixel,ncells)) ncells--; /* determine beginning and ending pixel of contiguous cells */ for (i=1,bpixel=epixel=pixel1=pixel2=pixel[0]; i<ncells; i++) { if (pixel[i]==pixel[i-1]+1) pixel2 = pixel[i]; else pixel1 = pixel2 = pixel[i]; if (pixel2-pixel1>=epixel-bpixel) { bpixel = pixel1; epixel = pixel2; } } /* number of pixels must be at least 8 */ npixels = epixel-bpixel+1; if (npixels<8) { XUngrabServer(dpy); return 0; } /* force number of contiguous cells to be an integer cubed */ for (i=2,imax=0; i*i*i<=npixels; i++,imax++); npixels = (imax+1)*(imax+1)*(imax+1); bpixel = epixel-npixels+1; /* free cells not in contiguous range */ for (i=0; i<ncells; i++) if (pixel[i]<bpixel || pixel[i]>epixel) XFreeColors(dpy,cmap,&pixel[i],1,0); /* store colors in contiguous range of allocated cells */ rmult = (imax+1)*(imax+1); gmult = imax+1; bmult = 1; for (i=0; i<npixels; i++) { color.pixel = bpixel+i; color.red = (unsigned short) (i/rmult); color.green = (unsigned short) ((i-color.red*rmult)/gmult); color.blue = (unsigned short) (i-color.red*rmult-color.green*gmult); color.red *= 65535/imax; color.green *= 65535/imax; color.blue *= 65535/imax; color.flags = DoRed|DoGreen|DoBlue; XStoreColor(dpy,cmap,&color); } /* set standard colormap */ scmap->colormap = cmap; scmap->red_max = imax; scmap->green_max = imax; scmap->blue_max = imax; scmap->red_mult = rmult; scmap->green_mult = gmult; scmap->blue_mult = bmult; scmap->base_pixel = bpixel; XSetStandardColormap(dpy,root,scmap,XA_RGB_DEFAULT_MAP); } /* ungrab the server before returning */ XUngrabServer(dpy); return 1; }