/* vi:set ts=8 sts=4 sw=4 noet: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * (C) 2001,2005 by Marcin Dalecki * * Implementation of dialog functions for the Motif GUI variant. * * Note about Lesstif: Apparently lesstif doesn't get the widget layout right, * when using a dynamic scrollbar policy. */ #include "vim.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern Widget vimShell; #ifdef FEAT_MENU # define apply_fontlist(w) gui_motif_menu_fontlist(w) #else # define apply_fontlist(w) #endif ///////////////////////////////////////////////////////////////////////////// // Font selection dialogue implementation. static char wild[3] = "*"; /* * FIXME: This is a generic function, which should be used throughout the whole * application. * * Add close_callback, which will be called when the user selects close from * the window menu. The close menu item usually activates f.kill which sends a * WM_DELETE_WINDOW protocol request for the window. */ static void add_cancel_action(Widget shell, XtCallbackProc close_callback, void *arg) { static Atom wmp_atom = 0; static Atom dw_atom = 0; Display *display = XtDisplay(shell); // deactivate the built-in delete response of killing the application XtVaSetValues(shell, XmNdeleteResponse, XmDO_NOTHING, NULL); // add a delete window protocol callback instead if (!dw_atom) { wmp_atom = XmInternAtom(display, "WM_PROTOCOLS", True); dw_atom = XmInternAtom(display, "WM_DELETE_WINDOW", True); } XmAddProtocolCallback(shell, wmp_atom, dw_atom, close_callback, arg); } #define MAX_FONTS 65535 #define MAX_FONT_NAME_LEN 256 #define MAX_ENTRIES_IN_LIST 5000 #define MAX_DISPLAY_SIZE 150 #define TEMP_BUF_SIZE 256 enum ListSpecifier { ENCODING, NAME, STYLE, SIZE, NONE }; typedef struct _SharedFontSelData { Widget dialog; Widget ok; Widget cancel; Widget encoding_pulldown; Widget encoding_menu; Widget list[NONE]; Widget name; Widget sample; char **names; // font name array of arrays int num; // number of font names String sel[NONE]; // selection category Boolean in_pixels; // toggle state - size in pixels char *font_name; // current font name XFontStruct *old; // font data structure for sample display XmFontList old_list; // font data structure for sample display Boolean exit; // used for program exit control } SharedFontSelData; /* * Checking access to the font name array for validity. */ static char * fn(SharedFontSelData *data, int i) { // Assertion checks: if (data->num < 0) abort(); if (i >= data->num) i = data->num - 1; if (i < 0) i = 0; return data->names[i]; } /* * Get a specific substring from a font name. */ static void get_part(char *in, int pos, char *out) { int i; int j; *out = '\0'; for (i = 0; (pos > 0) && (in[i] != '\0'); ++i) if (in[i] == '-') pos--; if (in[i] == '\0') return; for (j = 0; (in[i] != '-') && (in[i] != '\0'); ++i, ++j) out[j] = in[i]; out[j] = '\0'; } /* * Given a font name this function returns the part used in the first * scroll list. */ static void name_part(char *font, char *buf) { char buf2[TEMP_BUF_SIZE]; char buf3[TEMP_BUF_SIZE]; get_part(font, 2, buf2); get_part(font, 1, buf3); if (*buf3 != NUL) vim_snprintf(buf, TEMP_BUF_SIZE, "%s (%s)", buf2, buf3); else vim_snprintf(buf, TEMP_BUF_SIZE, "%s", buf2); } /* * Given a font name this function returns the part used in the second scroll list. */ static void style_part(char *font, char *buf) { char buf2[TEMP_BUF_SIZE]; char buf3[TEMP_BUF_SIZE]; get_part(font, 3, buf3); get_part(font, 5, buf2); if (!strcmp(buf2, "normal") && !strcmp(buf2, "Normal") && !strcmp(buf2, "NORMAL")) vim_snprintf(buf, TEMP_BUF_SIZE, "%s %s", buf3, buf2); else strcpy(buf, buf3); get_part(font, 6, buf2); if (buf2[0] != '\0') vim_snprintf(buf3, TEMP_BUF_SIZE, "%s %s", buf, buf2); else strcpy(buf3, buf); get_part(font, 4, buf2); if (!strcmp(buf2, "o") || !strcmp(buf2, "O")) vim_snprintf(buf, TEMP_BUF_SIZE, "%s oblique", buf3); else if (!strcmp(buf2, "i") || !strcmp(buf2, "I")) vim_snprintf(buf, TEMP_BUF_SIZE, "%s italic", buf3); if (!strcmp(buf, " ")) strcpy(buf, "-"); } /* * Given a font name this function returns the part used in the third * scroll list. */ static void size_part(char *font, char *buf, int inPixels) { int size; float temp; *buf = '\0'; if (inPixels) { get_part(font, 7, buf); if (*buf != NUL) { size = atoi(buf); sprintf(buf, "%3d", size); } } else { get_part(font, 8, buf); if (*buf != NUL) { size = atoi(buf); temp = (float)size / 10.0; size = temp; if (buf[strlen(buf) - 1] == '0') sprintf(buf, "%3d", size); else sprintf(buf, "%4.1f", temp); } } } /* * Given a font name this function returns the part used in the choice menu. */ static void encoding_part(char *font, char *buf) { char buf1[TEMP_BUF_SIZE]; char buf2[TEMP_BUF_SIZE]; *buf = '\0'; get_part(font, 13, buf1); get_part(font, 14, buf2); if (*buf1 != NUL && *buf2 != NUL) vim_snprintf(buf, TEMP_BUF_SIZE, "%s-%s", buf1, buf2); if (!strcmp(buf, " ")) strcpy(buf, "-"); } /* * Inserts a string into correct sorted position in a list. */ static void add_to_list(char **buf, char *item, int *count) { int i; int j; if (*count == MAX_ENTRIES_IN_LIST) return; // avoid duplication for (i = 0; i < *count; ++i) { if (!strcmp(buf[i], item)) return; } // find order place, but make sure that wild card comes first if (!strcmp(item, wild)) i = 0; else for (i = 0; i < *count; ++i) if (strcmp(buf[i], item) > 0 && strcmp(buf[i], wild)) break; // now insert the item for (j = *count; j > i; --j) buf[j] = buf[j-1]; buf[i] = XtNewString(item); ++(*count); } /* * True if the font matches some field. */ static Boolean match(SharedFontSelData *data, enum ListSpecifier l, int i) { char buf[TEMP_BUF_SIZE]; // An empty selection or a wild card matches anything. if (!data->sel[l] || !strcmp(data->sel[l], wild)) return True; // chunk out the desired part... switch (l) { case ENCODING: encoding_part(fn(data, i), buf); break; case NAME: name_part(fn(data, i), buf); break; case STYLE: style_part(fn(data, i), buf); break; case SIZE: size_part(fn(data, i), buf, data->in_pixels); break; default: ; } // ...and chew it now return !strcmp(buf, data->sel[l]); } static Boolean proportional(char *font) { char buf[TEMP_BUF_SIZE]; get_part(font, 11, buf); return !strcmp(buf, "p") || !strcmp(buf, "P"); } static void encoding_callback(Widget w, SharedFontSelData *data, XtPointer dummy); /* * Parse through the fontlist data and set up the three scroll lists. The fix * parameter can be used to exclude a list from any changes. This is used for * updates after selections caused by the users actions. */ static void fill_lists(enum ListSpecifier fix, SharedFontSelDat
/*
 *  Fast C2P (Chunky-to-Planar) Conversion
 *
 *  Copyright (C) 2003-2008 Geert Uytterhoeven
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License. See the file COPYING in the main directory of this archive
 *  for more details.
 */

#include <linux/module.h>
#include <linux/string.h>

#include <asm/unaligned.h>

#include "c2p.h"
#include "c2p_core.h"


    /*
     *  Perform a full C2P step on 16 8-bit pixels, stored in 4 32-bit words
     *  containing
     *    - 16 8-bit chunky pixels on input
     *    - permutated planar data (2 planes per 32-bit word) on output
     */

static void c2p_16x8(u32 d[4])
{
	transp4(d, 8, 2);
	transp4(d, 1, 2);
	transp4x(d, 16, 2);
	transp4x(d, 2, 2);
	transp4(d, 4, 1);
}


    /*
     *  Array containing the permutation indices of the planar data after c2p
     */

static const int perm_c2p_16x8[4] = { 1, 3, 0, 2 };


    /*
     *  Store a full block of iplan2 data after c2p conversion
     */

static inline void store_iplan2(void *dst, u32 bpp, u32 d[4])
{
	int i;

	for (i = 0; i < bpp/2; i++, dst += 4)
		put_unaligned_be32(d[perm_c2p_16x8[i]], dst);
}


    /*
     *  Store a partial block of iplan2 data after c2p conversion
     */

static inline void store_iplan2_masked(void *dst, u32 bpp, u32 d[4], u32 mask)
{
	int i;

	for (i = 0; i < bpp/2; i++, dst += 4)
		put_unaligned_be32(comp(d[perm_c2p_16x8[i]],
					get_unaligned_be32(dst), mask),
				   dst);
}


    /*
     *  c2p_iplan2 - Copy 8-bit chunky image data to an interleaved planar
     *  frame buffer with 2 bytes of interleave
     *  @dst: Starting address of the planar frame buffer
     *  @dx: Horizontal destination offset (in pixels)
     *  @dy: Vertical destination offset (in pixels)
     *  @width: Image width (in pixels)
     *  @height: Image height (in pixels)
     *  @dst_nextline: Frame buffer offset to the next line (in bytes)
     *  @src_nextline: Image offset to the next line (in bytes)
     *  @bpp: Bits per pixel of the planar frame buffer (2, 4, or 8)
     */

void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
		u32 height, u32 dst_nextline, u32 src_nextline, u32 bpp)
{
	union {
		u8 pixels[16];
		u32 words[4];
	} d;
	u32 dst_idx, first, last, w;
	const u8 *c;
	void *p;

	dst += dy*dst_nextline+(dx & ~15)*bpp;
	dst_idx = dx % 16;
	first = 0xffffU >> dst_idx;
	first |= first << 16;
	last = 0xffffU ^ (0xffffU >> ((dst_idx+width) % 16));
	last |= last << 16;
	while (height--) {
		c = src;
		p = dst;
		w = width;
		if (dst_idx+width <= 16) {
			/* Single destination word */
			first &= last;
			memset(d.pixels, 0, sizeof(d));
			memcpy(d.pixels+dst_idx, c, width);
			c += width;
			c2p_16x8(d.words);
			store_iplan2_masked(p, bpp, d.words, first);
			p += bpp*2;
		} else {
			/* Multiple destination words */
			w = width;
			/* Leading bits */
			if (dst_idx) {
				w = 16 - dst_idx;
				memset(d.pixels