diff options
30 files changed, 23220 insertions, 23161 deletions
diff --git a/libX11/src/KeyBind.c b/libX11/src/KeyBind.c index 6eb84328c..221cedd8c 100644 --- a/libX11/src/KeyBind.c +++ b/libX11/src/KeyBind.c @@ -1,1077 +1,1078 @@ -/*
-
-Copyright 1985, 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-/* Beware, here be monsters (still under construction... - JG */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xlibint.h>
-#include <X11/Xutil.h>
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_LATIN2
-#define XK_LATIN3
-#define XK_LATIN4
-#define XK_LATIN8
-#define XK_LATIN9
-#define XK_CYRILLIC
-#define XK_GREEK
-#define XK_ARMENIAN
-#define XK_CAUCASUS
-#define XK_VIETNAMESE
-#define XK_XKB_KEYS
-#include <X11/keysymdef.h>
-#include <stdio.h>
-
-#ifdef USE_OWN_COMPOSE
-#include "imComp.h"
-
-#endif
-
-#include "Xresource.h"
-#include "Key.h"
-
-#ifdef XKB
-#include "XKBlib.h"
-#include "XKBlibint.h"
-#define XKeycodeToKeysym _XKeycodeToKeysym
-#define XKeysymToKeycode _XKeysymToKeycode
-#define XLookupKeysym _XLookupKeysym
-#define XRefreshKeyboardMapping _XRefreshKeyboardMapping
-#define XLookupString _XLookupString
-/* XKBBind.c */
-#else
-#define XkbKeysymToModifiers _XKeysymToModifiers
-#endif
-
-#define AllMods (ShiftMask|LockMask|ControlMask| \
- Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
-
-static void
-ComputeMaskFromKeytrans(
- Display *dpy,
- register struct _XKeytrans *p);
-
-struct _XKeytrans {
- struct _XKeytrans *next;/* next on list */
- char *string; /* string to return when the time comes */
- int len; /* length of string (since NULL is legit)*/
- KeySym key; /* keysym rebound */
- unsigned int state; /* modifier state */
- KeySym *modifiers; /* modifier keysyms you want */
- int mlen; /* length of modifier list */
-};
-
-static KeySym
-KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
-{
- register int per = dpy->keysyms_per_keycode;
- register KeySym *syms;
- KeySym lsym, usym;
-
- if ((col < 0) || ((col >= per) && (col > 3)) ||
- ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
- return NoSymbol;
-
- syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
- if (col < 4) {
- if (col > 1) {
- while ((per > 2) && (syms[per - 1] == NoSymbol))
- per--;
- if (per < 3)
- col -= 2;
- }
- if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
- XConvertCase(syms[col&~1], &lsym, &usym);
- if (!(col & 1))
- return lsym;
- else if (usym == lsym)
- return NoSymbol;
- else
- return usym;
- }
- }
- return syms[col];
-}
-
-KeySym
-XKeycodeToKeysym(Display *dpy,
-#if NeedWidePrototypes
- unsigned int kc,
-#else
- KeyCode kc,
-#endif
- int col)
-{
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return NoSymbol;
- return KeyCodetoKeySym(dpy, kc, col);
-}
-
-KeyCode
-XKeysymToKeycode(
- Display *dpy,
- KeySym ks)
-{
- register int i, j;
-
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return (KeyCode) 0;
- for (j = 0; j < dpy->keysyms_per_keycode; j++) {
- for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
- if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks)
- return i;
- }
- }
- return 0;
-}
-
-KeySym
-XLookupKeysym(
- register XKeyEvent *event,
- int col)
-{
- if ((! event->display->keysyms) && (! _XKeyInitialize(event->display)))
- return NoSymbol;
- return KeyCodetoKeySym(event->display, event->keycode, col);
-}
-
-static void
-ResetModMap(
- Display *dpy)
-{
- register XModifierKeymap *map;
- register int i, j, n;
- KeySym sym;
- register struct _XKeytrans *p;
-
- map = dpy->modifiermap;
- /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock,
- * else if any contains Shift_Lock, then interpret as Shift_Lock,
- * else ignore Lock altogether.
- */
- dpy->lock_meaning = NoSymbol;
- /* Lock modifiers are in the second row of the matrix */
- n = 2 * map->max_keypermod;
- for (i = map->max_keypermod; i < n; i++) {
- for (j = 0; j < dpy->keysyms_per_keycode; j++) {
- sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
- if (sym == XK_Caps_Lock) {
- dpy->lock_meaning = XK_Caps_Lock;
- break;
- } else if (sym == XK_Shift_Lock) {
- dpy->lock_meaning = XK_Shift_Lock;
- }
- else if (sym == XK_ISO_Lock) {
- dpy->lock_meaning = XK_Caps_Lock;
- break;
- }
- }
- }
- /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
- dpy->mode_switch = 0;
- dpy->num_lock = 0;
- n *= 4;
- for (i = 3*map->max_keypermod; i < n; i++) {
- for (j = 0; j < dpy->keysyms_per_keycode; j++) {
- sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
- if (sym == XK_Mode_switch)
- dpy->mode_switch |= 1 << (i / map->max_keypermod);
- if (sym == XK_Num_Lock)
- dpy->num_lock |= 1 << (i / map->max_keypermod);
- }
- }
- for (p = dpy->key_bindings; p; p = p->next)
- ComputeMaskFromKeytrans(dpy, p);
-}
-
-static int
-InitModMap(
- Display *dpy)
-{
- register XModifierKeymap *map;
-
- if (! (map = XGetModifierMapping(dpy)))
- return 0;
- LockDisplay(dpy);
- if (dpy->modifiermap)
- XFreeModifiermap(dpy->modifiermap);
- dpy->modifiermap = map;
- dpy->free_funcs->modifiermap = XFreeModifiermap;
- if (dpy->keysyms)
- ResetModMap(dpy);
- UnlockDisplay(dpy);
- return 1;
-}
-
-int
-XRefreshKeyboardMapping(register XMappingEvent *event)
-{
-
- if(event->request == MappingKeyboard) {
- /* XXX should really only refresh what is necessary
- * for now, make initialize test fail
- */
- LockDisplay(event->display);
- if (event->display->keysyms) {
- Xfree ((char *)event->display->keysyms);
- event->display->keysyms = NULL;
- }
- UnlockDisplay(event->display);
- }
- if(event->request == MappingModifier) {
- LockDisplay(event->display);
- if (event->display->modifiermap) {
- XFreeModifiermap(event->display->modifiermap);
- event->display->modifiermap = NULL;
- }
- UnlockDisplay(event->display);
- /* go ahead and get it now, since initialize test may not fail */
- if (event->display->keysyms)
- (void) InitModMap(event->display);
- }
- return 1;
-}
-
-int
-_XKeyInitialize(
- Display *dpy)
-{
- int per, n;
- KeySym *keysyms;
-
- /*
- * lets go get the keysyms from the server.
- */
- if (!dpy->keysyms) {
- n = dpy->max_keycode - dpy->min_keycode + 1;
- keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode,
- n, &per);
- /* keysyms may be NULL */
- if (! keysyms) return 0;
-
- LockDisplay(dpy);
- if (dpy->keysyms)
- Xfree ((char *)dpy->keysyms);
- dpy->keysyms = keysyms;
- dpy->keysyms_per_keycode = per;
- if (dpy->modifiermap)
- ResetModMap(dpy);
- UnlockDisplay(dpy);
- }
- if (!dpy->modifiermap)
- return InitModMap(dpy);
- return 1;
-}
-
-static void
-UCSConvertCase( register unsigned code,
- KeySym *lower,
- KeySym *upper )
-{
- /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
- /* NB: Only converts simple one-to-one mappings. */
-
- /* Tables are used where they take less space than */
- /* the code to work out the mappings. Zero values mean */
- /* undefined code points. */
-
- static unsigned short const IPAExt_upper_mapping[] = { /* part only */
- 0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
- 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
- 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
- 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
- 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
- 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
- 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
- 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
- 0x0290, 0x0291, 0x01B7
- };
-
- static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */
- 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
- 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
- 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
- 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
- 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
- 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
- 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
- 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
- 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
- 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
- };
-
- static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */
- 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
- 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
- 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
- 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
- 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
- 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
- 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
- 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
- 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
- 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
- };
-
- static unsigned short const Greek_upper_mapping[] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
- 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
- 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
- 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
- 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
- 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
- 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
- 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
- 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
- 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
- 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
- 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
- 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- static unsigned short const Greek_lower_mapping[] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
- 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
- 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
- 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
- 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
- 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
- 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
- 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
- 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
- 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
- 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
- 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
- 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
- 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
- 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
- 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- static unsigned short const GreekExt_lower_mapping[] = {
- 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
- 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
- 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
- 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
- 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
- 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
- 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
- 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
- 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
- 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
- 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
- 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
- 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
- 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
- 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
- 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
- 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
- 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
- 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
- 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
- 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
- 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
- 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
- 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
- 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
- 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
- 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
- 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
- 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
- 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
- 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
- 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
- };
-
- static unsigned short const GreekExt_upper_mapping[] = {
- 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
- 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
- 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
- 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
- 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
- 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
- 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
- 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
- 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
- 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
- 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
- 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
- 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
- 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
- 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
- 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
- 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
- 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
- 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
- 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
- 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
- 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
- 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
- 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
- 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
- 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
- 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
- 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
- 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
- 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
- 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
- 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
- };
-
- *lower = code;
- *upper = code;
-
- /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
- if (code <= 0x00ff) {
- if (code >= 0x0041 && code <= 0x005a) /* A-Z */
- *lower += 0x20;
- else if (code >= 0x0061 && code <= 0x007a) /* a-z */
- *upper -= 0x20;
- else if ( (code >= 0x00c0 && code <= 0x00d6) ||
- (code >= 0x00d8 && code <= 0x00de) )
- *lower += 0x20;
- else if ( (code >= 0x00e0 && code <= 0x00f6) ||
- (code >= 0x00f8 && code <= 0x00fe) )
- *upper -= 0x20;
- else if (code == 0x00ff) /* y with diaeresis */
- *upper = 0x0178;
- else if (code == 0x00b5) /* micro sign */
- *upper = 0x039c;
- return;
- }
-
- /* Latin Extended-A, U+0100 to U+017F */
- if (code >= 0x0100 && code <= 0x017f) {
- if ( (code >= 0x0100 && code <= 0x012f) ||
- (code >= 0x0132 && code <= 0x0137) ||
- (code >= 0x014a && code <= 0x0177) ) {
- *upper = code & ~1;
- *lower = code | 1;
- }
- else if ( (code >= 0x0139 && code <= 0x0148) ||
- (code >= 0x0179 && code <= 0x017e) ) {
- if (code & 1)
- *lower += 1;
- else
- *upper -= 1;
- }
- else if (code == 0x0130)
- *lower = 0x0069;
- else if (code == 0x0131)
- *upper = 0x0049;
- else if (code == 0x0178)
- *lower = 0x00ff;
- else if (code == 0x017f)
- *upper = 0x0053;
- return;
- }
-
- /* Latin Extended-B, U+0180 to U+024F */
- if (code >= 0x0180 && code <= 0x024f) {
- if (code >= 0x01cd && code <= 0x01dc) {
- if (code & 1)
- *lower += 1;
- else
- *upper -= 1;
- }
- else if ( (code >= 0x01de && code <= 0x01ef) ||
- (code >= 0x01f4 && code <= 0x01f5) ||
- (code >= 0x01f8 && code <= 0x021f) ||
- (code >= 0x0222 && code <= 0x0233) ) {
- *lower |= 1;
- *upper &= ~1;
- }
- else if (code >= 0x0180 && code <= 0x01cc) {
- *lower = LatinExtB_lower_mapping[code - 0x0180];
- *upper = LatinExtB_upper_mapping[code - 0x0180];
- }
- else if (code == 0x01dd)
- *upper = 0x018e;
- else if (code == 0x01f1 || code == 0x01f2) {
- *lower = 0x01f3;
- *upper = 0x01f1;
- }
- else if (code == 0x01f3)
- *upper = 0x01f1;
- else if (code == 0x01f6)
- *lower = 0x0195;
- else if (code == 0x01f7)
- *lower = 0x01bf;
- else if (code == 0x0220)
- *lower = 0x019e;
- return;
- }
-
- /* IPA Extensions, U+0250 to U+02AF */
- if (code >= 0x0253 && code <= 0x0292) {
- *upper = IPAExt_upper_mapping[code - 0x0253];
- }
-
- /* Combining Diacritical Marks, U+0300 to U+036F */
- if (code == 0x0345) {
- *upper = 0x0399;
- }
-
- /* Greek and Coptic, U+0370 to U+03FF */
- if (code >= 0x0370 && code <= 0x03ff) {
- *lower = Greek_lower_mapping[code - 0x0370];
- *upper = Greek_upper_mapping[code - 0x0370];
- if (*upper == 0)
- *upper = code;
- if (*lower == 0)
- *lower = code;
- }
-
- /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
- if ( (code >= 0x0400 && code <= 0x04ff) ||
- (code >= 0x0500 && code <= 0x052f) ) {
- if (code >= 0x0400 && code <= 0x040f)
- *lower += 0x50;
- else if (code >= 0x0410 && code <= 0x042f)
- *lower += 0x20;
- else if (code >= 0x0430 && code <= 0x044f)
- *upper -= 0x20;
- else if (code >= 0x0450 && code <= 0x045f)
- *upper -= 0x50;
- else if ( (code >= 0x0460 && code <= 0x0481) ||
- (code >= 0x048a && code <= 0x04bf) ||
- (code >= 0x04d0 && code <= 0x04f5) ||
- (code >= 0x04f8 && code <= 0x04f9) ||
- (code >= 0x0500 && code <= 0x050f) ) {
- *upper &= ~1;
- *lower |= 1;
- }
- else if (code >= 0x04c1 && code <= 0x04ce) {
- if (code & 1)
- *lower += 1;
- else
- *upper -= 1;
- }
- }
-
- /* Armenian, U+0530 to U+058F */
- if (code >= 0x0530 && code <= 0x058f) {
- if (code >= 0x0531 && code <= 0x0556)
- *lower += 0x30;
- else if (code >=0x0561 && code <= 0x0586)
- *upper -= 0x30;
- }
-
- /* Latin Extended Additional, U+1E00 to U+1EFF */
- if (code >= 0x1e00 && code <= 0x1eff) {
- if ( (code >= 0x1e00 && code <= 0x1e95) ||
- (code >= 0x1ea0 && code <= 0x1ef9) ) {
- *upper &= ~1;
- *lower |= 1;
- }
- else if (code == 0x1e9b)
- *upper = 0x1e60;
- }
-
- /* Greek Extended, U+1F00 to U+1FFF */
- if (code >= 0x1f00 && code <= 0x1fff) {
- *lower = GreekExt_lower_mapping[code - 0x1f00];
- *upper = GreekExt_upper_mapping[code - 0x1f00];
- if (*upper == 0)
- *upper = code;
- if (*lower == 0)
- *lower = code;
- }
-
- /* Letterlike Symbols, U+2100 to U+214F */
- if (code >= 0x2100 && code <= 0x214f) {
- switch (code) {
- case 0x2126: *lower = 0x03c9; break;
- case 0x212a: *lower = 0x006b; break;
- case 0x212b: *lower = 0x00e5; break;
- }
- }
- /* Number Forms, U+2150 to U+218F */
- else if (code >= 0x2160 && code <= 0x216f)
- *lower += 0x10;
- else if (code >= 0x2170 && code <= 0x217f)
- *upper -= 0x10;
- /* Enclosed Alphanumerics, U+2460 to U+24FF */
- else if (code >= 0x24b6 && code <= 0x24cf)
- *lower += 0x1a;
- else if (code >= 0x24d0 && code <= 0x24e9)
- *upper -= 0x1a;
- /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
- else if (code >= 0xff21 && code <= 0xff3a)
- *lower += 0x20;
- else if (code >= 0xff41 && code <= 0xff5a)
- *upper -= 0x20;
- /* Deseret, U+10400 to U+104FF */
- else if (code >= 0x10400 && code <= 0x10427)
- *lower += 0x28;
- else if (code >= 0x10428 && code <= 0x1044f)
- *upper -= 0x28;
-}
-
-void
-XConvertCase(
- register KeySym sym,
- KeySym *lower,
- KeySym *upper)
-{
- /* Latin 1 keysym */
- if (sym < 0x100) {
- UCSConvertCase(sym, lower, upper);
- return;
- }
-
- /* Unicode keysym */
- if ((sym & 0xff000000) == 0x01000000) {
- UCSConvertCase((sym & 0x00ffffff), lower, upper);
- *upper |= 0x01000000;
- *lower |= 0x01000000;
- return;
- }
-
- /* Legacy keysym */
-
- *lower = sym;
- *upper = sym;
-
- switch(sym >> 8) {
- case 1: /* Latin 2 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym == XK_Aogonek)
- *lower = XK_aogonek;
- else if (sym >= XK_Lstroke && sym <= XK_Sacute)
- *lower += (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_Scaron && sym <= XK_Zacute)
- *lower += (XK_scaron - XK_Scaron);
- else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
- *lower += (XK_zcaron - XK_Zcaron);
- else if (sym == XK_aogonek)
- *upper = XK_Aogonek;
- else if (sym >= XK_lstroke && sym <= XK_sacute)
- *upper -= (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_scaron && sym <= XK_zacute)
- *upper -= (XK_scaron - XK_Scaron);
- else if (sym >= XK_zcaron && sym <= XK_zabovedot)
- *upper -= (XK_zcaron - XK_Zcaron);
- else if (sym >= XK_Racute && sym <= XK_Tcedilla)
- *lower += (XK_racute - XK_Racute);
- else if (sym >= XK_racute && sym <= XK_tcedilla)
- *upper -= (XK_racute - XK_Racute);
- break;
- case 2: /* Latin 3 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
- *lower += (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
- *lower += (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
- *upper -= (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
- *upper -= (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
- *lower += (XK_cabovedot - XK_Cabovedot);
- else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
- *upper -= (XK_cabovedot - XK_Cabovedot);
- break;
- case 3: /* Latin 4 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Rcedilla && sym <= XK_Tslash)
- *lower += (XK_rcedilla - XK_Rcedilla);
- else if (sym >= XK_rcedilla && sym <= XK_tslash)
- *upper -= (XK_rcedilla - XK_Rcedilla);
- else if (sym == XK_ENG)
- *lower = XK_eng;
- else if (sym == XK_eng)
- *upper = XK_ENG;
- else if (sym >= XK_Amacron && sym <= XK_Umacron)
- *lower += (XK_amacron - XK_Amacron);
- else if (sym >= XK_amacron && sym <= XK_umacron)
- *upper -= (XK_amacron - XK_Amacron);
- break;
- case 6: /* Cyrillic */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
- *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
- *upper += (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
- *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
- else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
- *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
- break;
- case 7: /* Greek */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
- *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
- sym != XK_Greek_iotaaccentdieresis &&
- sym != XK_Greek_upsilonaccentdieresis)
- *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
- *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
- else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
- sym != XK_Greek_finalsmallsigma)
- *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
- break;
- case 0x13: /* Latin 9 */
- if (sym == XK_OE)
- *lower = XK_oe;
- else if (sym == XK_oe)
- *upper = XK_OE;
- else if (sym == XK_Ydiaeresis)
- *lower = XK_ydiaeresis;
- break;
- }
-}
-
-int
-_XTranslateKey( register Display *dpy,
- KeyCode keycode,
- register unsigned int modifiers,
- unsigned int *modifiers_return,
- KeySym *keysym_return)
-{
- int per;
- register KeySym *syms;
- KeySym sym, lsym, usym;
-
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return 0;
- *modifiers_return = ((ShiftMask|LockMask)
- | dpy->mode_switch | dpy->num_lock);
- if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
- {
- *keysym_return = NoSymbol;
- return 1;
- }
- per = dpy->keysyms_per_keycode;
- syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
- while ((per > 2) && (syms[per - 1] == NoSymbol))
- per--;
- if ((per > 2) && (modifiers & dpy->mode_switch)) {
- syms += 2;
- per -= 2;
- }
- if ((modifiers & dpy->num_lock) &&
- (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
- if ((modifiers & ShiftMask) ||
- ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
- *keysym_return = syms[0];
- else
- *keysym_return = syms[1];
- } else if (!(modifiers & ShiftMask) &&
- (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
- if ((per == 1) || (syms[1] == NoSymbol))
- XConvertCase(syms[0], keysym_return, &usym);
- else
- *keysym_return = syms[0];
- } else if (!(modifiers & LockMask) ||
- (dpy->lock_meaning != XK_Caps_Lock)) {
- if ((per == 1) || ((usym = syms[1]) == NoSymbol))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- } else {
- if ((per == 1) || ((sym = syms[1]) == NoSymbol))
- sym = syms[0];
- XConvertCase(sym, &lsym, &usym);
- if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
- ((sym != usym) || (lsym == usym)))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- }
- if (*keysym_return == XK_VoidSymbol)
- *keysym_return = NoSymbol;
- return 1;
-}
-
-int
-_XTranslateKeySym(
- Display *dpy,
- register KeySym symbol,
- unsigned int modifiers,
- char *buffer,
- int nbytes)
-{
- register struct _XKeytrans *p;
- int length;
- unsigned long hiBytes;
- register unsigned char c;
-
- if (!symbol)
- return 0;
- /* see if symbol rebound, if so, return that string. */
- for (p = dpy->key_bindings; p; p = p->next) {
- if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
- length = p->len;
- if (length > nbytes) length = nbytes;
- memcpy (buffer, p->string, length);
- return length;
- }
- }
- /* try to convert to Latin-1, handling control */
- hiBytes = symbol >> 8;
- if (!(nbytes &&
- ((hiBytes == 0) ||
- ((hiBytes == 0xFF) &&
- (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
- (symbol == XK_Return) ||
- (symbol == XK_Escape) ||
- (symbol == XK_KP_Space) ||
- (symbol == XK_KP_Tab) ||
- (symbol == XK_KP_Enter) ||
- ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
- (symbol == XK_KP_Equal) ||
- (symbol == XK_Delete))))))
- return 0;
-
- /* if X keysym, convert to ascii by grabbing low 7 bits */
- if (symbol == XK_KP_Space)
- c = XK_space & 0x7F; /* patch encoding botch */
- else if (hiBytes == 0xFF)
- c = symbol & 0x7F;
- else
- c = symbol & 0xFF;
- /* only apply Control key if it makes sense, else ignore it */
- if (modifiers & ControlMask) {
- if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
- else if (c == '2') c = '\000';
- else if (c >= '3' && c <= '7') c -= ('3' - '\033');
- else if (c == '8') c = '\177';
- else if (c == '/') c = '_' & 0x1F;
- }
- buffer[0] = c;
- return 1;
-}
-
-/*ARGSUSED*/
-int
-XLookupString (
- register XKeyEvent *event,
- char *buffer, /* buffer */
- int nbytes, /* space in buffer for characters */
- KeySym *keysym,
- XComposeStatus *status) /* not implemented */
-{
- unsigned int modifiers;
- KeySym symbol;
-
- if (! _XTranslateKey(event->display, event->keycode, event->state,
- &modifiers, &symbol))
- return 0;
-
-#ifdef USE_OWN_COMPOSE
- if ( status ) {
- static int been_here= 0;
- if ( !been_here ) {
- XimCompInitTables();
- been_here = 1;
- }
- if ( !XimCompLegalStatus(status) ) {
- status->compose_ptr = NULL;
- status->chars_matched = 0;
- }
- if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
- XimCompIsComposeKey(symbol,event->keycode,status) ) {
- XimCompRtrn rtrn;
- switch (XimCompProcessSym(status,symbol,&rtrn)) {
- case XIM_COMP_IGNORE:
- break;
- case XIM_COMP_IN_PROGRESS:
- if ( keysym!=NULL )
- *keysym = NoSymbol;
- return 0;
- case XIM_COMP_FAIL:
- {
- int n = 0, len= 0;
- for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
- if ( nbytes-len > 0 ) {
- len+= _XTranslateKeySym(event->display,rtrn.sym[n],
- event->state,
- buffer+len,nbytes-len);
- }
- }
- if ( keysym!=NULL ) {
- if ( n==1 ) *keysym = rtrn.sym[0];
- else *keysym = NoSymbol;
- }
- return len;
- }
- case XIM_COMP_SUCCEED:
- {
- int len,n = 0;
-
- symbol = rtrn.matchSym;
- if ( keysym!=NULL ) *keysym = symbol;
- if ( rtrn.str[0]!='\0' ) {
- strncpy(buffer,rtrn.str,nbytes-1);
- buffer[nbytes-1]= '\0';
- len = strlen(buffer);
- }
- else {
- len = _XTranslateKeySym(event->display,symbol,
- event->state,
- buffer,nbytes);
- }
- for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
- if ( nbytes-len > 0 ) {
- len+= _XTranslateKeySym(event->display,rtrn.sym[n],
- event->state,
- buffer+len,nbytes-len);
- }
- }
- return len;
- }
- }
- }
- }
-#endif
-
- if (keysym)
- *keysym = symbol;
- /* arguable whether to use (event->state & ~modifiers) here */
- return _XTranslateKeySym(event->display, symbol, event->state,
- buffer, nbytes);
-}
-
-static void
-_XFreeKeyBindings(
- Display *dpy)
-{
- register struct _XKeytrans *p, *np;
-
- for (p = dpy->key_bindings; p; p = np) {
- np = p->next;
- Xfree(p->string);
- Xfree((char *)p->modifiers);
- Xfree((char *)p);
- }
-}
-
-int
-XRebindKeysym (
- Display *dpy,
- KeySym keysym,
- KeySym *mlist,
- int nm, /* number of modifiers in mlist */
- _Xconst unsigned char *str,
- int nbytes)
-{
- register struct _XKeytrans *tmp, *p;
- int nb;
-
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return 0;
- LockDisplay(dpy);
- tmp = dpy->key_bindings;
- nb = sizeof(KeySym) * nm;
-
- if ((! (p = (struct _XKeytrans *) Xcalloc( 1, sizeof(struct _XKeytrans)))) ||
- ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) &&
- (nbytes > 0)) ||
- ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) &&
- (nb > 0))) {
- if (p) {
- if (p->string) Xfree(p->string);
- if (p->modifiers) Xfree((char *) p->modifiers);
- Xfree((char *) p);
- }
- UnlockDisplay(dpy);
- return 0;
- }
-
- dpy->key_bindings = p;
- dpy->free_funcs->key_bindings = _XFreeKeyBindings;
- p->next = tmp; /* chain onto list */
- memcpy (p->string, (char *) str, nbytes);
- p->len = nbytes;
- memcpy ((char *) p->modifiers, (char *) mlist, nb);
- p->key = keysym;
- p->mlen = nm;
- ComputeMaskFromKeytrans(dpy, p);
- UnlockDisplay(dpy);
- return 0;
-}
-
-unsigned
-_XKeysymToModifiers(
- Display *dpy,
- KeySym ks)
-{
- CARD8 code,mods;
- register KeySym *kmax;
- register KeySym *k;
- register XModifierKeymap *m;
-
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return 0;
- kmax = dpy->keysyms +
- (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
- k = dpy->keysyms;
- m = dpy->modifiermap;
- mods= 0;
- while (k<kmax) {
- if (*k == ks ) {
- register int j = m->max_keypermod<<3;
-
- code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode);
-
- while (--j >= 0) {
- if (code == m->modifiermap[j])
- mods|= (1<<(j/m->max_keypermod));
- }
- }
- k++;
- }
- return mods;
-}
-
-/*
- * given a list of modifiers, computes the mask necessary for later matching.
- * This routine must lookup the key in the Keymap and then search to see
- * what modifier it is bound to, if any. Sets the AnyModifier bit if it
- * can't map some keysym to a modifier.
- */
-static void
-ComputeMaskFromKeytrans(
- Display *dpy,
- register struct _XKeytrans *p)
-{
- register int i;
-
- p->state = AnyModifier;
- for (i = 0; i < p->mlen; i++) {
- p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
- }
- p->state &= AllMods;
-}
+/* + +Copyright 1985, 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* Beware, here be monsters (still under construction... - JG */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#define XK_MISCELLANY +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_LATIN8 +#define XK_LATIN9 +#define XK_CYRILLIC +#define XK_GREEK +#define XK_ARMENIAN +#define XK_CAUCASUS +#define XK_VIETNAMESE +#define XK_XKB_KEYS +#define XK_SINHALA +#include <X11/keysymdef.h> +#include <stdio.h> + +#ifdef USE_OWN_COMPOSE +#include "imComp.h" + +#endif + +#include "Xresource.h" +#include "Key.h" + +#ifdef XKB +#include "XKBlib.h" +#include "XKBlibint.h" +#define XKeycodeToKeysym _XKeycodeToKeysym +#define XKeysymToKeycode _XKeysymToKeycode +#define XLookupKeysym _XLookupKeysym +#define XRefreshKeyboardMapping _XRefreshKeyboardMapping +#define XLookupString _XLookupString +/* XKBBind.c */ +#else +#define XkbKeysymToModifiers _XKeysymToModifiers +#endif + +#define AllMods (ShiftMask|LockMask|ControlMask| \ + Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) + +static void +ComputeMaskFromKeytrans( + Display *dpy, + register struct _XKeytrans *p); + +struct _XKeytrans { + struct _XKeytrans *next;/* next on list */ + char *string; /* string to return when the time comes */ + int len; /* length of string (since NULL is legit)*/ + KeySym key; /* keysym rebound */ + unsigned int state; /* modifier state */ + KeySym *modifiers; /* modifier keysyms you want */ + int mlen; /* length of modifier list */ +}; + +static KeySym +KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col) +{ + register int per = dpy->keysyms_per_keycode; + register KeySym *syms; + KeySym lsym, usym; + + if ((col < 0) || ((col >= per) && (col > 3)) || + ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) + return NoSymbol; + + syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; + if (col < 4) { + if (col > 1) { + while ((per > 2) && (syms[per - 1] == NoSymbol)) + per--; + if (per < 3) + col -= 2; + } + if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) { + XConvertCase(syms[col&~1], &lsym, &usym); + if (!(col & 1)) + return lsym; + else if (usym == lsym) + return NoSymbol; + else + return usym; + } + } + return syms[col]; +} + +KeySym +XKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int col) +{ + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return NoSymbol; + return KeyCodetoKeySym(dpy, kc, col); +} + +KeyCode +XKeysymToKeycode( + Display *dpy, + KeySym ks) +{ + register int i, j; + + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return (KeyCode) 0; + for (j = 0; j < dpy->keysyms_per_keycode; j++) { + for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { + if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks) + return i; + } + } + return 0; +} + +KeySym +XLookupKeysym( + register XKeyEvent *event, + int col) +{ + if ((! event->display->keysyms) && (! _XKeyInitialize(event->display))) + return NoSymbol; + return KeyCodetoKeySym(event->display, event->keycode, col); +} + +static void +ResetModMap( + Display *dpy) +{ + register XModifierKeymap *map; + register int i, j, n; + KeySym sym; + register struct _XKeytrans *p; + + map = dpy->modifiermap; + /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock, + * else if any contains Shift_Lock, then interpret as Shift_Lock, + * else ignore Lock altogether. + */ + dpy->lock_meaning = NoSymbol; + /* Lock modifiers are in the second row of the matrix */ + n = 2 * map->max_keypermod; + for (i = map->max_keypermod; i < n; i++) { + for (j = 0; j < dpy->keysyms_per_keycode; j++) { + sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); + if (sym == XK_Caps_Lock) { + dpy->lock_meaning = XK_Caps_Lock; + break; + } else if (sym == XK_Shift_Lock) { + dpy->lock_meaning = XK_Shift_Lock; + } + else if (sym == XK_ISO_Lock) { + dpy->lock_meaning = XK_Caps_Lock; + break; + } + } + } + /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */ + dpy->mode_switch = 0; + dpy->num_lock = 0; + n *= 4; + for (i = 3*map->max_keypermod; i < n; i++) { + for (j = 0; j < dpy->keysyms_per_keycode; j++) { + sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); + if (sym == XK_Mode_switch) + dpy->mode_switch |= 1 << (i / map->max_keypermod); + if (sym == XK_Num_Lock) + dpy->num_lock |= 1 << (i / map->max_keypermod); + } + } + for (p = dpy->key_bindings; p; p = p->next) + ComputeMaskFromKeytrans(dpy, p); +} + +static int +InitModMap( + Display *dpy) +{ + register XModifierKeymap *map; + + if (! (map = XGetModifierMapping(dpy))) + return 0; + LockDisplay(dpy); + if (dpy->modifiermap) + XFreeModifiermap(dpy->modifiermap); + dpy->modifiermap = map; + dpy->free_funcs->modifiermap = XFreeModifiermap; + if (dpy->keysyms) + ResetModMap(dpy); + UnlockDisplay(dpy); + return 1; +} + +int +XRefreshKeyboardMapping(register XMappingEvent *event) +{ + + if(event->request == MappingKeyboard) { + /* XXX should really only refresh what is necessary + * for now, make initialize test fail + */ + LockDisplay(event->display); + if (event->display->keysyms) { + Xfree ((char *)event->display->keysyms); + event->display->keysyms = NULL; + } + UnlockDisplay(event->display); + } + if(event->request == MappingModifier) { + LockDisplay(event->display); + if (event->display->modifiermap) { + XFreeModifiermap(event->display->modifiermap); + event->display->modifiermap = NULL; + } + UnlockDisplay(event->display); + /* go ahead and get it now, since initialize test may not fail */ + if (event->display->keysyms) + (void) InitModMap(event->display); + } + return 1; +} + +int +_XKeyInitialize( + Display *dpy) +{ + int per, n; + KeySym *keysyms; + + /* + * lets go get the keysyms from the server. + */ + if (!dpy->keysyms) { + n = dpy->max_keycode - dpy->min_keycode + 1; + keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode, + n, &per); + /* keysyms may be NULL */ + if (! keysyms) return 0; + + LockDisplay(dpy); + if (dpy->keysyms) + Xfree ((char *)dpy->keysyms); + dpy->keysyms = keysyms; + dpy->keysyms_per_keycode = per; + if (dpy->modifiermap) + ResetModMap(dpy); + UnlockDisplay(dpy); + } + if (!dpy->modifiermap) + return InitModMap(dpy); + return 1; +} + +static void +UCSConvertCase( register unsigned code, + KeySym *lower, + KeySym *upper ) +{ + /* Case conversion for UCS, as in Unicode Data version 4.0.0 */ + /* NB: Only converts simple one-to-one mappings. */ + + /* Tables are used where they take less space than */ + /* the code to work out the mappings. Zero values mean */ + /* undefined code points. */ + + static unsigned short const IPAExt_upper_mapping[] = { /* part only */ + 0x0181, 0x0186, 0x0255, 0x0189, 0x018A, + 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F, + 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, + 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C, + 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277, + 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, + 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287, + 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F, + 0x0290, 0x0291, 0x01B7 + }; + + static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */ + 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, + 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F, + 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197, + 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F, + 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7, + 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF, + 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7, + 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7, + 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7, + 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA + }; + + static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */ + 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, + 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, + 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, + 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, + 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, + 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, + 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, + 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, + 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, + 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC + }; + + static unsigned short const Greek_upper_mapping[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, + 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387, + 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A, + 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000, + 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7, + 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE, + 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6, + 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE, + 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7, + 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000 + }; + + static unsigned short const Greek_lower_mapping[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, + 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387, + 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, + 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, + 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, + 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, + 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, + 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, + 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8, + 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000 + }; + + static unsigned short const GreekExt_lower_mapping[] = { + 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, + 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, + 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, + 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, + 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, + 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, + 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, + 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, + 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, + 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, + 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, + 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57, + 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, + 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, + 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, + 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000, + 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, + 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, + 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, + 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, + 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, + 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, + 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, + 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF, + 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, + 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, + 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, + 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, + 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, + 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, + 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, + 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000 + }; + + static unsigned short const GreekExt_upper_mapping[] = { + 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, + 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, + 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, + 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, + 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, + 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, + 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, + 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, + 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, + 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, + 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F, + 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, + 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, + 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, + 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, + 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000, + 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, + 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, + 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, + 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, + 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, + 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, + 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, + 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF, + 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, + 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF, + 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, + 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, + 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7, + 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF, + 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, + 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000 + }; + + *lower = code; + *upper = code; + + /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */ + if (code <= 0x00ff) { + if (code >= 0x0041 && code <= 0x005a) /* A-Z */ + *lower += 0x20; + else if (code >= 0x0061 && code <= 0x007a) /* a-z */ + *upper -= 0x20; + else if ( (code >= 0x00c0 && code <= 0x00d6) || + (code >= 0x00d8 && code <= 0x00de) ) + *lower += 0x20; + else if ( (code >= 0x00e0 && code <= 0x00f6) || + (code >= 0x00f8 && code <= 0x00fe) ) + *upper -= 0x20; + else if (code == 0x00ff) /* y with diaeresis */ + *upper = 0x0178; + else if (code == 0x00b5) /* micro sign */ + *upper = 0x039c; + return; + } + + /* Latin Extended-A, U+0100 to U+017F */ + if (code >= 0x0100 && code <= 0x017f) { + if ( (code >= 0x0100 && code <= 0x012f) || + (code >= 0x0132 && code <= 0x0137) || + (code >= 0x014a && code <= 0x0177) ) { + *upper = code & ~1; + *lower = code | 1; + } + else if ( (code >= 0x0139 && code <= 0x0148) || + (code >= 0x0179 && code <= 0x017e) ) { + if (code & 1) + *lower += 1; + else + *upper -= 1; + } + else if (code == 0x0130) + *lower = 0x0069; + else if (code == 0x0131) + *upper = 0x0049; + else if (code == 0x0178) + *lower = 0x00ff; + else if (code == 0x017f) + *upper = 0x0053; + return; + } + + /* Latin Extended-B, U+0180 to U+024F */ + if (code >= 0x0180 && code <= 0x024f) { + if (code >= 0x01cd && code <= 0x01dc) { + if (code & 1) + *lower += 1; + else + *upper -= 1; + } + else if ( (code >= 0x01de && code <= 0x01ef) || + (code >= 0x01f4 && code <= 0x01f5) || + (code >= 0x01f8 && code <= 0x021f) || + (code >= 0x0222 && code <= 0x0233) ) { + *lower |= 1; + *upper &= ~1; + } + else if (code >= 0x0180 && code <= 0x01cc) { + *lower = LatinExtB_lower_mapping[code - 0x0180]; + *upper = LatinExtB_upper_mapping[code - 0x0180]; + } + else if (code == 0x01dd) + *upper = 0x018e; + else if (code == 0x01f1 || code == 0x01f2) { + *lower = 0x01f3; + *upper = 0x01f1; + } + else if (code == 0x01f3) + *upper = 0x01f1; + else if (code == 0x01f6) + *lower = 0x0195; + else if (code == 0x01f7) + *lower = 0x01bf; + else if (code == 0x0220) + *lower = 0x019e; + return; + } + + /* IPA Extensions, U+0250 to U+02AF */ + if (code >= 0x0253 && code <= 0x0292) { + *upper = IPAExt_upper_mapping[code - 0x0253]; + } + + /* Combining Diacritical Marks, U+0300 to U+036F */ + if (code == 0x0345) { + *upper = 0x0399; + } + + /* Greek and Coptic, U+0370 to U+03FF */ + if (code >= 0x0370 && code <= 0x03ff) { + *lower = Greek_lower_mapping[code - 0x0370]; + *upper = Greek_upper_mapping[code - 0x0370]; + if (*upper == 0) + *upper = code; + if (*lower == 0) + *lower = code; + } + + /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */ + if ( (code >= 0x0400 && code <= 0x04ff) || + (code >= 0x0500 && code <= 0x052f) ) { + if (code >= 0x0400 && code <= 0x040f) + *lower += 0x50; + else if (code >= 0x0410 && code <= 0x042f) + *lower += 0x20; + else if (code >= 0x0430 && code <= 0x044f) + *upper -= 0x20; + else if (code >= 0x0450 && code <= 0x045f) + *upper -= 0x50; + else if ( (code >= 0x0460 && code <= 0x0481) || + (code >= 0x048a && code <= 0x04bf) || + (code >= 0x04d0 && code <= 0x04f5) || + (code >= 0x04f8 && code <= 0x04f9) || + (code >= 0x0500 && code <= 0x050f) ) { + *upper &= ~1; + *lower |= 1; + } + else if (code >= 0x04c1 && code <= 0x04ce) { + if (code & 1) + *lower += 1; + else + *upper -= 1; + } + } + + /* Armenian, U+0530 to U+058F */ + if (code >= 0x0530 && code <= 0x058f) { + if (code >= 0x0531 && code <= 0x0556) + *lower += 0x30; + else if (code >=0x0561 && code <= 0x0586) + *upper -= 0x30; + } + + /* Latin Extended Additional, U+1E00 to U+1EFF */ + if (code >= 0x1e00 && code <= 0x1eff) { + if ( (code >= 0x1e00 && code <= 0x1e95) || + (code >= 0x1ea0 && code <= 0x1ef9) ) { + *upper &= ~1; + *lower |= 1; + } + else if (code == 0x1e9b) + *upper = 0x1e60; + } + + /* Greek Extended, U+1F00 to U+1FFF */ + if (code >= 0x1f00 && code <= 0x1fff) { + *lower = GreekExt_lower_mapping[code - 0x1f00]; + *upper = GreekExt_upper_mapping[code - 0x1f00]; + if (*upper == 0) + *upper = code; + if (*lower == 0) + *lower = code; + } + + /* Letterlike Symbols, U+2100 to U+214F */ + if (code >= 0x2100 && code <= 0x214f) { + switch (code) { + case 0x2126: *lower = 0x03c9; break; + case 0x212a: *lower = 0x006b; break; + case 0x212b: *lower = 0x00e5; break; + } + } + /* Number Forms, U+2150 to U+218F */ + else if (code >= 0x2160 && code <= 0x216f) + *lower += 0x10; + else if (code >= 0x2170 && code <= 0x217f) + *upper -= 0x10; + /* Enclosed Alphanumerics, U+2460 to U+24FF */ + else if (code >= 0x24b6 && code <= 0x24cf) + *lower += 0x1a; + else if (code >= 0x24d0 && code <= 0x24e9) + *upper -= 0x1a; + /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */ + else if (code >= 0xff21 && code <= 0xff3a) + *lower += 0x20; + else if (code >= 0xff41 && code <= 0xff5a) + *upper -= 0x20; + /* Deseret, U+10400 to U+104FF */ + else if (code >= 0x10400 && code <= 0x10427) + *lower += 0x28; + else if (code >= 0x10428 && code <= 0x1044f) + *upper -= 0x28; +} + +void +XConvertCase( + register KeySym sym, + KeySym *lower, + KeySym *upper) +{ + /* Latin 1 keysym */ + if (sym < 0x100) { + UCSConvertCase(sym, lower, upper); + return; + } + + /* Unicode keysym */ + if ((sym & 0xff000000) == 0x01000000) { + UCSConvertCase((sym & 0x00ffffff), lower, upper); + *upper |= 0x01000000; + *lower |= 0x01000000; + return; + } + + /* Legacy keysym */ + + *lower = sym; + *upper = sym; + + switch(sym >> 8) { + case 1: /* Latin 2 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym == XK_Aogonek) + *lower = XK_aogonek; + else if (sym >= XK_Lstroke && sym <= XK_Sacute) + *lower += (XK_lstroke - XK_Lstroke); + else if (sym >= XK_Scaron && sym <= XK_Zacute) + *lower += (XK_scaron - XK_Scaron); + else if (sym >= XK_Zcaron && sym <= XK_Zabovedot) + *lower += (XK_zcaron - XK_Zcaron); + else if (sym == XK_aogonek) + *upper = XK_Aogonek; + else if (sym >= XK_lstroke && sym <= XK_sacute) + *upper -= (XK_lstroke - XK_Lstroke); + else if (sym >= XK_scaron && sym <= XK_zacute) + *upper -= (XK_scaron - XK_Scaron); + else if (sym >= XK_zcaron && sym <= XK_zabovedot) + *upper -= (XK_zcaron - XK_Zcaron); + else if (sym >= XK_Racute && sym <= XK_Tcedilla) + *lower += (XK_racute - XK_Racute); + else if (sym >= XK_racute && sym <= XK_tcedilla) + *upper -= (XK_racute - XK_Racute); + break; + case 2: /* Latin 3 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Hstroke && sym <= XK_Hcircumflex) + *lower += (XK_hstroke - XK_Hstroke); + else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex) + *lower += (XK_gbreve - XK_Gbreve); + else if (sym >= XK_hstroke && sym <= XK_hcircumflex) + *upper -= (XK_hstroke - XK_Hstroke); + else if (sym >= XK_gbreve && sym <= XK_jcircumflex) + *upper -= (XK_gbreve - XK_Gbreve); + else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex) + *lower += (XK_cabovedot - XK_Cabovedot); + else if (sym >= XK_cabovedot && sym <= XK_scircumflex) + *upper -= (XK_cabovedot - XK_Cabovedot); + break; + case 3: /* Latin 4 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Rcedilla && sym <= XK_Tslash) + *lower += (XK_rcedilla - XK_Rcedilla); + else if (sym >= XK_rcedilla && sym <= XK_tslash) + *upper -= (XK_rcedilla - XK_Rcedilla); + else if (sym == XK_ENG) + *lower = XK_eng; + else if (sym == XK_eng) + *upper = XK_ENG; + else if (sym >= XK_Amacron && sym <= XK_Umacron) + *lower += (XK_amacron - XK_Amacron); + else if (sym >= XK_amacron && sym <= XK_umacron) + *upper -= (XK_amacron - XK_Amacron); + break; + case 6: /* Cyrillic */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE) + *lower -= (XK_Serbian_DJE - XK_Serbian_dje); + else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze) + *upper += (XK_Serbian_DJE - XK_Serbian_dje); + else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN) + *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu); + else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign) + *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu); + break; + case 7: /* Greek */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent) + *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); + else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent && + sym != XK_Greek_iotaaccentdieresis && + sym != XK_Greek_upsilonaccentdieresis) + *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); + else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA) + *lower += (XK_Greek_alpha - XK_Greek_ALPHA); + else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && + sym != XK_Greek_finalsmallsigma) + *upper -= (XK_Greek_alpha - XK_Greek_ALPHA); + break; + case 0x13: /* Latin 9 */ + if (sym == XK_OE) + *lower = XK_oe; + else if (sym == XK_oe) + *upper = XK_OE; + else if (sym == XK_Ydiaeresis) + *lower = XK_ydiaeresis; + break; + } +} + +int +_XTranslateKey( register Display *dpy, + KeyCode keycode, + register unsigned int modifiers, + unsigned int *modifiers_return, + KeySym *keysym_return) +{ + int per; + register KeySym *syms; + KeySym sym, lsym, usym; + + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return 0; + *modifiers_return = ((ShiftMask|LockMask) + | dpy->mode_switch | dpy->num_lock); + if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) + { + *keysym_return = NoSymbol; + return 1; + } + per = dpy->keysyms_per_keycode; + syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; + while ((per > 2) && (syms[per - 1] == NoSymbol)) + per--; + if ((per > 2) && (modifiers & dpy->mode_switch)) { + syms += 2; + per -= 2; + } + if ((modifiers & dpy->num_lock) && + (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) { + if ((modifiers & ShiftMask) || + ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock))) + *keysym_return = syms[0]; + else + *keysym_return = syms[1]; + } else if (!(modifiers & ShiftMask) && + (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) { + if ((per == 1) || (syms[1] == NoSymbol)) + XConvertCase(syms[0], keysym_return, &usym); + else + *keysym_return = syms[0]; + } else if (!(modifiers & LockMask) || + (dpy->lock_meaning != XK_Caps_Lock)) { + if ((per == 1) || ((usym = syms[1]) == NoSymbol)) + XConvertCase(syms[0], &lsym, &usym); + *keysym_return = usym; + } else { + if ((per == 1) || ((sym = syms[1]) == NoSymbol)) + sym = syms[0]; + XConvertCase(sym, &lsym, &usym); + if (!(modifiers & ShiftMask) && (sym != syms[0]) && + ((sym != usym) || (lsym == usym))) + XConvertCase(syms[0], &lsym, &usym); + *keysym_return = usym; + } + if (*keysym_return == XK_VoidSymbol) + *keysym_return = NoSymbol; + return 1; +} + +int +_XTranslateKeySym( + Display *dpy, + register KeySym symbol, + unsigned int modifiers, + char *buffer, + int nbytes) +{ + register struct _XKeytrans *p; + int length; + unsigned long hiBytes; + register unsigned char c; + + if (!symbol) + return 0; + /* see if symbol rebound, if so, return that string. */ + for (p = dpy->key_bindings; p; p = p->next) { + if (((modifiers & AllMods) == p->state) && (symbol == p->key)) { + length = p->len; + if (length > nbytes) length = nbytes; + memcpy (buffer, p->string, length); + return length; + } + } + /* try to convert to Latin-1, handling control */ + hiBytes = symbol >> 8; + if (!(nbytes && + ((hiBytes == 0) || + ((hiBytes == 0xFF) && + (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) || + (symbol == XK_Return) || + (symbol == XK_Escape) || + (symbol == XK_KP_Space) || + (symbol == XK_KP_Tab) || + (symbol == XK_KP_Enter) || + ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) || + (symbol == XK_KP_Equal) || + (symbol == XK_Delete)))))) + return 0; + + /* if X keysym, convert to ascii by grabbing low 7 bits */ + if (symbol == XK_KP_Space) + c = XK_space & 0x7F; /* patch encoding botch */ + else if (hiBytes == 0xFF) + c = symbol & 0x7F; + else + c = symbol & 0xFF; + /* only apply Control key if it makes sense, else ignore it */ + if (modifiers & ControlMask) { + if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; + else if (c == '2') c = '\000'; + else if (c >= '3' && c <= '7') c -= ('3' - '\033'); + else if (c == '8') c = '\177'; + else if (c == '/') c = '_' & 0x1F; + } + buffer[0] = c; + return 1; +} + +/*ARGSUSED*/ +int +XLookupString ( + register XKeyEvent *event, + char *buffer, /* buffer */ + int nbytes, /* space in buffer for characters */ + KeySym *keysym, + XComposeStatus *status) /* not implemented */ +{ + unsigned int modifiers; + KeySym symbol; + + if (! _XTranslateKey(event->display, event->keycode, event->state, + &modifiers, &symbol)) + return 0; + +#ifdef USE_OWN_COMPOSE + if ( status ) { + static int been_here= 0; + if ( !been_here ) { + XimCompInitTables(); + been_here = 1; + } + if ( !XimCompLegalStatus(status) ) { + status->compose_ptr = NULL; + status->chars_matched = 0; + } + if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) || + XimCompIsComposeKey(symbol,event->keycode,status) ) { + XimCompRtrn rtrn; + switch (XimCompProcessSym(status,symbol,&rtrn)) { + case XIM_COMP_IGNORE: + break; + case XIM_COMP_IN_PROGRESS: + if ( keysym!=NULL ) + *keysym = NoSymbol; + return 0; + case XIM_COMP_FAIL: + { + int n = 0, len= 0; + for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { + if ( nbytes-len > 0 ) { + len+= _XTranslateKeySym(event->display,rtrn.sym[n], + event->state, + buffer+len,nbytes-len); + } + } + if ( keysym!=NULL ) { + if ( n==1 ) *keysym = rtrn.sym[0]; + else *keysym = NoSymbol; + } + return len; + } + case XIM_COMP_SUCCEED: + { + int len,n = 0; + + symbol = rtrn.matchSym; + if ( keysym!=NULL ) *keysym = symbol; + if ( rtrn.str[0]!='\0' ) { + strncpy(buffer,rtrn.str,nbytes-1); + buffer[nbytes-1]= '\0'; + len = strlen(buffer); + } + else { + len = _XTranslateKeySym(event->display,symbol, + event->state, + buffer,nbytes); + } + for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { + if ( nbytes-len > 0 ) { + len+= _XTranslateKeySym(event->display,rtrn.sym[n], + event->state, + buffer+len,nbytes-len); + } + } + return len; + } + } + } + } +#endif + + if (keysym) + *keysym = symbol; + /* arguable whether to use (event->state & ~modifiers) here */ + return _XTranslateKeySym(event->display, symbol, event->state, + buffer, nbytes); +} + +static void +_XFreeKeyBindings( + Display *dpy) +{ + register struct _XKeytrans *p, *np; + + for (p = dpy->key_bindings; p; p = np) { + np = p->next; + Xfree(p->string); + Xfree((char *)p->modifiers); + Xfree((char *)p); + } +} + +int +XRebindKeysym ( + Display *dpy, + KeySym keysym, + KeySym *mlist, + int nm, /* number of modifiers in mlist */ + _Xconst unsigned char *str, + int nbytes) +{ + register struct _XKeytrans *tmp, *p; + int nb; + + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return 0; + LockDisplay(dpy); + tmp = dpy->key_bindings; + nb = sizeof(KeySym) * nm; + + if ((! (p = (struct _XKeytrans *) Xcalloc( 1, sizeof(struct _XKeytrans)))) || + ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) && + (nbytes > 0)) || + ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) && + (nb > 0))) { + if (p) { + if (p->string) Xfree(p->string); + if (p->modifiers) Xfree((char *) p->modifiers); + Xfree((char *) p); + } + UnlockDisplay(dpy); + return 0; + } + + dpy->key_bindings = p; + dpy->free_funcs->key_bindings = _XFreeKeyBindings; + p->next = tmp; /* chain onto list */ + memcpy (p->string, (char *) str, nbytes); + p->len = nbytes; + memcpy ((char *) p->modifiers, (char *) mlist, nb); + p->key = keysym; + p->mlen = nm; + ComputeMaskFromKeytrans(dpy, p); + UnlockDisplay(dpy); + return 0; +} + +unsigned +_XKeysymToModifiers( + Display *dpy, + KeySym ks) +{ + CARD8 code,mods; + register KeySym *kmax; + register KeySym *k; + register XModifierKeymap *m; + + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return 0; + kmax = dpy->keysyms + + (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; + k = dpy->keysyms; + m = dpy->modifiermap; + mods= 0; + while (k<kmax) { + if (*k == ks ) { + register int j = m->max_keypermod<<3; + + code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode); + + while (--j >= 0) { + if (code == m->modifiermap[j]) + mods|= (1<<(j/m->max_keypermod)); + } + } + k++; + } + return mods; +} + +/* + * given a list of modifiers, computes the mask necessary for later matching. + * This routine must lookup the key in the Keymap and then search to see + * what modifier it is bound to, if any. Sets the AnyModifier bit if it + * can't map some keysym to a modifier. + */ +static void +ComputeMaskFromKeytrans( + Display *dpy, + register struct _XKeytrans *p) +{ + register int i; + + p->state = AnyModifier; + for (i = 0; i < p->mlen; i++) { + p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); + } + p->state &= AllMods; +} diff --git a/mesalib/src/mapi/glapi/gen/Makefile b/mesalib/src/mapi/glapi/gen/Makefile index 1e4fee6aa..42eed1679 100644 --- a/mesalib/src/mapi/glapi/gen/Makefile +++ b/mesalib/src/mapi/glapi/gen/Makefile @@ -1,229 +1,226 @@ -# This file isn't used during a normal compilation since we don't want to
-# require Python in order to compile Mesa.
-# Instead, when the Mesa developers update/change the API interface it's
-# up to him/her to re-run this makefile and check in the newly generated files.
-
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-MESA_DIR = $(TOP)/src/mesa
-MESA_GLAPI_DIR = $(TOP)/src/mapi/glapi
-MESA_MAPI_DIR = $(TOP)/src/mapi/mapi
-MESA_GLX_DIR = $(TOP)/src/glx
-
-MESA_GLAPI_OUTPUTS = \
- $(MESA_GLAPI_DIR)/glapi_mapi_tmp.h \
- $(MESA_GLAPI_DIR)/glprocs.h \
- $(MESA_GLAPI_DIR)/glapitemp.h \
- $(MESA_GLAPI_DIR)/glapitable.h
-
-MESA_GLAPI_ASM_OUTPUTS = \
- $(MESA_GLAPI_DIR)/glapi_x86.S \
- $(MESA_GLAPI_DIR)/glapi_x86-64.S \
- $(MESA_GLAPI_DIR)/glapi_sparc.S
-
-MESA_OUTPUTS = \
- $(MESA_GLAPI_OUTPUTS) \
- $(MESA_GLAPI_ASM_OUTPUTS) \
- $(MESA_DIR)/main/enums.c \
- $(MESA_DIR)/main/glapidispatch.h \
- $(MESA_DIR)/main/remap_helper.h \
- $(MESA_GLX_DIR)/indirect.c \
- $(MESA_GLX_DIR)/indirect.h \
- $(MESA_GLX_DIR)/indirect_init.c \
- $(MESA_GLX_DIR)/indirect_size.h \
- $(MESA_GLX_DIR)/indirect_size.c
-
-######################################################################
-
-XORG_GLX_DIR = $(XORG_BASE)/glx
-XORG_GLAPI_DIR = $(XORG_BASE)/glx
-
-XORG_GLAPI_FILES = \
- $(XORG_GLAPI_DIR)/glapi.h \
- $(XORG_GLAPI_DIR)/glapi.c \
- $(XORG_GLAPI_DIR)/glapi_getproc.c \
- $(XORG_GLAPI_DIR)/glapi_nop.c \
- $(XORG_GLAPI_DIR)/glthread.c \
- $(XORG_GLAPI_DIR)/glthread.h
-
-XORG_GLAPI_OUTPUTS = \
- $(XORG_GLAPI_DIR)/glprocs.h \
- $(XORG_GLAPI_DIR)/glapitemp.h \
- $(XORG_GLAPI_DIR)/glapioffsets.h \
- $(XORG_GLAPI_DIR)/glapitable.h \
- $(XORG_GLAPI_DIR)/glapidispatch.h
-
-XORG_OUTPUTS = \
- $(XORG_GLAPI_FILES) \
- $(XORG_GLAPI_OUTPUTS) \
- $(XORG_GLX_DIR)/indirect_dispatch.c \
- $(XORG_GLX_DIR)/indirect_dispatch_swap.c \
- $(XORG_GLX_DIR)/indirect_dispatch.h \
- $(XORG_GLX_DIR)/indirect_reqsize.c \
- $(XORG_GLX_DIR)/indirect_reqsize.h \
- $(XORG_GLX_DIR)/indirect_size.h \
- $(XORG_GLX_DIR)/indirect_size_get.c \
- $(XORG_GLX_DIR)/indirect_size_get.h \
- $(XORG_GLX_DIR)/indirect_table.c
-
-######################################################################
-
-API_XML = \
- gl_API.xml \
- ARB_copy_buffer.xml \
- ARB_depth_clamp.xml \
- ARB_draw_buffers_blend.xml \
- ARB_draw_elements_base_vertex.xml \
- ARB_draw_instanced.xml \
- ARB_ES2_compatibility.xml \
- ARB_framebuffer_object.xml \
- ARB_geometry_shader4.xml \
- ARB_instanced_arrays.xml \
- ARB_map_buffer_range.xml \
- ARB_seamless_cube_map.xml \
- ARB_sync.xml \
- ARB_vertex_array_object.xml \
- APPLE_object_purgeable.xml \
- APPLE_vertex_array_object.xml \
- EXT_draw_buffers2.xml \
- EXT_framebuffer_object.xml \
- EXT_gpu_shader4.xml \
- EXT_packed_depth_stencil.xml \
- EXT_provoking_vertex.xml \
- EXT_separate_shader_objects.xml \
- EXT_texture_array.xml \
- EXT_texture_integer.xml \
- EXT_transform_feedback.xml \
- NV_conditional_render.xml \
- NV_primitive_restart.xml \
- NV_texture_barrier.xml \
- OES_EGL_image.xml \
- GL3x.xml
-
-
-COMMON = $(API_XML) gl_XML.py glX_XML.py license.py typeexpr.py
-
-COMMON_ES = \
- $(COMMON) \
- gl_and_es_API.xml \
- es_EXT.xml \
- ARB_ES2_compatibility.xml \
- ARB_get_program_binary.xml \
- OES_fixed_point.xml \
- OES_single_precision.xml
-
-COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py
-
-######################################################################
-
-all: mesa xorg
-
-mesa: $(MESA_OUTPUTS)
-
-xorg: check-xorg-source $(XORG_OUTPUTS)
-
-check-xorg-source:
- @if ! test -d $(XORG_GLX_DIR); then \
- echo "ERROR: Must specify path to xserver/GL/ checkout; set XORG_BASE env var."; \
- exit 1; \
- fi
-
-clean:
- -rm -f *~ *.pyo
- -rm -f $(MESA_OUTPUTS)
-
-######################################################################
-
-$(XORG_GLAPI_DIR)/%.c: $(MESA_GLAPI_DIR)/%.c
- cp $< $@
-
-$(XORG_GLAPI_DIR)/%.h: $(MESA_GLAPI_DIR)/%.h
- cp $< $@
-
-######################################################################
-
-$(MESA_GLAPI_DIR)/glapi_mapi_tmp.h: $(MESA_MAPI_DIR)/mapi_abi.py $(COMMON_ES)
- $(PYTHON2) $(PYTHON_FLAGS) $< \
- --printer glapi --mode lib gl_and_es_API.xml > $@
-
-$(MESA_GLAPI_DIR)/glprocs.h: gl_procs.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-$(MESA_GLAPI_DIR)/glapitemp.h: gl_apitemp.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-$(MESA_GLAPI_DIR)/glapitable.h: gl_table.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-######################################################################
-
-$(MESA_GLAPI_DIR)/glapi_x86.S: gl_x86_asm.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-$(MESA_GLAPI_DIR)/glapi_x86-64.S: gl_x86-64_asm.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-$(MESA_GLAPI_DIR)/glapi_sparc.S: gl_SPARC_asm.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-######################################################################
-
-$(MESA_DIR)/main/enums.c: gl_enums.py $(COMMON) $(ES_API)
- $(PYTHON2) $(PYTHON_FLAGS) $< -f gl_API.xml \
- -f $(MESA_GLAPI_DIR)/gen-es/es1_API.xml \
- -f $(MESA_GLAPI_DIR)/gen-es/es2_API.xml > $@
-
-$(MESA_DIR)/main/glapidispatch.h: gl_table.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m remap_table > $@
-
-$(MESA_DIR)/main/remap_helper.h: remap_helper.py $(COMMON)
- $(PYTHON2) $(PYTHON_FLAGS) $< > $@
-
-######################################################################
-
-$(MESA_GLX_DIR)/indirect.c: glX_proto_send.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m proto | $(INDENT) $(INDENT_FLAGS) > $@
-
-$(MESA_GLX_DIR)/indirect.h: glX_proto_send.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m init_h > $@
-
-$(MESA_GLX_DIR)/indirect_init.c: glX_proto_send.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m init_c > $@
-
-$(MESA_GLX_DIR)/indirect_size.h $(XORG_GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-set -h _INDIRECT_SIZE_H_ \
- | $(INDENT) $(INDENT_FLAGS) > $@
-
-$(MESA_GLX_DIR)/indirect_size.c: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c --only-set \
- | $(INDENT) $(INDENT_FLAGS) > $@
-
-######################################################################
-
-$(XORG_GLX_DIR)/indirect_dispatch.c: glX_proto_recv.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c > $@
-
-$(XORG_GLX_DIR)/indirect_dispatch_swap.c: glX_proto_recv.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c -s > $@
-
-$(XORG_GLX_DIR)/indirect_dispatch.h: glX_proto_recv.py gl_and_glX_API.xml $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_h -f gl_and_glX_API.xml -s > $@
-
-$(XORG_GLX_DIR)/indirect_size_get.h: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-get -h '_INDIRECT_SIZE_GET_H_' \
- | $(INDENT) $(INDENT_FLAGS) > $@
-
-$(XORG_GLX_DIR)/indirect_size_get.c: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c | $(INDENT) $(INDENT_FLAGS) > $@
-
-$(XORG_GLX_DIR)/indirect_reqsize.h: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_h --only-get -h '_INDIRECT_SIZE_GET_H_' \
- | $(INDENT) $(INDENT_FLAGS) -l200 > $@
-
-$(XORG_GLX_DIR)/indirect_reqsize.c: glX_proto_size.py $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_c | $(INDENT) $(INDENT_FLAGS) > $@
-
-$(XORG_GLX_DIR)/indirect_table.c: glX_server_table.py gl_and_glX_API.xml $(COMMON_GLX)
- $(PYTHON2) $(PYTHON_FLAGS) $< -f gl_and_glX_API.xml > $@
+# This file isn't used during a normal compilation since we don't want to +# require Python in order to compile Mesa. +# Instead, when the Mesa developers update/change the API interface it's +# up to him/her to re-run this makefile and check in the newly generated files. + + +TOP = ../../../.. +include $(TOP)/configs/current + +MESA_DIR = $(TOP)/src/mesa +MESA_GLAPI_DIR = $(TOP)/src/mapi/glapi +MESA_MAPI_DIR = $(TOP)/src/mapi/mapi +MESA_GLX_DIR = $(TOP)/src/glx + +MESA_GLAPI_OUTPUTS = \ + $(MESA_GLAPI_DIR)/glapi_mapi_tmp.h \ + $(MESA_GLAPI_DIR)/glprocs.h \ + $(MESA_GLAPI_DIR)/glapitemp.h \ + $(MESA_GLAPI_DIR)/glapitable.h + +MESA_GLAPI_ASM_OUTPUTS = \ + $(MESA_GLAPI_DIR)/glapi_x86.S \ + $(MESA_GLAPI_DIR)/glapi_x86-64.S \ + $(MESA_GLAPI_DIR)/glapi_sparc.S + +MESA_OUTPUTS = \ + $(MESA_GLAPI_OUTPUTS) \ + $(MESA_GLAPI_ASM_OUTPUTS) \ + $(MESA_DIR)/main/enums.c \ + $(MESA_DIR)/main/glapidispatch.h \ + $(MESA_DIR)/main/remap_helper.h \ + $(MESA_GLX_DIR)/indirect.c \ + $(MESA_GLX_DIR)/indirect.h \ + $(MESA_GLX_DIR)/indirect_init.c \ + $(MESA_GLX_DIR)/indirect_size.h \ + $(MESA_GLX_DIR)/indirect_size.c + +###################################################################### + +XORG_GLX_DIR = $(XORG_BASE)/glx +XORG_GLAPI_DIR = $(XORG_BASE)/glx + +XORG_GLAPI_FILES = \ + $(XORG_GLAPI_DIR)/glapi_getproc.c \ + $(XORG_GLAPI_DIR)/glapi_nop.c \ + $(XORG_GLAPI_DIR)/glthread.c \ + $(XORG_GLAPI_DIR)/glthread.h + +XORG_GLAPI_OUTPUTS = \ + $(XORG_GLAPI_DIR)/glprocs.h \ + $(XORG_GLAPI_DIR)/glapioffsets.h \ + $(XORG_GLAPI_DIR)/glapitable.h \ + $(XORG_GLAPI_DIR)/glapidispatch.h + +XORG_OUTPUTS = \ + $(XORG_GLAPI_FILES) \ + $(XORG_GLAPI_OUTPUTS) \ + $(XORG_GLX_DIR)/indirect_dispatch.c \ + $(XORG_GLX_DIR)/indirect_dispatch_swap.c \ + $(XORG_GLX_DIR)/indirect_dispatch.h \ + $(XORG_GLX_DIR)/indirect_reqsize.c \ + $(XORG_GLX_DIR)/indirect_reqsize.h \ + $(XORG_GLX_DIR)/indirect_size.h \ + $(XORG_GLX_DIR)/indirect_size_get.c \ + $(XORG_GLX_DIR)/indirect_size_get.h \ + $(XORG_GLX_DIR)/indirect_table.c + +###################################################################### + +API_XML = \ + gl_API.xml \ + ARB_copy_buffer.xml \ + ARB_depth_clamp.xml \ + ARB_draw_buffers_blend.xml \ + ARB_draw_elements_base_vertex.xml \ + ARB_draw_instanced.xml \ + ARB_ES2_compatibility.xml \ + ARB_framebuffer_object.xml \ + ARB_geometry_shader4.xml \ + ARB_instanced_arrays.xml \ + ARB_map_buffer_range.xml \ + ARB_seamless_cube_map.xml \ + ARB_sync.xml \ + ARB_vertex_array_object.xml \ + APPLE_object_purgeable.xml \ + APPLE_vertex_array_object.xml \ + EXT_draw_buffers2.xml \ + EXT_framebuffer_object.xml \ + EXT_gpu_shader4.xml \ + EXT_packed_depth_stencil.xml \ + EXT_provoking_vertex.xml \ + EXT_separate_shader_objects.xml \ + EXT_texture_array.xml \ + EXT_texture_integer.xml \ + EXT_transform_feedback.xml \ + NV_conditional_render.xml \ + NV_primitive_restart.xml \ + NV_texture_barrier.xml \ + OES_EGL_image.xml \ + GL3x.xml + + +COMMON = $(API_XML) gl_XML.py glX_XML.py license.py typeexpr.py + +COMMON_ES = \ + $(COMMON) \ + gl_and_es_API.xml \ + es_EXT.xml \ + ARB_ES2_compatibility.xml \ + ARB_get_program_binary.xml \ + OES_fixed_point.xml \ + OES_single_precision.xml + +COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py + +###################################################################### + +all: mesa xorg + +mesa: $(MESA_OUTPUTS) + +xorg: check-xorg-source $(XORG_OUTPUTS) + +check-xorg-source: + @if ! test -d $(XORG_GLX_DIR); then \ + echo "ERROR: Must specify path to xserver/GL/ checkout; set XORG_BASE env var."; \ + exit 1; \ + fi + +clean: + -rm -f *~ *.pyo + -rm -f $(MESA_OUTPUTS) + +###################################################################### + +$(XORG_GLAPI_DIR)/%.c: $(MESA_GLAPI_DIR)/%.c + cp $< $@ + +$(XORG_GLAPI_DIR)/%.h: $(MESA_GLAPI_DIR)/%.h + cp $< $@ + +###################################################################### + +$(MESA_GLAPI_DIR)/glapi_mapi_tmp.h: $(MESA_MAPI_DIR)/mapi_abi.py $(COMMON_ES) + $(PYTHON2) $(PYTHON_FLAGS) $< \ + --printer glapi --mode lib gl_and_es_API.xml > $@ + +$(MESA_GLAPI_DIR)/glprocs.h: gl_procs.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +$(MESA_GLAPI_DIR)/glapitemp.h: gl_apitemp.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +$(MESA_GLAPI_DIR)/glapitable.h: gl_table.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +###################################################################### + +$(MESA_GLAPI_DIR)/glapi_x86.S: gl_x86_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +$(MESA_GLAPI_DIR)/glapi_x86-64.S: gl_x86-64_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +$(MESA_GLAPI_DIR)/glapi_sparc.S: gl_SPARC_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +###################################################################### + +$(MESA_DIR)/main/enums.c: gl_enums.py $(COMMON) $(ES_API) + $(PYTHON2) $(PYTHON_FLAGS) $< -f gl_API.xml \ + -f $(MESA_GLAPI_DIR)/gen-es/es1_API.xml \ + -f $(MESA_GLAPI_DIR)/gen-es/es2_API.xml > $@ + +$(MESA_DIR)/main/glapidispatch.h: gl_table.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< -m remap_table > $@ + +$(MESA_DIR)/main/remap_helper.h: remap_helper.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +###################################################################### + +$(MESA_GLX_DIR)/indirect.c: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m proto | $(INDENT) $(INDENT_FLAGS) > $@ + +$(MESA_GLX_DIR)/indirect.h: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m init_h > $@ + +$(MESA_GLX_DIR)/indirect_init.c: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m init_c > $@ + +$(MESA_GLX_DIR)/indirect_size.h $(XORG_GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-set -h _INDIRECT_SIZE_H_ \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +$(MESA_GLX_DIR)/indirect_size.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c --only-set \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +###################################################################### + +$(XORG_GLX_DIR)/indirect_dispatch.c: glX_proto_recv.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c > $@ + +$(XORG_GLX_DIR)/indirect_dispatch_swap.c: glX_proto_recv.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c -s > $@ + +$(XORG_GLX_DIR)/indirect_dispatch.h: glX_proto_recv.py gl_and_glX_API.xml $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_h -f gl_and_glX_API.xml -s > $@ + +$(XORG_GLX_DIR)/indirect_size_get.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-get -h '_INDIRECT_SIZE_GET_H_' \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +$(XORG_GLX_DIR)/indirect_size_get.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c | $(INDENT) $(INDENT_FLAGS) > $@ + +$(XORG_GLX_DIR)/indirect_reqsize.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_h --only-get -h '_INDIRECT_SIZE_GET_H_' \ + | $(INDENT) $(INDENT_FLAGS) -l200 > $@ + +$(XORG_GLX_DIR)/indirect_reqsize.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_c | $(INDENT) $(INDENT_FLAGS) > $@ + +$(XORG_GLX_DIR)/indirect_table.c: glX_server_table.py gl_and_glX_API.xml $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -f gl_and_glX_API.xml > $@ diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index a3cae1cbc..81a2a4e7c 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -1,2527 +1,2527 @@ -/*
- * Copyright (C) 2010 Brian Paul All Rights Reserved.
- * Copyright (C) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Author: Kristian Høgsberg <krh@bitplanet.net>
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "enable.h"
-#include "enums.h"
-#include "extensions.h"
-#include "get.h"
-#include "macros.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-#include "state.h"
-#include "texcompress.h"
-#include "framebuffer.h"
-
-/* This is a table driven implemetation of the glGet*v() functions.
- * The basic idea is that most getters just look up an int somewhere
- * in struct gl_context and then convert it to a bool or float according to
- * which of glGetIntegerv() glGetBooleanv() etc is being called.
- * Instead of generating code to do this, we can just record the enum
- * value and the offset into struct gl_context in an array of structs. Then
- * in glGet*(), we lookup the struct for the enum in question, and use
- * the offset to get the int we need.
- *
- * Sometimes we need to look up a float, a boolean, a bit in a
- * bitfield, a matrix or other types instead, so we need to track the
- * type of the value in struct gl_context. And sometimes the value isn't in
- * struct gl_context but in the drawbuffer, the array object, current texture
- * unit, or maybe it's a computed value. So we need to also track
- * where or how to find the value. Finally, we sometimes need to
- * check that one of a number of extensions are enabled, the GL
- * version or flush or call _mesa_update_state(). This is done by
- * attaching optional extra information to the value description
- * struct, it's sort of like an array of opcodes that describe extra
- * checks or actions.
- *
- * Putting all this together we end up with struct value_desc below,
- * and with a couple of macros to help, the table of struct value_desc
- * is about as concise as the specification in the old python script.
- */
-
-#undef CONST
-
-#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE )
-#define FLOAT_TO_FIXED(F) ( ((F) * 65536.0f > INT_MAX) ? INT_MAX : \
- ((F) * 65536.0f < INT_MIN) ? INT_MIN : \
- (GLint) ((F) * 65536.0f) )
-
-#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
-#define INT_TO_FIXED(I) ( ((I) > SHRT_MAX) ? INT_MAX : \
- ((I) < SHRT_MIN) ? INT_MIN : \
- (GLint) ((I) * 65536) )
-
-#define INT64_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
-#define INT64_TO_INT(I) ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
-
-#define BOOLEAN_TO_INT(B) ( (GLint) (B) )
-#define BOOLEAN_TO_INT64(B) ( (GLint64) (B) )
-#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F )
-#define BOOLEAN_TO_FIXED(B) ( (GLint) ((B) ? 1 : 0) << 16 )
-
-#define ENUM_TO_INT64(E) ( (GLint64) (E) )
-#define ENUM_TO_FIXED(E) (E)
-
-enum value_type {
- TYPE_INVALID,
- TYPE_API_MASK,
- TYPE_INT,
- TYPE_INT_2,
- TYPE_INT_3,
- TYPE_INT_4,
- TYPE_INT_N,
- TYPE_INT64,
- TYPE_ENUM,
- TYPE_ENUM_2,
- TYPE_BOOLEAN,
- TYPE_BIT_0,
- TYPE_BIT_1,
- TYPE_BIT_2,
- TYPE_BIT_3,
- TYPE_BIT_4,
- TYPE_BIT_5,
- TYPE_FLOAT,
- TYPE_FLOAT_2,
- TYPE_FLOAT_3,
- TYPE_FLOAT_4,
- TYPE_FLOATN,
- TYPE_FLOATN_2,
- TYPE_FLOATN_3,
- TYPE_FLOATN_4,
- TYPE_DOUBLEN,
- TYPE_MATRIX,
- TYPE_MATRIX_T,
- TYPE_CONST
-};
-
-enum value_location {
- LOC_BUFFER,
- LOC_CONTEXT,
- LOC_ARRAY,
- LOC_TEXUNIT,
- LOC_CUSTOM
-};
-
-enum value_extra {
- EXTRA_END = 0x8000,
- EXTRA_VERSION_30,
- EXTRA_VERSION_31,
- EXTRA_VERSION_32,
- EXTRA_VERSION_ES2,
- EXTRA_NEW_BUFFERS,
- EXTRA_VALID_DRAW_BUFFER,
- EXTRA_VALID_TEXTURE_UNIT,
- EXTRA_FLUSH_CURRENT,
-};
-
-#define NO_EXTRA NULL
-#define NO_OFFSET 0
-
-struct value_desc {
- GLenum pname;
- GLubyte location; /**< enum value_location */
- GLubyte type; /**< enum value_type */
- int offset;
- const int *extra;
-};
-
-union value {
- GLfloat value_float;
- GLfloat value_float_4[4];
- GLmatrix *value_matrix;
- GLint value_int;
- GLint value_int_4[4];
- GLint64 value_int64;
- GLenum value_enum;
-
- /* Sigh, see GL_COMPRESSED_TEXTURE_FORMATS_ARB handling */
- struct {
- GLint n, ints[100];
- } value_int_n;
- GLboolean value_bool;
-};
-
-#define BUFFER_FIELD(field, type) \
- LOC_BUFFER, type, offsetof(struct gl_framebuffer, field)
-#define CONTEXT_FIELD(field, type) \
- LOC_CONTEXT, type, offsetof(struct gl_context, field)
-#define ARRAY_FIELD(field, type) \
- LOC_ARRAY, type, offsetof(struct gl_array_object, field)
-#define CONST(value) \
- LOC_CONTEXT, TYPE_CONST, value
-
-#define BUFFER_INT(field) BUFFER_FIELD(field, TYPE_INT)
-#define BUFFER_ENUM(field) BUFFER_FIELD(field, TYPE_ENUM)
-#define BUFFER_BOOL(field) BUFFER_FIELD(field, TYPE_BOOLEAN)
-
-#define CONTEXT_INT(field) CONTEXT_FIELD(field, TYPE_INT)
-#define CONTEXT_INT2(field) CONTEXT_FIELD(field, TYPE_INT_2)
-#define CONTEXT_INT64(field) CONTEXT_FIELD(field, TYPE_INT64)
-#define CONTEXT_ENUM(field) CONTEXT_FIELD(field, TYPE_ENUM)
-#define CONTEXT_ENUM2(field) CONTEXT_FIELD(field, TYPE_ENUM_2)
-#define CONTEXT_BOOL(field) CONTEXT_FIELD(field, TYPE_BOOLEAN)
-#define CONTEXT_BIT0(field) CONTEXT_FIELD(field, TYPE_BIT_0)
-#define CONTEXT_BIT1(field) CONTEXT_FIELD(field, TYPE_BIT_1)
-#define CONTEXT_BIT2(field) CONTEXT_FIELD(field, TYPE_BIT_2)
-#define CONTEXT_BIT3(field) CONTEXT_FIELD(field, TYPE_BIT_3)
-#define CONTEXT_BIT4(field) CONTEXT_FIELD(field, TYPE_BIT_4)
-#define CONTEXT_BIT5(field) CONTEXT_FIELD(field, TYPE_BIT_5)
-#define CONTEXT_FLOAT(field) CONTEXT_FIELD(field, TYPE_FLOAT)
-#define CONTEXT_FLOAT2(field) CONTEXT_FIELD(field, TYPE_FLOAT_2)
-#define CONTEXT_FLOAT3(field) CONTEXT_FIELD(field, TYPE_FLOAT_3)
-#define CONTEXT_FLOAT4(field) CONTEXT_FIELD(field, TYPE_FLOAT_4)
-#define CONTEXT_MATRIX(field) CONTEXT_FIELD(field, TYPE_MATRIX)
-#define CONTEXT_MATRIX_T(field) CONTEXT_FIELD(field, TYPE_MATRIX_T)
-
-#define ARRAY_INT(field) ARRAY_FIELD(field, TYPE_INT)
-#define ARRAY_ENUM(field) ARRAY_FIELD(field, TYPE_ENUM)
-#define ARRAY_BOOL(field) ARRAY_FIELD(field, TYPE_BOOLEAN)
-
-#define EXT(f) \
- offsetof(struct gl_extensions, f)
-
-#define EXTRA_EXT(e) \
- static const int extra_##e[] = { \
- EXT(e), EXTRA_END \
- }
-
-#define EXTRA_EXT2(e1, e2) \
- static const int extra_##e1##_##e2[] = { \
- EXT(e1), EXT(e2), EXTRA_END \
- }
-
-/* The 'extra' mechanism is a way to specify extra checks (such as
- * extensions or specific gl versions) or actions (flush current, new
- * buffers) that we need to do before looking up an enum. We need to
- * declare them all up front so we can refer to them in the value_desc
- * structs below. */
-
-static const int extra_new_buffers[] = {
- EXTRA_NEW_BUFFERS,
- EXTRA_END
-};
-
-static const int extra_valid_draw_buffer[] = {
- EXTRA_VALID_DRAW_BUFFER,
- EXTRA_END
-};
-
-static const int extra_valid_texture_unit[] = {
- EXTRA_VALID_TEXTURE_UNIT,
- EXTRA_END
-};
-
-static const int extra_flush_current_valid_texture_unit[] = {
- EXTRA_FLUSH_CURRENT,
- EXTRA_VALID_TEXTURE_UNIT,
- EXTRA_END
-};
-
-static const int extra_flush_current[] = {
- EXTRA_FLUSH_CURRENT,
- EXTRA_END
-};
-
-static const int extra_new_buffers_OES_read_format[] = {
- EXTRA_NEW_BUFFERS,
- EXT(OES_read_format),
- EXTRA_END
-};
-
-static const int extra_EXT_secondary_color_flush_current[] = {
- EXT(EXT_secondary_color),
- EXTRA_FLUSH_CURRENT,
- EXTRA_END
-};
-
-static const int extra_EXT_fog_coord_flush_current[] = {
- EXT(EXT_fog_coord),
- EXTRA_FLUSH_CURRENT,
- EXTRA_END
-};
-
-static const int extra_EXT_texture_integer[] = {
- EXT(EXT_texture_integer),
- EXTRA_END
-};
-
-static const int extra_EXT_gpu_shader4[] = {
- EXT(EXT_gpu_shader4),
- EXTRA_END
-};
-
-
-EXTRA_EXT(ARB_ES2_compatibility);
-EXTRA_EXT(ARB_multitexture);
-EXTRA_EXT(ARB_texture_cube_map);
-EXTRA_EXT(MESA_texture_array);
-EXTRA_EXT2(EXT_secondary_color, ARB_vertex_program);
-EXTRA_EXT(EXT_secondary_color);
-EXTRA_EXT(EXT_fog_coord);
-EXTRA_EXT(EXT_texture_lod_bias);
-EXTRA_EXT(EXT_texture_filter_anisotropic);
-EXTRA_EXT(IBM_rasterpos_clip);
-EXTRA_EXT(NV_point_sprite);
-EXTRA_EXT(SGIS_generate_mipmap);
-EXTRA_EXT(NV_vertex_program);
-EXTRA_EXT(NV_fragment_program);
-EXTRA_EXT(NV_texture_rectangle);
-EXTRA_EXT(EXT_stencil_two_side);
-EXTRA_EXT(NV_light_max_exponent);
-EXTRA_EXT(EXT_depth_bounds_test);
-EXTRA_EXT(ARB_depth_clamp);
-EXTRA_EXT(ATI_fragment_shader);
-EXTRA_EXT(EXT_framebuffer_blit);
-EXTRA_EXT(ARB_shader_objects);
-EXTRA_EXT(EXT_provoking_vertex);
-EXTRA_EXT(ARB_fragment_shader);
-EXTRA_EXT(ARB_fragment_program);
-EXTRA_EXT2(ARB_framebuffer_object, EXT_framebuffer_multisample);
-EXTRA_EXT(EXT_framebuffer_object);
-EXTRA_EXT(APPLE_vertex_array_object);
-EXTRA_EXT(ARB_seamless_cube_map);
-EXTRA_EXT(EXT_compiled_vertex_array);
-EXTRA_EXT(ARB_sync);
-EXTRA_EXT(ARB_vertex_shader);
-EXTRA_EXT(EXT_transform_feedback);
-EXTRA_EXT(ARB_transform_feedback2);
-EXTRA_EXT(EXT_pixel_buffer_object);
-EXTRA_EXT(ARB_vertex_program);
-EXTRA_EXT2(NV_point_sprite, ARB_point_sprite);
-EXTRA_EXT2(ARB_fragment_program, NV_fragment_program);
-EXTRA_EXT2(ARB_vertex_program, NV_vertex_program);
-EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
-EXTRA_EXT(ARB_vertex_buffer_object);
-EXTRA_EXT(ARB_geometry_shader4);
-EXTRA_EXT(ARB_copy_buffer);
-EXTRA_EXT(EXT_framebuffer_sRGB);
-
-static const int
-extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
- EXT(ARB_vertex_program),
- EXT(ARB_fragment_program),
- EXT(NV_vertex_program),
- EXTRA_END
-};
-
-static const int
-extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
- EXT(NV_vertex_program),
- EXT(ARB_vertex_program),
- EXT(ARB_fragment_program),
- EXT(NV_vertex_program),
- EXTRA_END
-};
-
-static const int
-extra_NV_primitive_restart[] = {
- EXT(NV_primitive_restart),
- EXTRA_END
-};
-
-static const int extra_version_30[] = { EXTRA_VERSION_30, EXTRA_END };
-static const int extra_version_31[] = { EXTRA_VERSION_31, EXTRA_END };
-static const int extra_version_32[] = { EXTRA_VERSION_32, EXTRA_END };
-
-static const int
-extra_ARB_vertex_program_version_es2[] = {
- EXT(ARB_vertex_program),
- EXTRA_VERSION_ES2,
- EXTRA_END
-};
-
-#define API_OPENGL_BIT (1 << API_OPENGL)
-#define API_OPENGLES_BIT (1 << API_OPENGLES)
-#define API_OPENGLES2_BIT (1 << API_OPENGLES2)
-
-/* This is the big table describing all the enums we accept in
- * glGet*v(). The table is partitioned into six parts: enums
- * understood by all GL APIs (OpenGL, GLES and GLES2), enums shared
- * between OpenGL and GLES, enums exclusive to GLES, etc for the
- * remaining combinations. When we add the enums to the hash table in
- * _mesa_init_get_hash(), we only add the enums for the API we're
- * instantiating and the different sections are guarded by #if
- * FEATURE_GL etc to make sure we only compile in the enums we may
- * need. */
-
-static const struct value_desc values[] = {
- /* Enums shared between OpenGL, GLES1 and GLES2 */
- { 0, 0, TYPE_API_MASK,
- API_OPENGL_BIT | API_OPENGLES_BIT | API_OPENGLES2_BIT, NO_EXTRA},
- { GL_ALPHA_BITS, BUFFER_INT(Visual.alphaBits), extra_new_buffers },
- { GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA },
- { GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
- { GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers },
- { GL_COLOR_CLEAR_VALUE, CONTEXT_FIELD(Color.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
- { GL_CULL_FACE, CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA },
- { GL_CULL_FACE_MODE, CONTEXT_ENUM(Polygon.CullFaceMode), NO_EXTRA },
- { GL_DEPTH_BITS, BUFFER_INT(Visual.depthBits), NO_EXTRA },
- { GL_DEPTH_CLEAR_VALUE, CONTEXT_FIELD(Depth.Clear, TYPE_DOUBLEN), NO_EXTRA },
- { GL_DEPTH_FUNC, CONTEXT_ENUM(Depth.Func), NO_EXTRA },
- { GL_DEPTH_RANGE, CONTEXT_FIELD(Viewport.Near, TYPE_FLOATN_2), NO_EXTRA },
- { GL_DEPTH_TEST, CONTEXT_BOOL(Depth.Test), NO_EXTRA },
- { GL_DEPTH_WRITEMASK, CONTEXT_BOOL(Depth.Mask), NO_EXTRA },
- { GL_DITHER, CONTEXT_BOOL(Color.DitherFlag), NO_EXTRA },
- { GL_FRONT_FACE, CONTEXT_ENUM(Polygon.FrontFace), NO_EXTRA },
- { GL_GREEN_BITS, BUFFER_INT(Visual.greenBits), extra_new_buffers },
- { GL_LINE_WIDTH, CONTEXT_FLOAT(Line.Width), NO_EXTRA },
- { GL_ALIASED_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidth), NO_EXTRA },
- { GL_MAX_ELEMENTS_VERTICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA },
- { GL_MAX_ELEMENTS_INDICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA },
- { GL_MAX_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_context, Const.MaxTextureLevels), NO_EXTRA },
- { GL_MAX_VIEWPORT_DIMS, CONTEXT_INT2(Const.MaxViewportWidth), NO_EXTRA },
- { GL_PACK_ALIGNMENT, CONTEXT_INT(Pack.Alignment), NO_EXTRA },
- { GL_ALIASED_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSize), NO_EXTRA },
- { GL_POLYGON_OFFSET_FACTOR, CONTEXT_FLOAT(Polygon.OffsetFactor ), NO_EXTRA },
- { GL_POLYGON_OFFSET_UNITS, CONTEXT_FLOAT(Polygon.OffsetUnits ), NO_EXTRA },
- { GL_POLYGON_OFFSET_FILL, CONTEXT_BOOL(Polygon.OffsetFill), NO_EXTRA },
- { GL_RED_BITS, BUFFER_INT(Visual.redBits), extra_new_buffers },
- { GL_SCISSOR_BOX, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
- { GL_SCISSOR_TEST, CONTEXT_BOOL(Scissor.Enabled), NO_EXTRA },
- { GL_STENCIL_BITS, BUFFER_INT(Visual.stencilBits), NO_EXTRA },
- { GL_STENCIL_CLEAR_VALUE, CONTEXT_INT(Stencil.Clear), NO_EXTRA },
- { GL_STENCIL_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_FUNC, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_PASS_DEPTH_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_PASS_DEPTH_PASS, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_REF, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_TEST, CONTEXT_BOOL(Stencil.Enabled), NO_EXTRA },
- { GL_STENCIL_VALUE_MASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
- { GL_STENCIL_WRITEMASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
- { GL_SUBPIXEL_BITS, CONTEXT_INT(Const.SubPixelBits), NO_EXTRA },
- { GL_TEXTURE_BINDING_2D, LOC_CUSTOM, TYPE_INT, TEXTURE_2D_INDEX, NO_EXTRA },
- { GL_UNPACK_ALIGNMENT, CONTEXT_INT(Unpack.Alignment), NO_EXTRA },
- { GL_VIEWPORT, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
-
- /* GL_ARB_multitexture */
- { GL_ACTIVE_TEXTURE_ARB,
- LOC_CUSTOM, TYPE_INT, 0, extra_ARB_multitexture },
-
- /* Note that all the OES_* extensions require that the Mesa "struct
- * gl_extensions" include a member with the name of the extension.
- * That structure does not yet include OES extensions (and we're
- * not sure whether it will). If it does, all the OES_*
- * extensions below should mark the dependency. */
-
- /* GL_ARB_texture_cube_map */
- { GL_TEXTURE_BINDING_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_INT,
- TEXTURE_CUBE_INDEX, extra_ARB_texture_cube_map },
- { GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_context, Const.MaxCubeTextureLevels),
- extra_ARB_texture_cube_map }, /* XXX: OES_texture_cube_map */
-
- /* XXX: OES_blend_subtract */
- { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
- { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
- { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].SrcA), NO_EXTRA },
- { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].DstA), NO_EXTRA },
-
- /* GL_BLEND_EQUATION_RGB, which is what we're really after, is
- * defined identically to GL_BLEND_EQUATION. */
- { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.Blend[0].EquationRGB), NO_EXTRA },
- { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].EquationA), NO_EXTRA },
-
- /* GL_ARB_texture_compression */
- { GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- { GL_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT_N, 0, NO_EXTRA },
-
- /* GL_ARB_multisample */
- { GL_SAMPLE_ALPHA_TO_COVERAGE_ARB,
- CONTEXT_BOOL(Multisample.SampleAlphaToCoverage), NO_EXTRA },
- { GL_SAMPLE_COVERAGE_ARB, CONTEXT_BOOL(Multisample.SampleCoverage), NO_EXTRA },
- { GL_SAMPLE_COVERAGE_VALUE_ARB,
- CONTEXT_FLOAT(Multisample.SampleCoverageValue), NO_EXTRA },
- { GL_SAMPLE_COVERAGE_INVERT_ARB,
- CONTEXT_BOOL(Multisample.SampleCoverageInvert), NO_EXTRA },
- { GL_SAMPLE_BUFFERS_ARB, BUFFER_INT(Visual.sampleBuffers), NO_EXTRA },
- { GL_SAMPLES_ARB, BUFFER_INT(Visual.samples), NO_EXTRA },
-
- /* GL_SGIS_generate_mipmap */
- { GL_GENERATE_MIPMAP_HINT_SGIS, CONTEXT_ENUM(Hint.GenerateMipmap),
- extra_SGIS_generate_mipmap },
-
- /* GL_ARB_vertex_buffer_object */
- { GL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
-
- /* GL_ARB_vertex_buffer_object */
- /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported */
- { GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_vertex_buffer_object },
-
- /* GL_ARB_copy_buffer */
- { GL_COPY_READ_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
- { GL_COPY_WRITE_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
-
- /* GL_OES_read_format */
- { GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0,
- extra_new_buffers_OES_read_format },
- { GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, LOC_CUSTOM, TYPE_INT, 0,
- extra_new_buffers_OES_read_format },
-
- /* GL_EXT_framebuffer_object */
- { GL_FRAMEBUFFER_BINDING_EXT, BUFFER_INT(Name),
- extra_EXT_framebuffer_object },
- { GL_RENDERBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_framebuffer_object },
- { GL_MAX_RENDERBUFFER_SIZE_EXT, CONTEXT_INT(Const.MaxRenderbufferSize),
- extra_EXT_framebuffer_object },
-
- /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's
- * GLSL: */
- { GL_MAX_CLIP_PLANES, CONTEXT_INT(Const.MaxClipPlanes), NO_EXTRA },
-
-#if FEATURE_GL || FEATURE_ES1
- /* Enums in OpenGL and GLES1 */
- { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES_BIT, NO_EXTRA },
- { GL_LIGHT0, CONTEXT_BOOL(Light.Light[0].Enabled), NO_EXTRA },
- { GL_LIGHT1, CONTEXT_BOOL(Light.Light[1].Enabled), NO_EXTRA },
- { GL_LIGHT2, CONTEXT_BOOL(Light.Light[2].Enabled), NO_EXTRA },
- { GL_LIGHT3, CONTEXT_BOOL(Light.Light[3].Enabled), NO_EXTRA },
- { GL_LIGHT4, CONTEXT_BOOL(Light.Light[4].Enabled), NO_EXTRA },
- { GL_LIGHT5, CONTEXT_BOOL(Light.Light[5].Enabled), NO_EXTRA },
- { GL_LIGHT6, CONTEXT_BOOL(Light.Light[6].Enabled), NO_EXTRA },
- { GL_LIGHT7, CONTEXT_BOOL(Light.Light[7].Enabled), NO_EXTRA },
- { GL_LIGHTING, CONTEXT_BOOL(Light.Enabled), NO_EXTRA },
- { GL_LIGHT_MODEL_AMBIENT,
- CONTEXT_FIELD(Light.Model.Ambient[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_LIGHT_MODEL_TWO_SIDE, CONTEXT_BOOL(Light.Model.TwoSide), NO_EXTRA },
- { GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA },
- { GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
- { GL_ALPHA_TEST_REF, CONTEXT_FIELD(Color.AlphaRef, TYPE_FLOATN), NO_EXTRA },
- { GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
- { GL_CLIP_PLANE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE3, CONTEXT_BIT3(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE4, CONTEXT_BIT4(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE5, CONTEXT_BIT5(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_COLOR_MATERIAL, CONTEXT_BOOL(Light.ColorMaterialEnabled), NO_EXTRA },
- { GL_CURRENT_COLOR,
- CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR0][0], TYPE_FLOATN_4),
- extra_flush_current },
- { GL_CURRENT_NORMAL,
- CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_NORMAL][0], TYPE_FLOATN_3),
- extra_flush_current },
- { GL_CURRENT_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0,
- extra_flush_current_valid_texture_unit },
- { GL_DISTANCE_ATTENUATION_EXT, CONTEXT_FLOAT3(Point.Params[0]), NO_EXTRA },
- { GL_FOG, CONTEXT_BOOL(Fog.Enabled), NO_EXTRA },
- { GL_FOG_COLOR, CONTEXT_FIELD(Fog.Color[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_FOG_DENSITY, CONTEXT_FLOAT(Fog.Density), NO_EXTRA },
- { GL_FOG_END, CONTEXT_FLOAT(Fog.End), NO_EXTRA },
- { GL_FOG_HINT, CONTEXT_ENUM(Hint.Fog), NO_EXTRA },
- { GL_FOG_MODE, CONTEXT_ENUM(Fog.Mode), NO_EXTRA },
- { GL_FOG_START, CONTEXT_FLOAT(Fog.Start), NO_EXTRA },
- { GL_LINE_SMOOTH, CONTEXT_BOOL(Line.SmoothFlag), NO_EXTRA },
- { GL_LINE_SMOOTH_HINT, CONTEXT_ENUM(Hint.LineSmooth), NO_EXTRA },
- { GL_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidthAA), NO_EXTRA },
- { GL_COLOR_LOGIC_OP, CONTEXT_BOOL(Color.ColorLogicOpEnabled), NO_EXTRA },
- { GL_LOGIC_OP_MODE, CONTEXT_ENUM(Color.LogicOp), NO_EXTRA },
- { GL_MATRIX_MODE, CONTEXT_ENUM(Transform.MatrixMode), NO_EXTRA },
- { GL_MAX_MODELVIEW_STACK_DEPTH, CONST(MAX_MODELVIEW_STACK_DEPTH), NO_EXTRA },
- { GL_MAX_PROJECTION_STACK_DEPTH, CONST(MAX_PROJECTION_STACK_DEPTH), NO_EXTRA },
- { GL_MAX_TEXTURE_STACK_DEPTH, CONST(MAX_TEXTURE_STACK_DEPTH), NO_EXTRA },
- { GL_MODELVIEW_MATRIX, CONTEXT_MATRIX(ModelviewMatrixStack.Top), NO_EXTRA },
- { GL_MODELVIEW_STACK_DEPTH, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_context, ModelviewMatrixStack.Depth), NO_EXTRA },
- { GL_NORMALIZE, CONTEXT_BOOL(Transform.Normalize), NO_EXTRA },
- { GL_PACK_SKIP_IMAGES_EXT, CONTEXT_INT(Pack.SkipImages), NO_EXTRA },
- { GL_PERSPECTIVE_CORRECTION_HINT, CONTEXT_ENUM(Hint.PerspectiveCorrection), NO_EXTRA },
- { GL_POINT_SIZE, CONTEXT_FLOAT(Point.Size), NO_EXTRA },
- { GL_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSizeAA), NO_EXTRA },
- { GL_POINT_SMOOTH, CONTEXT_BOOL(Point.SmoothFlag), NO_EXTRA },
- { GL_POINT_SMOOTH_HINT, CONTEXT_ENUM(Hint.PointSmooth), NO_EXTRA },
- { GL_POINT_SIZE_MIN_EXT, CONTEXT_FLOAT(Point.MinSize), NO_EXTRA },
- { GL_POINT_SIZE_MAX_EXT, CONTEXT_FLOAT(Point.MaxSize), NO_EXTRA },
- { GL_POINT_FADE_THRESHOLD_SIZE_EXT, CONTEXT_FLOAT(Point.Threshold), NO_EXTRA },
- { GL_PROJECTION_MATRIX, CONTEXT_MATRIX(ProjectionMatrixStack.Top), NO_EXTRA },
- { GL_PROJECTION_STACK_DEPTH, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_context, ProjectionMatrixStack.Depth), NO_EXTRA },
- { GL_RESCALE_NORMAL, CONTEXT_BOOL(Transform.RescaleNormals), NO_EXTRA },
- { GL_SHADE_MODEL, CONTEXT_ENUM(Light.ShadeModel), NO_EXTRA },
- { GL_TEXTURE_2D, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
- { GL_TEXTURE_MATRIX, LOC_CUSTOM, TYPE_MATRIX, 0, extra_valid_texture_unit },
- { GL_TEXTURE_STACK_DEPTH, LOC_CUSTOM, TYPE_INT, 0,
- extra_valid_texture_unit },
-
- { GL_VERTEX_ARRAY, ARRAY_BOOL(Vertex.Enabled), NO_EXTRA },
- { GL_VERTEX_ARRAY_SIZE, ARRAY_INT(Vertex.Size), NO_EXTRA },
- { GL_VERTEX_ARRAY_TYPE, ARRAY_ENUM(Vertex.Type), NO_EXTRA },
- { GL_VERTEX_ARRAY_STRIDE, ARRAY_INT(Vertex.Stride), NO_EXTRA },
- { GL_NORMAL_ARRAY, ARRAY_ENUM(Normal.Enabled), NO_EXTRA },
- { GL_NORMAL_ARRAY_TYPE, ARRAY_ENUM(Normal.Type), NO_EXTRA },
- { GL_NORMAL_ARRAY_STRIDE, ARRAY_INT(Normal.Stride), NO_EXTRA },
- { GL_COLOR_ARRAY, ARRAY_BOOL(Color.Enabled), NO_EXTRA },
- { GL_COLOR_ARRAY_SIZE, ARRAY_INT(Color.Size), NO_EXTRA },
- { GL_COLOR_ARRAY_TYPE, ARRAY_ENUM(Color.Type), NO_EXTRA },
- { GL_COLOR_ARRAY_STRIDE, ARRAY_INT(Color.Stride), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY,
- LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Enabled), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY_SIZE,
- LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Size), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY_TYPE,
- LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Type), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY_STRIDE,
- LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Stride), NO_EXTRA },
-
- /* GL_ARB_ES2_compatibility */
- { GL_SHADER_COMPILER, CONST(1), extra_ARB_ES2_compatibility },
- { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying),
- extra_ARB_ES2_compatibility },
- { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_ES2_compatibility },
- { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_ES2_compatibility },
-
- /* GL_ARB_multitexture */
- { GL_MAX_TEXTURE_UNITS_ARB,
- CONTEXT_INT(Const.MaxTextureUnits), extra_ARB_multitexture },
- { GL_CLIENT_ACTIVE_TEXTURE_ARB,
- LOC_CUSTOM, TYPE_INT, 0, extra_ARB_multitexture },
-
- /* GL_ARB_texture_cube_map */
- { GL_TEXTURE_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
- /* S, T, and R are always set at the same time */
- { GL_TEXTURE_GEN_STR_OES, LOC_TEXUNIT, TYPE_BIT_0,
- offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
-
- /* GL_ARB_multisample */
- { GL_MULTISAMPLE_ARB, CONTEXT_BOOL(Multisample.Enabled), NO_EXTRA },
- { GL_SAMPLE_ALPHA_TO_ONE_ARB, CONTEXT_BOOL(Multisample.SampleAlphaToOne), NO_EXTRA },
-
- /* GL_ARB_vertex_buffer_object */
- { GL_VERTEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, Vertex.BufferObj), NO_EXTRA },
- { GL_NORMAL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, Normal.BufferObj), NO_EXTRA },
- { GL_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, Color.BufferObj), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
-
- /* GL_OES_point_sprite */
- { GL_POINT_SPRITE_NV,
- CONTEXT_BOOL(Point.PointSprite),
- extra_NV_point_sprite_ARB_point_sprite },
-
- /* GL_ARB_fragment_shader */
- { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB,
- CONTEXT_INT(Const.FragmentProgram.MaxUniformComponents),
- extra_ARB_fragment_shader },
-
- /* GL_ARB_vertex_shader */
- { GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB,
- CONTEXT_INT(Const.VertexProgram.MaxUniformComponents),
- extra_ARB_vertex_shader },
- { GL_MAX_VARYING_FLOATS_ARB, LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_vertex_shader },
-
- /* GL_EXT_texture_lod_bias */
- { GL_MAX_TEXTURE_LOD_BIAS_EXT, CONTEXT_FLOAT(Const.MaxTextureLodBias),
- extra_EXT_texture_lod_bias },
-
- /* GL_EXT_texture_filter_anisotropic */
- { GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
- CONTEXT_FLOAT(Const.MaxTextureMaxAnisotropy),
- extra_EXT_texture_filter_anisotropic },
-#endif /* FEATURE_GL || FEATURE_ES1 */
-
-#if FEATURE_ES1
- { 0, 0, TYPE_API_MASK, API_OPENGLES_BIT },
- /* XXX: OES_matrix_get */
- { GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES },
- { GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES },
- { GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES },
-
- /* OES_point_size_array */
- { GL_POINT_SIZE_ARRAY_OES, ARRAY_FIELD(PointSize.Enabled, TYPE_BOOLEAN) },
- { GL_POINT_SIZE_ARRAY_TYPE_OES, ARRAY_FIELD(PointSize.Type, TYPE_ENUM) },
- { GL_POINT_SIZE_ARRAY_STRIDE_OES, ARRAY_FIELD(PointSize.Stride, TYPE_INT) },
- { GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, LOC_CUSTOM, TYPE_INT, 0 },
-#endif /* FEATURE_ES1 */
-
-#if FEATURE_GL || FEATURE_ES2
- { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES2_BIT, NO_EXTRA },
- /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's GLSL: */
- { GL_MAX_LIGHTS, CONTEXT_INT(Const.MaxLights), NO_EXTRA },
- { GL_MAX_TEXTURE_COORDS_ARB, /* == GL_MAX_TEXTURE_COORDS_NV */
- CONTEXT_INT(Const.MaxTextureCoordUnits),
- extra_ARB_fragment_program_NV_fragment_program },
-
- /* GL_ARB_draw_buffers */
- { GL_MAX_DRAW_BUFFERS_ARB, CONTEXT_INT(Const.MaxDrawBuffers), NO_EXTRA },
-
- { GL_BLEND_COLOR_EXT, CONTEXT_FIELD(Color.BlendColor[0], TYPE_FLOATN_4), NO_EXTRA },
- /* GL_ARB_fragment_program */
- { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */
- CONTEXT_INT(Const.MaxTextureImageUnits),
- extra_ARB_fragment_program_NV_fragment_program },
- { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB,
- CONTEXT_INT(Const.MaxVertexTextureImageUnits), extra_ARB_vertex_shader },
- { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB,
- CONTEXT_INT(Const.MaxCombinedTextureImageUnits),
- extra_ARB_vertex_shader },
-
- /* GL_ARB_shader_objects
- * Actually, this token isn't part of GL_ARB_shader_objects, but is
- * close enough for now. */
- { GL_CURRENT_PROGRAM, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_objects },
-
- /* OpenGL 2.0 */
- { GL_STENCIL_BACK_FUNC, CONTEXT_ENUM(Stencil.Function[1]), NO_EXTRA },
- { GL_STENCIL_BACK_VALUE_MASK, CONTEXT_INT(Stencil.ValueMask[1]), NO_EXTRA },
- { GL_STENCIL_BACK_WRITEMASK, CONTEXT_INT(Stencil.WriteMask[1]), NO_EXTRA },
- { GL_STENCIL_BACK_REF, CONTEXT_INT(Stencil.Ref[1]), NO_EXTRA },
- { GL_STENCIL_BACK_FAIL, CONTEXT_ENUM(Stencil.FailFunc[1]), NO_EXTRA },
- { GL_STENCIL_BACK_PASS_DEPTH_FAIL, CONTEXT_ENUM(Stencil.ZFailFunc[1]), NO_EXTRA },
- { GL_STENCIL_BACK_PASS_DEPTH_PASS, CONTEXT_ENUM(Stencil.ZPassFunc[1]), NO_EXTRA },
-
- { GL_MAX_VERTEX_ATTRIBS_ARB,
- CONTEXT_INT(Const.VertexProgram.MaxAttribs),
- extra_ARB_vertex_program_version_es2 },
-
- /* OES_texture_3D */
- { GL_TEXTURE_BINDING_3D, LOC_CUSTOM, TYPE_INT, TEXTURE_3D_INDEX, NO_EXTRA },
- { GL_MAX_3D_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_context, Const.Max3DTextureLevels), NO_EXTRA },
-
- /* GL_ARB_fragment_program/OES_standard_derivatives */
- { GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB,
- CONTEXT_ENUM(Hint.FragmentShaderDerivative), extra_ARB_fragment_shader },
-#endif /* FEATURE_GL || FEATURE_ES2 */
-
-#if FEATURE_ES2
- /* Enums unique to OpenGL ES 2.0 */
- { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA },
- { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), NO_EXTRA },
- { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- { GL_SHADER_COMPILER, CONST(1), NO_EXTRA },
- /* OES_get_program_binary */
- { GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
- { GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
-#endif /* FEATURE_ES2 */
-
-#if FEATURE_GL
- /* Remaining enums are only in OpenGL */
- { 0, 0, TYPE_API_MASK, API_OPENGL_BIT, NO_EXTRA },
- { GL_ACCUM_RED_BITS, BUFFER_INT(Visual.accumRedBits), NO_EXTRA },
- { GL_ACCUM_GREEN_BITS, BUFFER_INT(Visual.accumGreenBits), NO_EXTRA },
- { GL_ACCUM_BLUE_BITS, BUFFER_INT(Visual.accumBlueBits), NO_EXTRA },
- { GL_ACCUM_ALPHA_BITS, BUFFER_INT(Visual.accumAlphaBits), NO_EXTRA },
- { GL_ACCUM_CLEAR_VALUE, CONTEXT_FIELD(Accum.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_ALPHA_BIAS, CONTEXT_FLOAT(Pixel.AlphaBias), NO_EXTRA },
- { GL_ALPHA_SCALE, CONTEXT_FLOAT(Pixel.AlphaScale), NO_EXTRA },
- { GL_ATTRIB_STACK_DEPTH, CONTEXT_INT(AttribStackDepth), NO_EXTRA },
- { GL_AUTO_NORMAL, CONTEXT_BOOL(Eval.AutoNormal), NO_EXTRA },
- { GL_AUX_BUFFERS, BUFFER_INT(Visual.numAuxBuffers), NO_EXTRA },
- { GL_BLUE_BIAS, CONTEXT_FLOAT(Pixel.BlueBias), NO_EXTRA },
- { GL_BLUE_SCALE, CONTEXT_FLOAT(Pixel.BlueScale), NO_EXTRA },
- { GL_CLIENT_ATTRIB_STACK_DEPTH, CONTEXT_INT(ClientAttribStackDepth), NO_EXTRA },
- { GL_COLOR_MATERIAL_FACE, CONTEXT_ENUM(Light.ColorMaterialFace), NO_EXTRA },
- { GL_COLOR_MATERIAL_PARAMETER, CONTEXT_ENUM(Light.ColorMaterialMode), NO_EXTRA },
- { GL_CURRENT_INDEX,
- CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]),
- extra_flush_current },
- { GL_CURRENT_RASTER_COLOR,
- CONTEXT_FIELD(Current.RasterColor[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_CURRENT_RASTER_DISTANCE, CONTEXT_FLOAT(Current.RasterDistance), NO_EXTRA },
- { GL_CURRENT_RASTER_INDEX, CONST(1), NO_EXTRA },
- { GL_CURRENT_RASTER_POSITION, CONTEXT_FLOAT4(Current.RasterPos[0]), NO_EXTRA },
- { GL_CURRENT_RASTER_SECONDARY_COLOR,
- CONTEXT_FIELD(Current.RasterSecondaryColor[0], TYPE_FLOATN_4), NO_EXTRA },
- { GL_CURRENT_RASTER_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0,
- extra_valid_texture_unit },
- { GL_CURRENT_RASTER_POSITION_VALID, CONTEXT_BOOL(Current.RasterPosValid), NO_EXTRA },
- { GL_DEPTH_BIAS, CONTEXT_FLOAT(Pixel.DepthBias), NO_EXTRA },
- { GL_DEPTH_SCALE, CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA },
- { GL_DOUBLEBUFFER, BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA },
- { GL_DRAW_BUFFER, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
- { GL_EDGE_FLAG, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
- { GL_FEEDBACK_BUFFER_SIZE, CONTEXT_INT(Feedback.BufferSize), NO_EXTRA },
- { GL_FEEDBACK_BUFFER_TYPE, CONTEXT_ENUM(Feedback.Type), NO_EXTRA },
- { GL_FOG_INDEX, CONTEXT_FLOAT(Fog.Index), NO_EXTRA },
- { GL_GREEN_BIAS, CONTEXT_FLOAT(Pixel.GreenBias), NO_EXTRA },
- { GL_GREEN_SCALE, CONTEXT_FLOAT(Pixel.GreenScale), NO_EXTRA },
- { GL_INDEX_BITS, BUFFER_INT(Visual.indexBits), extra_new_buffers },
- { GL_INDEX_CLEAR_VALUE, CONTEXT_INT(Color.ClearIndex), NO_EXTRA },
- { GL_INDEX_MODE, CONST(0) , NO_EXTRA},
- { GL_INDEX_OFFSET, CONTEXT_INT(Pixel.IndexOffset), NO_EXTRA },
- { GL_INDEX_SHIFT, CONTEXT_INT(Pixel.IndexShift), NO_EXTRA },
- { GL_INDEX_WRITEMASK, CONTEXT_INT(Color.IndexMask), NO_EXTRA },
- { GL_LIGHT_MODEL_COLOR_CONTROL, CONTEXT_ENUM(Light.Model.ColorControl), NO_EXTRA },
- { GL_LIGHT_MODEL_LOCAL_VIEWER, CONTEXT_BOOL(Light.Model.LocalViewer), NO_EXTRA },
- { GL_LINE_STIPPLE, CONTEXT_BOOL(Line.StippleFlag), NO_EXTRA },
- { GL_LINE_STIPPLE_PATTERN, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- { GL_LINE_STIPPLE_REPEAT, CONTEXT_INT(Line.StippleFactor), NO_EXTRA },
- { GL_LINE_WIDTH_GRANULARITY, CONTEXT_FLOAT(Const.LineWidthGranularity), NO_EXTRA },
- { GL_LIST_BASE, CONTEXT_INT(List.ListBase), NO_EXTRA },
- { GL_LIST_INDEX, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- { GL_LIST_MODE, LOC_CUSTOM, TYPE_ENUM, 0, NO_EXTRA },
- { GL_INDEX_LOGIC_OP, CONTEXT_BOOL(Color.IndexLogicOpEnabled), NO_EXTRA },
- { GL_MAP1_COLOR_4, CONTEXT_BOOL(Eval.Map1Color4), NO_EXTRA },
- { GL_MAP1_GRID_DOMAIN, CONTEXT_FLOAT2(Eval.MapGrid1u1), NO_EXTRA },
- { GL_MAP1_GRID_SEGMENTS, CONTEXT_INT(Eval.MapGrid1un), NO_EXTRA },
- { GL_MAP1_INDEX, CONTEXT_BOOL(Eval.Map1Index), NO_EXTRA },
- { GL_MAP1_NORMAL, CONTEXT_BOOL(Eval.Map1Normal), NO_EXTRA },
- { GL_MAP1_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map1TextureCoord1), NO_EXTRA },
- { GL_MAP1_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map1TextureCoord2), NO_EXTRA },
- { GL_MAP1_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map1TextureCoord3), NO_EXTRA },
- { GL_MAP1_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map1TextureCoord4), NO_EXTRA },
- { GL_MAP1_VERTEX_3, CONTEXT_BOOL(Eval.Map1Vertex3), NO_EXTRA },
- { GL_MAP1_VERTEX_4, CONTEXT_BOOL(Eval.Map1Vertex4), NO_EXTRA },
- { GL_MAP2_COLOR_4, CONTEXT_BOOL(Eval.Map2Color4), NO_EXTRA },
- { GL_MAP2_GRID_DOMAIN, LOC_CUSTOM, TYPE_FLOAT_4, 0, NO_EXTRA },
- { GL_MAP2_GRID_SEGMENTS, CONTEXT_INT2(Eval.MapGrid2un), NO_EXTRA },
- { GL_MAP2_INDEX, CONTEXT_BOOL(Eval.Map2Index), NO_EXTRA },
- { GL_MAP2_NORMAL, CONTEXT_BOOL(Eval.Map2Normal), NO_EXTRA },
- { GL_MAP2_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map2TextureCoord1), NO_EXTRA },
- { GL_MAP2_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map2TextureCoord2), NO_EXTRA },
- { GL_MAP2_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map2TextureCoord3), NO_EXTRA },
- { GL_MAP2_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map2TextureCoord4), NO_EXTRA },
- { GL_MAP2_VERTEX_3, CONTEXT_BOOL(Eval.Map2Vertex3), NO_EXTRA },
- { GL_MAP2_VERTEX_4, CONTEXT_BOOL(Eval.Map2Vertex4), NO_EXTRA },
- { GL_MAP_COLOR, CONTEXT_BOOL(Pixel.MapColorFlag), NO_EXTRA },
- { GL_MAP_STENCIL, CONTEXT_BOOL(Pixel.MapStencilFlag), NO_EXTRA },
- { GL_MAX_ATTRIB_STACK_DEPTH, CONST(MAX_ATTRIB_STACK_DEPTH), NO_EXTRA },
- { GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, CONST(MAX_CLIENT_ATTRIB_STACK_DEPTH), NO_EXTRA },
-
- { GL_MAX_EVAL_ORDER, CONST(MAX_EVAL_ORDER), NO_EXTRA },
- { GL_MAX_LIST_NESTING, CONST(MAX_LIST_NESTING), NO_EXTRA },
- { GL_MAX_NAME_STACK_DEPTH, CONST(MAX_NAME_STACK_DEPTH), NO_EXTRA },
- { GL_MAX_PIXEL_MAP_TABLE, CONST(MAX_PIXEL_MAP_TABLE), NO_EXTRA },
- { GL_NAME_STACK_DEPTH, CONTEXT_INT(Select.NameStackDepth), NO_EXTRA },
- { GL_PACK_LSB_FIRST, CONTEXT_BOOL(Pack.LsbFirst), NO_EXTRA },
- { GL_PACK_ROW_LENGTH, CONTEXT_INT(Pack.RowLength), NO_EXTRA },
- { GL_PACK_SKIP_PIXELS, CONTEXT_INT(Pack.SkipPixels), NO_EXTRA },
- { GL_PACK_SKIP_ROWS, CONTEXT_INT(Pack.SkipRows), NO_EXTRA },
- { GL_PACK_SWAP_BYTES, CONTEXT_BOOL(Pack.SwapBytes), NO_EXTRA },
- { GL_PACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Pack.ImageHeight), NO_EXTRA },
- { GL_PACK_INVERT_MESA, CONTEXT_BOOL(Pack.Invert), NO_EXTRA },
- { GL_PIXEL_MAP_A_TO_A_SIZE, CONTEXT_INT(PixelMaps.AtoA.Size), NO_EXTRA },
- { GL_PIXEL_MAP_B_TO_B_SIZE, CONTEXT_INT(PixelMaps.BtoB.Size), NO_EXTRA },
- { GL_PIXEL_MAP_G_TO_G_SIZE, CONTEXT_INT(PixelMaps.GtoG.Size), NO_EXTRA },
- { GL_PIXEL_MAP_I_TO_A_SIZE, CONTEXT_INT(PixelMaps.ItoA.Size), NO_EXTRA },
- { GL_PIXEL_MAP_I_TO_B_SIZE, CONTEXT_INT(PixelMaps.ItoB.Size), NO_EXTRA },
- { GL_PIXEL_MAP_I_TO_G_SIZE, CONTEXT_INT(PixelMaps.ItoG.Size), NO_EXTRA },
- { GL_PIXEL_MAP_I_TO_I_SIZE, CONTEXT_INT(PixelMaps.ItoI.Size), NO_EXTRA },
- { GL_PIXEL_MAP_I_TO_R_SIZE, CONTEXT_INT(PixelMaps.ItoR.Size), NO_EXTRA },
- { GL_PIXEL_MAP_R_TO_R_SIZE, CONTEXT_INT(PixelMaps.RtoR.Size), NO_EXTRA },
- { GL_PIXEL_MAP_S_TO_S_SIZE, CONTEXT_INT(PixelMaps.StoS.Size), NO_EXTRA },
- { GL_POINT_SIZE_GRANULARITY, CONTEXT_FLOAT(Const.PointSizeGranularity), NO_EXTRA },
- { GL_POLYGON_MODE, CONTEXT_ENUM2(Polygon.FrontMode), NO_EXTRA },
- { GL_POLYGON_OFFSET_BIAS_EXT, CONTEXT_FLOAT(Polygon.OffsetUnits), NO_EXTRA },
- { GL_POLYGON_OFFSET_POINT, CONTEXT_BOOL(Polygon.OffsetPoint), NO_EXTRA },
- { GL_POLYGON_OFFSET_LINE, CONTEXT_BOOL(Polygon.OffsetLine), NO_EXTRA },
- { GL_POLYGON_SMOOTH, CONTEXT_BOOL(Polygon.SmoothFlag), NO_EXTRA },
- { GL_POLYGON_SMOOTH_HINT, CONTEXT_ENUM(Hint.PolygonSmooth), NO_EXTRA },
- { GL_POLYGON_STIPPLE, CONTEXT_BOOL(Polygon.StippleFlag), NO_EXTRA },
- { GL_READ_BUFFER, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
- { GL_RED_BIAS, CONTEXT_FLOAT(Pixel.RedBias), NO_EXTRA },
- { GL_RED_SCALE, CONTEXT_FLOAT(Pixel.RedScale), NO_EXTRA },
- { GL_RENDER_MODE, CONTEXT_ENUM(RenderMode), NO_EXTRA },
- { GL_RGBA_MODE, CONST(1), NO_EXTRA },
- { GL_SELECTION_BUFFER_SIZE, CONTEXT_INT(Select.BufferSize), NO_EXTRA },
- { GL_SHARED_TEXTURE_PALETTE_EXT, CONTEXT_BOOL(Texture.SharedPalette), NO_EXTRA },
-
- { GL_STEREO, BUFFER_INT(Visual.stereoMode), NO_EXTRA },
-
- { GL_TEXTURE_1D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
- { GL_TEXTURE_3D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
- { GL_TEXTURE_1D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
- { GL_TEXTURE_2D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
-
- { GL_TEXTURE_BINDING_1D, LOC_CUSTOM, TYPE_INT, TEXTURE_1D_INDEX, NO_EXTRA },
- { GL_TEXTURE_BINDING_1D_ARRAY, LOC_CUSTOM, TYPE_INT,
- TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array },
- { GL_TEXTURE_BINDING_2D_ARRAY, LOC_CUSTOM, TYPE_INT,
- TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array },
- { GL_MAX_ARRAY_TEXTURE_LAYERS_EXT,
- CONTEXT_INT(Const.MaxArrayTextureLayers), extra_MESA_texture_array },
-
- { GL_TEXTURE_GEN_S, LOC_TEXUNIT, TYPE_BIT_0,
- offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
- { GL_TEXTURE_GEN_T, LOC_TEXUNIT, TYPE_BIT_1,
- offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
- { GL_TEXTURE_GEN_R, LOC_TEXUNIT, TYPE_BIT_2,
- offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
- { GL_TEXTURE_GEN_Q, LOC_TEXUNIT, TYPE_BIT_3,
- offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
- { GL_UNPACK_LSB_FIRST, CONTEXT_BOOL(Unpack.LsbFirst), NO_EXTRA },
- { GL_UNPACK_ROW_LENGTH, CONTEXT_INT(Unpack.RowLength), NO_EXTRA },
- { GL_UNPACK_SKIP_PIXELS, CONTEXT_INT(Unpack.SkipPixels), NO_EXTRA },
- { GL_UNPACK_SKIP_ROWS, CONTEXT_INT(Unpack.SkipRows), NO_EXTRA },
- { GL_UNPACK_SWAP_BYTES, CONTEXT_BOOL(Unpack.SwapBytes), NO_EXTRA },
- { GL_UNPACK_SKIP_IMAGES_EXT, CONTEXT_INT(Unpack.SkipImages), NO_EXTRA },
- { GL_UNPACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Unpack.ImageHeight), NO_EXTRA },
- { GL_UNPACK_CLIENT_STORAGE_APPLE, CONTEXT_BOOL(Unpack.ClientStorage), NO_EXTRA },
- { GL_ZOOM_X, CONTEXT_FLOAT(Pixel.ZoomX), NO_EXTRA },
- { GL_ZOOM_Y, CONTEXT_FLOAT(Pixel.ZoomY), NO_EXTRA },
-
- /* Vertex arrays */
- { GL_VERTEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- { GL_NORMAL_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- { GL_COLOR_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- { GL_INDEX_ARRAY, ARRAY_BOOL(Index.Enabled), NO_EXTRA },
- { GL_INDEX_ARRAY_TYPE, ARRAY_ENUM(Index.Type), NO_EXTRA },
- { GL_INDEX_ARRAY_STRIDE, ARRAY_INT(Index.Stride), NO_EXTRA },
- { GL_INDEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- { GL_TEXTURE_COORD_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- { GL_EDGE_FLAG_ARRAY, ARRAY_BOOL(EdgeFlag.Enabled), NO_EXTRA },
- { GL_EDGE_FLAG_ARRAY_STRIDE, ARRAY_INT(EdgeFlag.Stride), NO_EXTRA },
- { GL_EDGE_FLAG_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
-
- /* GL_ARB_texture_compression */
- { GL_TEXTURE_COMPRESSION_HINT_ARB, CONTEXT_INT(Hint.TextureCompression), NO_EXTRA },
-
- /* GL_EXT_compiled_vertex_array */
- { GL_ARRAY_ELEMENT_LOCK_FIRST_EXT, CONTEXT_INT(Array.LockFirst),
- extra_EXT_compiled_vertex_array },
- { GL_ARRAY_ELEMENT_LOCK_COUNT_EXT, CONTEXT_INT(Array.LockCount),
- extra_EXT_compiled_vertex_array },
-
- /* GL_ARB_transpose_matrix */
- { GL_TRANSPOSE_MODELVIEW_MATRIX_ARB,
- CONTEXT_MATRIX_T(ModelviewMatrixStack), NO_EXTRA },
- { GL_TRANSPOSE_PROJECTION_MATRIX_ARB,
- CONTEXT_MATRIX_T(ProjectionMatrixStack.Top), NO_EXTRA },
- { GL_TRANSPOSE_TEXTURE_MATRIX_ARB, CONTEXT_MATRIX_T(TextureMatrixStack), NO_EXTRA },
-
- /* GL_EXT_secondary_color */
- { GL_COLOR_SUM_EXT, CONTEXT_BOOL(Fog.ColorSumEnabled),
- extra_EXT_secondary_color_ARB_vertex_program },
- { GL_CURRENT_SECONDARY_COLOR_EXT,
- CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR1][0], TYPE_FLOATN_4),
- extra_EXT_secondary_color_flush_current },
- { GL_SECONDARY_COLOR_ARRAY_EXT, ARRAY_BOOL(SecondaryColor.Enabled),
- extra_EXT_secondary_color },
- { GL_SECONDARY_COLOR_ARRAY_TYPE_EXT, ARRAY_ENUM(SecondaryColor.Type),
- extra_EXT_secondary_color },
- { GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT, ARRAY_INT(SecondaryColor.Stride),
- extra_EXT_secondary_color },
- { GL_SECONDARY_COLOR_ARRAY_SIZE_EXT, ARRAY_INT(SecondaryColor.Size),
- extra_EXT_secondary_color },
-
- /* GL_EXT_fog_coord */
- { GL_CURRENT_FOG_COORDINATE_EXT,
- CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]),
- extra_EXT_fog_coord_flush_current },
- { GL_FOG_COORDINATE_ARRAY_EXT, ARRAY_BOOL(FogCoord.Enabled),
- extra_EXT_fog_coord },
- { GL_FOG_COORDINATE_ARRAY_TYPE_EXT, ARRAY_ENUM(FogCoord.Type),
- extra_EXT_fog_coord },
- { GL_FOG_COORDINATE_ARRAY_STRIDE_EXT, ARRAY_INT(FogCoord.Stride),
- extra_EXT_fog_coord },
- { GL_FOG_COORDINATE_SOURCE_EXT, CONTEXT_ENUM(Fog.FogCoordinateSource),
- extra_EXT_fog_coord },
-
- /* GL_IBM_rasterpos_clip */
- { GL_RASTER_POSITION_UNCLIPPED_IBM,
- CONTEXT_BOOL(Transform.RasterPositionUnclipped),
- extra_IBM_rasterpos_clip },
-
- /* GL_NV_point_sprite */
- { GL_POINT_SPRITE_R_MODE_NV,
- CONTEXT_ENUM(Point.SpriteRMode), extra_NV_point_sprite },
- { GL_POINT_SPRITE_COORD_ORIGIN, CONTEXT_ENUM(Point.SpriteOrigin),
- extra_NV_point_sprite_ARB_point_sprite },
-
- /* GL_NV_vertex_program */
- { GL_VERTEX_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0,
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY0_NV, ARRAY_BOOL(VertexAttrib[0].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY1_NV, ARRAY_BOOL(VertexAttrib[1].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY2_NV, ARRAY_BOOL(VertexAttrib[2].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY3_NV, ARRAY_BOOL(VertexAttrib[3].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY4_NV, ARRAY_BOOL(VertexAttrib[4].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY5_NV, ARRAY_BOOL(VertexAttrib[5].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY6_NV, ARRAY_BOOL(VertexAttrib[6].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY7_NV, ARRAY_BOOL(VertexAttrib[7].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY8_NV, ARRAY_BOOL(VertexAttrib[8].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY9_NV, ARRAY_BOOL(VertexAttrib[9].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY10_NV, ARRAY_BOOL(VertexAttrib[10].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY11_NV, ARRAY_BOOL(VertexAttrib[11].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY12_NV, ARRAY_BOOL(VertexAttrib[12].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY13_NV, ARRAY_BOOL(VertexAttrib[13].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY14_NV, ARRAY_BOOL(VertexAttrib[14].Enabled),
- extra_NV_vertex_program },
- { GL_VERTEX_ATTRIB_ARRAY15_NV, ARRAY_BOOL(VertexAttrib[15].Enabled),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB0_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[0]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB1_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[1]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB2_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[2]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB3_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[3]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB4_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[4]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB5_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[5]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB6_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[6]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB7_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[7]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB8_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[8]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB9_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[9]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB10_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[10]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB11_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[11]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB12_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[12]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB13_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[13]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB14_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[14]),
- extra_NV_vertex_program },
- { GL_MAP1_VERTEX_ATTRIB15_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[15]),
- extra_NV_vertex_program },
-
- /* GL_NV_fragment_program */
- { GL_FRAGMENT_PROGRAM_NV, CONTEXT_BOOL(FragmentProgram.Enabled),
- extra_NV_fragment_program },
- { GL_FRAGMENT_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0,
- extra_NV_fragment_program },
- { GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV,
- CONST(MAX_NV_FRAGMENT_PROGRAM_PARAMS),
- extra_NV_fragment_program },
-
- /* GL_NV_texture_rectangle */
- { GL_TEXTURE_RECTANGLE_NV,
- LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_NV_texture_rectangle },
- { GL_TEXTURE_BINDING_RECTANGLE_NV,
- LOC_CUSTOM, TYPE_INT, TEXTURE_RECT_INDEX, extra_NV_texture_rectangle },
- { GL_MAX_RECTANGLE_TEXTURE_SIZE_NV,
- CONTEXT_INT(Const.MaxTextureRectSize), extra_NV_texture_rectangle },
-
- /* GL_EXT_stencil_two_side */
- { GL_STENCIL_TEST_TWO_SIDE_EXT, CONTEXT_BOOL(Stencil.TestTwoSide),
- extra_EXT_stencil_two_side },
- { GL_ACTIVE_STENCIL_FACE_EXT, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
-
- /* GL_NV_light_max_exponent */
- { GL_MAX_SHININESS_NV, CONTEXT_FLOAT(Const.MaxShininess),
- extra_NV_light_max_exponent },
- { GL_MAX_SPOT_EXPONENT_NV, CONTEXT_FLOAT(Const.MaxSpotExponent),
- extra_NV_light_max_exponent },
-
- /* GL_NV_primitive_restart */
- { GL_PRIMITIVE_RESTART_NV, CONTEXT_BOOL(Array.PrimitiveRestart),
- extra_NV_primitive_restart },
- { GL_PRIMITIVE_RESTART_INDEX_NV, CONTEXT_INT(Array.RestartIndex),
- extra_NV_primitive_restart },
-
- /* GL_ARB_vertex_buffer_object */
- { GL_INDEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, Index.BufferObj), NO_EXTRA },
- { GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, EdgeFlag.BufferObj), NO_EXTRA },
- { GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, SecondaryColor.BufferObj), NO_EXTRA },
- { GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
- offsetof(struct gl_array_object, FogCoord.BufferObj), NO_EXTRA },
-
- /* GL_EXT_pixel_buffer_object */
- { GL_PIXEL_PACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_pixel_buffer_object },
- { GL_PIXEL_UNPACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_pixel_buffer_object },
-
- /* GL_ARB_vertex_program */
- { GL_VERTEX_PROGRAM_ARB, /* == GL_VERTEX_PROGRAM_NV */
- CONTEXT_BOOL(VertexProgram.Enabled),
- extra_ARB_vertex_program_NV_vertex_program },
- { GL_VERTEX_PROGRAM_POINT_SIZE_ARB, /* == GL_VERTEX_PROGRAM_POINT_SIZE_NV*/
- CONTEXT_BOOL(VertexProgram.PointSizeEnabled),
- extra_ARB_vertex_program_NV_vertex_program },
- { GL_VERTEX_PROGRAM_TWO_SIDE_ARB, /* == GL_VERTEX_PROGRAM_TWO_SIDE_NV */
- CONTEXT_BOOL(VertexProgram.TwoSideEnabled),
- extra_ARB_vertex_program_NV_vertex_program },
- { GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB, /* == GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
- CONTEXT_INT(Const.MaxProgramMatrixStackDepth),
- extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
- { GL_MAX_PROGRAM_MATRICES_ARB, /* == GL_MAX_TRACK_MATRICES_NV */
- CONTEXT_INT(Const.MaxProgramMatrices),
- extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
- { GL_CURRENT_MATRIX_STACK_DEPTH_ARB, /* == GL_CURRENT_MATRIX_STACK_DEPTH_NV */
- LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
-
- { GL_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */
- LOC_CUSTOM, TYPE_MATRIX, 0,
- extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
- { GL_TRANSPOSE_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */
- LOC_CUSTOM, TYPE_MATRIX, 0,
- extra_ARB_vertex_program_ARB_fragment_program },
-
- { GL_PROGRAM_ERROR_POSITION_ARB, /* == GL_PROGRAM_ERROR_POSITION_NV */
- CONTEXT_INT(Program.ErrorPos),
- extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
-
- /* GL_ARB_fragment_program */
- { GL_FRAGMENT_PROGRAM_ARB, CONTEXT_BOOL(FragmentProgram.Enabled),
- extra_ARB_fragment_program },
-
- /* GL_EXT_depth_bounds_test */
- { GL_DEPTH_BOUNDS_TEST_EXT, CONTEXT_BOOL(Depth.BoundsTest),
- extra_EXT_depth_bounds_test },
- { GL_DEPTH_BOUNDS_EXT, CONTEXT_FLOAT2(Depth.BoundsMin),
- extra_EXT_depth_bounds_test },
-
- /* GL_ARB_depth_clamp*/
- { GL_DEPTH_CLAMP, CONTEXT_BOOL(Transform.DepthClamp),
- extra_ARB_depth_clamp },
-
- /* GL_ARB_draw_buffers */
- { GL_DRAW_BUFFER0_ARB, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
- { GL_DRAW_BUFFER1_ARB, BUFFER_ENUM(ColorDrawBuffer[1]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER2_ARB, BUFFER_ENUM(ColorDrawBuffer[2]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]),
- extra_valid_draw_buffer },
-
- /* GL_ATI_fragment_shader */
- { GL_NUM_FRAGMENT_REGISTERS_ATI, CONST(6), extra_ATI_fragment_shader },
- { GL_NUM_FRAGMENT_CONSTANTS_ATI, CONST(8), extra_ATI_fragment_shader },
- { GL_NUM_PASSES_ATI, CONST(2), extra_ATI_fragment_shader },
- { GL_NUM_INSTRUCTIONS_PER_PASS_ATI, CONST(8), extra_ATI_fragment_shader },
- { GL_NUM_INSTRUCTIONS_TOTAL_ATI, CONST(16), extra_ATI_fragment_shader },
- { GL_COLOR_ALPHA_PAIRING_ATI, CONST(GL_TRUE), extra_ATI_fragment_shader },
- { GL_NUM_LOOPBACK_COMPONENTS_ATI, CONST(3), extra_ATI_fragment_shader },
- { GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI,
- CONST(3), extra_ATI_fragment_shader },
-
- /* GL_EXT_framebuffer_object */
- { GL_MAX_COLOR_ATTACHMENTS_EXT, CONTEXT_INT(Const.MaxColorAttachments),
- extra_EXT_framebuffer_object },
-
- /* GL_EXT_framebuffer_blit
- * NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT */
- { GL_READ_FRAMEBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_framebuffer_blit },
-
- /* GL_EXT_provoking_vertex */
- { GL_PROVOKING_VERTEX_EXT,
- CONTEXT_BOOL(Light.ProvokingVertex), extra_EXT_provoking_vertex },
- { GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT,
- CONTEXT_BOOL(Const.QuadsFollowProvokingVertexConvention),
- extra_EXT_provoking_vertex },
-
- /* GL_ARB_framebuffer_object */
- { GL_MAX_SAMPLES, CONTEXT_INT(Const.MaxSamples),
- extra_ARB_framebuffer_object_EXT_framebuffer_multisample },
-
- /* GL_APPLE_vertex_array_object */
- { GL_VERTEX_ARRAY_BINDING_APPLE, ARRAY_INT(Name),
- extra_APPLE_vertex_array_object },
-
- /* GL_ARB_seamless_cube_map */
- { GL_TEXTURE_CUBE_MAP_SEAMLESS,
- CONTEXT_BOOL(Texture.CubeMapSeamless), extra_ARB_seamless_cube_map },
-
- /* GL_ARB_sync */
- { GL_MAX_SERVER_WAIT_TIMEOUT,
- CONTEXT_INT64(Const.MaxServerWaitTimeout), extra_ARB_sync },
-
- /* GL_EXT_texture_integer */
- { GL_RGBA_INTEGER_MODE_EXT, BUFFER_BOOL(_IntegerColor),
- extra_EXT_texture_integer },
-
- /* GL_EXT_transform_feedback */
- { GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_transform_feedback },
- { GL_RASTERIZER_DISCARD, CONTEXT_BOOL(TransformFeedback.RasterDiscard),
- extra_EXT_transform_feedback },
- { GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
- CONTEXT_INT(Const.MaxTransformFeedbackInterleavedComponents),
- extra_EXT_transform_feedback },
- { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
- CONTEXT_INT(Const.MaxTransformFeedbackSeparateAttribs),
- extra_EXT_transform_feedback },
- { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
- CONTEXT_INT(Const.MaxTransformFeedbackSeparateComponents),
- extra_EXT_transform_feedback },
-
- /* GL_ARB_transform_feedback2 */
- { GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, LOC_CUSTOM, TYPE_BOOLEAN, 0,
- extra_ARB_transform_feedback2 },
- { GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, LOC_CUSTOM, TYPE_BOOLEAN, 0,
- extra_ARB_transform_feedback2 },
- { GL_TRANSFORM_FEEDBACK_BINDING, LOC_CUSTOM, TYPE_INT, 0,
- extra_ARB_transform_feedback2 },
-
- /* GL_ARB_geometry_shader4 */
- { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB,
- CONTEXT_INT(Const.MaxGeometryTextureImageUnits),
- extra_ARB_geometry_shader4 },
- { GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB,
- CONTEXT_INT(Const.MaxGeometryOutputVertices),
- extra_ARB_geometry_shader4 },
- { GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB,
- CONTEXT_INT(Const.MaxGeometryTotalOutputComponents),
- extra_ARB_geometry_shader4 },
- { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB,
- CONTEXT_INT(Const.GeometryProgram.MaxUniformComponents),
- extra_ARB_geometry_shader4 },
- { GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB,
- CONTEXT_INT(Const.MaxGeometryVaryingComponents),
- extra_ARB_geometry_shader4 },
- { GL_MAX_VERTEX_VARYING_COMPONENTS_ARB,
- CONTEXT_INT(Const.MaxVertexVaryingComponents),
- extra_ARB_geometry_shader4 },
-
- /* GL_EXT_gpu_shader4 / GL 3.0 */
- { GL_MIN_PROGRAM_TEXEL_OFFSET,
- CONTEXT_INT(Const.MinProgramTexelOffset),
- extra_EXT_gpu_shader4 },
- { GL_MAX_PROGRAM_TEXEL_OFFSET,
- CONTEXT_INT(Const.MaxProgramTexelOffset),
- extra_EXT_gpu_shader4 },
-
- /* GL 3.0 */
- { GL_NUM_EXTENSIONS, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 },
- { GL_MAJOR_VERSION, CONTEXT_INT(VersionMajor), extra_version_30 },
- { GL_MINOR_VERSION, CONTEXT_INT(VersionMinor), extra_version_30 },
- { GL_CONTEXT_FLAGS, CONTEXT_INT(Const.ContextFlags), extra_version_30 },
-
- /* GL3.0 / GL_EXT_framebuffer_sRGB */
- { GL_FRAMEBUFFER_SRGB_EXT, CONTEXT_BOOL(Color.sRGBEnabled), extra_EXT_framebuffer_sRGB },
- { GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, BUFFER_INT(Visual.sRGBCapable), extra_EXT_framebuffer_sRGB },
-
- /* GL 3.1 */
- /* NOTE: different enum values for GL_PRIMITIVE_RESTART_NV
- * vs. GL_PRIMITIVE_RESTART!
- */
- { GL_PRIMITIVE_RESTART, CONTEXT_BOOL(Array.PrimitiveRestart),
- extra_version_31 },
- { GL_PRIMITIVE_RESTART_INDEX, CONTEXT_INT(Array.RestartIndex),
- extra_version_31 },
-
-
- /* GL 3.2 */
- { GL_CONTEXT_PROFILE_MASK, CONTEXT_INT(Const.ProfileMask),
- extra_version_32 },
-#endif /* FEATURE_GL */
-};
-
-/* All we need now is a way to look up the value struct from the enum.
- * The code generated by gcc for the old generated big switch
- * statement is a big, balanced, open coded if/else tree, essentially
- * an unrolled binary search. It would be natural to sort the new
- * enum table and use bsearch(), but we will use a read-only hash
- * table instead. bsearch() has a nice guaranteed worst case
- * performance, but we're also guaranteed to hit that worst case
- * (log2(n) iterations) for about half the enums. Instead, using an
- * open addressing hash table, we can find the enum on the first try
- * for 80% of the enums, 1 collision for 10% and never more than 5
- * collisions for any enum (typical numbers). And the code is very
- * simple, even though it feels a little magic. */
-
-static unsigned short table[1024];
-static const int prime_factor = 89, prime_step = 281;
-
-#ifdef GET_DEBUG
-static void
-print_table_stats(void)
-{
- int i, j, collisions[11], count, hash, mask;
- const struct value_desc *d;
-
- count = 0;
- mask = Elements(table) - 1;
- memset(collisions, 0, sizeof collisions);
-
- for (i = 0; i < Elements(table); i++) {
- if (!table[i])
- continue;
- count++;
- d = &values[table[i]];
- hash = (d->pname * prime_factor);
- j = 0;
- while (1) {
- if (values[table[hash & mask]].pname == d->pname)
- break;
- hash += prime_step;
- j++;
- }
-
- if (j < 10)
- collisions[j]++;
- else
- collisions[10]++;
- }
-
- printf("number of enums: %d (total %d)\n", count, Elements(values));
- for (i = 0; i < Elements(collisions) - 1; i++)
- if (collisions[i] > 0)
- printf(" %d enums with %d %scollisions\n",
- collisions[i], i, i == 10 ? "or more " : "");
-}
-#endif
-
-/**
- * Initialize the enum hash for a given API
- *
- * This is called from one_time_init() to insert the enum values that
- * are valid for the API in question into the enum hash table.
- *
- * \param the current context, for determining the API in question
- */
-void _mesa_init_get_hash(struct gl_context *ctx)
-{
- int i, hash, index, mask;
- int api_mask = 0, api_bit;
-
- mask = Elements(table) - 1;
- api_bit = 1 << ctx->API;
-
- for (i = 0; i < Elements(values); i++) {
- if (values[i].type == TYPE_API_MASK) {
- api_mask = values[i].offset;
- continue;
- }
- if (!(api_mask & api_bit))
- continue;
-
- hash = (values[i].pname * prime_factor) & mask;
- while (1) {
- index = hash & mask;
- if (!table[index]) {
- table[index] = i;
- break;
- }
- hash += prime_step;
- }
- }
-
-#ifdef GET_DEBUG
- print_table_stats();
-#endif
-}
-
-/**
- * Handle irregular enums
- *
- * Some values don't conform to the "well-known type at context
- * pointer + offset" pattern, so we have this function to catch all
- * the corner cases. Typically, it's a computed value or a one-off
- * pointer to a custom struct or something.
- *
- * In this case we can't return a pointer to the value, so we'll have
- * to use the temporary variable 'v' declared back in the calling
- * glGet*v() function to store the result.
- *
- * \param ctx the current context
- * \param d the struct value_desc that describes the enum
- * \param v pointer to the tmp declared in the calling glGet*v() function
- */
-static void
-find_custom_value(struct gl_context *ctx, const struct value_desc *d, union value *v)
-{
- struct gl_buffer_object *buffer_obj;
- struct gl_client_array *array;
- GLuint unit, *p;
-
- switch (d->pname) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_TEXTURE_CUBE_MAP_ARB:
- case GL_TEXTURE_RECTANGLE_NV:
- v->value_bool = _mesa_IsEnabled(d->pname);
- break;
-
- case GL_LINE_STIPPLE_PATTERN:
- /* This is the only GLushort, special case it here by promoting
- * to an int rather than introducing a new type. */
- v->value_int = ctx->Line.StipplePattern;
- break;
-
- case GL_CURRENT_RASTER_TEXTURE_COORDS:
- unit = ctx->Texture.CurrentUnit;
- v->value_float_4[0] = ctx->Current.RasterTexCoords[unit][0];
- v->value_float_4[1] = ctx->Current.RasterTexCoords[unit][1];
- v->value_float_4[2] = ctx->Current.RasterTexCoords[unit][2];
- v->value_float_4[3] = ctx->Current.RasterTexCoords[unit][3];
- break;
-
- case GL_CURRENT_TEXTURE_COORDS:
- unit = ctx->Texture.CurrentUnit;
- v->value_float_4[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0];
- v->value_float_4[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1];
- v->value_float_4[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2];
- v->value_float_4[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3];
- break;
-
- case GL_COLOR_WRITEMASK:
- v->value_int_4[0] = ctx->Color.ColorMask[0][RCOMP] ? 1 : 0;
- v->value_int_4[1] = ctx->Color.ColorMask[0][GCOMP] ? 1 : 0;
- v->value_int_4[2] = ctx->Color.ColorMask[0][BCOMP] ? 1 : 0;
- v->value_int_4[3] = ctx->Color.ColorMask[0][ACOMP] ? 1 : 0;
- break;
-
- case GL_EDGE_FLAG:
- v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0;
- break;
-
- case GL_READ_BUFFER:
- v->value_enum = ctx->ReadBuffer->ColorReadBuffer;
- break;
-
- case GL_MAP2_GRID_DOMAIN:
- v->value_float_4[0] = ctx->Eval.MapGrid2u1;
- v->value_float_4[1] = ctx->Eval.MapGrid2u2;
- v->value_float_4[2] = ctx->Eval.MapGrid2v1;
- v->value_float_4[3] = ctx->Eval.MapGrid2v2;
- break;
-
- case GL_TEXTURE_STACK_DEPTH:
- unit = ctx->Texture.CurrentUnit;
- v->value_int = ctx->TextureMatrixStack[unit].Depth + 1;
- break;
- case GL_TEXTURE_MATRIX:
- unit = ctx->Texture.CurrentUnit;
- v->value_matrix = ctx->TextureMatrixStack[unit].Top;
- break;
-
- case GL_TEXTURE_COORD_ARRAY:
- case GL_TEXTURE_COORD_ARRAY_SIZE:
- case GL_TEXTURE_COORD_ARRAY_TYPE:
- case GL_TEXTURE_COORD_ARRAY_STRIDE:
- array = &ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture];
- v->value_int = *(GLuint *) ((char *) array + d->offset);
- break;
-
- case GL_ACTIVE_TEXTURE_ARB:
- v->value_int = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
- break;
- case GL_CLIENT_ACTIVE_TEXTURE_ARB:
- v->value_int = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
- break;
-
- case GL_MODELVIEW_STACK_DEPTH:
- case GL_PROJECTION_STACK_DEPTH:
- v->value_int = *(GLint *) ((char *) ctx + d->offset) + 1;
- break;
-
- case GL_MAX_TEXTURE_SIZE:
- case GL_MAX_3D_TEXTURE_SIZE:
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
- p = (GLuint *) ((char *) ctx + d->offset);
- v->value_int = 1 << (*p - 1);
- break;
-
- case GL_SCISSOR_BOX:
- v->value_int_4[0] = ctx->Scissor.X;
- v->value_int_4[1] = ctx->Scissor.Y;
- v->value_int_4[2] = ctx->Scissor.Width;
- v->value_int_4[3] = ctx->Scissor.Height;
- break;
-
- case GL_LIST_INDEX:
- v->value_int =
- ctx->ListState.CurrentList ? ctx->ListState.CurrentList->Name : 0;
- break;
- case GL_LIST_MODE:
- if (!ctx->CompileFlag)
- v->value_enum = 0;
- else if (ctx->ExecuteFlag)
- v->value_enum = GL_COMPILE_AND_EXECUTE;
- else
- v->value_enum = GL_COMPILE;
- break;
-
- case GL_VIEWPORT:
- v->value_int_4[0] = ctx->Viewport.X;
- v->value_int_4[1] = ctx->Viewport.Y;
- v->value_int_4[2] = ctx->Viewport.Width;
- v->value_int_4[3] = ctx->Viewport.Height;
- break;
-
- case GL_ACTIVE_STENCIL_FACE_EXT:
- v->value_enum = ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT;
- break;
-
- case GL_STENCIL_FAIL:
- v->value_enum = ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_FUNC:
- v->value_enum = ctx->Stencil.Function[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_PASS_DEPTH_FAIL:
- v->value_enum = ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_PASS_DEPTH_PASS:
- v->value_enum = ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_REF:
- v->value_int = ctx->Stencil.Ref[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_VALUE_MASK:
- v->value_int = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace];
- break;
- case GL_STENCIL_WRITEMASK:
- v->value_int = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace];
- break;
-
- case GL_NUM_EXTENSIONS:
- v->value_int = _mesa_get_extension_count(ctx);
- break;
-
- case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
- v->value_int = _mesa_get_color_read_type(ctx);
- break;
- case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
- v->value_int = _mesa_get_color_read_format(ctx);
- break;
-
- case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
- v->value_int = ctx->CurrentStack->Depth + 1;
- break;
- case GL_CURRENT_MATRIX_ARB:
- case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
- v->value_matrix = ctx->CurrentStack->Top;
- break;
-
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
- v->value_int = _mesa_get_compressed_formats(ctx, NULL, GL_FALSE);
- break;
- case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
- v->value_int_n.n =
- _mesa_get_compressed_formats(ctx, v->value_int_n.ints, GL_FALSE);
- ASSERT(v->value_int_n.n <= 100);
- break;
-
- case GL_MAX_VARYING_FLOATS_ARB:
- v->value_int = ctx->Const.MaxVarying * 4;
- break;
-
- /* Various object names */
-
- case GL_TEXTURE_BINDING_1D:
- case GL_TEXTURE_BINDING_2D:
- case GL_TEXTURE_BINDING_3D:
- case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
- case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
- case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
- case GL_TEXTURE_BINDING_RECTANGLE_NV:
- unit = ctx->Texture.CurrentUnit;
- v->value_int =
- ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name;
- break;
-
- /* GL_ARB_vertex_buffer_object */
- case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
- case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
- case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
- case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
- case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
- case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
- case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
- buffer_obj = (struct gl_buffer_object *)
- ((char *) ctx->Array.ArrayObj + d->offset);
- v->value_int = buffer_obj->Name;
- break;
- case GL_ARRAY_BUFFER_BINDING_ARB:
- v->value_int = ctx->Array.ArrayBufferObj->Name;
- break;
- case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
- v->value_int =
- ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name;
- break;
- case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
- v->value_int = ctx->Array.ElementArrayBufferObj->Name;
- break;
-
- /* ARB_copy_buffer */
- case GL_COPY_READ_BUFFER:
- v->value_int = ctx->CopyReadBuffer->Name;
- break;
- case GL_COPY_WRITE_BUFFER:
- v->value_int = ctx->CopyWriteBuffer->Name;
- break;
-
- case GL_FRAGMENT_PROGRAM_BINDING_NV:
- v->value_int =
- ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0;
- break;
- case GL_VERTEX_PROGRAM_BINDING_NV:
- v->value_int =
- ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0;
- break;
- case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
- v->value_int = ctx->Pack.BufferObj->Name;
- break;
- case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
- v->value_int = ctx->Unpack.BufferObj->Name;
- break;
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- v->value_int = ctx->TransformFeedback.CurrentBuffer->Name;
- break;
- case GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED:
- v->value_int = ctx->TransformFeedback.CurrentObject->Paused;
- break;
- case GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE:
- v->value_int = ctx->TransformFeedback.CurrentObject->Active;
- break;
- case GL_TRANSFORM_FEEDBACK_BINDING:
- v->value_int = ctx->TransformFeedback.CurrentObject->Name;
- break;
- case GL_CURRENT_PROGRAM:
- v->value_int =
- ctx->Shader.ActiveProgram ? ctx->Shader.ActiveProgram->Name : 0;
- break;
- case GL_READ_FRAMEBUFFER_BINDING_EXT:
- v->value_int = ctx->ReadBuffer->Name;
- break;
- case GL_RENDERBUFFER_BINDING_EXT:
- v->value_int =
- ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
- break;
- case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
- v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name;
- break;
-
- case GL_MAX_VERTEX_UNIFORM_VECTORS:
- v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4;
- break;
-
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
- v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
- break;
- }
-}
-
-/**
- * Check extra constraints on a struct value_desc descriptor
- *
- * If a struct value_desc has a non-NULL extra pointer, it means that
- * there are a number of extra constraints to check or actions to
- * perform. The extras is just an integer array where each integer
- * encode different constraints or actions.
- *
- * \param ctx current context
- * \param func name of calling glGet*v() function for error reporting
- * \param d the struct value_desc that has the extra constraints
- *
- * \return GL_FALSE if one of the constraints was not satisfied,
- * otherwise GL_TRUE.
- */
-static GLboolean
-check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d)
-{
- const GLuint version = ctx->VersionMajor * 10 + ctx->VersionMinor;
- int total, enabled;
- const int *e;
-
- total = 0;
- enabled = 0;
- for (e = d->extra; *e != EXTRA_END; e++)
- switch (*e) {
- case EXTRA_VERSION_30:
- if (version >= 30) {
- total++;
- enabled++;
- }
- break;
- case EXTRA_VERSION_31:
- if (version >= 31) {
- total++;
- enabled++;
- }
- break;
- case EXTRA_VERSION_32:
- if (version >= 32) {
- total++;
- enabled++;
- }
- break;
- case EXTRA_VERSION_ES2:
- if (ctx->API == API_OPENGLES2) {
- total++;
- enabled++;
- }
- break;
- case EXTRA_NEW_BUFFERS:
- if (ctx->NewState & _NEW_BUFFERS)
- _mesa_update_state(ctx);
- break;
- case EXTRA_FLUSH_CURRENT:
- FLUSH_CURRENT(ctx, 0);
- break;
- case EXTRA_VALID_DRAW_BUFFER:
- if (d->pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(draw buffer %u)",
- func, d->pname - GL_DRAW_BUFFER0_ARB);
- return GL_FALSE;
- }
- break;
- case EXTRA_VALID_TEXTURE_UNIT:
- if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture %u)",
- func, ctx->Texture.CurrentUnit);
- return GL_FALSE;
- }
- break;
- case EXTRA_END:
- break;
- default: /* *e is a offset into the extension struct */
- total++;
- if (*(GLboolean *) ((char *) &ctx->Extensions + *e))
- enabled++;
- break;
- }
-
- if (total > 0 && enabled == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(d->pname));
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-static const struct value_desc error_value =
- { 0, 0, TYPE_INVALID, NO_OFFSET, NO_EXTRA };
-
-/**
- * Find the struct value_desc corresponding to the enum 'pname'.
- *
- * We hash the enum value to get an index into the 'table' array,
- * which holds the index in the 'values' array of struct value_desc.
- * Once we've found the entry, we do the extra checks, if any, then
- * look up the value and return a pointer to it.
- *
- * If the value has to be computed (for example, it's the result of a
- * function call or we need to add 1 to it), we use the tmp 'v' to
- * store the result.
- *
- * \param func name of glGet*v() func for error reporting
- * \param pname the enum value we're looking up
- * \param p is were we return the pointer to the value
- * \param v a tmp union value variable in the calling glGet*v() function
- *
- * \return the struct value_desc corresponding to the enum or a struct
- * value_desc of TYPE_INVALID if not found. This lets the calling
- * glGet*v() function jump right into a switch statement and
- * handle errors there instead of having to check for NULL.
- */
-static const struct value_desc *
-find_value(const char *func, GLenum pname, void **p, union value *v)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *unit;
- int mask, hash;
- const struct value_desc *d;
-
- mask = Elements(table) - 1;
- hash = (pname * prime_factor);
- while (1) {
- d = &values[table[hash & mask]];
-
- /* If the enum isn't valid, the hash walk ends with index 0,
- * which is the API mask entry at the beginning of values[]. */
- if (unlikely(d->type == TYPE_API_MASK)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
- return &error_value;
- }
-
- if (likely(d->pname == pname))
- break;
-
- hash += prime_step;
- }
-
- if (unlikely(d->extra && !check_extra(ctx, func, d)))
- return &error_value;
-
- switch (d->location) {
- case LOC_BUFFER:
- *p = ((char *) ctx->DrawBuffer + d->offset);
- return d;
- case LOC_CONTEXT:
- *p = ((char *) ctx + d->offset);
- return d;
- case LOC_ARRAY:
- *p = ((char *) ctx->Array.ArrayObj + d->offset);
- return d;
- case LOC_TEXUNIT:
- unit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- *p = ((char *) unit + d->offset);
- return d;
- case LOC_CUSTOM:
- find_custom_value(ctx, d, v);
- *p = v;
- return d;
- default:
- assert(0);
- break;
- }
-
- /* silence warning */
- return &error_value;
-}
-
-static const int transpose[] = {
- 0, 4, 8, 12,
- 1, 5, 9, 13,
- 2, 6, 10, 14,
- 3, 7, 11, 15
-};
-
-void GLAPIENTRY
-_mesa_GetBooleanv(GLenum pname, GLboolean *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetBooleanv", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = INT_TO_BOOLEAN(d->offset);
- break;
-
- case TYPE_FLOAT_4:
- case TYPE_FLOATN_4:
- params[3] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[3]);
- case TYPE_FLOAT_3:
- case TYPE_FLOATN_3:
- params[2] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[2]);
- case TYPE_FLOAT_2:
- case TYPE_FLOATN_2:
- params[1] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[1]);
- case TYPE_FLOAT:
- case TYPE_FLOATN:
- params[0] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[0]);
- break;
-
- case TYPE_DOUBLEN:
- params[0] = FLOAT_TO_BOOLEAN(((GLdouble *) p)[0]);
- break;
-
- case TYPE_INT_4:
- params[3] = INT_TO_BOOLEAN(((GLint *) p)[3]);
- case TYPE_INT_3:
- params[2] = INT_TO_BOOLEAN(((GLint *) p)[2]);
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = INT_TO_BOOLEAN(((GLint *) p)[1]);
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = INT_TO_BOOLEAN(((GLint *) p)[0]);
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]);
- break;
-
- case TYPE_INT64:
- params[0] = INT64_TO_BOOLEAN(((GLint64 *) p)[0]);
- break;
-
- case TYPE_BOOLEAN:
- params[0] = ((GLboolean*) p)[0];
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_BOOLEAN(m->m[i]);
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_BOOLEAN(m->m[transpose[i]]);
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = (*(GLbitfield *) p >> shift) & 1;
- break;
- }
-}
-
-void GLAPIENTRY
-_mesa_GetFloatv(GLenum pname, GLfloat *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetFloatv", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = (GLfloat) d->offset;
- break;
-
- case TYPE_FLOAT_4:
- case TYPE_FLOATN_4:
- params[3] = ((GLfloat *) p)[3];
- case TYPE_FLOAT_3:
- case TYPE_FLOATN_3:
- params[2] = ((GLfloat *) p)[2];
- case TYPE_FLOAT_2:
- case TYPE_FLOATN_2:
- params[1] = ((GLfloat *) p)[1];
- case TYPE_FLOAT:
- case TYPE_FLOATN:
- params[0] = ((GLfloat *) p)[0];
- break;
-
- case TYPE_DOUBLEN:
- params[0] = ((GLdouble *) p)[0];
- break;
-
- case TYPE_INT_4:
- params[3] = (GLfloat) (((GLint *) p)[3]);
- case TYPE_INT_3:
- params[2] = (GLfloat) (((GLint *) p)[2]);
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = (GLfloat) (((GLint *) p)[1]);
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = (GLfloat) (((GLint *) p)[0]);
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = INT_TO_FLOAT(v.value_int_n.ints[i]);
- break;
-
- case TYPE_INT64:
- params[0] = ((GLint64 *) p)[0];
- break;
-
- case TYPE_BOOLEAN:
- params[0] = BOOLEAN_TO_FLOAT(*(GLboolean*) p);
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = m->m[i];
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = m->m[transpose[i]];
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = BOOLEAN_TO_FLOAT((*(GLbitfield *) p >> shift) & 1);
- break;
- }
-}
-
-void GLAPIENTRY
-_mesa_GetIntegerv(GLenum pname, GLint *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetIntegerv", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = d->offset;
- break;
-
- case TYPE_FLOAT_4:
- params[3] = IROUND(((GLfloat *) p)[3]);
- case TYPE_FLOAT_3:
- params[2] = IROUND(((GLfloat *) p)[2]);
- case TYPE_FLOAT_2:
- params[1] = IROUND(((GLfloat *) p)[1]);
- case TYPE_FLOAT:
- params[0] = IROUND(((GLfloat *) p)[0]);
- break;
-
- case TYPE_FLOATN_4:
- params[3] = FLOAT_TO_INT(((GLfloat *) p)[3]);
- case TYPE_FLOATN_3:
- params[2] = FLOAT_TO_INT(((GLfloat *) p)[2]);
- case TYPE_FLOATN_2:
- params[1] = FLOAT_TO_INT(((GLfloat *) p)[1]);
- case TYPE_FLOATN:
- params[0] = FLOAT_TO_INT(((GLfloat *) p)[0]);
- break;
-
- case TYPE_DOUBLEN:
- params[0] = FLOAT_TO_INT(((GLdouble *) p)[0]);
- break;
-
- case TYPE_INT_4:
- params[3] = ((GLint *) p)[3];
- case TYPE_INT_3:
- params[2] = ((GLint *) p)[2];
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = ((GLint *) p)[1];
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = ((GLint *) p)[0];
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = v.value_int_n.ints[i];
- break;
-
- case TYPE_INT64:
- params[0] = INT64_TO_INT(((GLint64 *) p)[0]);
- break;
-
- case TYPE_BOOLEAN:
- params[0] = BOOLEAN_TO_INT(*(GLboolean*) p);
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_INT(m->m[i]);
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_INT(m->m[transpose[i]]);
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = (*(GLbitfield *) p >> shift) & 1;
- break;
- }
-}
-
-#if FEATURE_ARB_sync
-void GLAPIENTRY
-_mesa_GetInteger64v(GLenum pname, GLint64 *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetInteger64v", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = d->offset;
- break;
-
- case TYPE_FLOAT_4:
- params[3] = IROUND64(((GLfloat *) p)[3]);
- case TYPE_FLOAT_3:
- params[2] = IROUND64(((GLfloat *) p)[2]);
- case TYPE_FLOAT_2:
- params[1] = IROUND64(((GLfloat *) p)[1]);
- case TYPE_FLOAT:
- params[0] = IROUND64(((GLfloat *) p)[0]);
- break;
-
- case TYPE_FLOATN_4:
- params[3] = FLOAT_TO_INT64(((GLfloat *) p)[3]);
- case TYPE_FLOATN_3:
- params[2] = FLOAT_TO_INT64(((GLfloat *) p)[2]);
- case TYPE_FLOATN_2:
- params[1] = FLOAT_TO_INT64(((GLfloat *) p)[1]);
- case TYPE_FLOATN:
- params[0] = FLOAT_TO_INT64(((GLfloat *) p)[0]);
- break;
-
- case TYPE_DOUBLEN:
- params[0] = FLOAT_TO_INT64(((GLdouble *) p)[0]);
- break;
-
- case TYPE_INT_4:
- params[3] = ((GLint *) p)[3];
- case TYPE_INT_3:
- params[2] = ((GLint *) p)[2];
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = ((GLint *) p)[1];
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = ((GLint *) p)[0];
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]);
- break;
-
- case TYPE_INT64:
- params[0] = ((GLint64 *) p)[0];
- break;
-
- case TYPE_BOOLEAN:
- params[0] = ((GLboolean*) p)[0];
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_INT64(m->m[i]);
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_INT64(m->m[transpose[i]]);
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = (*(GLbitfield *) p >> shift) & 1;
- break;
- }
-}
-#endif /* FEATURE_ARB_sync */
-
-void GLAPIENTRY
-_mesa_GetDoublev(GLenum pname, GLdouble *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetDoublev", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = d->offset;
- break;
-
- case TYPE_FLOAT_4:
- case TYPE_FLOATN_4:
- params[3] = ((GLfloat *) p)[3];
- case TYPE_FLOAT_3:
- case TYPE_FLOATN_3:
- params[2] = ((GLfloat *) p)[2];
- case TYPE_FLOAT_2:
- case TYPE_FLOATN_2:
- params[1] = ((GLfloat *) p)[1];
- case TYPE_FLOAT:
- case TYPE_FLOATN:
- params[0] = ((GLfloat *) p)[0];
- break;
-
- case TYPE_DOUBLEN:
- params[0] = ((GLdouble *) p)[0];
- break;
-
- case TYPE_INT_4:
- params[3] = ((GLint *) p)[3];
- case TYPE_INT_3:
- params[2] = ((GLint *) p)[2];
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = ((GLint *) p)[1];
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = ((GLint *) p)[0];
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = v.value_int_n.ints[i];
- break;
-
- case TYPE_INT64:
- params[0] = ((GLint64 *) p)[0];
- break;
-
- case TYPE_BOOLEAN:
- params[0] = *(GLboolean*) p;
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = m->m[i];
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = m->m[transpose[i]];
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = (*(GLbitfield *) p >> shift) & 1;
- break;
- }
-}
-
-static enum value_type
-find_value_indexed(const char *func, GLenum pname, int index, union value *v)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- switch (pname) {
-
- case GL_BLEND:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.EXT_draw_buffers2)
- goto invalid_enum;
- v->value_int = (ctx->Color.BlendEnabled >> index) & 1;
- return TYPE_INT;
-
- case GL_BLEND_SRC:
- /* fall-through */
- case GL_BLEND_SRC_RGB:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].SrcRGB;
- return TYPE_INT;
- case GL_BLEND_SRC_ALPHA:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].SrcA;
- return TYPE_INT;
- case GL_BLEND_DST:
- /* fall-through */
- case GL_BLEND_DST_RGB:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].DstRGB;
- return TYPE_INT;
- case GL_BLEND_DST_ALPHA:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].DstA;
- return TYPE_INT;
- case GL_BLEND_EQUATION_RGB:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].EquationRGB;
- return TYPE_INT;
- case GL_BLEND_EQUATION_ALPHA:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.ARB_draw_buffers_blend)
- goto invalid_enum;
- v->value_int = ctx->Color.Blend[index].EquationA;
- return TYPE_INT;
-
- case GL_COLOR_WRITEMASK:
- if (index >= ctx->Const.MaxDrawBuffers)
- goto invalid_value;
- if (!ctx->Extensions.EXT_draw_buffers2)
- goto invalid_enum;
- v->value_int_4[0] = ctx->Color.ColorMask[index][RCOMP] ? 1 : 0;
- v->value_int_4[1] = ctx->Color.ColorMask[index][GCOMP] ? 1 : 0;
- v->value_int_4[2] = ctx->Color.ColorMask[index][BCOMP] ? 1 : 0;
- v->value_int_4[3] = ctx->Color.ColorMask[index][ACOMP] ? 1 : 0;
- return TYPE_INT_4;
-
- case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
- goto invalid_value;
- if (!ctx->Extensions.EXT_transform_feedback)
- goto invalid_enum;
- v->value_int64 = ctx->TransformFeedback.CurrentObject->Offset[index];
- return TYPE_INT64;
-
- case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
- goto invalid_value;
- if (!ctx->Extensions.EXT_transform_feedback)
- goto invalid_enum;
- v->value_int64 = ctx->TransformFeedback.CurrentObject->Size[index];
- return TYPE_INT64;
-
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
- goto invalid_value;
- if (!ctx->Extensions.EXT_transform_feedback)
- goto invalid_enum;
- v->value_int = ctx->TransformFeedback.CurrentObject->Buffers[index]->Name;
- return TYPE_INT;
- }
-
- invalid_enum:
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
- return TYPE_INVALID;
- invalid_value:
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
- return TYPE_INVALID;
-}
-
-void GLAPIENTRY
-_mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )
-{
- union value v;
- enum value_type type =
- find_value_indexed("glGetBooleanIndexedv", pname, index, &v);
-
- switch (type) {
- case TYPE_INT:
- params[0] = INT_TO_BOOLEAN(v.value_int);
- break;
- case TYPE_INT_4:
- params[0] = INT_TO_BOOLEAN(v.value_int_4[0]);
- params[1] = INT_TO_BOOLEAN(v.value_int_4[1]);
- params[2] = INT_TO_BOOLEAN(v.value_int_4[2]);
- params[3] = INT_TO_BOOLEAN(v.value_int_4[3]);
- break;
- case TYPE_INT64:
- params[0] = INT64_TO_BOOLEAN(v.value_int);
- break;
- default:
- ; /* nothing - GL error was recorded */
- }
-}
-
-void GLAPIENTRY
-_mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )
-{
- union value v;
- enum value_type type =
- find_value_indexed("glGetIntegerIndexedv", pname, index, &v);
-
- switch (type) {
- case TYPE_INT:
- params[0] = v.value_int;
- break;
- case TYPE_INT_4:
- params[0] = v.value_int_4[0];
- params[1] = v.value_int_4[1];
- params[2] = v.value_int_4[2];
- params[3] = v.value_int_4[3];
- break;
- case TYPE_INT64:
- params[0] = INT64_TO_INT(v.value_int);
- break;
- default:
- ; /* nothing - GL error was recorded */
- }
-}
-
-#if FEATURE_ARB_sync
-void GLAPIENTRY
-_mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )
-{
- union value v;
- enum value_type type =
- find_value_indexed("glGetIntegerIndexedv", pname, index, &v);
-
- switch (type) {
- case TYPE_INT:
- params[0] = v.value_int;
- break;
- case TYPE_INT_4:
- params[0] = v.value_int_4[0];
- params[1] = v.value_int_4[1];
- params[2] = v.value_int_4[2];
- params[3] = v.value_int_4[3];
- break;
- case TYPE_INT64:
- params[0] = v.value_int;
- break;
- default:
- ; /* nothing - GL error was recorded */
- }
-}
-#endif /* FEATURE_ARB_sync */
-
-#if FEATURE_ES1
-void GLAPIENTRY
-_mesa_GetFixedv(GLenum pname, GLfixed *params)
-{
- const struct value_desc *d;
- union value v;
- GLmatrix *m;
- int shift, i;
- void *p;
-
- d = find_value("glGetDoublev", pname, &p, &v);
- switch (d->type) {
- case TYPE_INVALID:
- break;
- case TYPE_CONST:
- params[0] = INT_TO_FIXED(d->offset);
- break;
-
- case TYPE_FLOAT_4:
- case TYPE_FLOATN_4:
- params[3] = FLOAT_TO_FIXED(((GLfloat *) p)[3]);
- case TYPE_FLOAT_3:
- case TYPE_FLOATN_3:
- params[2] = FLOAT_TO_FIXED(((GLfloat *) p)[2]);
- case TYPE_FLOAT_2:
- case TYPE_FLOATN_2:
- params[1] = FLOAT_TO_FIXED(((GLfloat *) p)[1]);
- case TYPE_FLOAT:
- case TYPE_FLOATN:
- params[0] = FLOAT_TO_FIXED(((GLfloat *) p)[0]);
- break;
-
- case TYPE_DOUBLEN:
- params[0] = FLOAT_TO_FIXED(((GLdouble *) p)[0]);
- break;
-
- case TYPE_INT_4:
- params[3] = INT_TO_FIXED(((GLint *) p)[3]);
- case TYPE_INT_3:
- params[2] = INT_TO_FIXED(((GLint *) p)[2]);
- case TYPE_INT_2:
- case TYPE_ENUM_2:
- params[1] = INT_TO_FIXED(((GLint *) p)[1]);
- case TYPE_INT:
- case TYPE_ENUM:
- params[0] = INT_TO_FIXED(((GLint *) p)[0]);
- break;
-
- case TYPE_INT_N:
- for (i = 0; i < v.value_int_n.n; i++)
- params[i] = INT_TO_FIXED(v.value_int_n.ints[i]);
- break;
-
- case TYPE_INT64:
- params[0] = ((GLint64 *) p)[0];
- break;
-
- case TYPE_BOOLEAN:
- params[0] = BOOLEAN_TO_FIXED(((GLboolean*) p)[0]);
- break;
-
- case TYPE_MATRIX:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_FIXED(m->m[i]);
- break;
-
- case TYPE_MATRIX_T:
- m = *(GLmatrix **) p;
- for (i = 0; i < 16; i++)
- params[i] = FLOAT_TO_FIXED(m->m[transpose[i]]);
- break;
-
- case TYPE_BIT_0:
- case TYPE_BIT_1:
- case TYPE_BIT_2:
- case TYPE_BIT_3:
- case TYPE_BIT_4:
- case TYPE_BIT_5:
- shift = d->type - TYPE_BIT_0;
- params[0] = BOOLEAN_TO_FIXED((*(GLbitfield *) p >> shift) & 1);
- break;
- }
-}
-#endif
+/* + * Copyright (C) 2010 Brian Paul All Rights Reserved. + * Copyright (C) 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: Kristian Høgsberg <krh@bitplanet.net> + */ + +#include "glheader.h" +#include "context.h" +#include "enable.h" +#include "enums.h" +#include "extensions.h" +#include "get.h" +#include "macros.h" +#include "mfeatures.h" +#include "mtypes.h" +#include "state.h" +#include "texcompress.h" +#include "framebuffer.h" + +/* This is a table driven implemetation of the glGet*v() functions. + * The basic idea is that most getters just look up an int somewhere + * in struct gl_context and then convert it to a bool or float according to + * which of glGetIntegerv() glGetBooleanv() etc is being called. + * Instead of generating code to do this, we can just record the enum + * value and the offset into struct gl_context in an array of structs. Then + * in glGet*(), we lookup the struct for the enum in question, and use + * the offset to get the int we need. + * + * Sometimes we need to look up a float, a boolean, a bit in a + * bitfield, a matrix or other types instead, so we need to track the + * type of the value in struct gl_context. And sometimes the value isn't in + * struct gl_context but in the drawbuffer, the array object, current texture + * unit, or maybe it's a computed value. So we need to also track + * where or how to find the value. Finally, we sometimes need to + * check that one of a number of extensions are enabled, the GL + * version or flush or call _mesa_update_state(). This is done by + * attaching optional extra information to the value description + * struct, it's sort of like an array of opcodes that describe extra + * checks or actions. + * + * Putting all this together we end up with struct value_desc below, + * and with a couple of macros to help, the table of struct value_desc + * is about as concise as the specification in the old python script. + */ + +#undef CONST + +#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE ) +#define FLOAT_TO_FIXED(F) ( ((F) * 65536.0f > INT_MAX) ? INT_MAX : \ + ((F) * 65536.0f < INT_MIN) ? INT_MIN : \ + (GLint) ((F) * 65536.0f) ) + +#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) +#define INT_TO_FIXED(I) ( ((I) > SHRT_MAX) ? INT_MAX : \ + ((I) < SHRT_MIN) ? INT_MIN : \ + (GLint) ((I) * 65536) ) + +#define INT64_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) +#define INT64_TO_INT(I) ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) ) + +#define BOOLEAN_TO_INT(B) ( (GLint) (B) ) +#define BOOLEAN_TO_INT64(B) ( (GLint64) (B) ) +#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F ) +#define BOOLEAN_TO_FIXED(B) ( (GLint) ((B) ? 1 : 0) << 16 ) + +#define ENUM_TO_INT64(E) ( (GLint64) (E) ) +#define ENUM_TO_FIXED(E) (E) + +enum value_type { + TYPE_INVALID, + TYPE_API_MASK, + TYPE_INT, + TYPE_INT_2, + TYPE_INT_3, + TYPE_INT_4, + TYPE_INT_N, + TYPE_INT64, + TYPE_ENUM, + TYPE_ENUM_2, + TYPE_BOOLEAN, + TYPE_BIT_0, + TYPE_BIT_1, + TYPE_BIT_2, + TYPE_BIT_3, + TYPE_BIT_4, + TYPE_BIT_5, + TYPE_FLOAT, + TYPE_FLOAT_2, + TYPE_FLOAT_3, + TYPE_FLOAT_4, + TYPE_FLOATN, + TYPE_FLOATN_2, + TYPE_FLOATN_3, + TYPE_FLOATN_4, + TYPE_DOUBLEN, + TYPE_MATRIX, + TYPE_MATRIX_T, + TYPE_CONST +}; + +enum value_location { + LOC_BUFFER, + LOC_CONTEXT, + LOC_ARRAY, + LOC_TEXUNIT, + LOC_CUSTOM +}; + +enum value_extra { + EXTRA_END = 0x8000, + EXTRA_VERSION_30, + EXTRA_VERSION_31, + EXTRA_VERSION_32, + EXTRA_VERSION_ES2, + EXTRA_NEW_BUFFERS, + EXTRA_VALID_DRAW_BUFFER, + EXTRA_VALID_TEXTURE_UNIT, + EXTRA_FLUSH_CURRENT, +}; + +#define NO_EXTRA NULL +#define NO_OFFSET 0 + +struct value_desc { + GLenum pname; + GLubyte location; /**< enum value_location */ + GLubyte type; /**< enum value_type */ + int offset; + const int *extra; +}; + +union value { + GLfloat value_float; + GLfloat value_float_4[4]; + GLmatrix *value_matrix; + GLint value_int; + GLint value_int_4[4]; + GLint64 value_int64; + GLenum value_enum; + + /* Sigh, see GL_COMPRESSED_TEXTURE_FORMATS_ARB handling */ + struct { + GLint n, ints[100]; + } value_int_n; + GLboolean value_bool; +}; + +#define BUFFER_FIELD(field, type) \ + LOC_BUFFER, type, offsetof(struct gl_framebuffer, field) +#define CONTEXT_FIELD(field, type) \ + LOC_CONTEXT, type, offsetof(struct gl_context, field) +#define ARRAY_FIELD(field, type) \ + LOC_ARRAY, type, offsetof(struct gl_array_object, field) +#define CONST(value) \ + LOC_CONTEXT, TYPE_CONST, value + +#define BUFFER_INT(field) BUFFER_FIELD(field, TYPE_INT) +#define BUFFER_ENUM(field) BUFFER_FIELD(field, TYPE_ENUM) +#define BUFFER_BOOL(field) BUFFER_FIELD(field, TYPE_BOOLEAN) + +#define CONTEXT_INT(field) CONTEXT_FIELD(field, TYPE_INT) +#define CONTEXT_INT2(field) CONTEXT_FIELD(field, TYPE_INT_2) +#define CONTEXT_INT64(field) CONTEXT_FIELD(field, TYPE_INT64) +#define CONTEXT_ENUM(field) CONTEXT_FIELD(field, TYPE_ENUM) +#define CONTEXT_ENUM2(field) CONTEXT_FIELD(field, TYPE_ENUM_2) +#define CONTEXT_BOOL(field) CONTEXT_FIELD(field, TYPE_BOOLEAN) +#define CONTEXT_BIT0(field) CONTEXT_FIELD(field, TYPE_BIT_0) +#define CONTEXT_BIT1(field) CONTEXT_FIELD(field, TYPE_BIT_1) +#define CONTEXT_BIT2(field) CONTEXT_FIELD(field, TYPE_BIT_2) +#define CONTEXT_BIT3(field) CONTEXT_FIELD(field, TYPE_BIT_3) +#define CONTEXT_BIT4(field) CONTEXT_FIELD(field, TYPE_BIT_4) +#define CONTEXT_BIT5(field) CONTEXT_FIELD(field, TYPE_BIT_5) +#define CONTEXT_FLOAT(field) CONTEXT_FIELD(field, TYPE_FLOAT) +#define CONTEXT_FLOAT2(field) CONTEXT_FIELD(field, TYPE_FLOAT_2) +#define CONTEXT_FLOAT3(field) CONTEXT_FIELD(field, TYPE_FLOAT_3) +#define CONTEXT_FLOAT4(field) CONTEXT_FIELD(field, TYPE_FLOAT_4) +#define CONTEXT_MATRIX(field) CONTEXT_FIELD(field, TYPE_MATRIX) +#define CONTEXT_MATRIX_T(field) CONTEXT_FIELD(field, TYPE_MATRIX_T) + +#define ARRAY_INT(field) ARRAY_FIELD(field, TYPE_INT) +#define ARRAY_ENUM(field) ARRAY_FIELD(field, TYPE_ENUM) +#define ARRAY_BOOL(field) ARRAY_FIELD(field, TYPE_BOOLEAN) + +#define EXT(f) \ + offsetof(struct gl_extensions, f) + +#define EXTRA_EXT(e) \ + static const int extra_##e[] = { \ + EXT(e), EXTRA_END \ + } + +#define EXTRA_EXT2(e1, e2) \ + static const int extra_##e1##_##e2[] = { \ + EXT(e1), EXT(e2), EXTRA_END \ + } + +/* The 'extra' mechanism is a way to specify extra checks (such as + * extensions or specific gl versions) or actions (flush current, new + * buffers) that we need to do before looking up an enum. We need to + * declare them all up front so we can refer to them in the value_desc + * structs below. */ + +static const int extra_new_buffers[] = { + EXTRA_NEW_BUFFERS, + EXTRA_END +}; + +static const int extra_valid_draw_buffer[] = { + EXTRA_VALID_DRAW_BUFFER, + EXTRA_END +}; + +static const int extra_valid_texture_unit[] = { + EXTRA_VALID_TEXTURE_UNIT, + EXTRA_END +}; + +static const int extra_flush_current_valid_texture_unit[] = { + EXTRA_FLUSH_CURRENT, + EXTRA_VALID_TEXTURE_UNIT, + EXTRA_END +}; + +static const int extra_flush_current[] = { + EXTRA_FLUSH_CURRENT, + EXTRA_END +}; + +static const int extra_new_buffers_OES_read_format[] = { + EXTRA_NEW_BUFFERS, + EXT(OES_read_format), + EXTRA_END +}; + +static const int extra_EXT_secondary_color_flush_current[] = { + EXT(EXT_secondary_color), + EXTRA_FLUSH_CURRENT, + EXTRA_END +}; + +static const int extra_EXT_fog_coord_flush_current[] = { + EXT(EXT_fog_coord), + EXTRA_FLUSH_CURRENT, + EXTRA_END +}; + +static const int extra_EXT_texture_integer[] = { + EXT(EXT_texture_integer), + EXTRA_END +}; + +static const int extra_EXT_gpu_shader4[] = { + EXT(EXT_gpu_shader4), + EXTRA_END +}; + + +EXTRA_EXT(ARB_ES2_compatibility); +EXTRA_EXT(ARB_multitexture); +EXTRA_EXT(ARB_texture_cube_map); +EXTRA_EXT(MESA_texture_array); +EXTRA_EXT2(EXT_secondary_color, ARB_vertex_program); +EXTRA_EXT(EXT_secondary_color); +EXTRA_EXT(EXT_fog_coord); +EXTRA_EXT(EXT_texture_lod_bias); +EXTRA_EXT(EXT_texture_filter_anisotropic); +EXTRA_EXT(IBM_rasterpos_clip); +EXTRA_EXT(NV_point_sprite); +EXTRA_EXT(SGIS_generate_mipmap); +EXTRA_EXT(NV_vertex_program); +EXTRA_EXT(NV_fragment_program); +EXTRA_EXT(NV_texture_rectangle); +EXTRA_EXT(EXT_stencil_two_side); +EXTRA_EXT(NV_light_max_exponent); +EXTRA_EXT(EXT_depth_bounds_test); +EXTRA_EXT(ARB_depth_clamp); +EXTRA_EXT(ATI_fragment_shader); +EXTRA_EXT(EXT_framebuffer_blit); +EXTRA_EXT(ARB_shader_objects); +EXTRA_EXT(EXT_provoking_vertex); +EXTRA_EXT(ARB_fragment_shader); +EXTRA_EXT(ARB_fragment_program); +EXTRA_EXT2(ARB_framebuffer_object, EXT_framebuffer_multisample); +EXTRA_EXT(EXT_framebuffer_object); +EXTRA_EXT(APPLE_vertex_array_object); +EXTRA_EXT(ARB_seamless_cube_map); +EXTRA_EXT(EXT_compiled_vertex_array); +EXTRA_EXT(ARB_sync); +EXTRA_EXT(ARB_vertex_shader); +EXTRA_EXT(EXT_transform_feedback); +EXTRA_EXT(ARB_transform_feedback2); +EXTRA_EXT(EXT_pixel_buffer_object); +EXTRA_EXT(ARB_vertex_program); +EXTRA_EXT2(NV_point_sprite, ARB_point_sprite); +EXTRA_EXT2(ARB_fragment_program, NV_fragment_program); +EXTRA_EXT2(ARB_vertex_program, NV_vertex_program); +EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program); +EXTRA_EXT(ARB_vertex_buffer_object); +EXTRA_EXT(ARB_geometry_shader4); +EXTRA_EXT(ARB_copy_buffer); +EXTRA_EXT(EXT_framebuffer_sRGB); + +static const int +extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = { + EXT(ARB_vertex_program), + EXT(ARB_fragment_program), + EXT(NV_vertex_program), + EXTRA_END +}; + +static const int +extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = { + EXT(NV_vertex_program), + EXT(ARB_vertex_program), + EXT(ARB_fragment_program), + EXT(NV_vertex_program), + EXTRA_END +}; + +static const int +extra_NV_primitive_restart[] = { + EXT(NV_primitive_restart), + EXTRA_END +}; + +static const int extra_version_30[] = { EXTRA_VERSION_30, EXTRA_END }; +static const int extra_version_31[] = { EXTRA_VERSION_31, EXTRA_END }; +static const int extra_version_32[] = { EXTRA_VERSION_32, EXTRA_END }; + +static const int +extra_ARB_vertex_program_version_es2[] = { + EXT(ARB_vertex_program), + EXTRA_VERSION_ES2, + EXTRA_END +}; + +#define API_OPENGL_BIT (1 << API_OPENGL) +#define API_OPENGLES_BIT (1 << API_OPENGLES) +#define API_OPENGLES2_BIT (1 << API_OPENGLES2) + +/* This is the big table describing all the enums we accept in + * glGet*v(). The table is partitioned into six parts: enums + * understood by all GL APIs (OpenGL, GLES and GLES2), enums shared + * between OpenGL and GLES, enums exclusive to GLES, etc for the + * remaining combinations. When we add the enums to the hash table in + * _mesa_init_get_hash(), we only add the enums for the API we're + * instantiating and the different sections are guarded by #if + * FEATURE_GL etc to make sure we only compile in the enums we may + * need. */ + +static const struct value_desc values[] = { + /* Enums shared between OpenGL, GLES1 and GLES2 */ + { 0, 0, TYPE_API_MASK, + API_OPENGL_BIT | API_OPENGLES_BIT | API_OPENGLES2_BIT, NO_EXTRA}, + { GL_ALPHA_BITS, BUFFER_INT(Visual.alphaBits), extra_new_buffers }, + { GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA }, + { GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA }, + { GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers }, + { GL_COLOR_CLEAR_VALUE, CONTEXT_FIELD(Color.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA }, + { GL_CULL_FACE, CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA }, + { GL_CULL_FACE_MODE, CONTEXT_ENUM(Polygon.CullFaceMode), NO_EXTRA }, + { GL_DEPTH_BITS, BUFFER_INT(Visual.depthBits), NO_EXTRA }, + { GL_DEPTH_CLEAR_VALUE, CONTEXT_FIELD(Depth.Clear, TYPE_DOUBLEN), NO_EXTRA }, + { GL_DEPTH_FUNC, CONTEXT_ENUM(Depth.Func), NO_EXTRA }, + { GL_DEPTH_RANGE, CONTEXT_FIELD(Viewport.Near, TYPE_FLOATN_2), NO_EXTRA }, + { GL_DEPTH_TEST, CONTEXT_BOOL(Depth.Test), NO_EXTRA }, + { GL_DEPTH_WRITEMASK, CONTEXT_BOOL(Depth.Mask), NO_EXTRA }, + { GL_DITHER, CONTEXT_BOOL(Color.DitherFlag), NO_EXTRA }, + { GL_FRONT_FACE, CONTEXT_ENUM(Polygon.FrontFace), NO_EXTRA }, + { GL_GREEN_BITS, BUFFER_INT(Visual.greenBits), extra_new_buffers }, + { GL_LINE_WIDTH, CONTEXT_FLOAT(Line.Width), NO_EXTRA }, + { GL_ALIASED_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidth), NO_EXTRA }, + { GL_MAX_ELEMENTS_VERTICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA }, + { GL_MAX_ELEMENTS_INDICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA }, + { GL_MAX_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_context, Const.MaxTextureLevels), NO_EXTRA }, + { GL_MAX_VIEWPORT_DIMS, CONTEXT_INT2(Const.MaxViewportWidth), NO_EXTRA }, + { GL_PACK_ALIGNMENT, CONTEXT_INT(Pack.Alignment), NO_EXTRA }, + { GL_ALIASED_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSize), NO_EXTRA }, + { GL_POLYGON_OFFSET_FACTOR, CONTEXT_FLOAT(Polygon.OffsetFactor ), NO_EXTRA }, + { GL_POLYGON_OFFSET_UNITS, CONTEXT_FLOAT(Polygon.OffsetUnits ), NO_EXTRA }, + { GL_POLYGON_OFFSET_FILL, CONTEXT_BOOL(Polygon.OffsetFill), NO_EXTRA }, + { GL_RED_BITS, BUFFER_INT(Visual.redBits), extra_new_buffers }, + { GL_SCISSOR_BOX, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA }, + { GL_SCISSOR_TEST, CONTEXT_BOOL(Scissor.Enabled), NO_EXTRA }, + { GL_STENCIL_BITS, BUFFER_INT(Visual.stencilBits), NO_EXTRA }, + { GL_STENCIL_CLEAR_VALUE, CONTEXT_INT(Stencil.Clear), NO_EXTRA }, + { GL_STENCIL_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_FUNC, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_PASS_DEPTH_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_PASS_DEPTH_PASS, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_REF, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_TEST, CONTEXT_BOOL(Stencil.Enabled), NO_EXTRA }, + { GL_STENCIL_VALUE_MASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA }, + { GL_STENCIL_WRITEMASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA }, + { GL_SUBPIXEL_BITS, CONTEXT_INT(Const.SubPixelBits), NO_EXTRA }, + { GL_TEXTURE_BINDING_2D, LOC_CUSTOM, TYPE_INT, TEXTURE_2D_INDEX, NO_EXTRA }, + { GL_UNPACK_ALIGNMENT, CONTEXT_INT(Unpack.Alignment), NO_EXTRA }, + { GL_VIEWPORT, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA }, + + /* GL_ARB_multitexture */ + { GL_ACTIVE_TEXTURE_ARB, + LOC_CUSTOM, TYPE_INT, 0, extra_ARB_multitexture }, + + /* Note that all the OES_* extensions require that the Mesa "struct + * gl_extensions" include a member with the name of the extension. + * That structure does not yet include OES extensions (and we're + * not sure whether it will). If it does, all the OES_* + * extensions below should mark the dependency. */ + + /* GL_ARB_texture_cube_map */ + { GL_TEXTURE_BINDING_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_INT, + TEXTURE_CUBE_INDEX, extra_ARB_texture_cube_map }, + { GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_context, Const.MaxCubeTextureLevels), + extra_ARB_texture_cube_map }, /* XXX: OES_texture_cube_map */ + + /* XXX: OES_blend_subtract */ + { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA }, + { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA }, + { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].SrcA), NO_EXTRA }, + { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].DstA), NO_EXTRA }, + + /* GL_BLEND_EQUATION_RGB, which is what we're really after, is + * defined identically to GL_BLEND_EQUATION. */ + { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.Blend[0].EquationRGB), NO_EXTRA }, + { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].EquationA), NO_EXTRA }, + + /* GL_ARB_texture_compression */ + { GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT_N, 0, NO_EXTRA }, + + /* GL_ARB_multisample */ + { GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, + CONTEXT_BOOL(Multisample.SampleAlphaToCoverage), NO_EXTRA }, + { GL_SAMPLE_COVERAGE_ARB, CONTEXT_BOOL(Multisample.SampleCoverage), NO_EXTRA }, + { GL_SAMPLE_COVERAGE_VALUE_ARB, + CONTEXT_FLOAT(Multisample.SampleCoverageValue), NO_EXTRA }, + { GL_SAMPLE_COVERAGE_INVERT_ARB, + CONTEXT_BOOL(Multisample.SampleCoverageInvert), NO_EXTRA }, + { GL_SAMPLE_BUFFERS_ARB, BUFFER_INT(Visual.sampleBuffers), NO_EXTRA }, + { GL_SAMPLES_ARB, BUFFER_INT(Visual.samples), NO_EXTRA }, + + /* GL_SGIS_generate_mipmap */ + { GL_GENERATE_MIPMAP_HINT_SGIS, CONTEXT_ENUM(Hint.GenerateMipmap), + extra_SGIS_generate_mipmap }, + + /* GL_ARB_vertex_buffer_object */ + { GL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + + /* GL_ARB_vertex_buffer_object */ + /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported */ + { GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_vertex_buffer_object }, + + /* GL_ARB_copy_buffer */ + { GL_COPY_READ_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer }, + { GL_COPY_WRITE_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer }, + + /* GL_OES_read_format */ + { GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0, + extra_new_buffers_OES_read_format }, + { GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, LOC_CUSTOM, TYPE_INT, 0, + extra_new_buffers_OES_read_format }, + + /* GL_EXT_framebuffer_object */ + { GL_FRAMEBUFFER_BINDING_EXT, BUFFER_INT(Name), + extra_EXT_framebuffer_object }, + { GL_RENDERBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0, + extra_EXT_framebuffer_object }, + { GL_MAX_RENDERBUFFER_SIZE_EXT, CONTEXT_INT(Const.MaxRenderbufferSize), + extra_EXT_framebuffer_object }, + + /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's + * GLSL: */ + { GL_MAX_CLIP_PLANES, CONTEXT_INT(Const.MaxClipPlanes), NO_EXTRA }, + +#if FEATURE_GL || FEATURE_ES1 + /* Enums in OpenGL and GLES1 */ + { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES_BIT, NO_EXTRA }, + { GL_LIGHT0, CONTEXT_BOOL(Light.Light[0].Enabled), NO_EXTRA }, + { GL_LIGHT1, CONTEXT_BOOL(Light.Light[1].Enabled), NO_EXTRA }, + { GL_LIGHT2, CONTEXT_BOOL(Light.Light[2].Enabled), NO_EXTRA }, + { GL_LIGHT3, CONTEXT_BOOL(Light.Light[3].Enabled), NO_EXTRA }, + { GL_LIGHT4, CONTEXT_BOOL(Light.Light[4].Enabled), NO_EXTRA }, + { GL_LIGHT5, CONTEXT_BOOL(Light.Light[5].Enabled), NO_EXTRA }, + { GL_LIGHT6, CONTEXT_BOOL(Light.Light[6].Enabled), NO_EXTRA }, + { GL_LIGHT7, CONTEXT_BOOL(Light.Light[7].Enabled), NO_EXTRA }, + { GL_LIGHTING, CONTEXT_BOOL(Light.Enabled), NO_EXTRA }, + { GL_LIGHT_MODEL_AMBIENT, + CONTEXT_FIELD(Light.Model.Ambient[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_LIGHT_MODEL_TWO_SIDE, CONTEXT_BOOL(Light.Model.TwoSide), NO_EXTRA }, + { GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA }, + { GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA }, + { GL_ALPHA_TEST_REF, CONTEXT_FIELD(Color.AlphaRef, TYPE_FLOATN), NO_EXTRA }, + { GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA }, + { GL_CLIP_PLANE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_CLIP_PLANE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_CLIP_PLANE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_CLIP_PLANE3, CONTEXT_BIT3(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_CLIP_PLANE4, CONTEXT_BIT4(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_CLIP_PLANE5, CONTEXT_BIT5(Transform.ClipPlanesEnabled), NO_EXTRA }, + { GL_COLOR_MATERIAL, CONTEXT_BOOL(Light.ColorMaterialEnabled), NO_EXTRA }, + { GL_CURRENT_COLOR, + CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR0][0], TYPE_FLOATN_4), + extra_flush_current }, + { GL_CURRENT_NORMAL, + CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_NORMAL][0], TYPE_FLOATN_3), + extra_flush_current }, + { GL_CURRENT_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0, + extra_flush_current_valid_texture_unit }, + { GL_DISTANCE_ATTENUATION_EXT, CONTEXT_FLOAT3(Point.Params[0]), NO_EXTRA }, + { GL_FOG, CONTEXT_BOOL(Fog.Enabled), NO_EXTRA }, + { GL_FOG_COLOR, CONTEXT_FIELD(Fog.Color[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_FOG_DENSITY, CONTEXT_FLOAT(Fog.Density), NO_EXTRA }, + { GL_FOG_END, CONTEXT_FLOAT(Fog.End), NO_EXTRA }, + { GL_FOG_HINT, CONTEXT_ENUM(Hint.Fog), NO_EXTRA }, + { GL_FOG_MODE, CONTEXT_ENUM(Fog.Mode), NO_EXTRA }, + { GL_FOG_START, CONTEXT_FLOAT(Fog.Start), NO_EXTRA }, + { GL_LINE_SMOOTH, CONTEXT_BOOL(Line.SmoothFlag), NO_EXTRA }, + { GL_LINE_SMOOTH_HINT, CONTEXT_ENUM(Hint.LineSmooth), NO_EXTRA }, + { GL_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidthAA), NO_EXTRA }, + { GL_COLOR_LOGIC_OP, CONTEXT_BOOL(Color.ColorLogicOpEnabled), NO_EXTRA }, + { GL_LOGIC_OP_MODE, CONTEXT_ENUM(Color.LogicOp), NO_EXTRA }, + { GL_MATRIX_MODE, CONTEXT_ENUM(Transform.MatrixMode), NO_EXTRA }, + { GL_MAX_MODELVIEW_STACK_DEPTH, CONST(MAX_MODELVIEW_STACK_DEPTH), NO_EXTRA }, + { GL_MAX_PROJECTION_STACK_DEPTH, CONST(MAX_PROJECTION_STACK_DEPTH), NO_EXTRA }, + { GL_MAX_TEXTURE_STACK_DEPTH, CONST(MAX_TEXTURE_STACK_DEPTH), NO_EXTRA }, + { GL_MODELVIEW_MATRIX, CONTEXT_MATRIX(ModelviewMatrixStack.Top), NO_EXTRA }, + { GL_MODELVIEW_STACK_DEPTH, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_context, ModelviewMatrixStack.Depth), NO_EXTRA }, + { GL_NORMALIZE, CONTEXT_BOOL(Transform.Normalize), NO_EXTRA }, + { GL_PACK_SKIP_IMAGES_EXT, CONTEXT_INT(Pack.SkipImages), NO_EXTRA }, + { GL_PERSPECTIVE_CORRECTION_HINT, CONTEXT_ENUM(Hint.PerspectiveCorrection), NO_EXTRA }, + { GL_POINT_SIZE, CONTEXT_FLOAT(Point.Size), NO_EXTRA }, + { GL_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSizeAA), NO_EXTRA }, + { GL_POINT_SMOOTH, CONTEXT_BOOL(Point.SmoothFlag), NO_EXTRA }, + { GL_POINT_SMOOTH_HINT, CONTEXT_ENUM(Hint.PointSmooth), NO_EXTRA }, + { GL_POINT_SIZE_MIN_EXT, CONTEXT_FLOAT(Point.MinSize), NO_EXTRA }, + { GL_POINT_SIZE_MAX_EXT, CONTEXT_FLOAT(Point.MaxSize), NO_EXTRA }, + { GL_POINT_FADE_THRESHOLD_SIZE_EXT, CONTEXT_FLOAT(Point.Threshold), NO_EXTRA }, + { GL_PROJECTION_MATRIX, CONTEXT_MATRIX(ProjectionMatrixStack.Top), NO_EXTRA }, + { GL_PROJECTION_STACK_DEPTH, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_context, ProjectionMatrixStack.Depth), NO_EXTRA }, + { GL_RESCALE_NORMAL, CONTEXT_BOOL(Transform.RescaleNormals), NO_EXTRA }, + { GL_SHADE_MODEL, CONTEXT_ENUM(Light.ShadeModel), NO_EXTRA }, + { GL_TEXTURE_2D, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA }, + { GL_TEXTURE_MATRIX, LOC_CUSTOM, TYPE_MATRIX, 0, extra_valid_texture_unit }, + { GL_TEXTURE_STACK_DEPTH, LOC_CUSTOM, TYPE_INT, 0, + extra_valid_texture_unit }, + + { GL_VERTEX_ARRAY, ARRAY_BOOL(Vertex.Enabled), NO_EXTRA }, + { GL_VERTEX_ARRAY_SIZE, ARRAY_INT(Vertex.Size), NO_EXTRA }, + { GL_VERTEX_ARRAY_TYPE, ARRAY_ENUM(Vertex.Type), NO_EXTRA }, + { GL_VERTEX_ARRAY_STRIDE, ARRAY_INT(Vertex.Stride), NO_EXTRA }, + { GL_NORMAL_ARRAY, ARRAY_BOOL(Normal.Enabled), NO_EXTRA }, + { GL_NORMAL_ARRAY_TYPE, ARRAY_ENUM(Normal.Type), NO_EXTRA }, + { GL_NORMAL_ARRAY_STRIDE, ARRAY_INT(Normal.Stride), NO_EXTRA }, + { GL_COLOR_ARRAY, ARRAY_BOOL(Color.Enabled), NO_EXTRA }, + { GL_COLOR_ARRAY_SIZE, ARRAY_INT(Color.Size), NO_EXTRA }, + { GL_COLOR_ARRAY_TYPE, ARRAY_ENUM(Color.Type), NO_EXTRA }, + { GL_COLOR_ARRAY_STRIDE, ARRAY_INT(Color.Stride), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY, + LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Enabled), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY_SIZE, + LOC_CUSTOM, TYPE_INT, offsetof(struct gl_client_array, Size), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY_TYPE, + LOC_CUSTOM, TYPE_ENUM, offsetof(struct gl_client_array, Type), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY_STRIDE, + LOC_CUSTOM, TYPE_INT, offsetof(struct gl_client_array, Stride), NO_EXTRA }, + + /* GL_ARB_ES2_compatibility */ + { GL_SHADER_COMPILER, CONST(1), extra_ARB_ES2_compatibility }, + { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), + extra_ARB_ES2_compatibility }, + { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_ES2_compatibility }, + { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_ES2_compatibility }, + + /* GL_ARB_multitexture */ + { GL_MAX_TEXTURE_UNITS_ARB, + CONTEXT_INT(Const.MaxTextureUnits), extra_ARB_multitexture }, + { GL_CLIENT_ACTIVE_TEXTURE_ARB, + LOC_CUSTOM, TYPE_INT, 0, extra_ARB_multitexture }, + + /* GL_ARB_texture_cube_map */ + { GL_TEXTURE_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA }, + /* S, T, and R are always set at the same time */ + { GL_TEXTURE_GEN_STR_OES, LOC_TEXUNIT, TYPE_BIT_0, + offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA }, + + /* GL_ARB_multisample */ + { GL_MULTISAMPLE_ARB, CONTEXT_BOOL(Multisample.Enabled), NO_EXTRA }, + { GL_SAMPLE_ALPHA_TO_ONE_ARB, CONTEXT_BOOL(Multisample.SampleAlphaToOne), NO_EXTRA }, + + /* GL_ARB_vertex_buffer_object */ + { GL_VERTEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, Vertex.BufferObj), NO_EXTRA }, + { GL_NORMAL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, Normal.BufferObj), NO_EXTRA }, + { GL_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, Color.BufferObj), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA }, + + /* GL_OES_point_sprite */ + { GL_POINT_SPRITE_NV, + CONTEXT_BOOL(Point.PointSprite), + extra_NV_point_sprite_ARB_point_sprite }, + + /* GL_ARB_fragment_shader */ + { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, + CONTEXT_INT(Const.FragmentProgram.MaxUniformComponents), + extra_ARB_fragment_shader }, + + /* GL_ARB_vertex_shader */ + { GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, + CONTEXT_INT(Const.VertexProgram.MaxUniformComponents), + extra_ARB_vertex_shader }, + { GL_MAX_VARYING_FLOATS_ARB, LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_vertex_shader }, + + /* GL_EXT_texture_lod_bias */ + { GL_MAX_TEXTURE_LOD_BIAS_EXT, CONTEXT_FLOAT(Const.MaxTextureLodBias), + extra_EXT_texture_lod_bias }, + + /* GL_EXT_texture_filter_anisotropic */ + { GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, + CONTEXT_FLOAT(Const.MaxTextureMaxAnisotropy), + extra_EXT_texture_filter_anisotropic }, +#endif /* FEATURE_GL || FEATURE_ES1 */ + +#if FEATURE_ES1 + { 0, 0, TYPE_API_MASK, API_OPENGLES_BIT }, + /* XXX: OES_matrix_get */ + { GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES }, + { GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES }, + { GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES }, + + /* OES_point_size_array */ + { GL_POINT_SIZE_ARRAY_OES, ARRAY_FIELD(PointSize.Enabled, TYPE_BOOLEAN) }, + { GL_POINT_SIZE_ARRAY_TYPE_OES, ARRAY_FIELD(PointSize.Type, TYPE_ENUM) }, + { GL_POINT_SIZE_ARRAY_STRIDE_OES, ARRAY_FIELD(PointSize.Stride, TYPE_INT) }, + { GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, LOC_CUSTOM, TYPE_INT, 0 }, +#endif /* FEATURE_ES1 */ + +#if FEATURE_GL || FEATURE_ES2 + { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES2_BIT, NO_EXTRA }, + /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's GLSL: */ + { GL_MAX_LIGHTS, CONTEXT_INT(Const.MaxLights), NO_EXTRA }, + { GL_MAX_TEXTURE_COORDS_ARB, /* == GL_MAX_TEXTURE_COORDS_NV */ + CONTEXT_INT(Const.MaxTextureCoordUnits), + extra_ARB_fragment_program_NV_fragment_program }, + + /* GL_ARB_draw_buffers */ + { GL_MAX_DRAW_BUFFERS_ARB, CONTEXT_INT(Const.MaxDrawBuffers), NO_EXTRA }, + + { GL_BLEND_COLOR_EXT, CONTEXT_FIELD(Color.BlendColor[0], TYPE_FLOATN_4), NO_EXTRA }, + /* GL_ARB_fragment_program */ + { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */ + CONTEXT_INT(Const.MaxTextureImageUnits), + extra_ARB_fragment_program_NV_fragment_program }, + { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, + CONTEXT_INT(Const.MaxVertexTextureImageUnits), extra_ARB_vertex_shader }, + { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, + CONTEXT_INT(Const.MaxCombinedTextureImageUnits), + extra_ARB_vertex_shader }, + + /* GL_ARB_shader_objects + * Actually, this token isn't part of GL_ARB_shader_objects, but is + * close enough for now. */ + { GL_CURRENT_PROGRAM, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_objects }, + + /* OpenGL 2.0 */ + { GL_STENCIL_BACK_FUNC, CONTEXT_ENUM(Stencil.Function[1]), NO_EXTRA }, + { GL_STENCIL_BACK_VALUE_MASK, CONTEXT_INT(Stencil.ValueMask[1]), NO_EXTRA }, + { GL_STENCIL_BACK_WRITEMASK, CONTEXT_INT(Stencil.WriteMask[1]), NO_EXTRA }, + { GL_STENCIL_BACK_REF, CONTEXT_INT(Stencil.Ref[1]), NO_EXTRA }, + { GL_STENCIL_BACK_FAIL, CONTEXT_ENUM(Stencil.FailFunc[1]), NO_EXTRA }, + { GL_STENCIL_BACK_PASS_DEPTH_FAIL, CONTEXT_ENUM(Stencil.ZFailFunc[1]), NO_EXTRA }, + { GL_STENCIL_BACK_PASS_DEPTH_PASS, CONTEXT_ENUM(Stencil.ZPassFunc[1]), NO_EXTRA }, + + { GL_MAX_VERTEX_ATTRIBS_ARB, + CONTEXT_INT(Const.VertexProgram.MaxAttribs), + extra_ARB_vertex_program_version_es2 }, + + /* OES_texture_3D */ + { GL_TEXTURE_BINDING_3D, LOC_CUSTOM, TYPE_INT, TEXTURE_3D_INDEX, NO_EXTRA }, + { GL_MAX_3D_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_context, Const.Max3DTextureLevels), NO_EXTRA }, + + /* GL_ARB_fragment_program/OES_standard_derivatives */ + { GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB, + CONTEXT_ENUM(Hint.FragmentShaderDerivative), extra_ARB_fragment_shader }, +#endif /* FEATURE_GL || FEATURE_ES2 */ + +#if FEATURE_ES2 + /* Enums unique to OpenGL ES 2.0 */ + { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA }, + { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), NO_EXTRA }, + { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_SHADER_COMPILER, CONST(1), NO_EXTRA }, + /* OES_get_program_binary */ + { GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA }, + { GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA }, +#endif /* FEATURE_ES2 */ + +#if FEATURE_GL + /* Remaining enums are only in OpenGL */ + { 0, 0, TYPE_API_MASK, API_OPENGL_BIT, NO_EXTRA }, + { GL_ACCUM_RED_BITS, BUFFER_INT(Visual.accumRedBits), NO_EXTRA }, + { GL_ACCUM_GREEN_BITS, BUFFER_INT(Visual.accumGreenBits), NO_EXTRA }, + { GL_ACCUM_BLUE_BITS, BUFFER_INT(Visual.accumBlueBits), NO_EXTRA }, + { GL_ACCUM_ALPHA_BITS, BUFFER_INT(Visual.accumAlphaBits), NO_EXTRA }, + { GL_ACCUM_CLEAR_VALUE, CONTEXT_FIELD(Accum.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_ALPHA_BIAS, CONTEXT_FLOAT(Pixel.AlphaBias), NO_EXTRA }, + { GL_ALPHA_SCALE, CONTEXT_FLOAT(Pixel.AlphaScale), NO_EXTRA }, + { GL_ATTRIB_STACK_DEPTH, CONTEXT_INT(AttribStackDepth), NO_EXTRA }, + { GL_AUTO_NORMAL, CONTEXT_BOOL(Eval.AutoNormal), NO_EXTRA }, + { GL_AUX_BUFFERS, BUFFER_INT(Visual.numAuxBuffers), NO_EXTRA }, + { GL_BLUE_BIAS, CONTEXT_FLOAT(Pixel.BlueBias), NO_EXTRA }, + { GL_BLUE_SCALE, CONTEXT_FLOAT(Pixel.BlueScale), NO_EXTRA }, + { GL_CLIENT_ATTRIB_STACK_DEPTH, CONTEXT_INT(ClientAttribStackDepth), NO_EXTRA }, + { GL_COLOR_MATERIAL_FACE, CONTEXT_ENUM(Light.ColorMaterialFace), NO_EXTRA }, + { GL_COLOR_MATERIAL_PARAMETER, CONTEXT_ENUM(Light.ColorMaterialMode), NO_EXTRA }, + { GL_CURRENT_INDEX, + CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]), + extra_flush_current }, + { GL_CURRENT_RASTER_COLOR, + CONTEXT_FIELD(Current.RasterColor[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_CURRENT_RASTER_DISTANCE, CONTEXT_FLOAT(Current.RasterDistance), NO_EXTRA }, + { GL_CURRENT_RASTER_INDEX, CONST(1), NO_EXTRA }, + { GL_CURRENT_RASTER_POSITION, CONTEXT_FLOAT4(Current.RasterPos[0]), NO_EXTRA }, + { GL_CURRENT_RASTER_SECONDARY_COLOR, + CONTEXT_FIELD(Current.RasterSecondaryColor[0], TYPE_FLOATN_4), NO_EXTRA }, + { GL_CURRENT_RASTER_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0, + extra_valid_texture_unit }, + { GL_CURRENT_RASTER_POSITION_VALID, CONTEXT_BOOL(Current.RasterPosValid), NO_EXTRA }, + { GL_DEPTH_BIAS, CONTEXT_FLOAT(Pixel.DepthBias), NO_EXTRA }, + { GL_DEPTH_SCALE, CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA }, + { GL_DOUBLEBUFFER, BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA }, + { GL_DRAW_BUFFER, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA }, + { GL_EDGE_FLAG, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA }, + { GL_FEEDBACK_BUFFER_SIZE, CONTEXT_INT(Feedback.BufferSize), NO_EXTRA }, + { GL_FEEDBACK_BUFFER_TYPE, CONTEXT_ENUM(Feedback.Type), NO_EXTRA }, + { GL_FOG_INDEX, CONTEXT_FLOAT(Fog.Index), NO_EXTRA }, + { GL_GREEN_BIAS, CONTEXT_FLOAT(Pixel.GreenBias), NO_EXTRA }, + { GL_GREEN_SCALE, CONTEXT_FLOAT(Pixel.GreenScale), NO_EXTRA }, + { GL_INDEX_BITS, BUFFER_INT(Visual.indexBits), extra_new_buffers }, + { GL_INDEX_CLEAR_VALUE, CONTEXT_INT(Color.ClearIndex), NO_EXTRA }, + { GL_INDEX_MODE, CONST(0) , NO_EXTRA}, + { GL_INDEX_OFFSET, CONTEXT_INT(Pixel.IndexOffset), NO_EXTRA }, + { GL_INDEX_SHIFT, CONTEXT_INT(Pixel.IndexShift), NO_EXTRA }, + { GL_INDEX_WRITEMASK, CONTEXT_INT(Color.IndexMask), NO_EXTRA }, + { GL_LIGHT_MODEL_COLOR_CONTROL, CONTEXT_ENUM(Light.Model.ColorControl), NO_EXTRA }, + { GL_LIGHT_MODEL_LOCAL_VIEWER, CONTEXT_BOOL(Light.Model.LocalViewer), NO_EXTRA }, + { GL_LINE_STIPPLE, CONTEXT_BOOL(Line.StippleFlag), NO_EXTRA }, + { GL_LINE_STIPPLE_PATTERN, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_LINE_STIPPLE_REPEAT, CONTEXT_INT(Line.StippleFactor), NO_EXTRA }, + { GL_LINE_WIDTH_GRANULARITY, CONTEXT_FLOAT(Const.LineWidthGranularity), NO_EXTRA }, + { GL_LIST_BASE, CONTEXT_INT(List.ListBase), NO_EXTRA }, + { GL_LIST_INDEX, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_LIST_MODE, LOC_CUSTOM, TYPE_ENUM, 0, NO_EXTRA }, + { GL_INDEX_LOGIC_OP, CONTEXT_BOOL(Color.IndexLogicOpEnabled), NO_EXTRA }, + { GL_MAP1_COLOR_4, CONTEXT_BOOL(Eval.Map1Color4), NO_EXTRA }, + { GL_MAP1_GRID_DOMAIN, CONTEXT_FLOAT2(Eval.MapGrid1u1), NO_EXTRA }, + { GL_MAP1_GRID_SEGMENTS, CONTEXT_INT(Eval.MapGrid1un), NO_EXTRA }, + { GL_MAP1_INDEX, CONTEXT_BOOL(Eval.Map1Index), NO_EXTRA }, + { GL_MAP1_NORMAL, CONTEXT_BOOL(Eval.Map1Normal), NO_EXTRA }, + { GL_MAP1_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map1TextureCoord1), NO_EXTRA }, + { GL_MAP1_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map1TextureCoord2), NO_EXTRA }, + { GL_MAP1_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map1TextureCoord3), NO_EXTRA }, + { GL_MAP1_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map1TextureCoord4), NO_EXTRA }, + { GL_MAP1_VERTEX_3, CONTEXT_BOOL(Eval.Map1Vertex3), NO_EXTRA }, + { GL_MAP1_VERTEX_4, CONTEXT_BOOL(Eval.Map1Vertex4), NO_EXTRA }, + { GL_MAP2_COLOR_4, CONTEXT_BOOL(Eval.Map2Color4), NO_EXTRA }, + { GL_MAP2_GRID_DOMAIN, LOC_CUSTOM, TYPE_FLOAT_4, 0, NO_EXTRA }, + { GL_MAP2_GRID_SEGMENTS, CONTEXT_INT2(Eval.MapGrid2un), NO_EXTRA }, + { GL_MAP2_INDEX, CONTEXT_BOOL(Eval.Map2Index), NO_EXTRA }, + { GL_MAP2_NORMAL, CONTEXT_BOOL(Eval.Map2Normal), NO_EXTRA }, + { GL_MAP2_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map2TextureCoord1), NO_EXTRA }, + { GL_MAP2_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map2TextureCoord2), NO_EXTRA }, + { GL_MAP2_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map2TextureCoord3), NO_EXTRA }, + { GL_MAP2_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map2TextureCoord4), NO_EXTRA }, + { GL_MAP2_VERTEX_3, CONTEXT_BOOL(Eval.Map2Vertex3), NO_EXTRA }, + { GL_MAP2_VERTEX_4, CONTEXT_BOOL(Eval.Map2Vertex4), NO_EXTRA }, + { GL_MAP_COLOR, CONTEXT_BOOL(Pixel.MapColorFlag), NO_EXTRA }, + { GL_MAP_STENCIL, CONTEXT_BOOL(Pixel.MapStencilFlag), NO_EXTRA }, + { GL_MAX_ATTRIB_STACK_DEPTH, CONST(MAX_ATTRIB_STACK_DEPTH), NO_EXTRA }, + { GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, CONST(MAX_CLIENT_ATTRIB_STACK_DEPTH), NO_EXTRA }, + + { GL_MAX_EVAL_ORDER, CONST(MAX_EVAL_ORDER), NO_EXTRA }, + { GL_MAX_LIST_NESTING, CONST(MAX_LIST_NESTING), NO_EXTRA }, + { GL_MAX_NAME_STACK_DEPTH, CONST(MAX_NAME_STACK_DEPTH), NO_EXTRA }, + { GL_MAX_PIXEL_MAP_TABLE, CONST(MAX_PIXEL_MAP_TABLE), NO_EXTRA }, + { GL_NAME_STACK_DEPTH, CONTEXT_INT(Select.NameStackDepth), NO_EXTRA }, + { GL_PACK_LSB_FIRST, CONTEXT_BOOL(Pack.LsbFirst), NO_EXTRA }, + { GL_PACK_ROW_LENGTH, CONTEXT_INT(Pack.RowLength), NO_EXTRA }, + { GL_PACK_SKIP_PIXELS, CONTEXT_INT(Pack.SkipPixels), NO_EXTRA }, + { GL_PACK_SKIP_ROWS, CONTEXT_INT(Pack.SkipRows), NO_EXTRA }, + { GL_PACK_SWAP_BYTES, CONTEXT_BOOL(Pack.SwapBytes), NO_EXTRA }, + { GL_PACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Pack.ImageHeight), NO_EXTRA }, + { GL_PACK_INVERT_MESA, CONTEXT_BOOL(Pack.Invert), NO_EXTRA }, + { GL_PIXEL_MAP_A_TO_A_SIZE, CONTEXT_INT(PixelMaps.AtoA.Size), NO_EXTRA }, + { GL_PIXEL_MAP_B_TO_B_SIZE, CONTEXT_INT(PixelMaps.BtoB.Size), NO_EXTRA }, + { GL_PIXEL_MAP_G_TO_G_SIZE, CONTEXT_INT(PixelMaps.GtoG.Size), NO_EXTRA }, + { GL_PIXEL_MAP_I_TO_A_SIZE, CONTEXT_INT(PixelMaps.ItoA.Size), NO_EXTRA }, + { GL_PIXEL_MAP_I_TO_B_SIZE, CONTEXT_INT(PixelMaps.ItoB.Size), NO_EXTRA }, + { GL_PIXEL_MAP_I_TO_G_SIZE, CONTEXT_INT(PixelMaps.ItoG.Size), NO_EXTRA }, + { GL_PIXEL_MAP_I_TO_I_SIZE, CONTEXT_INT(PixelMaps.ItoI.Size), NO_EXTRA }, + { GL_PIXEL_MAP_I_TO_R_SIZE, CONTEXT_INT(PixelMaps.ItoR.Size), NO_EXTRA }, + { GL_PIXEL_MAP_R_TO_R_SIZE, CONTEXT_INT(PixelMaps.RtoR.Size), NO_EXTRA }, + { GL_PIXEL_MAP_S_TO_S_SIZE, CONTEXT_INT(PixelMaps.StoS.Size), NO_EXTRA }, + { GL_POINT_SIZE_GRANULARITY, CONTEXT_FLOAT(Const.PointSizeGranularity), NO_EXTRA }, + { GL_POLYGON_MODE, CONTEXT_ENUM2(Polygon.FrontMode), NO_EXTRA }, + { GL_POLYGON_OFFSET_BIAS_EXT, CONTEXT_FLOAT(Polygon.OffsetUnits), NO_EXTRA }, + { GL_POLYGON_OFFSET_POINT, CONTEXT_BOOL(Polygon.OffsetPoint), NO_EXTRA }, + { GL_POLYGON_OFFSET_LINE, CONTEXT_BOOL(Polygon.OffsetLine), NO_EXTRA }, + { GL_POLYGON_SMOOTH, CONTEXT_BOOL(Polygon.SmoothFlag), NO_EXTRA }, + { GL_POLYGON_SMOOTH_HINT, CONTEXT_ENUM(Hint.PolygonSmooth), NO_EXTRA }, + { GL_POLYGON_STIPPLE, CONTEXT_BOOL(Polygon.StippleFlag), NO_EXTRA }, + { GL_READ_BUFFER, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + { GL_RED_BIAS, CONTEXT_FLOAT(Pixel.RedBias), NO_EXTRA }, + { GL_RED_SCALE, CONTEXT_FLOAT(Pixel.RedScale), NO_EXTRA }, + { GL_RENDER_MODE, CONTEXT_ENUM(RenderMode), NO_EXTRA }, + { GL_RGBA_MODE, CONST(1), NO_EXTRA }, + { GL_SELECTION_BUFFER_SIZE, CONTEXT_INT(Select.BufferSize), NO_EXTRA }, + { GL_SHARED_TEXTURE_PALETTE_EXT, CONTEXT_BOOL(Texture.SharedPalette), NO_EXTRA }, + + { GL_STEREO, BUFFER_INT(Visual.stereoMode), NO_EXTRA }, + + { GL_TEXTURE_1D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA }, + { GL_TEXTURE_3D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA }, + { GL_TEXTURE_1D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA }, + { GL_TEXTURE_2D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA }, + + { GL_TEXTURE_BINDING_1D, LOC_CUSTOM, TYPE_INT, TEXTURE_1D_INDEX, NO_EXTRA }, + { GL_TEXTURE_BINDING_1D_ARRAY, LOC_CUSTOM, TYPE_INT, + TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array }, + { GL_TEXTURE_BINDING_2D_ARRAY, LOC_CUSTOM, TYPE_INT, + TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array }, + { GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, + CONTEXT_INT(Const.MaxArrayTextureLayers), extra_MESA_texture_array }, + + { GL_TEXTURE_GEN_S, LOC_TEXUNIT, TYPE_BIT_0, + offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA }, + { GL_TEXTURE_GEN_T, LOC_TEXUNIT, TYPE_BIT_1, + offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA }, + { GL_TEXTURE_GEN_R, LOC_TEXUNIT, TYPE_BIT_2, + offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA }, + { GL_TEXTURE_GEN_Q, LOC_TEXUNIT, TYPE_BIT_3, + offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA }, + { GL_UNPACK_LSB_FIRST, CONTEXT_BOOL(Unpack.LsbFirst), NO_EXTRA }, + { GL_UNPACK_ROW_LENGTH, CONTEXT_INT(Unpack.RowLength), NO_EXTRA }, + { GL_UNPACK_SKIP_PIXELS, CONTEXT_INT(Unpack.SkipPixels), NO_EXTRA }, + { GL_UNPACK_SKIP_ROWS, CONTEXT_INT(Unpack.SkipRows), NO_EXTRA }, + { GL_UNPACK_SWAP_BYTES, CONTEXT_BOOL(Unpack.SwapBytes), NO_EXTRA }, + { GL_UNPACK_SKIP_IMAGES_EXT, CONTEXT_INT(Unpack.SkipImages), NO_EXTRA }, + { GL_UNPACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Unpack.ImageHeight), NO_EXTRA }, + { GL_UNPACK_CLIENT_STORAGE_APPLE, CONTEXT_BOOL(Unpack.ClientStorage), NO_EXTRA }, + { GL_ZOOM_X, CONTEXT_FLOAT(Pixel.ZoomX), NO_EXTRA }, + { GL_ZOOM_Y, CONTEXT_FLOAT(Pixel.ZoomY), NO_EXTRA }, + + /* Vertex arrays */ + { GL_VERTEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + { GL_NORMAL_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + { GL_COLOR_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + { GL_INDEX_ARRAY, ARRAY_BOOL(Index.Enabled), NO_EXTRA }, + { GL_INDEX_ARRAY_TYPE, ARRAY_ENUM(Index.Type), NO_EXTRA }, + { GL_INDEX_ARRAY_STRIDE, ARRAY_INT(Index.Stride), NO_EXTRA }, + { GL_INDEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + { GL_TEXTURE_COORD_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + { GL_EDGE_FLAG_ARRAY, ARRAY_BOOL(EdgeFlag.Enabled), NO_EXTRA }, + { GL_EDGE_FLAG_ARRAY_STRIDE, ARRAY_INT(EdgeFlag.Stride), NO_EXTRA }, + { GL_EDGE_FLAG_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA }, + + /* GL_ARB_texture_compression */ + { GL_TEXTURE_COMPRESSION_HINT_ARB, CONTEXT_INT(Hint.TextureCompression), NO_EXTRA }, + + /* GL_EXT_compiled_vertex_array */ + { GL_ARRAY_ELEMENT_LOCK_FIRST_EXT, CONTEXT_INT(Array.LockFirst), + extra_EXT_compiled_vertex_array }, + { GL_ARRAY_ELEMENT_LOCK_COUNT_EXT, CONTEXT_INT(Array.LockCount), + extra_EXT_compiled_vertex_array }, + + /* GL_ARB_transpose_matrix */ + { GL_TRANSPOSE_MODELVIEW_MATRIX_ARB, + CONTEXT_MATRIX_T(ModelviewMatrixStack), NO_EXTRA }, + { GL_TRANSPOSE_PROJECTION_MATRIX_ARB, + CONTEXT_MATRIX_T(ProjectionMatrixStack.Top), NO_EXTRA }, + { GL_TRANSPOSE_TEXTURE_MATRIX_ARB, CONTEXT_MATRIX_T(TextureMatrixStack), NO_EXTRA }, + + /* GL_EXT_secondary_color */ + { GL_COLOR_SUM_EXT, CONTEXT_BOOL(Fog.ColorSumEnabled), + extra_EXT_secondary_color_ARB_vertex_program }, + { GL_CURRENT_SECONDARY_COLOR_EXT, + CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR1][0], TYPE_FLOATN_4), + extra_EXT_secondary_color_flush_current }, + { GL_SECONDARY_COLOR_ARRAY_EXT, ARRAY_BOOL(SecondaryColor.Enabled), + extra_EXT_secondary_color }, + { GL_SECONDARY_COLOR_ARRAY_TYPE_EXT, ARRAY_ENUM(SecondaryColor.Type), + extra_EXT_secondary_color }, + { GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT, ARRAY_INT(SecondaryColor.Stride), + extra_EXT_secondary_color }, + { GL_SECONDARY_COLOR_ARRAY_SIZE_EXT, ARRAY_INT(SecondaryColor.Size), + extra_EXT_secondary_color }, + + /* GL_EXT_fog_coord */ + { GL_CURRENT_FOG_COORDINATE_EXT, + CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]), + extra_EXT_fog_coord_flush_current }, + { GL_FOG_COORDINATE_ARRAY_EXT, ARRAY_BOOL(FogCoord.Enabled), + extra_EXT_fog_coord }, + { GL_FOG_COORDINATE_ARRAY_TYPE_EXT, ARRAY_ENUM(FogCoord.Type), + extra_EXT_fog_coord }, + { GL_FOG_COORDINATE_ARRAY_STRIDE_EXT, ARRAY_INT(FogCoord.Stride), + extra_EXT_fog_coord }, + { GL_FOG_COORDINATE_SOURCE_EXT, CONTEXT_ENUM(Fog.FogCoordinateSource), + extra_EXT_fog_coord }, + + /* GL_IBM_rasterpos_clip */ + { GL_RASTER_POSITION_UNCLIPPED_IBM, + CONTEXT_BOOL(Transform.RasterPositionUnclipped), + extra_IBM_rasterpos_clip }, + + /* GL_NV_point_sprite */ + { GL_POINT_SPRITE_R_MODE_NV, + CONTEXT_ENUM(Point.SpriteRMode), extra_NV_point_sprite }, + { GL_POINT_SPRITE_COORD_ORIGIN, CONTEXT_ENUM(Point.SpriteOrigin), + extra_NV_point_sprite_ARB_point_sprite }, + + /* GL_NV_vertex_program */ + { GL_VERTEX_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0, + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY0_NV, ARRAY_BOOL(VertexAttrib[0].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY1_NV, ARRAY_BOOL(VertexAttrib[1].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY2_NV, ARRAY_BOOL(VertexAttrib[2].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY3_NV, ARRAY_BOOL(VertexAttrib[3].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY4_NV, ARRAY_BOOL(VertexAttrib[4].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY5_NV, ARRAY_BOOL(VertexAttrib[5].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY6_NV, ARRAY_BOOL(VertexAttrib[6].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY7_NV, ARRAY_BOOL(VertexAttrib[7].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY8_NV, ARRAY_BOOL(VertexAttrib[8].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY9_NV, ARRAY_BOOL(VertexAttrib[9].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY10_NV, ARRAY_BOOL(VertexAttrib[10].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY11_NV, ARRAY_BOOL(VertexAttrib[11].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY12_NV, ARRAY_BOOL(VertexAttrib[12].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY13_NV, ARRAY_BOOL(VertexAttrib[13].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY14_NV, ARRAY_BOOL(VertexAttrib[14].Enabled), + extra_NV_vertex_program }, + { GL_VERTEX_ATTRIB_ARRAY15_NV, ARRAY_BOOL(VertexAttrib[15].Enabled), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB0_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[0]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB1_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[1]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB2_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[2]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB3_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[3]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB4_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[4]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB5_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[5]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB6_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[6]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB7_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[7]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB8_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[8]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB9_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[9]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB10_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[10]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB11_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[11]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB12_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[12]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB13_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[13]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB14_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[14]), + extra_NV_vertex_program }, + { GL_MAP1_VERTEX_ATTRIB15_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[15]), + extra_NV_vertex_program }, + + /* GL_NV_fragment_program */ + { GL_FRAGMENT_PROGRAM_NV, CONTEXT_BOOL(FragmentProgram.Enabled), + extra_NV_fragment_program }, + { GL_FRAGMENT_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0, + extra_NV_fragment_program }, + { GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV, + CONST(MAX_NV_FRAGMENT_PROGRAM_PARAMS), + extra_NV_fragment_program }, + + /* GL_NV_texture_rectangle */ + { GL_TEXTURE_RECTANGLE_NV, + LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_NV_texture_rectangle }, + { GL_TEXTURE_BINDING_RECTANGLE_NV, + LOC_CUSTOM, TYPE_INT, TEXTURE_RECT_INDEX, extra_NV_texture_rectangle }, + { GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, + CONTEXT_INT(Const.MaxTextureRectSize), extra_NV_texture_rectangle }, + + /* GL_EXT_stencil_two_side */ + { GL_STENCIL_TEST_TWO_SIDE_EXT, CONTEXT_BOOL(Stencil.TestTwoSide), + extra_EXT_stencil_two_side }, + { GL_ACTIVE_STENCIL_FACE_EXT, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA }, + + /* GL_NV_light_max_exponent */ + { GL_MAX_SHININESS_NV, CONTEXT_FLOAT(Const.MaxShininess), + extra_NV_light_max_exponent }, + { GL_MAX_SPOT_EXPONENT_NV, CONTEXT_FLOAT(Const.MaxSpotExponent), + extra_NV_light_max_exponent }, + + /* GL_NV_primitive_restart */ + { GL_PRIMITIVE_RESTART_NV, CONTEXT_BOOL(Array.PrimitiveRestart), + extra_NV_primitive_restart }, + { GL_PRIMITIVE_RESTART_INDEX_NV, CONTEXT_INT(Array.RestartIndex), + extra_NV_primitive_restart }, + + /* GL_ARB_vertex_buffer_object */ + { GL_INDEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, Index.BufferObj), NO_EXTRA }, + { GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, EdgeFlag.BufferObj), NO_EXTRA }, + { GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, SecondaryColor.BufferObj), NO_EXTRA }, + { GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, + offsetof(struct gl_array_object, FogCoord.BufferObj), NO_EXTRA }, + + /* GL_EXT_pixel_buffer_object */ + { GL_PIXEL_PACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0, + extra_EXT_pixel_buffer_object }, + { GL_PIXEL_UNPACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0, + extra_EXT_pixel_buffer_object }, + + /* GL_ARB_vertex_program */ + { GL_VERTEX_PROGRAM_ARB, /* == GL_VERTEX_PROGRAM_NV */ + CONTEXT_BOOL(VertexProgram.Enabled), + extra_ARB_vertex_program_NV_vertex_program }, + { GL_VERTEX_PROGRAM_POINT_SIZE_ARB, /* == GL_VERTEX_PROGRAM_POINT_SIZE_NV*/ + CONTEXT_BOOL(VertexProgram.PointSizeEnabled), + extra_ARB_vertex_program_NV_vertex_program }, + { GL_VERTEX_PROGRAM_TWO_SIDE_ARB, /* == GL_VERTEX_PROGRAM_TWO_SIDE_NV */ + CONTEXT_BOOL(VertexProgram.TwoSideEnabled), + extra_ARB_vertex_program_NV_vertex_program }, + { GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB, /* == GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */ + CONTEXT_INT(Const.MaxProgramMatrixStackDepth), + extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program }, + { GL_MAX_PROGRAM_MATRICES_ARB, /* == GL_MAX_TRACK_MATRICES_NV */ + CONTEXT_INT(Const.MaxProgramMatrices), + extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program }, + { GL_CURRENT_MATRIX_STACK_DEPTH_ARB, /* == GL_CURRENT_MATRIX_STACK_DEPTH_NV */ + LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program }, + + { GL_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */ + LOC_CUSTOM, TYPE_MATRIX, 0, + extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program }, + { GL_TRANSPOSE_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */ + LOC_CUSTOM, TYPE_MATRIX, 0, + extra_ARB_vertex_program_ARB_fragment_program }, + + { GL_PROGRAM_ERROR_POSITION_ARB, /* == GL_PROGRAM_ERROR_POSITION_NV */ + CONTEXT_INT(Program.ErrorPos), + extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program }, + + /* GL_ARB_fragment_program */ + { GL_FRAGMENT_PROGRAM_ARB, CONTEXT_BOOL(FragmentProgram.Enabled), + extra_ARB_fragment_program }, + + /* GL_EXT_depth_bounds_test */ + { GL_DEPTH_BOUNDS_TEST_EXT, CONTEXT_BOOL(Depth.BoundsTest), + extra_EXT_depth_bounds_test }, + { GL_DEPTH_BOUNDS_EXT, CONTEXT_FLOAT2(Depth.BoundsMin), + extra_EXT_depth_bounds_test }, + + /* GL_ARB_depth_clamp*/ + { GL_DEPTH_CLAMP, CONTEXT_BOOL(Transform.DepthClamp), + extra_ARB_depth_clamp }, + + /* GL_ARB_draw_buffers */ + { GL_DRAW_BUFFER0_ARB, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA }, + { GL_DRAW_BUFFER1_ARB, BUFFER_ENUM(ColorDrawBuffer[1]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER2_ARB, BUFFER_ENUM(ColorDrawBuffer[2]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]), + extra_valid_draw_buffer }, + + /* GL_ATI_fragment_shader */ + { GL_NUM_FRAGMENT_REGISTERS_ATI, CONST(6), extra_ATI_fragment_shader }, + { GL_NUM_FRAGMENT_CONSTANTS_ATI, CONST(8), extra_ATI_fragment_shader }, + { GL_NUM_PASSES_ATI, CONST(2), extra_ATI_fragment_shader }, + { GL_NUM_INSTRUCTIONS_PER_PASS_ATI, CONST(8), extra_ATI_fragment_shader }, + { GL_NUM_INSTRUCTIONS_TOTAL_ATI, CONST(16), extra_ATI_fragment_shader }, + { GL_COLOR_ALPHA_PAIRING_ATI, CONST(GL_TRUE), extra_ATI_fragment_shader }, + { GL_NUM_LOOPBACK_COMPONENTS_ATI, CONST(3), extra_ATI_fragment_shader }, + { GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI, + CONST(3), extra_ATI_fragment_shader }, + + /* GL_EXT_framebuffer_object */ + { GL_MAX_COLOR_ATTACHMENTS_EXT, CONTEXT_INT(Const.MaxColorAttachments), + extra_EXT_framebuffer_object }, + + /* GL_EXT_framebuffer_blit + * NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT */ + { GL_READ_FRAMEBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0, + extra_EXT_framebuffer_blit }, + + /* GL_EXT_provoking_vertex */ + { GL_PROVOKING_VERTEX_EXT, + CONTEXT_BOOL(Light.ProvokingVertex), extra_EXT_provoking_vertex }, + { GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT, + CONTEXT_BOOL(Const.QuadsFollowProvokingVertexConvention), + extra_EXT_provoking_vertex }, + + /* GL_ARB_framebuffer_object */ + { GL_MAX_SAMPLES, CONTEXT_INT(Const.MaxSamples), + extra_ARB_framebuffer_object_EXT_framebuffer_multisample }, + + /* GL_APPLE_vertex_array_object */ + { GL_VERTEX_ARRAY_BINDING_APPLE, ARRAY_INT(Name), + extra_APPLE_vertex_array_object }, + + /* GL_ARB_seamless_cube_map */ + { GL_TEXTURE_CUBE_MAP_SEAMLESS, + CONTEXT_BOOL(Texture.CubeMapSeamless), extra_ARB_seamless_cube_map }, + + /* GL_ARB_sync */ + { GL_MAX_SERVER_WAIT_TIMEOUT, + CONTEXT_INT64(Const.MaxServerWaitTimeout), extra_ARB_sync }, + + /* GL_EXT_texture_integer */ + { GL_RGBA_INTEGER_MODE_EXT, BUFFER_BOOL(_IntegerColor), + extra_EXT_texture_integer }, + + /* GL_EXT_transform_feedback */ + { GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, LOC_CUSTOM, TYPE_INT, 0, + extra_EXT_transform_feedback }, + { GL_RASTERIZER_DISCARD, CONTEXT_BOOL(TransformFeedback.RasterDiscard), + extra_EXT_transform_feedback }, + { GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, + CONTEXT_INT(Const.MaxTransformFeedbackInterleavedComponents), + extra_EXT_transform_feedback }, + { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + CONTEXT_INT(Const.MaxTransformFeedbackSeparateAttribs), + extra_EXT_transform_feedback }, + { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, + CONTEXT_INT(Const.MaxTransformFeedbackSeparateComponents), + extra_EXT_transform_feedback }, + + /* GL_ARB_transform_feedback2 */ + { GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, LOC_CUSTOM, TYPE_BOOLEAN, 0, + extra_ARB_transform_feedback2 }, + { GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, LOC_CUSTOM, TYPE_BOOLEAN, 0, + extra_ARB_transform_feedback2 }, + { GL_TRANSFORM_FEEDBACK_BINDING, LOC_CUSTOM, TYPE_INT, 0, + extra_ARB_transform_feedback2 }, + + /* GL_ARB_geometry_shader4 */ + { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB, + CONTEXT_INT(Const.MaxGeometryTextureImageUnits), + extra_ARB_geometry_shader4 }, + { GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB, + CONTEXT_INT(Const.MaxGeometryOutputVertices), + extra_ARB_geometry_shader4 }, + { GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB, + CONTEXT_INT(Const.MaxGeometryTotalOutputComponents), + extra_ARB_geometry_shader4 }, + { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB, + CONTEXT_INT(Const.GeometryProgram.MaxUniformComponents), + extra_ARB_geometry_shader4 }, + { GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB, + CONTEXT_INT(Const.MaxGeometryVaryingComponents), + extra_ARB_geometry_shader4 }, + { GL_MAX_VERTEX_VARYING_COMPONENTS_ARB, + CONTEXT_INT(Const.MaxVertexVaryingComponents), + extra_ARB_geometry_shader4 }, + + /* GL_EXT_gpu_shader4 / GL 3.0 */ + { GL_MIN_PROGRAM_TEXEL_OFFSET, + CONTEXT_INT(Const.MinProgramTexelOffset), + extra_EXT_gpu_shader4 }, + { GL_MAX_PROGRAM_TEXEL_OFFSET, + CONTEXT_INT(Const.MaxProgramTexelOffset), + extra_EXT_gpu_shader4 }, + + /* GL 3.0 */ + { GL_NUM_EXTENSIONS, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 }, + { GL_MAJOR_VERSION, CONTEXT_INT(VersionMajor), extra_version_30 }, + { GL_MINOR_VERSION, CONTEXT_INT(VersionMinor), extra_version_30 }, + { GL_CONTEXT_FLAGS, CONTEXT_INT(Const.ContextFlags), extra_version_30 }, + + /* GL3.0 / GL_EXT_framebuffer_sRGB */ + { GL_FRAMEBUFFER_SRGB_EXT, CONTEXT_BOOL(Color.sRGBEnabled), extra_EXT_framebuffer_sRGB }, + { GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, BUFFER_INT(Visual.sRGBCapable), extra_EXT_framebuffer_sRGB }, + + /* GL 3.1 */ + /* NOTE: different enum values for GL_PRIMITIVE_RESTART_NV + * vs. GL_PRIMITIVE_RESTART! + */ + { GL_PRIMITIVE_RESTART, CONTEXT_BOOL(Array.PrimitiveRestart), + extra_version_31 }, + { GL_PRIMITIVE_RESTART_INDEX, CONTEXT_INT(Array.RestartIndex), + extra_version_31 }, + + + /* GL 3.2 */ + { GL_CONTEXT_PROFILE_MASK, CONTEXT_INT(Const.ProfileMask), + extra_version_32 }, +#endif /* FEATURE_GL */ +}; + +/* All we need now is a way to look up the value struct from the enum. + * The code generated by gcc for the old generated big switch + * statement is a big, balanced, open coded if/else tree, essentially + * an unrolled binary search. It would be natural to sort the new + * enum table and use bsearch(), but we will use a read-only hash + * table instead. bsearch() has a nice guaranteed worst case + * performance, but we're also guaranteed to hit that worst case + * (log2(n) iterations) for about half the enums. Instead, using an + * open addressing hash table, we can find the enum on the first try + * for 80% of the enums, 1 collision for 10% and never more than 5 + * collisions for any enum (typical numbers). And the code is very + * simple, even though it feels a little magic. */ + +static unsigned short table[1024]; +static const int prime_factor = 89, prime_step = 281; + +#ifdef GET_DEBUG +static void +print_table_stats(void) +{ + int i, j, collisions[11], count, hash, mask; + const struct value_desc *d; + + count = 0; + mask = Elements(table) - 1; + memset(collisions, 0, sizeof collisions); + + for (i = 0; i < Elements(table); i++) { + if (!table[i]) + continue; + count++; + d = &values[table[i]]; + hash = (d->pname * prime_factor); + j = 0; + while (1) { + if (values[table[hash & mask]].pname == d->pname) + break; + hash += prime_step; + j++; + } + + if (j < 10) + collisions[j]++; + else + collisions[10]++; + } + + printf("number of enums: %d (total %d)\n", count, Elements(values)); + for (i = 0; i < Elements(collisions) - 1; i++) + if (collisions[i] > 0) + printf(" %d enums with %d %scollisions\n", + collisions[i], i, i == 10 ? "or more " : ""); +} +#endif + +/** + * Initialize the enum hash for a given API + * + * This is called from one_time_init() to insert the enum values that + * are valid for the API in question into the enum hash table. + * + * \param the current context, for determining the API in question + */ +void _mesa_init_get_hash(struct gl_context *ctx) +{ + int i, hash, index, mask; + int api_mask = 0, api_bit; + + mask = Elements(table) - 1; + api_bit = 1 << ctx->API; + + for (i = 0; i < Elements(values); i++) { + if (values[i].type == TYPE_API_MASK) { + api_mask = values[i].offset; + continue; + } + if (!(api_mask & api_bit)) + continue; + + hash = (values[i].pname * prime_factor) & mask; + while (1) { + index = hash & mask; + if (!table[index]) { + table[index] = i; + break; + } + hash += prime_step; + } + } + +#ifdef GET_DEBUG + print_table_stats(); +#endif +} + +/** + * Handle irregular enums + * + * Some values don't conform to the "well-known type at context + * pointer + offset" pattern, so we have this function to catch all + * the corner cases. Typically, it's a computed value or a one-off + * pointer to a custom struct or something. + * + * In this case we can't return a pointer to the value, so we'll have + * to use the temporary variable 'v' declared back in the calling + * glGet*v() function to store the result. + * + * \param ctx the current context + * \param d the struct value_desc that describes the enum + * \param v pointer to the tmp declared in the calling glGet*v() function + */ +static void +find_custom_value(struct gl_context *ctx, const struct value_desc *d, union value *v) +{ + struct gl_buffer_object **buffer_obj; + struct gl_client_array *array; + GLuint unit, *p; + + switch (d->pname) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_RECTANGLE_NV: + v->value_bool = _mesa_IsEnabled(d->pname); + break; + + case GL_LINE_STIPPLE_PATTERN: + /* This is the only GLushort, special case it here by promoting + * to an int rather than introducing a new type. */ + v->value_int = ctx->Line.StipplePattern; + break; + + case GL_CURRENT_RASTER_TEXTURE_COORDS: + unit = ctx->Texture.CurrentUnit; + v->value_float_4[0] = ctx->Current.RasterTexCoords[unit][0]; + v->value_float_4[1] = ctx->Current.RasterTexCoords[unit][1]; + v->value_float_4[2] = ctx->Current.RasterTexCoords[unit][2]; + v->value_float_4[3] = ctx->Current.RasterTexCoords[unit][3]; + break; + + case GL_CURRENT_TEXTURE_COORDS: + unit = ctx->Texture.CurrentUnit; + v->value_float_4[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]; + v->value_float_4[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]; + v->value_float_4[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]; + v->value_float_4[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]; + break; + + case GL_COLOR_WRITEMASK: + v->value_int_4[0] = ctx->Color.ColorMask[0][RCOMP] ? 1 : 0; + v->value_int_4[1] = ctx->Color.ColorMask[0][GCOMP] ? 1 : 0; + v->value_int_4[2] = ctx->Color.ColorMask[0][BCOMP] ? 1 : 0; + v->value_int_4[3] = ctx->Color.ColorMask[0][ACOMP] ? 1 : 0; + break; + + case GL_EDGE_FLAG: + v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0; + break; + + case GL_READ_BUFFER: + v->value_enum = ctx->ReadBuffer->ColorReadBuffer; + break; + + case GL_MAP2_GRID_DOMAIN: + v->value_float_4[0] = ctx->Eval.MapGrid2u1; + v->value_float_4[1] = ctx->Eval.MapGrid2u2; + v->value_float_4[2] = ctx->Eval.MapGrid2v1; + v->value_float_4[3] = ctx->Eval.MapGrid2v2; + break; + + case GL_TEXTURE_STACK_DEPTH: + unit = ctx->Texture.CurrentUnit; + v->value_int = ctx->TextureMatrixStack[unit].Depth + 1; + break; + case GL_TEXTURE_MATRIX: + unit = ctx->Texture.CurrentUnit; + v->value_matrix = ctx->TextureMatrixStack[unit].Top; + break; + + case GL_TEXTURE_COORD_ARRAY: + case GL_TEXTURE_COORD_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + array = &ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture]; + v->value_int = *(GLuint *) ((char *) array + d->offset); + break; + + case GL_ACTIVE_TEXTURE_ARB: + v->value_int = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + v->value_int = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture; + break; + + case GL_MODELVIEW_STACK_DEPTH: + case GL_PROJECTION_STACK_DEPTH: + v->value_int = *(GLint *) ((char *) ctx + d->offset) + 1; + break; + + case GL_MAX_TEXTURE_SIZE: + case GL_MAX_3D_TEXTURE_SIZE: + case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: + p = (GLuint *) ((char *) ctx + d->offset); + v->value_int = 1 << (*p - 1); + break; + + case GL_SCISSOR_BOX: + v->value_int_4[0] = ctx->Scissor.X; + v->value_int_4[1] = ctx->Scissor.Y; + v->value_int_4[2] = ctx->Scissor.Width; + v->value_int_4[3] = ctx->Scissor.Height; + break; + + case GL_LIST_INDEX: + v->value_int = + ctx->ListState.CurrentList ? ctx->ListState.CurrentList->Name : 0; + break; + case GL_LIST_MODE: + if (!ctx->CompileFlag) + v->value_enum = 0; + else if (ctx->ExecuteFlag) + v->value_enum = GL_COMPILE_AND_EXECUTE; + else + v->value_enum = GL_COMPILE; + break; + + case GL_VIEWPORT: + v->value_int_4[0] = ctx->Viewport.X; + v->value_int_4[1] = ctx->Viewport.Y; + v->value_int_4[2] = ctx->Viewport.Width; + v->value_int_4[3] = ctx->Viewport.Height; + break; + + case GL_ACTIVE_STENCIL_FACE_EXT: + v->value_enum = ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT; + break; + + case GL_STENCIL_FAIL: + v->value_enum = ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_FUNC: + v->value_enum = ctx->Stencil.Function[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + v->value_enum = ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_PASS_DEPTH_PASS: + v->value_enum = ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_REF: + v->value_int = ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_VALUE_MASK: + v->value_int = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; + break; + case GL_STENCIL_WRITEMASK: + v->value_int = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; + break; + + case GL_NUM_EXTENSIONS: + v->value_int = _mesa_get_extension_count(ctx); + break; + + case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: + v->value_int = _mesa_get_color_read_type(ctx); + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: + v->value_int = _mesa_get_color_read_format(ctx); + break; + + case GL_CURRENT_MATRIX_STACK_DEPTH_ARB: + v->value_int = ctx->CurrentStack->Depth + 1; + break; + case GL_CURRENT_MATRIX_ARB: + case GL_TRANSPOSE_CURRENT_MATRIX_ARB: + v->value_matrix = ctx->CurrentStack->Top; + break; + + case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: + v->value_int = _mesa_get_compressed_formats(ctx, NULL, GL_FALSE); + break; + case GL_COMPRESSED_TEXTURE_FORMATS_ARB: + v->value_int_n.n = + _mesa_get_compressed_formats(ctx, v->value_int_n.ints, GL_FALSE); + ASSERT(v->value_int_n.n <= 100); + break; + + case GL_MAX_VARYING_FLOATS_ARB: + v->value_int = ctx->Const.MaxVarying * 4; + break; + + /* Various object names */ + + case GL_TEXTURE_BINDING_1D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_1D_ARRAY_EXT: + case GL_TEXTURE_BINDING_2D_ARRAY_EXT: + case GL_TEXTURE_BINDING_CUBE_MAP_ARB: + case GL_TEXTURE_BINDING_RECTANGLE_NV: + unit = ctx->Texture.CurrentUnit; + v->value_int = + ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name; + break; + + /* GL_ARB_vertex_buffer_object */ + case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: + case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: + case GL_COLOR_ARRAY_BUFFER_BINDING_ARB: + case GL_INDEX_ARRAY_BUFFER_BINDING_ARB: + case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB: + case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB: + case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB: + buffer_obj = (struct gl_buffer_object **) + ((char *) ctx->Array.ArrayObj + d->offset); + v->value_int = (*buffer_obj)->Name; + break; + case GL_ARRAY_BUFFER_BINDING_ARB: + v->value_int = ctx->Array.ArrayBufferObj->Name; + break; + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB: + v->value_int = + ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name; + break; + case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: + v->value_int = ctx->Array.ElementArrayBufferObj->Name; + break; + + /* ARB_copy_buffer */ + case GL_COPY_READ_BUFFER: + v->value_int = ctx->CopyReadBuffer->Name; + break; + case GL_COPY_WRITE_BUFFER: + v->value_int = ctx->CopyWriteBuffer->Name; + break; + + case GL_FRAGMENT_PROGRAM_BINDING_NV: + v->value_int = + ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0; + break; + case GL_VERTEX_PROGRAM_BINDING_NV: + v->value_int = + ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0; + break; + case GL_PIXEL_PACK_BUFFER_BINDING_EXT: + v->value_int = ctx->Pack.BufferObj->Name; + break; + case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT: + v->value_int = ctx->Unpack.BufferObj->Name; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + v->value_int = ctx->TransformFeedback.CurrentBuffer->Name; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED: + v->value_int = ctx->TransformFeedback.CurrentObject->Paused; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE: + v->value_int = ctx->TransformFeedback.CurrentObject->Active; + break; + case GL_TRANSFORM_FEEDBACK_BINDING: + v->value_int = ctx->TransformFeedback.CurrentObject->Name; + break; + case GL_CURRENT_PROGRAM: + v->value_int = + ctx->Shader.ActiveProgram ? ctx->Shader.ActiveProgram->Name : 0; + break; + case GL_READ_FRAMEBUFFER_BINDING_EXT: + v->value_int = ctx->ReadBuffer->Name; + break; + case GL_RENDERBUFFER_BINDING_EXT: + v->value_int = + ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0; + break; + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name; + break; + + case GL_MAX_VERTEX_UNIFORM_VECTORS: + v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4; + break; + + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4; + break; + } +} + +/** + * Check extra constraints on a struct value_desc descriptor + * + * If a struct value_desc has a non-NULL extra pointer, it means that + * there are a number of extra constraints to check or actions to + * perform. The extras is just an integer array where each integer + * encode different constraints or actions. + * + * \param ctx current context + * \param func name of calling glGet*v() function for error reporting + * \param d the struct value_desc that has the extra constraints + * + * \return GL_FALSE if one of the constraints was not satisfied, + * otherwise GL_TRUE. + */ +static GLboolean +check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d) +{ + const GLuint version = ctx->VersionMajor * 10 + ctx->VersionMinor; + int total, enabled; + const int *e; + + total = 0; + enabled = 0; + for (e = d->extra; *e != EXTRA_END; e++) + switch (*e) { + case EXTRA_VERSION_30: + if (version >= 30) { + total++; + enabled++; + } + break; + case EXTRA_VERSION_31: + if (version >= 31) { + total++; + enabled++; + } + break; + case EXTRA_VERSION_32: + if (version >= 32) { + total++; + enabled++; + } + break; + case EXTRA_VERSION_ES2: + if (ctx->API == API_OPENGLES2) { + total++; + enabled++; + } + break; + case EXTRA_NEW_BUFFERS: + if (ctx->NewState & _NEW_BUFFERS) + _mesa_update_state(ctx); + break; + case EXTRA_FLUSH_CURRENT: + FLUSH_CURRENT(ctx, 0); + break; + case EXTRA_VALID_DRAW_BUFFER: + if (d->pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(draw buffer %u)", + func, d->pname - GL_DRAW_BUFFER0_ARB); + return GL_FALSE; + } + break; + case EXTRA_VALID_TEXTURE_UNIT: + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture %u)", + func, ctx->Texture.CurrentUnit); + return GL_FALSE; + } + break; + case EXTRA_END: + break; + default: /* *e is a offset into the extension struct */ + total++; + if (*(GLboolean *) ((char *) &ctx->Extensions + *e)) + enabled++; + break; + } + + if (total > 0 && enabled == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func, + _mesa_lookup_enum_by_nr(d->pname)); + return GL_FALSE; + } + + return GL_TRUE; +} + +static const struct value_desc error_value = + { 0, 0, TYPE_INVALID, NO_OFFSET, NO_EXTRA }; + +/** + * Find the struct value_desc corresponding to the enum 'pname'. + * + * We hash the enum value to get an index into the 'table' array, + * which holds the index in the 'values' array of struct value_desc. + * Once we've found the entry, we do the extra checks, if any, then + * look up the value and return a pointer to it. + * + * If the value has to be computed (for example, it's the result of a + * function call or we need to add 1 to it), we use the tmp 'v' to + * store the result. + * + * \param func name of glGet*v() func for error reporting + * \param pname the enum value we're looking up + * \param p is were we return the pointer to the value + * \param v a tmp union value variable in the calling glGet*v() function + * + * \return the struct value_desc corresponding to the enum or a struct + * value_desc of TYPE_INVALID if not found. This lets the calling + * glGet*v() function jump right into a switch statement and + * handle errors there instead of having to check for NULL. + */ +static const struct value_desc * +find_value(const char *func, GLenum pname, void **p, union value *v) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *unit; + int mask, hash; + const struct value_desc *d; + + mask = Elements(table) - 1; + hash = (pname * prime_factor); + while (1) { + d = &values[table[hash & mask]]; + + /* If the enum isn't valid, the hash walk ends with index 0, + * which is the API mask entry at the beginning of values[]. */ + if (unlikely(d->type == TYPE_API_MASK)) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func, + _mesa_lookup_enum_by_nr(pname)); + return &error_value; + } + + if (likely(d->pname == pname)) + break; + + hash += prime_step; + } + + if (unlikely(d->extra && !check_extra(ctx, func, d))) + return &error_value; + + switch (d->location) { + case LOC_BUFFER: + *p = ((char *) ctx->DrawBuffer + d->offset); + return d; + case LOC_CONTEXT: + *p = ((char *) ctx + d->offset); + return d; + case LOC_ARRAY: + *p = ((char *) ctx->Array.ArrayObj + d->offset); + return d; + case LOC_TEXUNIT: + unit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + *p = ((char *) unit + d->offset); + return d; + case LOC_CUSTOM: + find_custom_value(ctx, d, v); + *p = v; + return d; + default: + assert(0); + break; + } + + /* silence warning */ + return &error_value; +} + +static const int transpose[] = { + 0, 4, 8, 12, + 1, 5, 9, 13, + 2, 6, 10, 14, + 3, 7, 11, 15 +}; + +void GLAPIENTRY +_mesa_GetBooleanv(GLenum pname, GLboolean *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetBooleanv", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = INT_TO_BOOLEAN(d->offset); + break; + + case TYPE_FLOAT_4: + case TYPE_FLOATN_4: + params[3] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[3]); + case TYPE_FLOAT_3: + case TYPE_FLOATN_3: + params[2] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[2]); + case TYPE_FLOAT_2: + case TYPE_FLOATN_2: + params[1] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[1]); + case TYPE_FLOAT: + case TYPE_FLOATN: + params[0] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[0]); + break; + + case TYPE_DOUBLEN: + params[0] = FLOAT_TO_BOOLEAN(((GLdouble *) p)[0]); + break; + + case TYPE_INT_4: + params[3] = INT_TO_BOOLEAN(((GLint *) p)[3]); + case TYPE_INT_3: + params[2] = INT_TO_BOOLEAN(((GLint *) p)[2]); + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = INT_TO_BOOLEAN(((GLint *) p)[1]); + case TYPE_INT: + case TYPE_ENUM: + params[0] = INT_TO_BOOLEAN(((GLint *) p)[0]); + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]); + break; + + case TYPE_INT64: + params[0] = INT64_TO_BOOLEAN(((GLint64 *) p)[0]); + break; + + case TYPE_BOOLEAN: + params[0] = ((GLboolean*) p)[0]; + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_BOOLEAN(m->m[i]); + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_BOOLEAN(m->m[transpose[i]]); + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = (*(GLbitfield *) p >> shift) & 1; + break; + } +} + +void GLAPIENTRY +_mesa_GetFloatv(GLenum pname, GLfloat *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetFloatv", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = (GLfloat) d->offset; + break; + + case TYPE_FLOAT_4: + case TYPE_FLOATN_4: + params[3] = ((GLfloat *) p)[3]; + case TYPE_FLOAT_3: + case TYPE_FLOATN_3: + params[2] = ((GLfloat *) p)[2]; + case TYPE_FLOAT_2: + case TYPE_FLOATN_2: + params[1] = ((GLfloat *) p)[1]; + case TYPE_FLOAT: + case TYPE_FLOATN: + params[0] = ((GLfloat *) p)[0]; + break; + + case TYPE_DOUBLEN: + params[0] = ((GLdouble *) p)[0]; + break; + + case TYPE_INT_4: + params[3] = (GLfloat) (((GLint *) p)[3]); + case TYPE_INT_3: + params[2] = (GLfloat) (((GLint *) p)[2]); + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = (GLfloat) (((GLint *) p)[1]); + case TYPE_INT: + case TYPE_ENUM: + params[0] = (GLfloat) (((GLint *) p)[0]); + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = INT_TO_FLOAT(v.value_int_n.ints[i]); + break; + + case TYPE_INT64: + params[0] = ((GLint64 *) p)[0]; + break; + + case TYPE_BOOLEAN: + params[0] = BOOLEAN_TO_FLOAT(*(GLboolean*) p); + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = m->m[i]; + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = m->m[transpose[i]]; + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = BOOLEAN_TO_FLOAT((*(GLbitfield *) p >> shift) & 1); + break; + } +} + +void GLAPIENTRY +_mesa_GetIntegerv(GLenum pname, GLint *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetIntegerv", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = d->offset; + break; + + case TYPE_FLOAT_4: + params[3] = IROUND(((GLfloat *) p)[3]); + case TYPE_FLOAT_3: + params[2] = IROUND(((GLfloat *) p)[2]); + case TYPE_FLOAT_2: + params[1] = IROUND(((GLfloat *) p)[1]); + case TYPE_FLOAT: + params[0] = IROUND(((GLfloat *) p)[0]); + break; + + case TYPE_FLOATN_4: + params[3] = FLOAT_TO_INT(((GLfloat *) p)[3]); + case TYPE_FLOATN_3: + params[2] = FLOAT_TO_INT(((GLfloat *) p)[2]); + case TYPE_FLOATN_2: + params[1] = FLOAT_TO_INT(((GLfloat *) p)[1]); + case TYPE_FLOATN: + params[0] = FLOAT_TO_INT(((GLfloat *) p)[0]); + break; + + case TYPE_DOUBLEN: + params[0] = FLOAT_TO_INT(((GLdouble *) p)[0]); + break; + + case TYPE_INT_4: + params[3] = ((GLint *) p)[3]; + case TYPE_INT_3: + params[2] = ((GLint *) p)[2]; + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = ((GLint *) p)[1]; + case TYPE_INT: + case TYPE_ENUM: + params[0] = ((GLint *) p)[0]; + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = v.value_int_n.ints[i]; + break; + + case TYPE_INT64: + params[0] = INT64_TO_INT(((GLint64 *) p)[0]); + break; + + case TYPE_BOOLEAN: + params[0] = BOOLEAN_TO_INT(*(GLboolean*) p); + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_INT(m->m[i]); + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_INT(m->m[transpose[i]]); + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = (*(GLbitfield *) p >> shift) & 1; + break; + } +} + +#if FEATURE_ARB_sync +void GLAPIENTRY +_mesa_GetInteger64v(GLenum pname, GLint64 *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetInteger64v", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = d->offset; + break; + + case TYPE_FLOAT_4: + params[3] = IROUND64(((GLfloat *) p)[3]); + case TYPE_FLOAT_3: + params[2] = IROUND64(((GLfloat *) p)[2]); + case TYPE_FLOAT_2: + params[1] = IROUND64(((GLfloat *) p)[1]); + case TYPE_FLOAT: + params[0] = IROUND64(((GLfloat *) p)[0]); + break; + + case TYPE_FLOATN_4: + params[3] = FLOAT_TO_INT64(((GLfloat *) p)[3]); + case TYPE_FLOATN_3: + params[2] = FLOAT_TO_INT64(((GLfloat *) p)[2]); + case TYPE_FLOATN_2: + params[1] = FLOAT_TO_INT64(((GLfloat *) p)[1]); + case TYPE_FLOATN: + params[0] = FLOAT_TO_INT64(((GLfloat *) p)[0]); + break; + + case TYPE_DOUBLEN: + params[0] = FLOAT_TO_INT64(((GLdouble *) p)[0]); + break; + + case TYPE_INT_4: + params[3] = ((GLint *) p)[3]; + case TYPE_INT_3: + params[2] = ((GLint *) p)[2]; + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = ((GLint *) p)[1]; + case TYPE_INT: + case TYPE_ENUM: + params[0] = ((GLint *) p)[0]; + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]); + break; + + case TYPE_INT64: + params[0] = ((GLint64 *) p)[0]; + break; + + case TYPE_BOOLEAN: + params[0] = ((GLboolean*) p)[0]; + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_INT64(m->m[i]); + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_INT64(m->m[transpose[i]]); + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = (*(GLbitfield *) p >> shift) & 1; + break; + } +} +#endif /* FEATURE_ARB_sync */ + +void GLAPIENTRY +_mesa_GetDoublev(GLenum pname, GLdouble *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetDoublev", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = d->offset; + break; + + case TYPE_FLOAT_4: + case TYPE_FLOATN_4: + params[3] = ((GLfloat *) p)[3]; + case TYPE_FLOAT_3: + case TYPE_FLOATN_3: + params[2] = ((GLfloat *) p)[2]; + case TYPE_FLOAT_2: + case TYPE_FLOATN_2: + params[1] = ((GLfloat *) p)[1]; + case TYPE_FLOAT: + case TYPE_FLOATN: + params[0] = ((GLfloat *) p)[0]; + break; + + case TYPE_DOUBLEN: + params[0] = ((GLdouble *) p)[0]; + break; + + case TYPE_INT_4: + params[3] = ((GLint *) p)[3]; + case TYPE_INT_3: + params[2] = ((GLint *) p)[2]; + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = ((GLint *) p)[1]; + case TYPE_INT: + case TYPE_ENUM: + params[0] = ((GLint *) p)[0]; + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = v.value_int_n.ints[i]; + break; + + case TYPE_INT64: + params[0] = ((GLint64 *) p)[0]; + break; + + case TYPE_BOOLEAN: + params[0] = *(GLboolean*) p; + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = m->m[i]; + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = m->m[transpose[i]]; + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = (*(GLbitfield *) p >> shift) & 1; + break; + } +} + +static enum value_type +find_value_indexed(const char *func, GLenum pname, int index, union value *v) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (pname) { + + case GL_BLEND: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.EXT_draw_buffers2) + goto invalid_enum; + v->value_int = (ctx->Color.BlendEnabled >> index) & 1; + return TYPE_INT; + + case GL_BLEND_SRC: + /* fall-through */ + case GL_BLEND_SRC_RGB: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].SrcRGB; + return TYPE_INT; + case GL_BLEND_SRC_ALPHA: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].SrcA; + return TYPE_INT; + case GL_BLEND_DST: + /* fall-through */ + case GL_BLEND_DST_RGB: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].DstRGB; + return TYPE_INT; + case GL_BLEND_DST_ALPHA: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].DstA; + return TYPE_INT; + case GL_BLEND_EQUATION_RGB: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].EquationRGB; + return TYPE_INT; + case GL_BLEND_EQUATION_ALPHA: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.ARB_draw_buffers_blend) + goto invalid_enum; + v->value_int = ctx->Color.Blend[index].EquationA; + return TYPE_INT; + + case GL_COLOR_WRITEMASK: + if (index >= ctx->Const.MaxDrawBuffers) + goto invalid_value; + if (!ctx->Extensions.EXT_draw_buffers2) + goto invalid_enum; + v->value_int_4[0] = ctx->Color.ColorMask[index][RCOMP] ? 1 : 0; + v->value_int_4[1] = ctx->Color.ColorMask[index][GCOMP] ? 1 : 0; + v->value_int_4[2] = ctx->Color.ColorMask[index][BCOMP] ? 1 : 0; + v->value_int_4[3] = ctx->Color.ColorMask[index][ACOMP] ? 1 : 0; + return TYPE_INT_4; + + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) + goto invalid_value; + if (!ctx->Extensions.EXT_transform_feedback) + goto invalid_enum; + v->value_int64 = ctx->TransformFeedback.CurrentObject->Offset[index]; + return TYPE_INT64; + + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) + goto invalid_value; + if (!ctx->Extensions.EXT_transform_feedback) + goto invalid_enum; + v->value_int64 = ctx->TransformFeedback.CurrentObject->Size[index]; + return TYPE_INT64; + + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) + goto invalid_value; + if (!ctx->Extensions.EXT_transform_feedback) + goto invalid_enum; + v->value_int = ctx->TransformFeedback.CurrentObject->Buffers[index]->Name; + return TYPE_INT; + } + + invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func, + _mesa_lookup_enum_by_nr(pname)); + return TYPE_INVALID; + invalid_value: + _mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=%s)", func, + _mesa_lookup_enum_by_nr(pname)); + return TYPE_INVALID; +} + +void GLAPIENTRY +_mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params ) +{ + union value v; + enum value_type type = + find_value_indexed("glGetBooleanIndexedv", pname, index, &v); + + switch (type) { + case TYPE_INT: + params[0] = INT_TO_BOOLEAN(v.value_int); + break; + case TYPE_INT_4: + params[0] = INT_TO_BOOLEAN(v.value_int_4[0]); + params[1] = INT_TO_BOOLEAN(v.value_int_4[1]); + params[2] = INT_TO_BOOLEAN(v.value_int_4[2]); + params[3] = INT_TO_BOOLEAN(v.value_int_4[3]); + break; + case TYPE_INT64: + params[0] = INT64_TO_BOOLEAN(v.value_int); + break; + default: + ; /* nothing - GL error was recorded */ + } +} + +void GLAPIENTRY +_mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params ) +{ + union value v; + enum value_type type = + find_value_indexed("glGetIntegerIndexedv", pname, index, &v); + + switch (type) { + case TYPE_INT: + params[0] = v.value_int; + break; + case TYPE_INT_4: + params[0] = v.value_int_4[0]; + params[1] = v.value_int_4[1]; + params[2] = v.value_int_4[2]; + params[3] = v.value_int_4[3]; + break; + case TYPE_INT64: + params[0] = INT64_TO_INT(v.value_int); + break; + default: + ; /* nothing - GL error was recorded */ + } +} + +#if FEATURE_ARB_sync +void GLAPIENTRY +_mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params ) +{ + union value v; + enum value_type type = + find_value_indexed("glGetIntegerIndexedv", pname, index, &v); + + switch (type) { + case TYPE_INT: + params[0] = v.value_int; + break; + case TYPE_INT_4: + params[0] = v.value_int_4[0]; + params[1] = v.value_int_4[1]; + params[2] = v.value_int_4[2]; + params[3] = v.value_int_4[3]; + break; + case TYPE_INT64: + params[0] = v.value_int; + break; + default: + ; /* nothing - GL error was recorded */ + } +} +#endif /* FEATURE_ARB_sync */ + +#if FEATURE_ES1 +void GLAPIENTRY +_mesa_GetFixedv(GLenum pname, GLfixed *params) +{ + const struct value_desc *d; + union value v; + GLmatrix *m; + int shift, i; + void *p; + + d = find_value("glGetDoublev", pname, &p, &v); + switch (d->type) { + case TYPE_INVALID: + break; + case TYPE_CONST: + params[0] = INT_TO_FIXED(d->offset); + break; + + case TYPE_FLOAT_4: + case TYPE_FLOATN_4: + params[3] = FLOAT_TO_FIXED(((GLfloat *) p)[3]); + case TYPE_FLOAT_3: + case TYPE_FLOATN_3: + params[2] = FLOAT_TO_FIXED(((GLfloat *) p)[2]); + case TYPE_FLOAT_2: + case TYPE_FLOATN_2: + params[1] = FLOAT_TO_FIXED(((GLfloat *) p)[1]); + case TYPE_FLOAT: + case TYPE_FLOATN: + params[0] = FLOAT_TO_FIXED(((GLfloat *) p)[0]); + break; + + case TYPE_DOUBLEN: + params[0] = FLOAT_TO_FIXED(((GLdouble *) p)[0]); + break; + + case TYPE_INT_4: + params[3] = INT_TO_FIXED(((GLint *) p)[3]); + case TYPE_INT_3: + params[2] = INT_TO_FIXED(((GLint *) p)[2]); + case TYPE_INT_2: + case TYPE_ENUM_2: + params[1] = INT_TO_FIXED(((GLint *) p)[1]); + case TYPE_INT: + case TYPE_ENUM: + params[0] = INT_TO_FIXED(((GLint *) p)[0]); + break; + + case TYPE_INT_N: + for (i = 0; i < v.value_int_n.n; i++) + params[i] = INT_TO_FIXED(v.value_int_n.ints[i]); + break; + + case TYPE_INT64: + params[0] = ((GLint64 *) p)[0]; + break; + + case TYPE_BOOLEAN: + params[0] = BOOLEAN_TO_FIXED(((GLboolean*) p)[0]); + break; + + case TYPE_MATRIX: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_FIXED(m->m[i]); + break; + + case TYPE_MATRIX_T: + m = *(GLmatrix **) p; + for (i = 0; i < 16; i++) + params[i] = FLOAT_TO_FIXED(m->m[transpose[i]]); + break; + + case TYPE_BIT_0: + case TYPE_BIT_1: + case TYPE_BIT_2: + case TYPE_BIT_3: + case TYPE_BIT_4: + case TYPE_BIT_5: + shift = d->type - TYPE_BIT_0; + params[0] = BOOLEAN_TO_FIXED((*(GLbitfield *) p >> shift) & 1); + break; + } +} +#endif diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 831774fa4..39577bb02 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -3022,11 +3022,6 @@ struct gl_matrix_stack _NEW_POINT | \ _NEW_PROGRAM | \ _NEW_MODELVIEW) - -#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ - _NEW_TEXTURE) - -#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL) /*@}*/ diff --git a/mesalib/src/mesa/main/pixel.c b/mesalib/src/mesa/main/pixel.c index 195fa234b..da99c9b6f 100644 --- a/mesalib/src/mesa/main/pixel.c +++ b/mesalib/src/mesa/main/pixel.c @@ -617,7 +617,7 @@ update_image_transfer_state(struct gl_context *ctx) */ void _mesa_update_pixel( struct gl_context *ctx, GLuint new_state ) { - if (new_state & _MESA_NEW_TRANSFER_STATE) + if (new_state & _NEW_PIXEL) update_image_transfer_state(ctx); } diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index f50f2af1e..118ed1d28 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -1,734 +1,734 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * \file state.c
- * State management.
- *
- * This file manages recalculation of derived values in struct gl_context.
- */
-
-
-#include "glheader.h"
-#include "mtypes.h"
-#include "context.h"
-#include "debug.h"
-#include "macros.h"
-#include "ffvertex_prog.h"
-#include "framebuffer.h"
-#include "light.h"
-#include "matrix.h"
-#include "pixel.h"
-#include "program/program.h"
-#include "program/prog_parameter.h"
-#include "state.h"
-#include "stencil.h"
-#include "texenvprogram.h"
-#include "texobj.h"
-#include "texstate.h"
-
-
-static void
-update_separate_specular(struct gl_context *ctx)
-{
- if (_mesa_need_secondary_color(ctx))
- ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
- else
- ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR;
-}
-
-
-/**
- * Compute the index of the last array element that can be safely accessed
- * in a vertex array. We can really only do this when the array lives in
- * a VBO.
- * The array->_MaxElement field will be updated.
- * Later in glDrawArrays/Elements/etc we can do some bounds checking.
- */
-static void
-compute_max_element(struct gl_client_array *array)
-{
- assert(array->Enabled);
- if (array->BufferObj->Name) {
- GLsizeiptrARB offset = (GLsizeiptrARB) array->Ptr;
- GLsizeiptrARB obj_size = (GLsizeiptrARB) array->BufferObj->Size;
-
- if (offset < obj_size) {
- array->_MaxElement = (obj_size - offset +
- array->StrideB -
- array->_ElementSize) / array->StrideB;
- } else {
- array->_MaxElement = 0;
- }
- }
- else {
- /* user-space array, no idea how big it is */
- array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
- }
-}
-
-
-/**
- * Helper for update_arrays().
- * \return min(current min, array->_MaxElement).
- */
-static GLuint
-update_min(GLuint min, struct gl_client_array *array)
-{
- compute_max_element(array);
- return MIN2(min, array->_MaxElement);
-}
-
-
-/**
- * Update ctx->Array._MaxElement (the max legal index into all enabled arrays).
- * Need to do this upon new array state or new buffer object state.
- */
-static void
-update_arrays( struct gl_context *ctx )
-{
- struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
- GLuint i, min = ~0;
-
- /* find min of _MaxElement values for all enabled arrays */
-
- /* 0 */
- if (ctx->VertexProgram._Current
- && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
- }
- else if (arrayObj->Vertex.Enabled) {
- min = update_min(min, &arrayObj->Vertex);
- }
-
- /* 1 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]);
- }
- /* no conventional vertex weight array */
-
- /* 2 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
- }
- else if (arrayObj->Normal.Enabled) {
- min = update_min(min, &arrayObj->Normal);
- }
-
- /* 3 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
- }
- else if (arrayObj->Color.Enabled) {
- min = update_min(min, &arrayObj->Color);
- }
-
- /* 4 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]);
- }
- else if (arrayObj->SecondaryColor.Enabled) {
- min = update_min(min, &arrayObj->SecondaryColor);
- }
-
- /* 5 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]);
- }
- else if (arrayObj->FogCoord.Enabled) {
- min = update_min(min, &arrayObj->FogCoord);
- }
-
- /* 6 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]);
- }
- else if (arrayObj->Index.Enabled) {
- min = update_min(min, &arrayObj->Index);
- }
-
- /* 7 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]);
- }
-
- /* 8..15 */
- for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) {
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[i].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[i]);
- }
- else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits
- && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) {
- min = update_min(min, &arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]);
- }
- }
-
- /* 16..31 */
- if (ctx->VertexProgram._Current) {
- for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) {
- if (arrayObj->VertexAttrib[i].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[i]);
- }
- }
- }
-
- if (arrayObj->EdgeFlag.Enabled) {
- min = update_min(min, &arrayObj->EdgeFlag);
- }
-
- /* _MaxElement is one past the last legal array element */
- arrayObj->_MaxElement = min;
-}
-
-
-/**
- * Update the following fields:
- * ctx->VertexProgram._Enabled
- * ctx->FragmentProgram._Enabled
- * ctx->ATIFragmentShader._Enabled
- * This needs to be done before texture state validation.
- */
-static void
-update_program_enables(struct gl_context *ctx)
-{
- /* These _Enabled flags indicate if the program is enabled AND valid. */
- ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
- && ctx->VertexProgram.Current->Base.Instructions;
- ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
- && ctx->FragmentProgram.Current->Base.Instructions;
- ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
- && ctx->ATIFragmentShader.Current->Instructions[0];
-}
-
-
-/**
- * Update vertex/fragment program state. In particular, update these fields:
- * ctx->VertexProgram._Current
- * ctx->VertexProgram._TnlProgram,
- * These point to the highest priority enabled vertex/fragment program or are
- * NULL if fixed-function processing is to be done.
- *
- * This function needs to be called after texture state validation in case
- * we're generating a fragment program from fixed-function texture state.
- *
- * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
- * or fragment program is being used.
- */
-static GLbitfield
-update_program(struct gl_context *ctx)
-{
- const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
- const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram;
- const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
- const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
- const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
- const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
- GLbitfield new_state = 0x0;
-
- /*
- * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
- * pointers to the programs that should be used for rendering. If either
- * is NULL, use fixed-function code paths.
- *
- * These programs may come from several sources. The priority is as
- * follows:
- * 1. OpenGL 2.0/ARB vertex/fragment shaders
- * 2. ARB/NV vertex/fragment programs
- * 3. Programs derived from fixed-function state.
- *
- * Note: it's possible for a vertex shader to get used with a fragment
- * program (and vice versa) here, but in practice that shouldn't ever
- * come up, or matter.
- */
-
- if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) {
- /* Use shader programs */
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
- fsProg->FragmentProgram);
- }
- else if (ctx->FragmentProgram._Enabled) {
- /* use user-defined vertex program */
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
- ctx->FragmentProgram.Current);
- }
- else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
- /* Use fragment program generated from fixed-function state.
- */
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
- _mesa_get_fixed_func_fragment_program(ctx));
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
- ctx->FragmentProgram._Current);
- }
- else {
- /* no fragment program */
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
- }
-
- if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) {
- /* Use shader programs */
- _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
- gsProg->GeometryProgram);
- } else {
- /* no fragment program */
- _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
- }
-
- /* Examine vertex program after fragment program as
- * _mesa_get_fixed_func_vertex_program() needs to know active
- * fragprog inputs.
- */
- if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) {
- /* Use shader programs */
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- vsProg->VertexProgram);
- }
- else if (ctx->VertexProgram._Enabled) {
- /* use user-defined vertex program */
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- ctx->VertexProgram.Current);
- }
- else if (ctx->VertexProgram._MaintainTnlProgram) {
- /* Use vertex program generated from fixed-function state.
- */
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- _mesa_get_fixed_func_vertex_program(ctx));
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
- ctx->VertexProgram._Current);
- }
- else {
- /* no vertex program */
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
- }
-
- /* Let the driver know what's happening:
- */
- if (ctx->FragmentProgram._Current != prevFP) {
- new_state |= _NEW_PROGRAM;
- if (ctx->Driver.BindProgram) {
- ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
- (struct gl_program *) ctx->FragmentProgram._Current);
- }
- }
-
- if (ctx->GeometryProgram._Current != prevGP) {
- new_state |= _NEW_PROGRAM;
- if (ctx->Driver.BindProgram) {
- ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
- (struct gl_program *) ctx->GeometryProgram._Current);
- }
- }
-
- if (ctx->VertexProgram._Current != prevVP) {
- new_state |= _NEW_PROGRAM;
- if (ctx->Driver.BindProgram) {
- ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
- (struct gl_program *) ctx->VertexProgram._Current);
- }
- }
-
- return new_state;
-}
-
-
-/**
- * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
- */
-static GLbitfield
-update_program_constants(struct gl_context *ctx)
-{
- GLbitfield new_state = 0x0;
-
- if (ctx->FragmentProgram._Current) {
- const struct gl_program_parameter_list *params =
- ctx->FragmentProgram._Current->Base.Parameters;
- if (params && params->StateFlags & ctx->NewState) {
- new_state |= _NEW_PROGRAM_CONSTANTS;
- }
- }
-
- if (ctx->GeometryProgram._Current) {
- const struct gl_program_parameter_list *params =
- ctx->GeometryProgram._Current->Base.Parameters;
- /*FIXME: StateFlags is always 0 because we have unnamed constant
- * not state changes */
- if (params /*&& params->StateFlags & ctx->NewState*/) {
- new_state |= _NEW_PROGRAM_CONSTANTS;
- }
- }
-
- if (ctx->VertexProgram._Current) {
- const struct gl_program_parameter_list *params =
- ctx->VertexProgram._Current->Base.Parameters;
- if (params && params->StateFlags & ctx->NewState) {
- new_state |= _NEW_PROGRAM_CONSTANTS;
- }
- }
-
- return new_state;
-}
-
-
-
-
-static void
-update_viewport_matrix(struct gl_context *ctx)
-{
- const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
-
- ASSERT(depthMax > 0);
-
- /* Compute scale and bias values. This is really driver-specific
- * and should be maintained elsewhere if at all.
- * NOTE: RasterPos uses this.
- */
- _math_matrix_viewport(&ctx->Viewport._WindowMap,
- ctx->Viewport.X, ctx->Viewport.Y,
- ctx->Viewport.Width, ctx->Viewport.Height,
- ctx->Viewport.Near, ctx->Viewport.Far,
- depthMax);
-}
-
-
-/**
- * Update derived multisample state.
- */
-static void
-update_multisample(struct gl_context *ctx)
-{
- ctx->Multisample._Enabled = GL_FALSE;
- if (ctx->Multisample.Enabled &&
- ctx->DrawBuffer &&
- ctx->DrawBuffer->Visual.sampleBuffers)
- ctx->Multisample._Enabled = GL_TRUE;
-}
-
-
-/**
- * Update derived color/blend/logicop state.
- */
-static void
-update_color(struct gl_context *ctx)
-{
- /* This is needed to support 1.1's RGB logic ops AND
- * 1.0's blending logicops.
- */
- ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx);
-}
-
-
-/*
- * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
- * in ctx->_TriangleCaps if needed.
- */
-static void
-update_polygon(struct gl_context *ctx)
-{
- ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET);
-
- if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
- ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
-
- if ( ctx->Polygon.OffsetPoint
- || ctx->Polygon.OffsetLine
- || ctx->Polygon.OffsetFill)
- ctx->_TriangleCaps |= DD_TRI_OFFSET;
-}
-
-
-/**
- * Update the ctx->_TriangleCaps bitfield.
- * XXX that bitfield should really go away someday!
- * This function must be called after other update_*() functions since
- * there are dependencies on some other derived values.
- */
-#if 0
-static void
-update_tricaps(struct gl_context *ctx, GLbitfield new_state)
-{
- ctx->_TriangleCaps = 0;
-
- /*
- * Points
- */
- if (1/*new_state & _NEW_POINT*/) {
- if (ctx->Point.SmoothFlag)
- ctx->_TriangleCaps |= DD_POINT_SMOOTH;
- if (ctx->Point._Attenuated)
- ctx->_TriangleCaps |= DD_POINT_ATTEN;
- }
-
- /*
- * Lines
- */
- if (1/*new_state & _NEW_LINE*/) {
- if (ctx->Line.SmoothFlag)
- ctx->_TriangleCaps |= DD_LINE_SMOOTH;
- if (ctx->Line.StippleFlag)
- ctx->_TriangleCaps |= DD_LINE_STIPPLE;
- }
-
- /*
- * Polygons
- */
- if (1/*new_state & _NEW_POLYGON*/) {
- if (ctx->Polygon.SmoothFlag)
- ctx->_TriangleCaps |= DD_TRI_SMOOTH;
- if (ctx->Polygon.StippleFlag)
- ctx->_TriangleCaps |= DD_TRI_STIPPLE;
- if (ctx->Polygon.FrontMode != GL_FILL
- || ctx->Polygon.BackMode != GL_FILL)
- ctx->_TriangleCaps |= DD_TRI_UNFILLED;
- if (ctx->Polygon.CullFlag
- && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
- ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
- if (ctx->Polygon.OffsetPoint ||
- ctx->Polygon.OffsetLine ||
- ctx->Polygon.OffsetFill)
- ctx->_TriangleCaps |= DD_TRI_OFFSET;
- }
-
- /*
- * Lighting and shading
- */
- if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
- ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
- if (ctx->Light.ShadeModel == GL_FLAT)
- ctx->_TriangleCaps |= DD_FLATSHADE;
- if (_mesa_need_secondary_color(ctx))
- ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
-
- /*
- * Stencil
- */
- if (ctx->Stencil._TestTwoSide)
- ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
-}
-#endif
-
-
-/**
- * Compute derived GL state.
- * If __struct gl_contextRec::NewState is non-zero then this function \b must
- * be called before rendering anything.
- *
- * Calls dd_function_table::UpdateState to perform any internal state
- * management necessary.
- *
- * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
- * _mesa_update_buffer_bounds(),
- * _mesa_update_lighting() and _mesa_update_tnl_spaces().
- */
-void
-_mesa_update_state_locked( struct gl_context *ctx )
-{
- GLbitfield new_state = ctx->NewState;
- GLbitfield prog_flags = _NEW_PROGRAM;
- GLbitfield new_prog_state = 0x0;
-
- if (new_state == _NEW_CURRENT_ATTRIB)
- goto out;
-
- if (MESA_VERBOSE & VERBOSE_STATE)
- _mesa_print_state("_mesa_update_state", new_state);
-
- /* Determine which state flags effect vertex/fragment program state */
- if (ctx->FragmentProgram._MaintainTexEnvProgram) {
- prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
- _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
- _NEW_PROGRAM);
- }
- if (ctx->VertexProgram._MaintainTnlProgram) {
- prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
- _NEW_TRANSFORM | _NEW_POINT |
- _NEW_FOG | _NEW_LIGHT |
- _MESA_NEW_NEED_EYE_COORDS);
- }
-
- /*
- * Now update derived state info
- */
-
- if (new_state & prog_flags)
- update_program_enables( ctx );
-
- if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
- _mesa_update_modelview_project( ctx, new_state );
-
- if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
- _mesa_update_texture( ctx, new_state );
-
- if (new_state & _NEW_BUFFERS)
- _mesa_update_framebuffer(ctx);
-
- if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
- _mesa_update_draw_buffer_bounds( ctx );
-
- if (new_state & _NEW_POLYGON)
- update_polygon( ctx );
-
- if (new_state & _NEW_LIGHT)
- _mesa_update_lighting( ctx );
-
- if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
- _mesa_update_stencil( ctx );
-
- if (new_state & _MESA_NEW_TRANSFER_STATE)
- _mesa_update_pixel( ctx, new_state );
-
- if (new_state & _DD_NEW_SEPARATE_SPECULAR)
- update_separate_specular( ctx );
-
- if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
- update_viewport_matrix(ctx);
-
- if (new_state & _NEW_MULTISAMPLE)
- update_multisample( ctx );
-
- if (new_state & _NEW_COLOR)
- update_color( ctx );
-
-#if 0
- if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
- | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
- update_tricaps( ctx, new_state );
-#endif
-
- /* ctx->_NeedEyeCoords is now up to date.
- *
- * If the truth value of this variable has changed, update for the
- * new lighting space and recompute the positions of lights and the
- * normal transform.
- *
- * If the lighting space hasn't changed, may still need to recompute
- * light positions & normal transforms for other reasons.
- */
- if (new_state & _MESA_NEW_NEED_EYE_COORDS)
- _mesa_update_tnl_spaces( ctx, new_state );
-
- if (new_state & prog_flags) {
- /* When we generate programs from fixed-function vertex/fragment state
- * this call may generate/bind a new program. If so, we need to
- * propogate the _NEW_PROGRAM flag to the driver.
- */
- new_prog_state |= update_program( ctx );
- }
-
- if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT))
- update_arrays( ctx );
-
- out:
- new_prog_state |= update_program_constants(ctx);
-
- /*
- * Give the driver a chance to act upon the new_state flags.
- * The driver might plug in different span functions, for example.
- * Also, this is where the driver can invalidate the state of any
- * active modules (such as swrast_setup, swrast, tnl, etc).
- *
- * Set ctx->NewState to zero to avoid recursion if
- * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?)
- */
- new_state = ctx->NewState | new_prog_state;
- ctx->NewState = 0;
- ctx->Driver.UpdateState(ctx, new_state);
- ctx->Array.NewState = 0;
- if (!ctx->Array.RebindArrays)
- ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0;
-}
-
-
-/* This is the usual entrypoint for state updates:
- */
-void
-_mesa_update_state( struct gl_context *ctx )
-{
- _mesa_lock_context_textures(ctx);
- _mesa_update_state_locked(ctx);
- _mesa_unlock_context_textures(ctx);
-}
-
-
-
-
-/**
- * Want to figure out which fragment program inputs are actually
- * constant/current values from ctx->Current. These should be
- * referenced as a tracked state variable rather than a fragment
- * program input, to save the overhead of putting a constant value in
- * every submitted vertex, transferring it to hardware, interpolating
- * it across the triangle, etc...
- *
- * When there is a VP bound, just use vp->outputs. But when we're
- * generating vp from fixed function state, basically want to
- * calculate:
- *
- * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
- * potential_vp_outputs )
- *
- * Where potential_vp_outputs is calculated by looking at enabled
- * texgen, etc.
- *
- * The generated fragment program should then only declare inputs that
- * may vary or otherwise differ from the ctx->Current values.
- * Otherwise, the fp should track them as state values instead.
- */
-void
-_mesa_set_varying_vp_inputs( struct gl_context *ctx,
- GLbitfield varying_inputs )
-{
- if (ctx->varying_vp_inputs != varying_inputs) {
- ctx->varying_vp_inputs = varying_inputs;
- ctx->NewState |= _NEW_ARRAY;
- /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/
- }
-}
-
-
-/**
- * Used by drivers to tell core Mesa that the driver is going to
- * install/ use its own vertex program. In particular, this will
- * prevent generated fragment programs from using state vars instead
- * of ordinary varyings/inputs.
- */
-void
-_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
-{
- if (ctx->VertexProgram._Overriden != flag) {
- ctx->VertexProgram._Overriden = flag;
-
- /* Set one of the bits which will trigger fragment program
- * regeneration:
- */
- ctx->NewState |= _NEW_PROGRAM;
- }
-}
+/* + * Mesa 3-D graphics library + * Version: 7.3 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \file state.c + * State management. + * + * This file manages recalculation of derived values in struct gl_context. + */ + + +#include "glheader.h" +#include "mtypes.h" +#include "context.h" +#include "debug.h" +#include "macros.h" +#include "ffvertex_prog.h" +#include "framebuffer.h" +#include "light.h" +#include "matrix.h" +#include "pixel.h" +#include "program/program.h" +#include "program/prog_parameter.h" +#include "state.h" +#include "stencil.h" +#include "texenvprogram.h" +#include "texobj.h" +#include "texstate.h" + + +static void +update_separate_specular(struct gl_context *ctx) +{ + if (_mesa_need_secondary_color(ctx)) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; +} + + +/** + * Compute the index of the last array element that can be safely accessed + * in a vertex array. We can really only do this when the array lives in + * a VBO. + * The array->_MaxElement field will be updated. + * Later in glDrawArrays/Elements/etc we can do some bounds checking. + */ +static void +compute_max_element(struct gl_client_array *array) +{ + assert(array->Enabled); + if (array->BufferObj->Name) { + GLsizeiptrARB offset = (GLsizeiptrARB) array->Ptr; + GLsizeiptrARB obj_size = (GLsizeiptrARB) array->BufferObj->Size; + + if (offset < obj_size) { + array->_MaxElement = (obj_size - offset + + array->StrideB - + array->_ElementSize) / array->StrideB; + } else { + array->_MaxElement = 0; + } + } + else { + /* user-space array, no idea how big it is */ + array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ + } +} + + +/** + * Helper for update_arrays(). + * \return min(current min, array->_MaxElement). + */ +static GLuint +update_min(GLuint min, struct gl_client_array *array) +{ + compute_max_element(array); + return MIN2(min, array->_MaxElement); +} + + +/** + * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). + * Need to do this upon new array state or new buffer object state. + */ +static void +update_arrays( struct gl_context *ctx ) +{ + struct gl_array_object *arrayObj = ctx->Array.ArrayObj; + GLuint i, min = ~0; + + /* find min of _MaxElement values for all enabled arrays */ + + /* 0 */ + if (ctx->VertexProgram._Current + && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); + } + else if (arrayObj->Vertex.Enabled) { + min = update_min(min, &arrayObj->Vertex); + } + + /* 1 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]); + } + /* no conventional vertex weight array */ + + /* 2 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); + } + else if (arrayObj->Normal.Enabled) { + min = update_min(min, &arrayObj->Normal); + } + + /* 3 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); + } + else if (arrayObj->Color.Enabled) { + min = update_min(min, &arrayObj->Color); + } + + /* 4 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); + } + else if (arrayObj->SecondaryColor.Enabled) { + min = update_min(min, &arrayObj->SecondaryColor); + } + + /* 5 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); + } + else if (arrayObj->FogCoord.Enabled) { + min = update_min(min, &arrayObj->FogCoord); + } + + /* 6 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); + } + else if (arrayObj->Index.Enabled) { + min = update_min(min, &arrayObj->Index); + } + + /* 7 */ + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); + } + + /* 8..15 */ + for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { + if (ctx->VertexProgram._Enabled + && arrayObj->VertexAttrib[i].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[i]); + } + else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits + && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { + min = update_min(min, &arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]); + } + } + + /* 16..31 */ + if (ctx->VertexProgram._Current) { + for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) { + if (arrayObj->VertexAttrib[i].Enabled) { + min = update_min(min, &arrayObj->VertexAttrib[i]); + } + } + } + + if (arrayObj->EdgeFlag.Enabled) { + min = update_min(min, &arrayObj->EdgeFlag); + } + + /* _MaxElement is one past the last legal array element */ + arrayObj->_MaxElement = min; +} + + +/** + * Update the following fields: + * ctx->VertexProgram._Enabled + * ctx->FragmentProgram._Enabled + * ctx->ATIFragmentShader._Enabled + * This needs to be done before texture state validation. + */ +static void +update_program_enables(struct gl_context *ctx) +{ + /* These _Enabled flags indicate if the program is enabled AND valid. */ + ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled + && ctx->VertexProgram.Current->Base.Instructions; + ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled + && ctx->FragmentProgram.Current->Base.Instructions; + ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled + && ctx->ATIFragmentShader.Current->Instructions[0]; +} + + +/** + * Update vertex/fragment program state. In particular, update these fields: + * ctx->VertexProgram._Current + * ctx->VertexProgram._TnlProgram, + * These point to the highest priority enabled vertex/fragment program or are + * NULL if fixed-function processing is to be done. + * + * This function needs to be called after texture state validation in case + * we're generating a fragment program from fixed-function texture state. + * + * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex + * or fragment program is being used. + */ +static GLbitfield +update_program(struct gl_context *ctx) +{ + const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram; + const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram; + const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; + const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; + const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; + const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; + GLbitfield new_state = 0x0; + + /* + * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current + * pointers to the programs that should be used for rendering. If either + * is NULL, use fixed-function code paths. + * + * These programs may come from several sources. The priority is as + * follows: + * 1. OpenGL 2.0/ARB vertex/fragment shaders + * 2. ARB/NV vertex/fragment programs + * 3. Programs derived from fixed-function state. + * + * Note: it's possible for a vertex shader to get used with a fragment + * program (and vice versa) here, but in practice that shouldn't ever + * come up, or matter. + */ + + if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) { + /* Use shader programs */ + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + fsProg->FragmentProgram); + } + else if (ctx->FragmentProgram._Enabled) { + /* use user-defined vertex program */ + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + ctx->FragmentProgram.Current); + } + else if (ctx->FragmentProgram._MaintainTexEnvProgram) { + /* Use fragment program generated from fixed-function state. + */ + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + _mesa_get_fixed_func_fragment_program(ctx)); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + ctx->FragmentProgram._Current); + } + else { + /* no fragment program */ + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + } + + if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) { + /* Use shader programs */ + _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, + gsProg->GeometryProgram); + } else { + /* no fragment program */ + _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); + } + + /* Examine vertex program after fragment program as + * _mesa_get_fixed_func_vertex_program() needs to know active + * fragprog inputs. + */ + if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) { + /* Use shader programs */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + vsProg->VertexProgram); + } + else if (ctx->VertexProgram._Enabled) { + /* use user-defined vertex program */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + ctx->VertexProgram.Current); + } + else if (ctx->VertexProgram._MaintainTnlProgram) { + /* Use vertex program generated from fixed-function state. + */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + _mesa_get_fixed_func_vertex_program(ctx)); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, + ctx->VertexProgram._Current); + } + else { + /* no vertex program */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + } + + /* Let the driver know what's happening: + */ + if (ctx->FragmentProgram._Current != prevFP) { + new_state |= _NEW_PROGRAM; + if (ctx->Driver.BindProgram) { + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + (struct gl_program *) ctx->FragmentProgram._Current); + } + } + + if (ctx->GeometryProgram._Current != prevGP) { + new_state |= _NEW_PROGRAM; + if (ctx->Driver.BindProgram) { + ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM, + (struct gl_program *) ctx->GeometryProgram._Current); + } + } + + if (ctx->VertexProgram._Current != prevVP) { + new_state |= _NEW_PROGRAM; + if (ctx->Driver.BindProgram) { + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + (struct gl_program *) ctx->VertexProgram._Current); + } + } + + return new_state; +} + + +/** + * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. + */ +static GLbitfield +update_program_constants(struct gl_context *ctx) +{ + GLbitfield new_state = 0x0; + + if (ctx->FragmentProgram._Current) { + const struct gl_program_parameter_list *params = + ctx->FragmentProgram._Current->Base.Parameters; + if (params && params->StateFlags & ctx->NewState) { + new_state |= _NEW_PROGRAM_CONSTANTS; + } + } + + if (ctx->GeometryProgram._Current) { + const struct gl_program_parameter_list *params = + ctx->GeometryProgram._Current->Base.Parameters; + /*FIXME: StateFlags is always 0 because we have unnamed constant + * not state changes */ + if (params /*&& params->StateFlags & ctx->NewState*/) { + new_state |= _NEW_PROGRAM_CONSTANTS; + } + } + + if (ctx->VertexProgram._Current) { + const struct gl_program_parameter_list *params = + ctx->VertexProgram._Current->Base.Parameters; + if (params && params->StateFlags & ctx->NewState) { + new_state |= _NEW_PROGRAM_CONSTANTS; + } + } + + return new_state; +} + + + + +static void +update_viewport_matrix(struct gl_context *ctx) +{ + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; + + ASSERT(depthMax > 0); + + /* Compute scale and bias values. This is really driver-specific + * and should be maintained elsewhere if at all. + * NOTE: RasterPos uses this. + */ + _math_matrix_viewport(&ctx->Viewport._WindowMap, + ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height, + ctx->Viewport.Near, ctx->Viewport.Far, + depthMax); +} + + +/** + * Update derived multisample state. + */ +static void +update_multisample(struct gl_context *ctx) +{ + ctx->Multisample._Enabled = GL_FALSE; + if (ctx->Multisample.Enabled && + ctx->DrawBuffer && + ctx->DrawBuffer->Visual.sampleBuffers) + ctx->Multisample._Enabled = GL_TRUE; +} + + +/** + * Update derived color/blend/logicop state. + */ +static void +update_color(struct gl_context *ctx) +{ + /* This is needed to support 1.1's RGB logic ops AND + * 1.0's blending logicops. + */ + ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx); +} + + +/* + * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET + * in ctx->_TriangleCaps if needed. + */ +static void +update_polygon(struct gl_context *ctx) +{ + ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); + + if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + + if ( ctx->Polygon.OffsetPoint + || ctx->Polygon.OffsetLine + || ctx->Polygon.OffsetFill) + ctx->_TriangleCaps |= DD_TRI_OFFSET; +} + + +/** + * Update the ctx->_TriangleCaps bitfield. + * XXX that bitfield should really go away someday! + * This function must be called after other update_*() functions since + * there are dependencies on some other derived values. + */ +#if 0 +static void +update_tricaps(struct gl_context *ctx, GLbitfield new_state) +{ + ctx->_TriangleCaps = 0; + + /* + * Points + */ + if (1/*new_state & _NEW_POINT*/) { + if (ctx->Point.SmoothFlag) + ctx->_TriangleCaps |= DD_POINT_SMOOTH; + if (ctx->Point._Attenuated) + ctx->_TriangleCaps |= DD_POINT_ATTEN; + } + + /* + * Lines + */ + if (1/*new_state & _NEW_LINE*/) { + if (ctx->Line.SmoothFlag) + ctx->_TriangleCaps |= DD_LINE_SMOOTH; + if (ctx->Line.StippleFlag) + ctx->_TriangleCaps |= DD_LINE_STIPPLE; + } + + /* + * Polygons + */ + if (1/*new_state & _NEW_POLYGON*/) { + if (ctx->Polygon.SmoothFlag) + ctx->_TriangleCaps |= DD_TRI_SMOOTH; + if (ctx->Polygon.StippleFlag) + ctx->_TriangleCaps |= DD_TRI_STIPPLE; + if (ctx->Polygon.FrontMode != GL_FILL + || ctx->Polygon.BackMode != GL_FILL) + ctx->_TriangleCaps |= DD_TRI_UNFILLED; + if (ctx->Polygon.CullFlag + && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + if (ctx->Polygon.OffsetPoint || + ctx->Polygon.OffsetLine || + ctx->Polygon.OffsetFill) + ctx->_TriangleCaps |= DD_TRI_OFFSET; + } + + /* + * Lighting and shading + */ + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; + if (ctx->Light.ShadeModel == GL_FLAT) + ctx->_TriangleCaps |= DD_FLATSHADE; + if (_mesa_need_secondary_color(ctx)) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + + /* + * Stencil + */ + if (ctx->Stencil._TestTwoSide) + ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; +} +#endif + + +/** + * Compute derived GL state. + * If __struct gl_contextRec::NewState is non-zero then this function \b must + * be called before rendering anything. + * + * Calls dd_function_table::UpdateState to perform any internal state + * management necessary. + * + * \sa _mesa_update_modelview_project(), _mesa_update_texture(), + * _mesa_update_buffer_bounds(), + * _mesa_update_lighting() and _mesa_update_tnl_spaces(). + */ +void +_mesa_update_state_locked( struct gl_context *ctx ) +{ + GLbitfield new_state = ctx->NewState; + GLbitfield prog_flags = _NEW_PROGRAM; + GLbitfield new_prog_state = 0x0; + + if (new_state == _NEW_CURRENT_ATTRIB) + goto out; + + if (MESA_VERBOSE & VERBOSE_STATE) + _mesa_print_state("_mesa_update_state", new_state); + + /* Determine which state flags effect vertex/fragment program state */ + if (ctx->FragmentProgram._MaintainTexEnvProgram) { + prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | + _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | + _NEW_PROGRAM); + } + if (ctx->VertexProgram._MaintainTnlProgram) { + prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | + _NEW_TRANSFORM | _NEW_POINT | + _NEW_FOG | _NEW_LIGHT | + _MESA_NEW_NEED_EYE_COORDS); + } + + /* + * Now update derived state info + */ + + if (new_state & prog_flags) + update_program_enables( ctx ); + + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) + _mesa_update_modelview_project( ctx, new_state ); + + if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) + _mesa_update_texture( ctx, new_state ); + + if (new_state & _NEW_BUFFERS) + _mesa_update_framebuffer(ctx); + + if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) + _mesa_update_draw_buffer_bounds( ctx ); + + if (new_state & _NEW_POLYGON) + update_polygon( ctx ); + + if (new_state & _NEW_LIGHT) + _mesa_update_lighting( ctx ); + + if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) + _mesa_update_stencil( ctx ); + + if (new_state & _NEW_PIXEL) + _mesa_update_pixel( ctx, new_state ); + + if (new_state & _DD_NEW_SEPARATE_SPECULAR) + update_separate_specular( ctx ); + + if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) + update_viewport_matrix(ctx); + + if (new_state & _NEW_MULTISAMPLE) + update_multisample( ctx ); + + if (new_state & _NEW_COLOR) + update_color( ctx ); + +#if 0 + if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT + | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) + update_tricaps( ctx, new_state ); +#endif + + /* ctx->_NeedEyeCoords is now up to date. + * + * If the truth value of this variable has changed, update for the + * new lighting space and recompute the positions of lights and the + * normal transform. + * + * If the lighting space hasn't changed, may still need to recompute + * light positions & normal transforms for other reasons. + */ + if (new_state & _MESA_NEW_NEED_EYE_COORDS) + _mesa_update_tnl_spaces( ctx, new_state ); + + if (new_state & prog_flags) { + /* When we generate programs from fixed-function vertex/fragment state + * this call may generate/bind a new program. If so, we need to + * propogate the _NEW_PROGRAM flag to the driver. + */ + new_prog_state |= update_program( ctx ); + } + + if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) + update_arrays( ctx ); + + out: + new_prog_state |= update_program_constants(ctx); + + /* + * Give the driver a chance to act upon the new_state flags. + * The driver might plug in different span functions, for example. + * Also, this is where the driver can invalidate the state of any + * active modules (such as swrast_setup, swrast, tnl, etc). + * + * Set ctx->NewState to zero to avoid recursion if + * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) + */ + new_state = ctx->NewState | new_prog_state; + ctx->NewState = 0; + ctx->Driver.UpdateState(ctx, new_state); + ctx->Array.NewState = 0; + if (!ctx->Array.RebindArrays) + ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; +} + + +/* This is the usual entrypoint for state updates: + */ +void +_mesa_update_state( struct gl_context *ctx ) +{ + _mesa_lock_context_textures(ctx); + _mesa_update_state_locked(ctx); + _mesa_unlock_context_textures(ctx); +} + + + + +/** + * Want to figure out which fragment program inputs are actually + * constant/current values from ctx->Current. These should be + * referenced as a tracked state variable rather than a fragment + * program input, to save the overhead of putting a constant value in + * every submitted vertex, transferring it to hardware, interpolating + * it across the triangle, etc... + * + * When there is a VP bound, just use vp->outputs. But when we're + * generating vp from fixed function state, basically want to + * calculate: + * + * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | + * potential_vp_outputs ) + * + * Where potential_vp_outputs is calculated by looking at enabled + * texgen, etc. + * + * The generated fragment program should then only declare inputs that + * may vary or otherwise differ from the ctx->Current values. + * Otherwise, the fp should track them as state values instead. + */ +void +_mesa_set_varying_vp_inputs( struct gl_context *ctx, + GLbitfield varying_inputs ) +{ + if (ctx->varying_vp_inputs != varying_inputs) { + ctx->varying_vp_inputs = varying_inputs; + ctx->NewState |= _NEW_ARRAY; + /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ + } +} + + +/** + * Used by drivers to tell core Mesa that the driver is going to + * install/ use its own vertex program. In particular, this will + * prevent generated fragment programs from using state vars instead + * of ordinary varyings/inputs. + */ +void +_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) +{ + if (ctx->VertexProgram._Overriden != flag) { + ctx->VertexProgram._Overriden = flag; + + /* Set one of the bits which will trigger fragment program + * regeneration: + */ + ctx->NewState |= _NEW_PROGRAM; + } +} diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 2a3037f61..c6b8c05b1 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -55,9 +55,7 @@ * In particular, we care about pixel transfer state and buffer state * (such as glReadBuffer to make sure we read from the right renderbuffer). */ -#define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \ - _NEW_BUFFERS | \ - _NEW_PIXEL) +#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) @@ -2434,7 +2432,7 @@ teximage(struct gl_context *ctx, GLuint dims, return; /* error was recorded */ } - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); texObj = _mesa_get_current_tex_object(ctx, target); @@ -2580,7 +2578,7 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) return; } - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); texObj = _mesa_get_current_tex_object(ctx, target); @@ -2637,7 +2635,7 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, return; } - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset, diff --git a/pixman/test/composite.c b/pixman/test/composite.c index a86e5ed68..e6d52b990 100644 --- a/pixman/test/composite.c +++ b/pixman/test/composite.c @@ -868,7 +868,7 @@ main (int argc, char **argv) { #define N_TESTS (8 * 1024 * 1024) int result = 0; - int i; + uint32_t i; if (argc > 1) { @@ -890,15 +890,22 @@ main (int argc, char **argv) } } + uint32_t seed; + + if (getenv ("PIXMAN_RANDOMIZE_TESTS")) + seed = get_random_seed(); + else + seed = 1; + #ifdef USE_OPENMP -# pragma omp parallel for default(none) shared(result) shared(argv) +# pragma omp parallel for default(none) shared(result, argv, seed) #endif - for (i = 1; i <= N_TESTS; ++i) + for (i = seed; i <= N_TESTS; ++i) { if (!result && !run_test (i)) { - printf ("Test %d failed.\n", i); - + printf ("Test 0x%08X failed.\n", i); + result = i; } } diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c index 166dc6d2c..d496f93e2 100644 --- a/pixman/test/stress-test.c +++ b/pixman/test/stress-test.c @@ -1,4 +1,6 @@ +#include <stdio.h> #include "utils.h" +#include <sys/types.h> #if 0 #define fence_malloc malloc @@ -730,11 +732,17 @@ static const pixman_op_t op_list[] = }; static void -run_test (uint32_t seed) +run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod) { pixman_image_t *source, *mask, *dest; pixman_op_t op; + if (verbose) + { + if (mod == 0 || (seed % mod) == 0) + printf ("Seed 0x%08x\n", seed); + } + lcg_srand (seed); source = create_random_image (); @@ -787,6 +795,7 @@ main (int argc, char **argv) uint32_t seed = 1; uint32_t n_tests = 0xffffffff; uint32_t mod = 0; + pixman_bool_t use_threads = TRUE; uint32_t i; pixman_disable_out_of_bounds_workaround (); @@ -811,6 +820,7 @@ main (int argc, char **argv) else if (strcmp (argv[i], "-s") == 0 && i + 1 < argc) { get_int (argv[i + 1], &seed); + use_threads = FALSE; i++; } else if (strcmp (argv[i], "-n") == 0 && i + 1 < argc) @@ -825,7 +835,7 @@ main (int argc, char **argv) printf ("Options:\n\n" "-n <number> Number of tests to run\n" - "-s <seed> Seed of first test\n" + "-s <seed> Seed of first test (ignored if PIXMAN_RANDOMIZE_TESTS is set)\n" "-v Print out seeds\n" "-v <n> Print out every n'th seed\n\n"); @@ -836,19 +846,24 @@ main (int argc, char **argv) if (n_tests == 0xffffffff) n_tests = 8000; - /* FIXME: seed 2005763 fails in set_lum() with divide by zero */ + if (getenv ("PIXMAN_RANDOMIZE_TESTS")) + { + seed = get_random_seed(); + printf ("First seed: 0x%08x\n", seed); + } + + if (use_threads) + { #ifdef USE_OPENMP # pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed) #endif - for (i = seed; i < seed + n_tests; ++i) + for (i = seed; i < seed + n_tests; ++i) + run_test (i, verbose, mod); + } + else { - if (verbose) - { - if (mod == 0 || (i % mod) == 0) - printf ("Seed %d\n", i); - } - - run_test (i); + for (i = seed; i < seed + n_tests; ++i) + run_test (i, verbose, mod); } return 0; diff --git a/pixman/test/utils.c b/pixman/test/utils.c index ee68d272c..56701c4bb 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -1,575 +1,585 @@ -#define _GNU_SOURCE
-
-#include "utils.h"
-#include <signal.h>
-
-#ifdef HAVE_GETTIMEOFDAY
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#ifdef HAVE_FENV_H
-#include <fenv.h>
-#endif
-
-/* Random number seed
- */
-
-uint32_t lcg_seed;
-
-/*----------------------------------------------------------------------------*\
- * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
- *
- * This program generates the CRC-32 values for the files named in the
- * command-line arguments. These are the same CRC-32 values used by GZIP,
- * PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and
- * used independently.
- *
- * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
- *
- * Based on the byte-oriented implementation "File Verification Using CRC"
- * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
- *
- * v1.0.0: original release.
- * v1.0.1: fixed printf formats.
- * v1.0.2: fixed something else.
- * v1.0.3: replaced CRC constant table by generator function.
- * v1.0.4: reformatted code, made ANSI C. 1994-12-05.
- * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
-\*----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------*\
- * NAME:
- * Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
- * DESCRIPTION:
- * Computes or accumulates the CRC-32 value for a memory buffer.
- * The 'inCrc32' gives a previously accumulated CRC-32 value to allow
- * a CRC to be generated for multiple sequential buffer-fuls of data.
- * The 'inCrc32' for the first buffer must be zero.
- * ARGUMENTS:
- * inCrc32 - accumulated CRC-32 value, must be 0 on first call
- * buf - buffer to compute CRC-32 value for
- * bufLen - number of bytes in buffer
- * RETURNS:
- * crc32 - computed CRC-32 value
- * ERRORS:
- * (no errors are possible)
-\*----------------------------------------------------------------------------*/
-
-uint32_t
-compute_crc32 (uint32_t in_crc32,
- const void *buf,
- size_t buf_len)
-{
- static const uint32_t crc_table[256] = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
- 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
- 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
- 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
- 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
- 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
- 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
- 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
- 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
- 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
- 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
- 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
- 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
- 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
- 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
- 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
- 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
- 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
- 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
- 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
- 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
- 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
- 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
- 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
- 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
- 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
- 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
- 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
- };
-
- uint32_t crc32;
- unsigned char * byte_buf;
- size_t i;
-
- /* accumulate crc32 for buffer */
- crc32 = in_crc32 ^ 0xFFFFFFFF;
- byte_buf = (unsigned char*) buf;
-
- for (i = 0; i < buf_len; i++)
- crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
-
- return (crc32 ^ 0xFFFFFFFF);
-}
-
-/* perform endian conversion of pixel data
- */
-void
-image_endian_swap (pixman_image_t *img)
-{
- int stride = pixman_image_get_stride (img);
- uint32_t *data = pixman_image_get_data (img);
- int height = pixman_image_get_height (img);
- int bpp = PIXMAN_FORMAT_BPP (pixman_image_get_format (img));
- int i, j;
-
- /* swap bytes only on big endian systems */
- volatile uint16_t endian_check_var = 0x1234;
- if (*(volatile uint8_t *)&endian_check_var != 0x12)
- return;
-
- if (bpp == 8)
- return;
-
- for (i = 0; i < height; i++)
- {
- uint8_t *line_data = (uint8_t *)data + stride * i;
-
- switch (bpp)
- {
- case 1:
- for (j = 0; j < stride; j++)
- {
- line_data[j] =
- ((line_data[j] & 0x80) >> 7) |
- ((line_data[j] & 0x40) >> 5) |
- ((line_data[j] & 0x20) >> 3) |
- ((line_data[j] & 0x10) >> 1) |
- ((line_data[j] & 0x08) << 1) |
- ((line_data[j] & 0x04) << 3) |
- ((line_data[j] & 0x02) << 5) |
- ((line_data[j] & 0x01) << 7);
- }
- break;
- case 4:
- for (j = 0; j < stride; j++)
- {
- line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
- }
- break;
- case 16:
- for (j = 0; j + 2 <= stride; j += 2)
- {
- char t1 = line_data[j + 0];
- char t2 = line_data[j + 1];
-
- line_data[j + 1] = t1;
- line_data[j + 0] = t2;
- }
- break;
- case 24:
- for (j = 0; j + 3 <= stride; j += 3)
- {
- char t1 = line_data[j + 0];
- char t2 = line_data[j + 1];
- char t3 = line_data[j + 2];
-
- line_data[j + 2] = t1;
- line_data[j + 1] = t2;
- line_data[j + 0] = t3;
- }
- break;
- case 32:
- for (j = 0; j + 4 <= stride; j += 4)
- {
- char t1 = line_data[j + 0];
- char t2 = line_data[j + 1];
- char t3 = line_data[j + 2];
- char t4 = line_data[j + 3];
-
- line_data[j + 3] = t1;
- line_data[j + 2] = t2;
- line_data[j + 1] = t3;
- line_data[j + 0] = t4;
- }
- break;
- default:
- assert (FALSE);
- break;
- }
- }
-}
-
-#define N_LEADING_PROTECTED 10
-#define N_TRAILING_PROTECTED 10
-
-typedef struct
-{
- void *addr;
- uint32_t len;
- uint8_t *trailing;
- int n_bytes;
-} info_t;
-
-#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H)
-
-/* This is apparently necessary on at least OS X */
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-void *
-fence_malloc (int64_t len)
-{
- unsigned long page_size = getpagesize();
- unsigned long page_mask = page_size - 1;
- uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
- uint32_t n_bytes =
- (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
- n_payload_bytes) & ~page_mask;
- uint8_t *initial_page;
- uint8_t *leading_protected;
- uint8_t *trailing_protected;
- uint8_t *payload;
- uint8_t *addr;
-
- if (len < 0)
- abort();
-
- addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
- -1, 0);
-
- if (addr == MAP_FAILED)
- {
- printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
- return NULL;
- }
-
- initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask);
- leading_protected = initial_page + page_size;
- payload = leading_protected + N_LEADING_PROTECTED * page_size;
- trailing_protected = payload + n_payload_bytes;
-
- ((info_t *)initial_page)->addr = addr;
- ((info_t *)initial_page)->len = len;
- ((info_t *)initial_page)->trailing = trailing_protected;
- ((info_t *)initial_page)->n_bytes = n_bytes;
-
- if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
- PROT_NONE) == -1) ||
- (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
- PROT_NONE) == -1))
- {
- munmap (addr, n_bytes);
- return NULL;
- }
-
- return payload;
-}
-
-void
-fence_free (void *data)
-{
- uint32_t page_size = getpagesize();
- uint8_t *payload = data;
- uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
- uint8_t *initial_page = leading_protected - page_size;
- info_t *info = (info_t *)initial_page;
-
- munmap (info->addr, info->n_bytes);
-}
-
-#else
-
-void *
-fence_malloc (int64_t len)
-{
- return malloc (len);
-}
-
-void
-fence_free (void *data)
-{
- free (data);
-}
-
-#endif
-
-uint8_t *
-make_random_bytes (int n_bytes)
-{
- uint8_t *bytes = fence_malloc (n_bytes);
- int i;
-
- if (!bytes)
- return NULL;
-
- for (i = 0; i < n_bytes; ++i)
- bytes[i] = lcg_rand () & 0xff;
-
- return bytes;
-}
-
-/*
- * A function, which can be used as a core part of the test programs,
- * intended to detect various problems with the help of fuzzing input
- * to pixman API (according to some templates, aka "smart" fuzzing).
- * Some general information about such testing can be found here:
- * http://en.wikipedia.org/wiki/Fuzz_testing
- *
- * It may help detecting:
- * - crashes on bad handling of valid or reasonably invalid input to
- * pixman API.
- * - deviations from the behavior of older pixman releases.
- * - deviations from the behavior of the same pixman release, but
- * configured in a different way (for example with SIMD optimizations
- * disabled), or running on a different OS or hardware.
- *
- * The test is performed by calling a callback function a huge number
- * of times. The callback function is expected to run some snippet of
- * pixman code with pseudorandom variations to the data feeded to
- * pixman API. A result of running each callback function should be
- * some deterministic value which depends on test number (test number
- * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
- * callback function is expected to print to stdout some information
- * about what it does.
- *
- * Return values from many small tests are accumulated together and
- * used as final checksum, which can be compared to some expected
- * value. Running the tests not individually, but in a batch helps
- * to reduce process start overhead and also allows to parallelize
- * testing and utilize multiple CPU cores.
- *
- * The resulting executable can be run without any arguments. In
- * this case it runs a batch of tests starting from 1 and up to
- * 'default_number_of_iterations'. The resulting checksum is
- * compared with 'expected_checksum' and FAIL or PASS verdict
- * depends on the result of this comparison.
- *
- * If the executable is run with 2 numbers provided as command line
- * arguments, they specify the starting and ending numbers for a test
- * batch.
- *
- * If the executable is run with only one number provided as a command
- * line argument, then this number is used to call the callback function
- * once, and also with verbose flag set.
- */
-int
-fuzzer_test_main (const char *test_name,
- int default_number_of_iterations,
- uint32_t expected_checksum,
- uint32_t (*test_function)(int testnum, int verbose),
- int argc,
- const char *argv[])
-{
- int i, n1 = 1, n2 = 0;
- uint32_t checksum = 0;
- int verbose = getenv ("VERBOSE") != NULL;
-
- if (argc >= 3)
- {
- n1 = atoi (argv[1]);
- n2 = atoi (argv[2]);
- if (n2 < n1)
- {
- printf ("invalid test range\n");
- return 1;
- }
- }
- else if (argc >= 2)
- {
- n2 = atoi (argv[1]);
- checksum = test_function (n2, 1);
- printf ("%d: checksum=%08X\n", n2, checksum);
- return 0;
- }
- else
- {
- n1 = 1;
- n2 = default_number_of_iterations;
- }
-
-#ifdef USE_OPENMP
- #pragma omp parallel for reduction(+:checksum) default(none) \
- shared(n1, n2, test_function, verbose)
-#endif
- for (i = n1; i <= n2; i++)
- {
- uint32_t crc = test_function (i, 0);
- if (verbose)
- printf ("%d: %08X\n", i, crc);
- checksum += crc;
- }
-
- if (n1 == 1 && n2 == default_number_of_iterations)
- {
- if (checksum == expected_checksum)
- {
- printf ("%s test passed (checksum=%08X)\n",
- test_name, checksum);
- }
- else
- {
- printf ("%s test failed! (checksum=%08X, expected %08X)\n",
- test_name, checksum, expected_checksum);
- return 1;
- }
- }
- else
- {
- printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
- }
-
- return 0;
-}
-
-/* Try to obtain current time in seconds */
-double
-gettime (void)
-{
-#ifdef HAVE_GETTIMEOFDAY
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
- return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
-#else
- return (double)clock() / (double)CLOCKS_PER_SEC;
-#endif
-}
-
-static const char *global_msg;
-
-static void
-on_alarm (int signo)
-{
- printf ("%s\n", global_msg);
- exit (1);
-}
-
-void
-fail_after (int seconds, const char *msg)
-{
-#ifdef HAVE_SIGACTION
-#ifdef HAVE_ALARM
- struct sigaction action;
-
- global_msg = msg;
-
- memset (&action, 0, sizeof (action));
- action.sa_handler = on_alarm;
-
- alarm (seconds);
-
- sigaction (SIGALRM, &action, NULL);
-#endif
-#endif
-}
-
-void
-enable_fp_exceptions (void)
-{
-#ifdef HAVE_FENV_H
-#ifdef HAVE_FEENABLEEXCEPT
- /* Note: we don't enable the FE_INEXACT trap because
- * that happens quite commonly. It is possible that
- * over- and underflow should similarly be considered
- * okay, but for now the test suite passes with them
- * enabled, and it's useful to know if they start
- * occuring.
- */
- feenableexcept (FE_DIVBYZERO |
- FE_INVALID |
- FE_OVERFLOW |
- FE_UNDERFLOW);
-#endif
-#endif
-}
-
-void *
-aligned_malloc (size_t align, size_t size)
-{
- void *result;
-
-#ifdef HAVE_POSIX_MEMALIGN
- if (posix_memalign (&result, align, size) != 0)
- result = NULL;
-#else
- result = malloc (size);
-#endif
-
- return result;
-}
-
-#define CONVERT_15(c, is_rgb) \
- (is_rgb? \
- ((((c) >> 3) & 0x001f) | \
- (((c) >> 6) & 0x03e0) | \
- (((c) >> 9) & 0x7c00)) : \
- (((((c) >> 16) & 0xff) * 153 + \
- (((c) >> 8) & 0xff) * 301 + \
- (((c) ) & 0xff) * 58) >> 2))
-
-void
-initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
-{
- int i;
- uint32_t mask = (1 << depth) - 1;
-
- for (i = 0; i < 32768; ++i)
- palette->ent[i] = lcg_rand() & mask;
-
- memset (palette->rgba, 0, sizeof (palette->rgba));
-
- for (i = 0; i < mask + 1; ++i)
- {
- uint32_t rgba24;
- pixman_bool_t retry;
- uint32_t i15;
-
- /* We filled the rgb->index map with random numbers, but we
- * do need the ability to round trip, that is if some indexed
- * color expands to an argb24, then the 15 bit version of that
- * color must map back to the index. Anything else, we don't
- * care about too much.
- */
- do
- {
- uint32_t old_idx;
-
- rgba24 = lcg_rand();
- i15 = CONVERT_15 (rgba24, is_rgb);
-
- old_idx = palette->ent[i15];
- if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
- retry = 1;
- else
- retry = 0;
- } while (retry);
-
- palette->rgba[i] = rgba24;
- palette->ent[i15] = i;
- }
-
- for (i = 0; i < mask + 1; ++i)
- {
- assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
- }
-}
+#define _GNU_SOURCE + +#include "utils.h" +#include <signal.h> + +#ifdef HAVE_GETTIMEOFDAY +#include <sys/time.h> +#else +#include <time.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +#ifdef HAVE_FENV_H +#include <fenv.h> +#endif + +/* Random number seed + */ + +uint32_t lcg_seed; + +/*----------------------------------------------------------------------------*\ + * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29. + * + * This program generates the CRC-32 values for the files named in the + * command-line arguments. These are the same CRC-32 values used by GZIP, + * PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and + * used independently. + * + * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE. + * + * Based on the byte-oriented implementation "File Verification Using CRC" + * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67. + * + * v1.0.0: original release. + * v1.0.1: fixed printf formats. + * v1.0.2: fixed something else. + * v1.0.3: replaced CRC constant table by generator function. + * v1.0.4: reformatted code, made ANSI C. 1994-12-05. + * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29. +\*----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*\ + * NAME: + * Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer + * DESCRIPTION: + * Computes or accumulates the CRC-32 value for a memory buffer. + * The 'inCrc32' gives a previously accumulated CRC-32 value to allow + * a CRC to be generated for multiple sequential buffer-fuls of data. + * The 'inCrc32' for the first buffer must be zero. + * ARGUMENTS: + * inCrc32 - accumulated CRC-32 value, must be 0 on first call + * buf - buffer to compute CRC-32 value for + * bufLen - number of bytes in buffer + * RETURNS: + * crc32 - computed CRC-32 value + * ERRORS: + * (no errors are possible) +\*----------------------------------------------------------------------------*/ + +uint32_t +compute_crc32 (uint32_t in_crc32, + const void *buf, + size_t buf_len) +{ + static const uint32_t crc_table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + uint32_t crc32; + unsigned char * byte_buf; + size_t i; + + /* accumulate crc32 for buffer */ + crc32 = in_crc32 ^ 0xFFFFFFFF; + byte_buf = (unsigned char*) buf; + + for (i = 0; i < buf_len; i++) + crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF]; + + return (crc32 ^ 0xFFFFFFFF); +} + +/* perform endian conversion of pixel data + */ +void +image_endian_swap (pixman_image_t *img) +{ + int stride = pixman_image_get_stride (img); + uint32_t *data = pixman_image_get_data (img); + int height = pixman_image_get_height (img); + int bpp = PIXMAN_FORMAT_BPP (pixman_image_get_format (img)); + int i, j; + + /* swap bytes only on big endian systems */ + volatile uint16_t endian_check_var = 0x1234; + if (*(volatile uint8_t *)&endian_check_var != 0x12) + return; + + if (bpp == 8) + return; + + for (i = 0; i < height; i++) + { + uint8_t *line_data = (uint8_t *)data + stride * i; + + switch (bpp) + { + case 1: + for (j = 0; j < stride; j++) + { + line_data[j] = + ((line_data[j] & 0x80) >> 7) | + ((line_data[j] & 0x40) >> 5) | + ((line_data[j] & 0x20) >> 3) | + ((line_data[j] & 0x10) >> 1) | + ((line_data[j] & 0x08) << 1) | + ((line_data[j] & 0x04) << 3) | + ((line_data[j] & 0x02) << 5) | + ((line_data[j] & 0x01) << 7); + } + break; + case 4: + for (j = 0; j < stride; j++) + { + line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4); + } + break; + case 16: + for (j = 0; j + 2 <= stride; j += 2) + { + char t1 = line_data[j + 0]; + char t2 = line_data[j + 1]; + + line_data[j + 1] = t1; + line_data[j + 0] = t2; + } + break; + case 24: + for (j = 0; j + 3 <= stride; j += 3) + { + char t1 = line_data[j + 0]; + char t2 = line_data[j + 1]; + char t3 = line_data[j + 2]; + + line_data[j + 2] = t1; + line_data[j + 1] = t2; + line_data[j + 0] = t3; + } + break; + case 32: + for (j = 0; j + 4 <= stride; j += 4) + { + char t1 = line_data[j + 0]; + char t2 = line_data[j + 1]; + char t3 = line_data[j + 2]; + char t4 = line_data[j + 3]; + + line_data[j + 3] = t1; + line_data[j + 2] = t2; + line_data[j + 1] = t3; + line_data[j + 0] = t4; + } + break; + default: + assert (FALSE); + break; + } + } +} + +#define N_LEADING_PROTECTED 10 +#define N_TRAILING_PROTECTED 10 + +typedef struct +{ + void *addr; + uint32_t len; + uint8_t *trailing; + int n_bytes; +} info_t; + +#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) + +/* This is apparently necessary on at least OS X */ +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void * +fence_malloc (int64_t len) +{ + unsigned long page_size = getpagesize(); + unsigned long page_mask = page_size - 1; + uint32_t n_payload_bytes = (len + page_mask) & ~page_mask; + uint32_t n_bytes = + (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) + + n_payload_bytes) & ~page_mask; + uint8_t *initial_page; + uint8_t *leading_protected; + uint8_t *trailing_protected; + uint8_t *payload; + uint8_t *addr; + + if (len < 0) + abort(); + + addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + + if (addr == MAP_FAILED) + { + printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes); + return NULL; + } + + initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask); + leading_protected = initial_page + page_size; + payload = leading_protected + N_LEADING_PROTECTED * page_size; + trailing_protected = payload + n_payload_bytes; + + ((info_t *)initial_page)->addr = addr; + ((info_t *)initial_page)->len = len; + ((info_t *)initial_page)->trailing = trailing_protected; + ((info_t *)initial_page)->n_bytes = n_bytes; + + if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size, + PROT_NONE) == -1) || + (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size, + PROT_NONE) == -1)) + { + munmap (addr, n_bytes); + return NULL; + } + + return payload; +} + +void +fence_free (void *data) +{ + uint32_t page_size = getpagesize(); + uint8_t *payload = data; + uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size; + uint8_t *initial_page = leading_protected - page_size; + info_t *info = (info_t *)initial_page; + + munmap (info->addr, info->n_bytes); +} + +#else + +void * +fence_malloc (int64_t len) +{ + return malloc (len); +} + +void +fence_free (void *data) +{ + free (data); +} + +#endif + +uint8_t * +make_random_bytes (int n_bytes) +{ + uint8_t *bytes = fence_malloc (n_bytes); + int i; + + if (!bytes) + return NULL; + + for (i = 0; i < n_bytes; ++i) + bytes[i] = lcg_rand () & 0xff; + + return bytes; +} + +/* + * A function, which can be used as a core part of the test programs, + * intended to detect various problems with the help of fuzzing input + * to pixman API (according to some templates, aka "smart" fuzzing). + * Some general information about such testing can be found here: + * http://en.wikipedia.org/wiki/Fuzz_testing + * + * It may help detecting: + * - crashes on bad handling of valid or reasonably invalid input to + * pixman API. + * - deviations from the behavior of older pixman releases. + * - deviations from the behavior of the same pixman release, but + * configured in a different way (for example with SIMD optimizations + * disabled), or running on a different OS or hardware. + * + * The test is performed by calling a callback function a huge number + * of times. The callback function is expected to run some snippet of + * pixman code with pseudorandom variations to the data feeded to + * pixman API. A result of running each callback function should be + * some deterministic value which depends on test number (test number + * can be used as a seed for PRNG). When 'verbose' argument is nonzero, + * callback function is expected to print to stdout some information + * about what it does. + * + * Return values from many small tests are accumulated together and + * used as final checksum, which can be compared to some expected + * value. Running the tests not individually, but in a batch helps + * to reduce process start overhead and also allows to parallelize + * testing and utilize multiple CPU cores. + * + * The resulting executable can be run without any arguments. In + * this case it runs a batch of tests starting from 1 and up to + * 'default_number_of_iterations'. The resulting checksum is + * compared with 'expected_checksum' and FAIL or PASS verdict + * depends on the result of this comparison. + * + * If the executable is run with 2 numbers provided as command line + * arguments, they specify the starting and ending numbers for a test + * batch. + * + * If the executable is run with only one number provided as a command + * line argument, then this number is used to call the callback function + * once, and also with verbose flag set. + */ +int +fuzzer_test_main (const char *test_name, + int default_number_of_iterations, + uint32_t expected_checksum, + uint32_t (*test_function)(int testnum, int verbose), + int argc, + const char *argv[]) +{ + int i, n1 = 1, n2 = 0; + uint32_t checksum = 0; + int verbose = getenv ("VERBOSE") != NULL; + + if (argc >= 3) + { + n1 = atoi (argv[1]); + n2 = atoi (argv[2]); + if (n2 < n1) + { + printf ("invalid test range\n"); + return 1; + } + } + else if (argc >= 2) + { + n2 = atoi (argv[1]); + checksum = test_function (n2, 1); + printf ("%d: checksum=%08X\n", n2, checksum); + return 0; + } + else + { + n1 = 1; + n2 = default_number_of_iterations; + } + +#ifdef USE_OPENMP + #pragma omp parallel for reduction(+:checksum) default(none) \ + shared(n1, n2, test_function, verbose) +#endif + for (i = n1; i <= n2; i++) + { + uint32_t crc = test_function (i, 0); + if (verbose) + printf ("%d: %08X\n", i, crc); + checksum += crc; + } + + if (n1 == 1 && n2 == default_number_of_iterations) + { + if (checksum == expected_checksum) + { + printf ("%s test passed (checksum=%08X)\n", + test_name, checksum); + } + else + { + printf ("%s test failed! (checksum=%08X, expected %08X)\n", + test_name, checksum, expected_checksum); + return 1; + } + } + else + { + printf ("%d-%d: checksum=%08X\n", n1, n2, checksum); + } + + return 0; +} + +/* Try to obtain current time in seconds */ +double +gettime (void) +{ +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + + gettimeofday (&tv, NULL); + return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.; +#else + return (double)clock() / (double)CLOCKS_PER_SEC; +#endif +} + +uint32_t +get_random_seed (void) +{ + double d = gettime(); + + lcg_srand (*(uint32_t *)&d); + + return lcg_rand_u32 (); +} + +static const char *global_msg; + +static void +on_alarm (int signo) +{ + printf ("%s\n", global_msg); + exit (1); +} + +void +fail_after (int seconds, const char *msg) +{ +#ifdef HAVE_SIGACTION +#ifdef HAVE_ALARM + struct sigaction action; + + global_msg = msg; + + memset (&action, 0, sizeof (action)); + action.sa_handler = on_alarm; + + alarm (seconds); + + sigaction (SIGALRM, &action, NULL); +#endif +#endif +} + +void +enable_fp_exceptions (void) +{ +#ifdef HAVE_FENV_H +#ifdef HAVE_FEENABLEEXCEPT + /* Note: we don't enable the FE_INEXACT trap because + * that happens quite commonly. It is possible that + * over- and underflow should similarly be considered + * okay, but for now the test suite passes with them + * enabled, and it's useful to know if they start + * occuring. + */ + feenableexcept (FE_DIVBYZERO | + FE_INVALID | + FE_OVERFLOW | + FE_UNDERFLOW); +#endif +#endif +} + +void * +aligned_malloc (size_t align, size_t size) +{ + void *result; + +#ifdef HAVE_POSIX_MEMALIGN + if (posix_memalign (&result, align, size) != 0) + result = NULL; +#else + result = malloc (size); +#endif + + return result; +} + +#define CONVERT_15(c, is_rgb) \ + (is_rgb? \ + ((((c) >> 3) & 0x001f) | \ + (((c) >> 6) & 0x03e0) | \ + (((c) >> 9) & 0x7c00)) : \ + (((((c) >> 16) & 0xff) * 153 + \ + (((c) >> 8) & 0xff) * 301 + \ + (((c) ) & 0xff) * 58) >> 2)) + +void +initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) +{ + int i; + uint32_t mask = (1 << depth) - 1; + + for (i = 0; i < 32768; ++i) + palette->ent[i] = lcg_rand() & mask; + + memset (palette->rgba, 0, sizeof (palette->rgba)); + + for (i = 0; i < mask + 1; ++i) + { + uint32_t rgba24; + pixman_bool_t retry; + uint32_t i15; + + /* We filled the rgb->index map with random numbers, but we + * do need the ability to round trip, that is if some indexed + * color expands to an argb24, then the 15 bit version of that + * color must map back to the index. Anything else, we don't + * care about too much. + */ + do + { + uint32_t old_idx; + + rgba24 = lcg_rand(); + i15 = CONVERT_15 (rgba24, is_rgb); + + old_idx = palette->ent[i15]; + if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15) + retry = 1; + else + retry = 0; + } while (retry); + + palette->rgba[i] = rgba24; + palette->ent[i15] = i; + } + + for (i = 0; i < mask + 1; ++i) + { + assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i); + } +} diff --git a/pixman/test/utils.h b/pixman/test/utils.h index 5643c1228..615ad7841 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -1,137 +1,140 @@ -#include <stdlib.h>
-#include <config.h>
-#include <assert.h>
-#include "pixman-private.h" /* For 'inline' definition */
-
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-
-/* A primitive pseudorandom number generator,
- * taken from POSIX.1-2001 example
- */
-
-extern uint32_t lcg_seed;
-#ifdef USE_OPENMP
-#pragma omp threadprivate(lcg_seed)
-#endif
-
-static inline uint32_t
-lcg_rand (void)
-{
- lcg_seed = lcg_seed * 1103515245 + 12345;
- return ((uint32_t)(lcg_seed / 65536) % 32768);
-}
-
-static inline void
-lcg_srand (uint32_t seed)
-{
- lcg_seed = seed;
-}
-
-static inline uint32_t
-lcg_rand_n (int max)
-{
- return lcg_rand () % max;
-}
-
-static inline uint32_t
-lcg_rand_N (int max)
-{
- uint32_t lo = lcg_rand ();
- uint32_t hi = lcg_rand () << 15;
- return (lo | hi) % max;
-}
-
-static inline uint32_t
-lcg_rand_u32 (void)
-{
- uint32_t lo = lcg_rand();
- uint32_t hi = lcg_rand();
-
- return (hi << 16) | lo;
-}
-
-/* CRC 32 computation
- */
-uint32_t
-compute_crc32 (uint32_t in_crc32,
- const void *buf,
- size_t buf_len);
-
-/* perform endian conversion of pixel data
- */
-void
-image_endian_swap (pixman_image_t *img);
-
-/* Allocate memory that is bounded by protected pages,
- * so that out-of-bounds access will cause segfaults
- */
-void *
-fence_malloc (int64_t len);
-
-void
-fence_free (void *data);
-
-/* Generate n_bytes random bytes in fence_malloced memory */
-uint8_t *
-make_random_bytes (int n_bytes);
-
-/* Return current time in seconds */
-double
-gettime (void);
-
-/* main body of the fuzzer test */
-int
-fuzzer_test_main (const char *test_name,
- int default_number_of_iterations,
- uint32_t expected_checksum,
- uint32_t (*test_function)(int testnum, int verbose),
- int argc,
- const char *argv[]);
-
-void
-fail_after (int seconds, const char *msg);
-
-/* If possible, enable traps for floating point exceptions */
-void enable_fp_exceptions(void);
-
-/* A pair of macros which can help to detect corruption of
- * floating point registers after a function call. This may
- * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
- * path code, or ARM NEON assembly optimized function forgets
- * to save/restore d8-d15 registers before use.
- */
-
-#define FLOAT_REGS_CORRUPTION_DETECTOR_START() \
- static volatile double frcd_volatile_constant1 = 123451; \
- static volatile double frcd_volatile_constant2 = 123452; \
- static volatile double frcd_volatile_constant3 = 123453; \
- static volatile double frcd_volatile_constant4 = 123454; \
- static volatile double frcd_volatile_constant5 = 123455; \
- static volatile double frcd_volatile_constant6 = 123456; \
- static volatile double frcd_volatile_constant7 = 123457; \
- static volatile double frcd_volatile_constant8 = 123458; \
- double frcd_canary_variable1 = frcd_volatile_constant1; \
- double frcd_canary_variable2 = frcd_volatile_constant2; \
- double frcd_canary_variable3 = frcd_volatile_constant3; \
- double frcd_canary_variable4 = frcd_volatile_constant4; \
- double frcd_canary_variable5 = frcd_volatile_constant5; \
- double frcd_canary_variable6 = frcd_volatile_constant6; \
- double frcd_canary_variable7 = frcd_volatile_constant7; \
- double frcd_canary_variable8 = frcd_volatile_constant8;
-
-#define FLOAT_REGS_CORRUPTION_DETECTOR_FINISH() \
- assert (frcd_canary_variable1 == frcd_volatile_constant1); \
- assert (frcd_canary_variable2 == frcd_volatile_constant2); \
- assert (frcd_canary_variable3 == frcd_volatile_constant3); \
- assert (frcd_canary_variable4 == frcd_volatile_constant4); \
- assert (frcd_canary_variable5 == frcd_volatile_constant5); \
- assert (frcd_canary_variable6 == frcd_volatile_constant6); \
- assert (frcd_canary_variable7 == frcd_volatile_constant7); \
- assert (frcd_canary_variable8 == frcd_volatile_constant8);
-
-/* Try to get an aligned memory chunk */
-void *
-aligned_malloc (size_t align, size_t size);
-
-void
-initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
+#include <stdlib.h> +#include <config.h> +#include <assert.h> +#include "pixman-private.h" /* For 'inline' definition */ + +#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) + +/* A primitive pseudorandom number generator, + * taken from POSIX.1-2001 example + */ + +extern uint32_t lcg_seed; +#ifdef USE_OPENMP +#pragma omp threadprivate(lcg_seed) +#endif + +static inline uint32_t +lcg_rand (void) +{ + lcg_seed = lcg_seed * 1103515245 + 12345; + return ((uint32_t)(lcg_seed / 65536) % 32768); +} + +static inline void +lcg_srand (uint32_t seed) +{ + lcg_seed = seed; +} + +static inline uint32_t +lcg_rand_n (int max) +{ + return lcg_rand () % max; +} + +static inline uint32_t +lcg_rand_N (int max) +{ + uint32_t lo = lcg_rand (); + uint32_t hi = lcg_rand () << 15; + return (lo | hi) % max; +} + +static inline uint32_t +lcg_rand_u32 (void) +{ + uint32_t lo = lcg_rand(); + uint32_t hi = lcg_rand(); + + return (hi << 16) | lo; +} + +/* CRC 32 computation + */ +uint32_t +compute_crc32 (uint32_t in_crc32, + const void *buf, + size_t buf_len); + +/* perform endian conversion of pixel data + */ +void +image_endian_swap (pixman_image_t *img); + +/* Allocate memory that is bounded by protected pages, + * so that out-of-bounds access will cause segfaults + */ +void * +fence_malloc (int64_t len); + +void +fence_free (void *data); + +/* Generate n_bytes random bytes in fence_malloced memory */ +uint8_t * +make_random_bytes (int n_bytes); + +/* Return current time in seconds */ +double +gettime (void); + +uint32_t +get_random_seed (void); + +/* main body of the fuzzer test */ +int +fuzzer_test_main (const char *test_name, + int default_number_of_iterations, + uint32_t expected_checksum, + uint32_t (*test_function)(int testnum, int verbose), + int argc, + const char *argv[]); + +void +fail_after (int seconds, const char *msg); + +/* If possible, enable traps for floating point exceptions */ +void enable_fp_exceptions(void); + +/* A pair of macros which can help to detect corruption of + * floating point registers after a function call. This may + * happen if _mm_empty() call is forgotten in MMX/SSE2 fast + * path code, or ARM NEON assembly optimized function forgets + * to save/restore d8-d15 registers before use. + */ + +#define FLOAT_REGS_CORRUPTION_DETECTOR_START() \ + static volatile double frcd_volatile_constant1 = 123451; \ + static volatile double frcd_volatile_constant2 = 123452; \ + static volatile double frcd_volatile_constant3 = 123453; \ + static volatile double frcd_volatile_constant4 = 123454; \ + static volatile double frcd_volatile_constant5 = 123455; \ + static volatile double frcd_volatile_constant6 = 123456; \ + static volatile double frcd_volatile_constant7 = 123457; \ + static volatile double frcd_volatile_constant8 = 123458; \ + double frcd_canary_variable1 = frcd_volatile_constant1; \ + double frcd_canary_variable2 = frcd_volatile_constant2; \ + double frcd_canary_variable3 = frcd_volatile_constant3; \ + double frcd_canary_variable4 = frcd_volatile_constant4; \ + double frcd_canary_variable5 = frcd_volatile_constant5; \ + double frcd_canary_variable6 = frcd_volatile_constant6; \ + double frcd_canary_variable7 = frcd_volatile_constant7; \ + double frcd_canary_variable8 = frcd_volatile_constant8; + +#define FLOAT_REGS_CORRUPTION_DETECTOR_FINISH() \ + assert (frcd_canary_variable1 == frcd_volatile_constant1); \ + assert (frcd_canary_variable2 == frcd_volatile_constant2); \ + assert (frcd_canary_variable3 == frcd_volatile_constant3); \ + assert (frcd_canary_variable4 == frcd_volatile_constant4); \ + assert (frcd_canary_variable5 == frcd_volatile_constant5); \ + assert (frcd_canary_variable6 == frcd_volatile_constant6); \ + assert (frcd_canary_variable7 == frcd_volatile_constant7); \ + assert (frcd_canary_variable8 == frcd_volatile_constant8); + +/* Try to get an aligned memory chunk */ +void * +aligned_malloc (size_t align, size_t size); + +void +initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb); diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index 391346a6b..00afe94f1 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -393,7 +393,7 @@ static void XineramaInitData(ScreenPtr pScreen) int i, w, h; RegionNull(&PanoramiXScreenRegion); - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { BoxRec TheBox; RegionRec ScreenRegion; @@ -413,7 +413,7 @@ static void XineramaInitData(ScreenPtr pScreen) PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width; PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height; - for (i = 1; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS_FORWARD_SKIP(i) { pScreen = screenInfo.screens[i]; w = pScreen->x + pScreen->width; h = pScreen->y + pScreen->height; @@ -478,7 +478,7 @@ void PanoramiXExtensionInit(int argc, char *argv[]) * run in non-PanoramiXeen mode. */ - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { pScreen = screenInfo.screens[i]; pScreenPriv = malloc(sizeof(PanoramiXScreenRec)); dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey, @@ -740,7 +740,7 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth) int j, k; Bool found = FALSE; - for (j = 1; j < PanoramiXNumScreens; j++) { + FOR_NSCREENS_FORWARD_SKIP(j) { pScreen = screenInfo.screens[j]; for (k = 0; k < pScreen->numDepths; k++) { if (pScreen->allowedDepths[k].depth == pDepth->depth) { @@ -773,7 +773,7 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual) int j, k; Bool found = FALSE; - for (j = 1; j < PanoramiXNumScreens; j++) { + FOR_NSCREENS_FORWARD_SKIP(j) { pScreen = screenInfo.screens[j]; found = FALSE; @@ -836,7 +836,7 @@ PanoramiXConsolidate(void) saver = malloc(sizeof(PanoramiXRes)); saver->type = XRT_WINDOW; - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { ScreenPtr pScreen = screenInfo.screens[i]; root->info[i].id = pScreen->root->drawable.id; root->u.win.class = InputOutput; @@ -1074,7 +1074,7 @@ ProcXineramaQueryScreens(ClientPtr client) xXineramaScreenInfo scratch; int i; - for(i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { scratch.x_org = screenInfo.screens[i]->x; scratch.y_org = screenInfo.screens[i]->y; scratch.width = screenInfo.screens[i]->width; @@ -1179,7 +1179,7 @@ XineramaGetImageData( depth = (format == XYPixmap) ? 1 : pDraw->depth; - for(i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { BoxRec TheBox; ScreenPtr pScreen; pDraw = pDrawables[i]; diff --git a/xorg-server/Xext/panoramiX.h b/xorg-server/Xext/panoramiX.h index 1bf6194c6..71651e558 100644 --- a/xorg-server/Xext/panoramiX.h +++ b/xorg-server/Xext/panoramiX.h @@ -1,78 +1,80 @@ -/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
-
-
-/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
-
-/*
- * PanoramiX definitions
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _PANORAMIX_H_
-#define _PANORAMIX_H_
-
-#define _PANORAMIX_SERVER
-#include <X11/extensions/panoramiXproto.h>
-#undef _PANORAMIX_SERVER
-#include "gcstruct.h"
-
-
-typedef struct _PanoramiXInfo {
- XID id ;
-} PanoramiXInfo;
-
-typedef struct {
- PanoramiXInfo info[MAXSCREENS];
- RESTYPE type;
- union {
- struct {
- char visibility;
- char class;
- char root;
- } win;
- struct {
- Bool shared;
- } pix;
- struct {
- Bool root;
- } pict;
- char raw_data[4];
- } u;
-} PanoramiXRes;
-
-#define FOR_NSCREENS_FORWARD(j) for(j = 0; j < PanoramiXNumScreens; j++)
-#define FOR_NSCREENS_BACKWARD(j) for(j = PanoramiXNumScreens - 1; j >= 0; j--)
-#define FOR_NSCREENS(j) FOR_NSCREENS_FORWARD(j)
-
-#define IS_SHARED_PIXMAP(r) (((r)->type == XRT_PIXMAP) && (r)->u.pix.shared)
-
-#endif /* _PANORAMIX_H_ */
+/***************************************************************** + +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. + +******************************************************************/ + + +/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */ + +/* + * PanoramiX definitions + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _PANORAMIX_H_ +#define _PANORAMIX_H_ + +#define _PANORAMIX_SERVER +#include <X11/extensions/panoramiXproto.h> +#undef _PANORAMIX_SERVER +#include "gcstruct.h" +#include "dixstruct.h" + +typedef struct _PanoramiXInfo { + XID id ; +} PanoramiXInfo; + +typedef struct { + PanoramiXInfo info[MAXSCREENS]; + RESTYPE type; + union { + struct { + char visibility; + char class; + char root; + } win; + struct { + Bool shared; + } pix; + struct { + Bool root; + } pict; + char raw_data[4]; + } u; +} PanoramiXRes; + +#define FOR_NSCREENS_FORWARD(j) for(j = 0; j < PanoramiXNumScreens; j++) +#define FOR_NSCREENS_FORWARD_SKIP(j) for(j = 1; j < PanoramiXNumScreens; j++) +#define FOR_NSCREENS_BACKWARD(j) for(j = PanoramiXNumScreens - 1; j >= 0; j--) +#define FOR_NSCREENS(j) FOR_NSCREENS_FORWARD(j) + +#define IS_SHARED_PIXMAP(r) (((r)->type == XRT_PIXMAP) && (r)->u.pix.shared) + +#define IS_ROOT_DRAWABLE(d) (((d)->type == XRT_WINDOW) && (d)->u.win.root) +#endif /* _PANORAMIX_H_ */ diff --git a/xorg-server/Xext/panoramiXprocs.c b/xorg-server/Xext/panoramiXprocs.c index 615246bab..9ea461173 100644 --- a/xorg-server/Xext/panoramiXprocs.c +++ b/xorg-server/Xext/panoramiXprocs.c @@ -1,2428 +1,2418 @@ -/*****************************************************************
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-******************************************************************/
-
-/* Massively rewritten by Mark Vojkovich <markv@valinux.com> */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "gcstruct.h"
-#include "colormapst.h"
-#include "scrnintstr.h"
-#include "opaque.h"
-#include "inputstr.h"
-#include "migc.h"
-#include "misc.h"
-#include "dixstruct.h"
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#include "resource.h"
-#include "panoramiXh.h"
-
-#define XINERAMA_IMAGE_BUFSIZE (256*1024)
-#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
- CWDontPropagate | CWOverrideRedirect | CWCursor )
-
-int PanoramiXCreateWindow(ClientPtr client)
-{
- PanoramiXRes *parent, *newWin;
- PanoramiXRes *backPix = NULL;
- PanoramiXRes *bordPix = NULL;
- PanoramiXRes *cmap = NULL;
- REQUEST(xCreateWindowReq);
- int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
- int result, len, j;
- int orig_x, orig_y;
- XID orig_visual, tmp;
- Bool parentIsRoot;
-
- REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&parent, stuff->parent,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if(stuff->class == CopyFromParent)
- stuff->class = parent->u.win.class;
-
- if((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
-
- if ((Mask)stuff->mask & CWBackPixmap) {
- pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pback_offset);
- if ((tmp != None) && (tmp != ParentRelative)) {
- result = dixLookupResourceByType((pointer *)&backPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & CWBorderPixmap) {
- pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pbord_offset);
- if (tmp != CopyFromParent) {
- result = dixLookupResourceByType((pointer *)&bordPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & CWColormap) {
- cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
- tmp = *((CARD32 *) &stuff[1] + cmap_offset);
- if ((tmp != CopyFromParent) && (tmp != None)) {
- result = dixLookupResourceByType((pointer *)&cmap, tmp,
- XRT_COLORMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(!(newWin = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newWin->type = XRT_WINDOW;
- newWin->u.win.visibility = VisibilityNotViewable;
- newWin->u.win.class = stuff->class;
- newWin->u.win.root = FALSE;
- newWin->info[0].id = stuff->wid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newWin->info[j].id = FakeClientID(client->index);
-
- if (stuff->class == InputOnly)
- stuff->visual = CopyFromParent;
- orig_visual = stuff->visual;
- orig_x = stuff->x;
- orig_y = stuff->y;
- parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
- (stuff->parent == screenInfo.screens[0]->screensaver.wid);
- FOR_NSCREENS_BACKWARD(j) {
- stuff->wid = newWin->info[j].id;
- stuff->parent = parent->info[j].id;
- if (parentIsRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- if (backPix)
- *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
- if (bordPix)
- *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
- if (cmap)
- *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
- if ( orig_visual != CopyFromParent )
- stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
- result = (*SavedProcVector[X_CreateWindow])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
- else
- free(newWin);
-
- return result;
-}
-
-
-int PanoramiXChangeWindowAttributes(ClientPtr client)
-{
- PanoramiXRes *win;
- PanoramiXRes *backPix = NULL;
- PanoramiXRes *bordPix = NULL;
- PanoramiXRes *cmap = NULL;
- REQUEST(xChangeWindowAttributesReq);
- int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
- if (Ones(stuff->valueMask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if((win->u.win.class == InputOnly) &&
- (stuff->valueMask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
-
- if ((Mask)stuff->valueMask & CWBackPixmap) {
- pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pback_offset);
- if ((tmp != None) && (tmp != ParentRelative)) {
- result = dixLookupResourceByType((pointer *)&backPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->valueMask & CWBorderPixmap) {
- pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pbord_offset);
- if (tmp != CopyFromParent) {
- result = dixLookupResourceByType((pointer *)&bordPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->valueMask & CWColormap) {
- cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1));
- tmp = *((CARD32 *) &stuff[1] + cmap_offset);
- if ((tmp != CopyFromParent) && (tmp != None)) {
- result = dixLookupResourceByType((pointer *)&cmap, tmp,
- XRT_COLORMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- if (backPix)
- *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
- if (bordPix)
- *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
- if (cmap)
- *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
- result = (*SavedProcVector[X_ChangeWindowAttributes])(client);
- }
-
- return result;
-}
-
-
-int PanoramiXDestroyWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_DestroyWindow])(client);
- if(result != Success) break;
- }
-
- /* Since ProcDestroyWindow is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXDestroySubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_DestroySubwindows])(client);
- if(result != Success) break;
- }
-
- /* DestroySubwindows is using FreeResource which will free
- our resources for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXChangeSaveSet(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xChangeSaveSetReq);
-
- REQUEST_SIZE_MATCH(xChangeSaveSetReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- result = (*SavedProcVector[X_ChangeSaveSet])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXReparentWindow(ClientPtr client)
-{
- PanoramiXRes *win, *parent;
- int result, j;
- int x, y;
- Bool parentIsRoot;
- REQUEST(xReparentWindowReq);
-
- REQUEST_SIZE_MATCH(xReparentWindowReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&parent, stuff->parent,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- x = stuff->x;
- y = stuff->y;
- parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
- (stuff->parent == screenInfo.screens[0]->screensaver.wid);
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- stuff->parent = parent->info[j].id;
- if(parentIsRoot) {
- stuff->x = x - screenInfo.screens[j]->x;
- stuff->y = y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ReparentWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXMapWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_MapWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXMapSubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_MapSubwindows])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXUnmapWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_UnmapWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXUnmapSubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_UnmapSubwindows])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXConfigureWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- PanoramiXRes *sib = NULL;
- WindowPtr pWin;
- int result, j, len, sib_offset = 0, x = 0, y = 0;
- int x_offset = -1;
- int y_offset = -1;
- REQUEST(xConfigureWindowReq);
-
- REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- /* because we need the parent */
- result = dixLookupResourceByType((pointer *)&pWin, stuff->window,
- RT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if ((Mask)stuff->mask & CWSibling) {
- XID tmp;
- sib_offset = Ones((Mask)stuff->mask & (CWSibling - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) {
- result = dixLookupResourceByType((pointer *)&sib, tmp, XRT_WINDOW,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) ||
- (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid)))
- {
- if ((Mask)stuff->mask & CWX) {
- x_offset = 0;
- x = *((CARD32 *)&stuff[1]);
- }
- if ((Mask)stuff->mask & CWY) {
- y_offset = (x_offset == -1) ? 0 : 1;
- y = *((CARD32 *) &stuff[1] + y_offset);
- }
- }
-
- /* have to go forward or you get expose events before
- ConfigureNotify events */
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- if(sib)
- *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id;
- if(x_offset >= 0)
- *((CARD32 *) &stuff[1] + x_offset) = x - screenInfo.screens[j]->x;
- if(y_offset >= 0)
- *((CARD32 *) &stuff[1] + y_offset) = y - screenInfo.screens[j]->y;
- result = (*SavedProcVector[X_ConfigureWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXCirculateWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xCirculateWindowReq);
-
- REQUEST_SIZE_MATCH(xCirculateWindowReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- result = (*SavedProcVector[X_CirculateWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXGetGeometry(ClientPtr client)
-{
- xGetGeometryReply rep;
- DrawablePtr pDraw;
- int rc;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.root = screenInfo.screens[0]->root->drawable.id;
- rep.depth = pDraw->depth;
- rep.width = pDraw->width;
- rep.height = pDraw->height;
- rep.x = rep.y = rep.borderWidth = 0;
-
- if (stuff->id == rep.root) {
- xWindowRoot *root = (xWindowRoot *)
- (ConnectionInfo + connBlockScreenStart);
-
- rep.width = root->pixWidth;
- rep.height = root->pixHeight;
- } else
- if (WindowDrawable(pDraw->type))
- {
- WindowPtr pWin = (WindowPtr)pDraw;
- rep.x = pWin->origin.x - wBorderWidth (pWin);
- rep.y = pWin->origin.y - wBorderWidth (pWin);
- if((pWin->parent == screenInfo.screens[0]->root) ||
- (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- rep.x += screenInfo.screens[0]->x;
- rep.y += screenInfo.screens[0]->y;
- }
- rep.borderWidth = pWin->borderWidth;
- }
-
- WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
- return Success;
-}
-
-int PanoramiXTranslateCoords(ClientPtr client)
-{
- INT16 x, y;
- REQUEST(xTranslateCoordsReq);
- int rc;
- WindowPtr pWin, pDst;
- xTranslateCoordsReply rep;
-
- REQUEST_SIZE_MATCH(xTranslateCoordsReq);
- rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
- if (rc != Success)
- return rc;
- rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
- if (rc != Success)
- return rc;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.sameScreen = xTrue;
- rep.child = None;
-
- if((pWin == screenInfo.screens[0]->root) ||
- (pWin->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- x = stuff->srcX - screenInfo.screens[0]->x;
- y = stuff->srcY - screenInfo.screens[0]->y;
- } else {
- x = pWin->drawable.x + stuff->srcX;
- y = pWin->drawable.y + stuff->srcY;
- }
- pWin = pDst->firstChild;
- while (pWin) {
- BoxRec box;
- if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
- (x < pWin->drawable.x + (int)pWin->drawable.width +
- wBorderWidth (pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
- (y < pWin->drawable.y + (int)pWin->drawable.height +
- wBorderWidth (pWin))
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) ||
- RegionContainsPoint(wBoundingShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box))
- )
- {
- rep.child = pWin->drawable.id;
- pWin = (WindowPtr) NULL;
- }
- else
- pWin = pWin->nextSib;
- }
- rep.dstX = x - pDst->drawable.x;
- rep.dstY = y - pDst->drawable.y;
- if((pDst == screenInfo.screens[0]->root) ||
- (pDst->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- rep.dstX += screenInfo.screens[0]->x;
- rep.dstY += screenInfo.screens[0]->y;
- }
-
- WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
- return Success;
-}
-
-int PanoramiXCreatePixmap(ClientPtr client)
-{
- PanoramiXRes *refDraw, *newPix;
- int result, j;
- REQUEST(xCreatePixmapReq);
-
- REQUEST_SIZE_MATCH(xCreatePixmapReq);
- client->errorValue = stuff->pid;
-
- result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(!(newPix = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPix->type = XRT_PIXMAP;
- newPix->u.pix.shared = FALSE;
- newPix->info[0].id = stuff->pid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newPix->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPix->info[j].id;
- stuff->drawable = refDraw->info[j].id;
- result = (*SavedProcVector[X_CreatePixmap])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
- else
- free(newPix);
-
- return result;
-}
-
-
-int PanoramiXFreePixmap(ClientPtr client)
-{
- PanoramiXRes *pix;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&pix, stuff->id, XRT_PIXMAP,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = pix->info[j].id;
- result = (*SavedProcVector[X_FreePixmap])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreePixmap is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXCreateGC(ClientPtr client)
-{
- PanoramiXRes *refDraw;
- PanoramiXRes *newGC;
- PanoramiXRes *stip = NULL;
- PanoramiXRes *tile = NULL;
- PanoramiXRes *clip = NULL;
- REQUEST(xCreateGCReq);
- int tile_offset = 0, stip_offset = 0, clip_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xCreateGCReq);
-
- client->errorValue = stuff->gc;
- len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if ((Mask)stuff->mask & GCTile) {
- tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
- result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCStipple) {
- stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
- result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCClipMask) {
- clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
- result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(!(newGC = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newGC->type = XRT_GC;
- newGC->info[0].id = stuff->gc;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newGC->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = newGC->info[j].id;
- stuff->drawable = refDraw->info[j].id;
- if (tile)
- *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
- if (stip)
- *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
- if (clip)
- *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
- result = (*SavedProcVector[X_CreateGC])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newGC->info[0].id, XRT_GC, newGC);
- else
- free(newGC);
-
- return result;
-}
-
-int PanoramiXChangeGC(ClientPtr client)
-{
- PanoramiXRes *gc;
- PanoramiXRes *stip = NULL;
- PanoramiXRes *tile = NULL;
- PanoramiXRes *clip = NULL;
- REQUEST(xChangeGCReq);
- int tile_offset = 0, stip_offset = 0, clip_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xChangeGCReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- if ((Mask)stuff->mask & GCTile) {
- tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
- result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCStipple) {
- stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
- result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCClipMask) {
- clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
- result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- if (tile)
- *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
- if (stip)
- *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
- if (clip)
- *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
- result = (*SavedProcVector[X_ChangeGC])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXCopyGC(ClientPtr client)
-{
- PanoramiXRes *srcGC, *dstGC;
- int result, j;
- REQUEST(xCopyGCReq);
-
- REQUEST_SIZE_MATCH(xCopyGCReq);
-
- result = dixLookupResourceByType((pointer *)&srcGC, stuff->srcGC, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&dstGC, stuff->dstGC, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS(j) {
- stuff->srcGC = srcGC->info[j].id;
- stuff->dstGC = dstGC->info[j].id;
- result = (*SavedProcVector[X_CopyGC])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXSetDashes(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xSetDashesReq);
-
- REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- result = (*SavedProcVector[X_SetDashes])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXSetClipRectangles(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xSetClipRectanglesReq);
-
- REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- result = (*SavedProcVector[X_SetClipRectangles])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXFreeGC(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->id, XRT_GC,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = gc->info[j].id;
- result = (*SavedProcVector[X_FreeGC])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreeGC is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXClearToBackground(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j, x, y;
- Bool isRoot;
- REQUEST(xClearAreaReq);
-
- REQUEST_SIZE_MATCH(xClearAreaReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- x = stuff->x;
- y = stuff->y;
- isRoot = win->u.win.root;
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- if(isRoot) {
- stuff->x = x - screenInfo.screens[j]->x;
- stuff->y = y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ClearArea])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-/*
- For Window to Pixmap copies you're screwed since each screen's
- pixmap will look like what it sees on its screen. Unless the
- screens overlap and the window lies on each, the two copies
- will be out of sync. To remedy this we do a GetImage and PutImage
- in place of the copy. Doing this as a single Image isn't quite
- correct since it will include the obscured areas but we will
- have to fix this later. (MArk).
-*/
-
-int PanoramiXCopyArea(ClientPtr client)
-{
- int j, result, srcx, srcy, dstx, dsty;
- PanoramiXRes *gc, *src, *dst;
- Bool srcIsRoot = FALSE;
- Bool dstIsRoot = FALSE;
- Bool srcShared, dstShared;
- REQUEST(xCopyAreaReq);
-
- REQUEST_SIZE_MATCH(xCopyAreaReq);
-
- result = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- srcShared = IS_SHARED_PIXMAP(src);
-
- result = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- dstShared = IS_SHARED_PIXMAP(dst);
-
- if(dstShared && srcShared)
- return (* SavedProcVector[X_CopyArea])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- if((dst->type == XRT_WINDOW) && dst->u.win.root)
- dstIsRoot = TRUE;
- if((src->type == XRT_WINDOW) && src->u.win.root)
- srcIsRoot = TRUE;
-
- srcx = stuff->srcX; srcy = stuff->srcY;
- dstx = stuff->dstX; dsty = stuff->dstY;
- if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
- DrawablePtr drawables[MAXSCREENS];
- DrawablePtr pDst;
- GCPtr pGC;
- char *data;
- int pitch, rc;
-
- FOR_NSCREENS(j) {
- rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- }
-
- pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
- if(!(data = calloc(1, stuff->height * pitch)))
- return BadAlloc;
-
- XineramaGetImageData(drawables, srcx, srcy,
- stuff->width, stuff->height, ZPixmap, ~0, data, pitch,
- srcIsRoot);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess);
- if(drawables[0]->depth != pDst->depth) {
- client->errorValue = stuff->dstDrawable;
- free(data);
- return BadMatch;
- }
-
- (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
- stuff->width, stuff->height,
- 0, ZPixmap, data);
-
- if(dstShared) break;
- }
-
- free(data);
- } else {
- DrawablePtr pDst = NULL, pSrc = NULL;
- GCPtr pGC = NULL;
- RegionRec totalReg;
- int rc;
-
- RegionNull(&totalReg);
- FOR_NSCREENS_BACKWARD(j) {
- RegionPtr pRgn;
- stuff->dstDrawable = dst->info[j].id;
- stuff->srcDrawable = src->info[j].id;
- stuff->gc = gc->info[j].id;
- if (srcIsRoot) {
- stuff->srcX = srcx - screenInfo.screens[j]->x;
- stuff->srcY = srcy - screenInfo.screens[j]->y;
- }
- if (dstIsRoot) {
- stuff->dstX = dstx - screenInfo.screens[j]->x;
- stuff->dstY = dsty - screenInfo.screens[j]->y;
- }
-
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
-
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if ((pDst->pScreen != pSrc->pScreen) ||
- (pDst->depth != pSrc->depth)) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- } else
- pSrc = pDst;
-
- pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
- stuff->srcX, stuff->srcY,
- stuff->width, stuff->height,
- stuff->dstX, stuff->dstY);
- if(pGC->graphicsExposures && pRgn) {
- if(srcIsRoot) {
- RegionTranslate(pRgn,
- screenInfo.screens[j]->x, screenInfo.screens[j]->y);
- }
- RegionAppend(&totalReg, pRgn);
- RegionDestroy(pRgn);
- }
-
- if(dstShared)
- break;
- }
-
- if(pGC->graphicsExposures) {
- Bool overlap;
- RegionValidate(&totalReg, &overlap);
- (*pDst->pScreen->SendGraphicsExpose)(
- client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
- RegionUninit(&totalReg);
- }
- }
-
- return Success;
-}
-
-
-int PanoramiXCopyPlane(ClientPtr client)
-{
- int j, srcx, srcy, dstx, dsty, rc;
- PanoramiXRes *gc, *src, *dst;
- Bool srcIsRoot = FALSE;
- Bool dstIsRoot = FALSE;
- Bool srcShared, dstShared;
- DrawablePtr psrcDraw, pdstDraw = NULL;
- GCPtr pGC = NULL;
- RegionRec totalReg;
- REQUEST(xCopyPlaneReq);
-
- REQUEST_SIZE_MATCH(xCopyPlaneReq);
-
- rc = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- srcShared = IS_SHARED_PIXMAP(src);
-
- rc = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- dstShared = IS_SHARED_PIXMAP(dst);
-
- if(dstShared && srcShared)
- return (* SavedProcVector[X_CopyPlane])(client);
-
- rc = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (rc != Success)
- return rc;
-
- if((dst->type == XRT_WINDOW) && dst->u.win.root)
- dstIsRoot = TRUE;
- if((src->type == XRT_WINDOW) && src->u.win.root)
- srcIsRoot = TRUE;
-
- srcx = stuff->srcX; srcy = stuff->srcY;
- dstx = stuff->dstX; dsty = stuff->dstY;
-
- RegionNull(&totalReg);
- FOR_NSCREENS_BACKWARD(j) {
- RegionPtr pRgn;
- stuff->dstDrawable = dst->info[j].id;
- stuff->srcDrawable = src->info[j].id;
- stuff->gc = gc->info[j].id;
- if (srcIsRoot) {
- stuff->srcX = srcx - screenInfo.screens[j]->x;
- stuff->srcY = srcy - screenInfo.screens[j]->y;
- }
- if (dstIsRoot) {
- stuff->dstX = dstx - screenInfo.screens[j]->x;
- stuff->dstY = dsty - screenInfo.screens[j]->y;
- }
-
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (pdstDraw->pScreen != psrcDraw->pScreen) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- } else
- psrcDraw = pdstDraw;
-
- if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
- (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
- client->errorValue = stuff->bitPlane;
- return BadValue;
- }
-
- pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC,
- stuff->srcX, stuff->srcY,
- stuff->width, stuff->height,
- stuff->dstX, stuff->dstY, stuff->bitPlane);
- if(pGC->graphicsExposures && pRgn) {
- RegionAppend(&totalReg, pRgn);
- RegionDestroy(pRgn);
- }
-
- if(dstShared)
- break;
- }
-
- if(pGC->graphicsExposures) {
- Bool overlap;
- RegionValidate(&totalReg, &overlap);
- (*pdstDraw->pScreen->SendGraphicsExpose)(
- client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0);
- RegionUninit(&totalReg);
- }
-
- return Success;
-}
-
-
-int PanoramiXPolyPoint(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- int result, npoint, j;
- xPoint *origPts;
- Bool isRoot;
- REQUEST(xPolyPointReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyPointReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyPoint])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
- if (npoint > 0) {
- origPts = malloc(npoint * sizeof(xPoint));
- memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPoint *pnts = (xPoint*)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyPoint])(client);
- if(result != Success) break;
- }
- free(origPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyLine(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- int result, npoint, j;
- xPoint *origPts;
- Bool isRoot;
- REQUEST(xPolyLineReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyLineReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyLine])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
- if (npoint > 0){
- origPts = malloc(npoint * sizeof(xPoint));
- memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPoint *pnts = (xPoint*)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyLine])(client);
- if(result != Success) break;
- }
- free(origPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolySegment(ClientPtr client)
-{
- int result, nsegs, i, j;
- PanoramiXRes *gc, *draw;
- xSegment *origSegs;
- Bool isRoot;
- REQUEST(xPolySegmentReq);
-
- REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolySegment])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
- if(nsegs & 4) return BadLength;
- nsegs >>= 3;
- if (nsegs > 0) {
- origSegs = malloc(nsegs * sizeof(xSegment));
- memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xSegment *segs = (xSegment*)&stuff[1];
-
- for (i = nsegs; i--; segs++) {
- segs->x1 -= x_off;
- segs->x2 -= x_off;
- segs->y1 -= y_off;
- segs->y2 -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolySegment])(client);
- if(result != Success) break;
- }
- free(origSegs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyRectangle(ClientPtr client)
-{
- int result, nrects, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xRectangle *origRecs;
- REQUEST(xPolyRectangleReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyRectangle])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
- if(nrects & 4) return BadLength;
- nrects >>= 3;
- if (nrects > 0){
- origRecs = malloc(nrects * sizeof(xRectangle));
- memcpy((char *)origRecs,(char *)&stuff[1],nrects * sizeof(xRectangle));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
-
- if(x_off || y_off) {
- xRectangle *rects = (xRectangle *) &stuff[1];
-
- for (i = nrects; i--; rects++) {
- rects->x -= x_off;
- rects->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyRectangle])(client);
- if(result != Success) break;
- }
- free(origRecs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyArc(ClientPtr client)
-{
- int result, narcs, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xArc *origArcs;
- REQUEST(xPolyArcReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyArcReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyArc])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
- if(narcs % sizeof(xArc)) return BadLength;
- narcs /= sizeof(xArc);
- if (narcs > 0){
- origArcs = malloc(narcs * sizeof(xArc));
- memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xArc *arcs = (xArc *) &stuff[1];
-
- for (i = narcs; i--; arcs++) {
- arcs->x -= x_off;
- arcs->y -= y_off;
- }
- }
- }
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyArc])(client);
- if(result != Success) break;
- }
- free(origArcs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXFillPoly(ClientPtr client)
-{
- int result, count, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- DDXPointPtr locPts;
- REQUEST(xFillPolyReq);
-
- REQUEST_AT_LEAST_SIZE(xFillPolyReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_FillPoly])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
- if (count > 0){
- locPts = malloc(count * sizeof(DDXPointRec));
- memcpy((char *)locPts, (char *)&stuff[1], count * sizeof(DDXPointRec));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- DDXPointPtr pnts = (DDXPointPtr)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : count;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_FillPoly])(client);
- if(result != Success) break;
- }
- free(locPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyFillRectangle(ClientPtr client)
-{
- int result, things, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xRectangle *origRects;
- REQUEST(xPolyFillRectangleReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyFillRectangle])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
- if(things & 4) return BadLength;
- things >>= 3;
- if (things > 0){
- origRects = malloc(things * sizeof(xRectangle));
- memcpy((char*)origRects,(char*)&stuff[1], things * sizeof(xRectangle));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origRects, things * sizeof(xRectangle));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xRectangle *rects = (xRectangle *) &stuff[1];
-
- for (i = things; i--; rects++) {
- rects->x -= x_off;
- rects->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyFillRectangle])(client);
- if(result != Success) break;
- }
- free(origRects);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyFillArc(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, narcs, i, j;
- xArc *origArcs;
- REQUEST(xPolyFillArcReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyFillArc])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
- if (narcs % sizeof(xArc)) return BadLength;
- narcs /= sizeof(xArc);
- if (narcs > 0) {
- origArcs = malloc(narcs * sizeof(xArc));
- memcpy((char *) origArcs, (char *)&stuff[1], narcs * sizeof(xArc));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xArc *arcs = (xArc *) &stuff[1];
-
- for (i = narcs; i--; arcs++) {
- arcs->x -= x_off;
- arcs->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyFillArc])(client);
- if(result != Success) break;
- }
- free(origArcs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPutImage(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int j, result, orig_x, orig_y;
- REQUEST(xPutImageReq);
-
- REQUEST_AT_LEAST_SIZE(xPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PutImage])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->dstX;
- orig_y = stuff->dstY;
- FOR_NSCREENS_BACKWARD(j){
- if (isRoot) {
- stuff->dstX = orig_x - screenInfo.screens[j]->x;
- stuff->dstY = orig_y - screenInfo.screens[j]->y;
- }
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PutImage])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXGetImage(ClientPtr client)
-{
- DrawablePtr drawables[MAXSCREENS];
- DrawablePtr pDraw;
- PanoramiXRes *draw;
- xGetImageReply xgi;
- Bool isRoot;
- char *pBuf;
- int i, x, y, w, h, format, rc;
- Mask plane = 0, planemask;
- int linesDone, nlines, linesPerBuf;
- long widthBytesLine, length;
-
- REQUEST(xGetImageReq);
-
- REQUEST_SIZE_MATCH(xGetImageReq);
-
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- if(draw->type == XRT_PIXMAP)
- return (*SavedProcVector[X_GetImage])(client);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if(!((WindowPtr)pDraw)->realized)
- return BadMatch;
-
- x = stuff->x;
- y = stuff->y;
- w = stuff->width;
- h = stuff->height;
- format = stuff->format;
- planemask = stuff->planeMask;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- if(isRoot) {
- if( /* check for being onscreen */
- x < 0 || x + w > PanoramiXPixWidth ||
- y < 0 || y + h > PanoramiXPixHeight )
- return BadMatch;
- } else {
- if( /* check for being onscreen */
- screenInfo.screens[0]->x + pDraw->x + x < 0 ||
- screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
- screenInfo.screens[0]->y + pDraw->y + y < 0 ||
- screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
- /* check for being inside of border */
- x < - wBorderWidth((WindowPtr)pDraw) ||
- x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- y < -wBorderWidth((WindowPtr)pDraw) ||
- y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
- return BadMatch;
- }
-
- drawables[0] = pDraw;
- for(i = 1; i < PanoramiXNumScreens; i++) {
- rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- }
-
- xgi.visual = wVisual (((WindowPtr) pDraw));
- xgi.type = X_Reply;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
- if(format == ZPixmap) {
- widthBytesLine = PixmapBytePad(w, pDraw->depth);
- length = widthBytesLine * h;
-
-
- } else {
- widthBytesLine = BitmapBytePad(w);
- plane = ((Mask)1) << (pDraw->depth - 1);
- /* only planes asked for */
- length = widthBytesLine * h *
- Ones(planemask & (plane | (plane - 1)));
-
- }
-
- xgi.length = bytes_to_int32(length);
-
- if (widthBytesLine == 0 || h == 0)
- linesPerBuf = 0;
- else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE)
- linesPerBuf = 1;
- else {
- linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine;
- if (linesPerBuf > h)
- linesPerBuf = h;
- }
- length = linesPerBuf * widthBytesLine;
- if(!(pBuf = malloc(length)))
- return BadAlloc;
-
- WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
-
- if (linesPerBuf == 0) {
- /* nothing to do */
- }
- else if (format == ZPixmap) {
- linesDone = 0;
- while (h - linesDone > 0) {
- nlines = min(linesPerBuf, h - linesDone);
-
- if(pDraw->depth == 1)
- memset(pBuf, 0, nlines * widthBytesLine);
-
- XineramaGetImageData(drawables, x, y + linesDone, w, nlines,
- format, planemask, pBuf, widthBytesLine, isRoot);
-
- (void)WriteToClient(client,
- (int)(nlines * widthBytesLine),
- pBuf);
- linesDone += nlines;
- }
- } else { /* XYPixmap */
- for (; plane; plane >>= 1) {
- if (planemask & plane) {
- linesDone = 0;
- while (h - linesDone > 0) {
- nlines = min(linesPerBuf, h - linesDone);
-
- memset(pBuf, 0, nlines * widthBytesLine);
-
- XineramaGetImageData(drawables, x, y + linesDone, w,
- nlines, format, plane, pBuf,
- widthBytesLine, isRoot);
-
- (void)WriteToClient(client,
- (int)(nlines * widthBytesLine),
- pBuf);
-
- linesDone += nlines;
- }
- }
- }
- }
- free(pBuf);
- return Success;
-}
-
-
-/* The text stuff should be rewritten so that duplication happens
- at the GlyphBlt level. That is, loading the font and getting
- the glyphs should only happen once */
-
-int
-PanoramiXPolyText8(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, j;
- int orig_x, orig_y;
- REQUEST(xPolyTextReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyTextReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyText8])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_PolyText8])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-int
-PanoramiXPolyText16(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, j;
- int orig_x, orig_y;
- REQUEST(xPolyTextReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyTextReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyText16])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_PolyText16])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXImageText8(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int orig_x, orig_y;
- REQUEST(xImageTextReq);
-
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_ImageText8])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ImageText8])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXImageText16(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int orig_x, orig_y;
- REQUEST(xImageTextReq);
-
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_ImageText16])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ImageText16])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-
-int PanoramiXCreateColormap(ClientPtr client)
-{
- PanoramiXRes *win, *newCmap;
- int result, j, orig_visual;
- REQUEST(xCreateColormapReq);
-
- REQUEST_SIZE_MATCH(xCreateColormapReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- if(!(newCmap = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newCmap->type = XRT_COLORMAP;
- newCmap->info[0].id = stuff->mid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newCmap->info[j].id = FakeClientID(client->index);
-
- orig_visual = stuff->visual;
- FOR_NSCREENS_BACKWARD(j){
- stuff->mid = newCmap->info[j].id;
- stuff->window = win->info[j].id;
- stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
- result = (* SavedProcVector[X_CreateColormap])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
- else
- free(newCmap);
-
- return result;
-}
-
-
-int PanoramiXFreeColormap(ClientPtr client)
-{
- PanoramiXRes *cmap;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_FreeColormap])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreeColormap is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int
-PanoramiXCopyColormapAndFree(ClientPtr client)
-{
- PanoramiXRes *cmap, *newCmap;
- int result, j;
- REQUEST(xCopyColormapAndFreeReq);
-
- REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
-
- client->errorValue = stuff->srcCmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->srcCmap,
- XRT_COLORMAP, client,
- DixReadAccess | DixWriteAccess);
- if (result != Success)
- return result;
-
- if(!(newCmap = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newCmap->type = XRT_COLORMAP;
- newCmap->info[0].id = stuff->mid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newCmap->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->srcCmap = cmap->info[j].id;
- stuff->mid = newCmap->info[j].id;
- result = (* SavedProcVector[X_CopyColormapAndFree])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
- else
- free(newCmap);
-
- return result;
-}
-
-
-int PanoramiXInstallColormap(ClientPtr client)
-{
- REQUEST(xResourceReq);
- int result, j;
- PanoramiXRes *cmap;
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_InstallColormap])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXUninstallColormap(ClientPtr client)
-{
- REQUEST(xResourceReq);
- int result, j;
- PanoramiXRes *cmap;
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_UninstallColormap])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorReq);
-
- REQUEST_SIZE_MATCH(xAllocColorReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColor])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocNamedColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocNamedColorReq);
-
- REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocNamedColor])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColorCells(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorCellsReq);
-
- REQUEST_SIZE_MATCH(xAllocColorCellsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColorCells])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColorPlanes(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorPlanesReq);
-
- REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColorPlanes])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-
-int PanoramiXFreeColors(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xFreeColorsReq);
-
- REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_FreeColors])(client);
- }
- return result;
-}
-
-
-int PanoramiXStoreColors(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xStoreColorsReq);
-
- REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_StoreColors])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXStoreNamedColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xStoreNamedColorReq);
-
- REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_StoreNamedColor])(client);
- if(result != Success) break;
- }
- return result;
-}
+/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ + +/* Massively rewritten by Mark Vojkovich <markv@valinux.com> */ + + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xproto.h> +#include "windowstr.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "colormapst.h" +#include "scrnintstr.h" +#include "opaque.h" +#include "inputstr.h" +#include "migc.h" +#include "misc.h" +#include "dixstruct.h" +#include "panoramiX.h" +#include "panoramiXsrv.h" +#include "resource.h" +#include "panoramiXh.h" + +#define XINERAMA_IMAGE_BUFSIZE (256*1024) +#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ + CWDontPropagate | CWOverrideRedirect | CWCursor ) + +int PanoramiXCreateWindow(ClientPtr client) +{ + PanoramiXRes *parent, *newWin; + PanoramiXRes *backPix = NULL; + PanoramiXRes *bordPix = NULL; + PanoramiXRes *cmap = NULL; + REQUEST(xCreateWindowReq); + int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; + int result, len, j; + int orig_x, orig_y; + XID orig_visual, tmp; + Bool parentIsRoot; + + REQUEST_AT_LEAST_SIZE(xCreateWindowReq); + + len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&parent, stuff->parent, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if(stuff->class == CopyFromParent) + stuff->class = parent->u.win.class; + + if((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK))) + return BadMatch; + + if ((Mask)stuff->mask & CWBackPixmap) { + pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pback_offset); + if ((tmp != None) && (tmp != ParentRelative)) { + result = dixLookupResourceByType((pointer *)&backPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & CWBorderPixmap) { + pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pbord_offset); + if (tmp != CopyFromParent) { + result = dixLookupResourceByType((pointer *)&bordPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & CWColormap) { + cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); + tmp = *((CARD32 *) &stuff[1] + cmap_offset); + if ((tmp != CopyFromParent) && (tmp != None)) { + result = dixLookupResourceByType((pointer *)&cmap, tmp, + XRT_COLORMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(!(newWin = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newWin->type = XRT_WINDOW; + newWin->u.win.visibility = VisibilityNotViewable; + newWin->u.win.class = stuff->class; + newWin->u.win.root = FALSE; + panoramix_setup_ids(newWin, client, stuff->wid); + + if (stuff->class == InputOnly) + stuff->visual = CopyFromParent; + orig_visual = stuff->visual; + orig_x = stuff->x; + orig_y = stuff->y; + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || + (stuff->parent == screenInfo.screens[0]->screensaver.wid); + FOR_NSCREENS_BACKWARD(j) { + stuff->wid = newWin->info[j].id; + stuff->parent = parent->info[j].id; + if (parentIsRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + if (backPix) + *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id; + if (bordPix) + *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id; + if (cmap) + *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id; + if ( orig_visual != CopyFromParent ) + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); + result = (*SavedProcVector[X_CreateWindow])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newWin->info[0].id, XRT_WINDOW, newWin); + else + free(newWin); + + return result; +} + + +int PanoramiXChangeWindowAttributes(ClientPtr client) +{ + PanoramiXRes *win; + PanoramiXRes *backPix = NULL; + PanoramiXRes *bordPix = NULL; + PanoramiXRes *cmap = NULL; + REQUEST(xChangeWindowAttributesReq); + int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); + + len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); + if (Ones(stuff->valueMask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if((win->u.win.class == InputOnly) && + (stuff->valueMask & (~INPUTONLY_LEGAL_MASK))) + return BadMatch; + + if ((Mask)stuff->valueMask & CWBackPixmap) { + pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pback_offset); + if ((tmp != None) && (tmp != ParentRelative)) { + result = dixLookupResourceByType((pointer *)&backPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->valueMask & CWBorderPixmap) { + pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pbord_offset); + if (tmp != CopyFromParent) { + result = dixLookupResourceByType((pointer *)&bordPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->valueMask & CWColormap) { + cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1)); + tmp = *((CARD32 *) &stuff[1] + cmap_offset); + if ((tmp != CopyFromParent) && (tmp != None)) { + result = dixLookupResourceByType((pointer *)&cmap, tmp, + XRT_COLORMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + if (backPix) + *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id; + if (bordPix) + *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id; + if (cmap) + *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id; + result = (*SavedProcVector[X_ChangeWindowAttributes])(client); + } + + return result; +} + + +int PanoramiXDestroyWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_DestroyWindow])(client); + if(result != Success) break; + } + + /* Since ProcDestroyWindow is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXDestroySubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_DestroySubwindows])(client); + if(result != Success) break; + } + + /* DestroySubwindows is using FreeResource which will free + our resources for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXChangeSaveSet(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xChangeSaveSetReq); + + REQUEST_SIZE_MATCH(xChangeSaveSetReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + result = (*SavedProcVector[X_ChangeSaveSet])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXReparentWindow(ClientPtr client) +{ + PanoramiXRes *win, *parent; + int result, j; + int x, y; + Bool parentIsRoot; + REQUEST(xReparentWindowReq); + + REQUEST_SIZE_MATCH(xReparentWindowReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&parent, stuff->parent, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + x = stuff->x; + y = stuff->y; + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || + (stuff->parent == screenInfo.screens[0]->screensaver.wid); + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + stuff->parent = parent->info[j].id; + if(parentIsRoot) { + stuff->x = x - screenInfo.screens[j]->x; + stuff->y = y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ReparentWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXMapWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_MapWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXMapSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_MapSubwindows])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXUnmapWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_UnmapWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXUnmapSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_UnmapSubwindows])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXConfigureWindow(ClientPtr client) +{ + PanoramiXRes *win; + PanoramiXRes *sib = NULL; + WindowPtr pWin; + int result, j, len, sib_offset = 0, x = 0, y = 0; + int x_offset = -1; + int y_offset = -1; + REQUEST(xConfigureWindowReq); + + REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); + + len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + /* because we need the parent */ + result = dixLookupResourceByType((pointer *)&pWin, stuff->window, + RT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if ((Mask)stuff->mask & CWSibling) { + XID tmp; + sib_offset = Ones((Mask)stuff->mask & (CWSibling - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) { + result = dixLookupResourceByType((pointer *)&sib, tmp, XRT_WINDOW, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) || + (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid))) + { + if ((Mask)stuff->mask & CWX) { + x_offset = 0; + x = *((CARD32 *)&stuff[1]); + } + if ((Mask)stuff->mask & CWY) { + y_offset = (x_offset == -1) ? 0 : 1; + y = *((CARD32 *) &stuff[1] + y_offset); + } + } + + /* have to go forward or you get expose events before + ConfigureNotify events */ + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + if(sib) + *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id; + if(x_offset >= 0) + *((CARD32 *) &stuff[1] + x_offset) = x - screenInfo.screens[j]->x; + if(y_offset >= 0) + *((CARD32 *) &stuff[1] + y_offset) = y - screenInfo.screens[j]->y; + result = (*SavedProcVector[X_ConfigureWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXCirculateWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xCirculateWindowReq); + + REQUEST_SIZE_MATCH(xCirculateWindowReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + result = (*SavedProcVector[X_CirculateWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXGetGeometry(ClientPtr client) +{ + xGetGeometryReply rep; + DrawablePtr pDraw; + int rc; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.root = screenInfo.screens[0]->root->drawable.id; + rep.depth = pDraw->depth; + rep.width = pDraw->width; + rep.height = pDraw->height; + rep.x = rep.y = rep.borderWidth = 0; + + if (stuff->id == rep.root) { + xWindowRoot *root = (xWindowRoot *) + (ConnectionInfo + connBlockScreenStart); + + rep.width = root->pixWidth; + rep.height = root->pixHeight; + } else + if (WindowDrawable(pDraw->type)) + { + WindowPtr pWin = (WindowPtr)pDraw; + rep.x = pWin->origin.x - wBorderWidth (pWin); + rep.y = pWin->origin.y - wBorderWidth (pWin); + if((pWin->parent == screenInfo.screens[0]->root) || + (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + rep.x += screenInfo.screens[0]->x; + rep.y += screenInfo.screens[0]->y; + } + rep.borderWidth = pWin->borderWidth; + } + + WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); + return Success; +} + +int PanoramiXTranslateCoords(ClientPtr client) +{ + INT16 x, y; + REQUEST(xTranslateCoordsReq); + int rc; + WindowPtr pWin, pDst; + xTranslateCoordsReply rep; + + REQUEST_SIZE_MATCH(xTranslateCoordsReq); + rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess); + if (rc != Success) + return rc; + rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess); + if (rc != Success) + return rc; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.sameScreen = xTrue; + rep.child = None; + + if((pWin == screenInfo.screens[0]->root) || + (pWin->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + x = stuff->srcX - screenInfo.screens[0]->x; + y = stuff->srcY - screenInfo.screens[0]->y; + } else { + x = pWin->drawable.x + stuff->srcX; + y = pWin->drawable.y + stuff->srcY; + } + pWin = pDst->firstChild; + while (pWin) { + BoxRec box; + if ((pWin->mapped) && + (x >= pWin->drawable.x - wBorderWidth (pWin)) && + (x < pWin->drawable.x + (int)pWin->drawable.width + + wBorderWidth (pWin)) && + (y >= pWin->drawable.y - wBorderWidth (pWin)) && + (y < pWin->drawable.y + (int)pWin->drawable.height + + wBorderWidth (pWin)) + /* When a window is shaped, a further check + * is made to see if the point is inside + * borderSize + */ + && (!wBoundingShape(pWin) || + RegionContainsPoint(wBoundingShape(pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box)) + ) + { + rep.child = pWin->drawable.id; + pWin = (WindowPtr) NULL; + } + else + pWin = pWin->nextSib; + } + rep.dstX = x - pDst->drawable.x; + rep.dstY = y - pDst->drawable.y; + if((pDst == screenInfo.screens[0]->root) || + (pDst->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + rep.dstX += screenInfo.screens[0]->x; + rep.dstY += screenInfo.screens[0]->y; + } + + WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); + return Success; +} + +int PanoramiXCreatePixmap(ClientPtr client) +{ + PanoramiXRes *refDraw, *newPix; + int result, j; + REQUEST(xCreatePixmapReq); + + REQUEST_SIZE_MATCH(xCreatePixmapReq); + client->errorValue = stuff->pid; + + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = FALSE; + panoramix_setup_ids(newPix, client, stuff->pid); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPix->info[j].id; + stuff->drawable = refDraw->info[j].id; + result = (*SavedProcVector[X_CreatePixmap])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPix->info[0].id, XRT_PIXMAP, newPix); + else + free(newPix); + + return result; +} + + +int PanoramiXFreePixmap(ClientPtr client) +{ + PanoramiXRes *pix; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&pix, stuff->id, XRT_PIXMAP, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = pix->info[j].id; + result = (*SavedProcVector[X_FreePixmap])(client); + if(result != Success) break; + } + + /* Since ProcFreePixmap is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXCreateGC(ClientPtr client) +{ + PanoramiXRes *refDraw; + PanoramiXRes *newGC; + PanoramiXRes *stip = NULL; + PanoramiXRes *tile = NULL; + PanoramiXRes *clip = NULL; + REQUEST(xCreateGCReq); + int tile_offset = 0, stip_offset = 0, clip_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xCreateGCReq); + + client->errorValue = stuff->gc; + len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if ((Mask)stuff->mask & GCTile) { + tile_offset = Ones((Mask)stuff->mask & (GCTile - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) { + result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCStipple) { + stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) { + result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCClipMask) { + clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) { + result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(!(newGC = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newGC->type = XRT_GC; + panoramix_setup_ids(newGC, client, stuff->gc); + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = newGC->info[j].id; + stuff->drawable = refDraw->info[j].id; + if (tile) + *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id; + if (stip) + *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id; + if (clip) + *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id; + result = (*SavedProcVector[X_CreateGC])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newGC->info[0].id, XRT_GC, newGC); + else + free(newGC); + + return result; +} + +int PanoramiXChangeGC(ClientPtr client) +{ + PanoramiXRes *gc; + PanoramiXRes *stip = NULL; + PanoramiXRes *tile = NULL; + PanoramiXRes *clip = NULL; + REQUEST(xChangeGCReq); + int tile_offset = 0, stip_offset = 0, clip_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xChangeGCReq); + + len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + if ((Mask)stuff->mask & GCTile) { + tile_offset = Ones((Mask)stuff->mask & (GCTile - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) { + result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCStipple) { + stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) { + result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCClipMask) { + clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) { + result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + if (tile) + *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id; + if (stip) + *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id; + if (clip) + *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id; + result = (*SavedProcVector[X_ChangeGC])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXCopyGC(ClientPtr client) +{ + PanoramiXRes *srcGC, *dstGC; + int result, j; + REQUEST(xCopyGCReq); + + REQUEST_SIZE_MATCH(xCopyGCReq); + + result = dixLookupResourceByType((pointer *)&srcGC, stuff->srcGC, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&dstGC, stuff->dstGC, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS(j) { + stuff->srcGC = srcGC->info[j].id; + stuff->dstGC = dstGC->info[j].id; + result = (*SavedProcVector[X_CopyGC])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXSetDashes(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xSetDashesReq); + + REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + result = (*SavedProcVector[X_SetDashes])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXSetClipRectangles(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xSetClipRectanglesReq); + + REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + result = (*SavedProcVector[X_SetClipRectangles])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXFreeGC(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&gc, stuff->id, XRT_GC, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = gc->info[j].id; + result = (*SavedProcVector[X_FreeGC])(client); + if(result != Success) break; + } + + /* Since ProcFreeGC is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXClearToBackground(ClientPtr client) +{ + PanoramiXRes *win; + int result, j, x, y; + Bool isRoot; + REQUEST(xClearAreaReq); + + REQUEST_SIZE_MATCH(xClearAreaReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + x = stuff->x; + y = stuff->y; + isRoot = win->u.win.root; + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + if(isRoot) { + stuff->x = x - screenInfo.screens[j]->x; + stuff->y = y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ClearArea])(client); + if(result != Success) break; + } + + return result; +} + + +/* + For Window to Pixmap copies you're screwed since each screen's + pixmap will look like what it sees on its screen. Unless the + screens overlap and the window lies on each, the two copies + will be out of sync. To remedy this we do a GetImage and PutImage + in place of the copy. Doing this as a single Image isn't quite + correct since it will include the obscured areas but we will + have to fix this later. (MArk). +*/ + +int PanoramiXCopyArea(ClientPtr client) +{ + int j, result, srcx, srcy, dstx, dsty; + PanoramiXRes *gc, *src, *dst; + Bool srcIsRoot = FALSE; + Bool dstIsRoot = FALSE; + Bool srcShared, dstShared; + REQUEST(xCopyAreaReq); + + REQUEST_SIZE_MATCH(xCopyAreaReq); + + result = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + srcShared = IS_SHARED_PIXMAP(src); + + result = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + dstShared = IS_SHARED_PIXMAP(dst); + + if(dstShared && srcShared) + return (* SavedProcVector[X_CopyArea])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + if((dst->type == XRT_WINDOW) && dst->u.win.root) + dstIsRoot = TRUE; + if((src->type == XRT_WINDOW) && src->u.win.root) + srcIsRoot = TRUE; + + srcx = stuff->srcX; srcy = stuff->srcY; + dstx = stuff->dstX; dsty = stuff->dstY; + if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) { + DrawablePtr drawables[MAXSCREENS]; + DrawablePtr pDst; + GCPtr pGC; + char *data; + int pitch, rc; + + FOR_NSCREENS(j) { + rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + } + + pitch = PixmapBytePad(stuff->width, drawables[0]->depth); + if(!(data = calloc(1, stuff->height * pitch))) + return BadAlloc; + + XineramaGetImageData(drawables, srcx, srcy, + stuff->width, stuff->height, ZPixmap, ~0, data, pitch, + srcIsRoot); + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess); + if(drawables[0]->depth != pDst->depth) { + client->errorValue = stuff->dstDrawable; + free(data); + return BadMatch; + } + + (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty, + stuff->width, stuff->height, + 0, ZPixmap, data); + + if(dstShared) break; + } + + free(data); + } else { + DrawablePtr pDst = NULL, pSrc = NULL; + GCPtr pGC = NULL; + RegionRec totalReg; + int rc; + + RegionNull(&totalReg); + FOR_NSCREENS_BACKWARD(j) { + RegionPtr pRgn; + stuff->dstDrawable = dst->info[j].id; + stuff->srcDrawable = src->info[j].id; + stuff->gc = gc->info[j].id; + if (srcIsRoot) { + stuff->srcX = srcx - screenInfo.screens[j]->x; + stuff->srcY = srcy - screenInfo.screens[j]->y; + } + if (dstIsRoot) { + stuff->dstX = dstx - screenInfo.screens[j]->x; + stuff->dstY = dsty - screenInfo.screens[j]->y; + } + + VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); + + if (stuff->dstDrawable != stuff->srcDrawable) { + rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if ((pDst->pScreen != pSrc->pScreen) || + (pDst->depth != pSrc->depth)) { + client->errorValue = stuff->dstDrawable; + return BadMatch; + } + } else + pSrc = pDst; + + pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, + stuff->srcX, stuff->srcY, + stuff->width, stuff->height, + stuff->dstX, stuff->dstY); + if(pGC->graphicsExposures && pRgn) { + if(srcIsRoot) { + RegionTranslate(pRgn, + screenInfo.screens[j]->x, screenInfo.screens[j]->y); + } + RegionAppend(&totalReg, pRgn); + RegionDestroy(pRgn); + } + + if(dstShared) + break; + } + + if(pGC->graphicsExposures) { + Bool overlap; + RegionValidate(&totalReg, &overlap); + (*pDst->pScreen->SendGraphicsExpose)( + client, &totalReg, stuff->dstDrawable, X_CopyArea, 0); + RegionUninit(&totalReg); + } + } + + return Success; +} + + +int PanoramiXCopyPlane(ClientPtr client) +{ + int j, srcx, srcy, dstx, dsty, rc; + PanoramiXRes *gc, *src, *dst; + Bool srcIsRoot = FALSE; + Bool dstIsRoot = FALSE; + Bool srcShared, dstShared; + DrawablePtr psrcDraw, pdstDraw = NULL; + GCPtr pGC = NULL; + RegionRec totalReg; + REQUEST(xCopyPlaneReq); + + REQUEST_SIZE_MATCH(xCopyPlaneReq); + + rc = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable, + XRC_DRAWABLE, client, DixReadAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + srcShared = IS_SHARED_PIXMAP(src); + + rc = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + dstShared = IS_SHARED_PIXMAP(dst); + + if(dstShared && srcShared) + return (* SavedProcVector[X_CopyPlane])(client); + + rc = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (rc != Success) + return rc; + + if((dst->type == XRT_WINDOW) && dst->u.win.root) + dstIsRoot = TRUE; + if((src->type == XRT_WINDOW) && src->u.win.root) + srcIsRoot = TRUE; + + srcx = stuff->srcX; srcy = stuff->srcY; + dstx = stuff->dstX; dsty = stuff->dstY; + + RegionNull(&totalReg); + FOR_NSCREENS_BACKWARD(j) { + RegionPtr pRgn; + stuff->dstDrawable = dst->info[j].id; + stuff->srcDrawable = src->info[j].id; + stuff->gc = gc->info[j].id; + if (srcIsRoot) { + stuff->srcX = srcx - screenInfo.screens[j]->x; + stuff->srcY = srcy - screenInfo.screens[j]->y; + } + if (dstIsRoot) { + stuff->dstX = dstx - screenInfo.screens[j]->x; + stuff->dstY = dsty - screenInfo.screens[j]->y; + } + + VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); + if (stuff->dstDrawable != stuff->srcDrawable) { + rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (pdstDraw->pScreen != psrcDraw->pScreen) { + client->errorValue = stuff->dstDrawable; + return BadMatch; + } + } else + psrcDraw = pdstDraw; + + if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || + (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) { + client->errorValue = stuff->bitPlane; + return BadValue; + } + + pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, + stuff->srcX, stuff->srcY, + stuff->width, stuff->height, + stuff->dstX, stuff->dstY, stuff->bitPlane); + if(pGC->graphicsExposures && pRgn) { + RegionAppend(&totalReg, pRgn); + RegionDestroy(pRgn); + } + + if(dstShared) + break; + } + + if(pGC->graphicsExposures) { + Bool overlap; + RegionValidate(&totalReg, &overlap); + (*pdstDraw->pScreen->SendGraphicsExpose)( + client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0); + RegionUninit(&totalReg); + } + + return Success; +} + + +int PanoramiXPolyPoint(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + int result, npoint, j; + xPoint *origPts; + Bool isRoot; + REQUEST(xPolyPointReq); + + REQUEST_AT_LEAST_SIZE(xPolyPointReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyPoint])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); + if (npoint > 0) { + origPts = malloc(npoint * sizeof(xPoint)); + memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPoint *pnts = (xPoint*)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyPoint])(client); + if(result != Success) break; + } + free(origPts); + return result; + } else + return Success; +} + + +int PanoramiXPolyLine(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + int result, npoint, j; + xPoint *origPts; + Bool isRoot; + REQUEST(xPolyLineReq); + + REQUEST_AT_LEAST_SIZE(xPolyLineReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyLine])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); + if (npoint > 0){ + origPts = malloc(npoint * sizeof(xPoint)); + memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPoint *pnts = (xPoint*)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyLine])(client); + if(result != Success) break; + } + free(origPts); + return result; + } else + return Success; +} + + +int PanoramiXPolySegment(ClientPtr client) +{ + int result, nsegs, i, j; + PanoramiXRes *gc, *draw; + xSegment *origSegs; + Bool isRoot; + REQUEST(xPolySegmentReq); + + REQUEST_AT_LEAST_SIZE(xPolySegmentReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolySegment])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); + if(nsegs & 4) return BadLength; + nsegs >>= 3; + if (nsegs > 0) { + origSegs = malloc(nsegs * sizeof(xSegment)); + memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xSegment *segs = (xSegment*)&stuff[1]; + + for (i = nsegs; i--; segs++) { + segs->x1 -= x_off; + segs->x2 -= x_off; + segs->y1 -= y_off; + segs->y2 -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolySegment])(client); + if(result != Success) break; + } + free(origSegs); + return result; + } else + return Success; +} + + +int PanoramiXPolyRectangle(ClientPtr client) +{ + int result, nrects, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xRectangle *origRecs; + REQUEST(xPolyRectangleReq); + + REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyRectangle])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); + if(nrects & 4) return BadLength; + nrects >>= 3; + if (nrects > 0){ + origRecs = malloc(nrects * sizeof(xRectangle)); + memcpy((char *)origRecs,(char *)&stuff[1],nrects * sizeof(xRectangle)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) &stuff[1]; + + for (i = nrects; i--; rects++) { + rects->x -= x_off; + rects->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyRectangle])(client); + if(result != Success) break; + } + free(origRecs); + return result; + } else + return Success; +} + + +int PanoramiXPolyArc(ClientPtr client) +{ + int result, narcs, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xArc *origArcs; + REQUEST(xPolyArcReq); + + REQUEST_AT_LEAST_SIZE(xPolyArcReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyArc])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + narcs = (client->req_len << 2) - sizeof(xPolyArcReq); + if(narcs % sizeof(xArc)) return BadLength; + narcs /= sizeof(xArc); + if (narcs > 0){ + origArcs = malloc(narcs * sizeof(xArc)); + memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xArc *arcs = (xArc *) &stuff[1]; + + for (i = narcs; i--; arcs++) { + arcs->x -= x_off; + arcs->y -= y_off; + } + } + } + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyArc])(client); + if(result != Success) break; + } + free(origArcs); + return result; + } else + return Success; +} + + +int PanoramiXFillPoly(ClientPtr client) +{ + int result, count, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + DDXPointPtr locPts; + REQUEST(xFillPolyReq); + + REQUEST_AT_LEAST_SIZE(xFillPolyReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_FillPoly])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); + if (count > 0){ + locPts = malloc(count * sizeof(DDXPointRec)); + memcpy((char *)locPts, (char *)&stuff[1], count * sizeof(DDXPointRec)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + DDXPointPtr pnts = (DDXPointPtr)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : count; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_FillPoly])(client); + if(result != Success) break; + } + free(locPts); + return result; + } else + return Success; +} + + +int PanoramiXPolyFillRectangle(ClientPtr client) +{ + int result, things, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xRectangle *origRects; + REQUEST(xPolyFillRectangleReq); + + REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyFillRectangle])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); + if(things & 4) return BadLength; + things >>= 3; + if (things > 0){ + origRects = malloc(things * sizeof(xRectangle)); + memcpy((char*)origRects,(char*)&stuff[1], things * sizeof(xRectangle)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origRects, things * sizeof(xRectangle)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) &stuff[1]; + + for (i = things; i--; rects++) { + rects->x -= x_off; + rects->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyFillRectangle])(client); + if(result != Success) break; + } + free(origRects); + return result; + } else + return Success; +} + + +int PanoramiXPolyFillArc(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, narcs, i, j; + xArc *origArcs; + REQUEST(xPolyFillArcReq); + + REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyFillArc])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); + if (narcs % sizeof(xArc)) return BadLength; + narcs /= sizeof(xArc); + if (narcs > 0) { + origArcs = malloc(narcs * sizeof(xArc)); + memcpy((char *) origArcs, (char *)&stuff[1], narcs * sizeof(xArc)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xArc *arcs = (xArc *) &stuff[1]; + + for (i = narcs; i--; arcs++) { + arcs->x -= x_off; + arcs->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyFillArc])(client); + if(result != Success) break; + } + free(origArcs); + return result; + } else + return Success; +} + + +int PanoramiXPutImage(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int j, result, orig_x, orig_y; + REQUEST(xPutImageReq); + + REQUEST_AT_LEAST_SIZE(xPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PutImage])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->dstX; + orig_y = stuff->dstY; + FOR_NSCREENS_BACKWARD(j){ + if (isRoot) { + stuff->dstX = orig_x - screenInfo.screens[j]->x; + stuff->dstY = orig_y - screenInfo.screens[j]->y; + } + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PutImage])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXGetImage(ClientPtr client) +{ + DrawablePtr drawables[MAXSCREENS]; + DrawablePtr pDraw; + PanoramiXRes *draw; + xGetImageReply xgi; + Bool isRoot; + char *pBuf; + int i, x, y, w, h, format, rc; + Mask plane = 0, planemask; + int linesDone, nlines, linesPerBuf; + long widthBytesLine, length; + + REQUEST(xGetImageReq); + + REQUEST_SIZE_MATCH(xGetImageReq); + + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { + client->errorValue = stuff->format; + return BadValue; + } + + rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + if(draw->type == XRT_PIXMAP) + return (*SavedProcVector[X_GetImage])(client); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if(!((WindowPtr)pDraw)->realized) + return BadMatch; + + x = stuff->x; + y = stuff->y; + w = stuff->width; + h = stuff->height; + format = stuff->format; + planemask = stuff->planeMask; + + isRoot = IS_ROOT_DRAWABLE(draw); + + if(isRoot) { + if( /* check for being onscreen */ + x < 0 || x + w > PanoramiXPixWidth || + y < 0 || y + h > PanoramiXPixHeight ) + return BadMatch; + } else { + if( /* check for being onscreen */ + screenInfo.screens[0]->x + pDraw->x + x < 0 || + screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || + screenInfo.screens[0]->y + pDraw->y + y < 0 || + screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || + /* check for being inside of border */ + x < - wBorderWidth((WindowPtr)pDraw) || + x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + y < -wBorderWidth((WindowPtr)pDraw) || + y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) + return BadMatch; + } + + drawables[0] = pDraw; + FOR_NSCREENS_FORWARD_SKIP(i) { + rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + } + + xgi.visual = wVisual (((WindowPtr) pDraw)); + xgi.type = X_Reply; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + if(format == ZPixmap) { + widthBytesLine = PixmapBytePad(w, pDraw->depth); + length = widthBytesLine * h; + + + } else { + widthBytesLine = BitmapBytePad(w); + plane = ((Mask)1) << (pDraw->depth - 1); + /* only planes asked for */ + length = widthBytesLine * h * + Ones(planemask & (plane | (plane - 1))); + + } + + xgi.length = bytes_to_int32(length); + + if (widthBytesLine == 0 || h == 0) + linesPerBuf = 0; + else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE) + linesPerBuf = 1; + else { + linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine; + if (linesPerBuf > h) + linesPerBuf = h; + } + length = linesPerBuf * widthBytesLine; + if(!(pBuf = malloc(length))) + return BadAlloc; + + WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); + + if (linesPerBuf == 0) { + /* nothing to do */ + } + else if (format == ZPixmap) { + linesDone = 0; + while (h - linesDone > 0) { + nlines = min(linesPerBuf, h - linesDone); + + if(pDraw->depth == 1) + memset(pBuf, 0, nlines * widthBytesLine); + + XineramaGetImageData(drawables, x, y + linesDone, w, nlines, + format, planemask, pBuf, widthBytesLine, isRoot); + + (void)WriteToClient(client, + (int)(nlines * widthBytesLine), + pBuf); + linesDone += nlines; + } + } else { /* XYPixmap */ + for (; plane; plane >>= 1) { + if (planemask & plane) { + linesDone = 0; + while (h - linesDone > 0) { + nlines = min(linesPerBuf, h - linesDone); + + memset(pBuf, 0, nlines * widthBytesLine); + + XineramaGetImageData(drawables, x, y + linesDone, w, + nlines, format, plane, pBuf, + widthBytesLine, isRoot); + + (void)WriteToClient(client, + (int)(nlines * widthBytesLine), + pBuf); + + linesDone += nlines; + } + } + } + } + free(pBuf); + return Success; +} + + +/* The text stuff should be rewritten so that duplication happens + at the GlyphBlt level. That is, loading the font and getting + the glyphs should only happen once */ + +int +PanoramiXPolyText8(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, j; + int orig_x, orig_y; + REQUEST(xPolyTextReq); + + REQUEST_AT_LEAST_SIZE(xPolyTextReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyText8])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_PolyText8])(client); + if(result != Success) break; + } + return result; +} + +int +PanoramiXPolyText16(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, j; + int orig_x, orig_y; + REQUEST(xPolyTextReq); + + REQUEST_AT_LEAST_SIZE(xPolyTextReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyText16])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_PolyText16])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXImageText8(ClientPtr client) +{ + int result, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + int orig_x, orig_y; + REQUEST(xImageTextReq); + + REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_ImageText8])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ImageText8])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXImageText16(ClientPtr client) +{ + int result, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + int orig_x, orig_y; + REQUEST(xImageTextReq); + + REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_ImageText16])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ImageText16])(client); + if(result != Success) break; + } + return result; +} + + + +int PanoramiXCreateColormap(ClientPtr client) +{ + PanoramiXRes *win, *newCmap; + int result, j, orig_visual; + REQUEST(xCreateColormapReq); + + REQUEST_SIZE_MATCH(xCreateColormapReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + if(!(newCmap = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newCmap->type = XRT_COLORMAP; + panoramix_setup_ids(newCmap, client, stuff->mid); + + orig_visual = stuff->visual; + FOR_NSCREENS_BACKWARD(j){ + stuff->mid = newCmap->info[j].id; + stuff->window = win->info[j].id; + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); + result = (* SavedProcVector[X_CreateColormap])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap); + else + free(newCmap); + + return result; +} + + +int PanoramiXFreeColormap(ClientPtr client) +{ + PanoramiXRes *cmap; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_FreeColormap])(client); + if(result != Success) break; + } + + /* Since ProcFreeColormap is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int +PanoramiXCopyColormapAndFree(ClientPtr client) +{ + PanoramiXRes *cmap, *newCmap; + int result, j; + REQUEST(xCopyColormapAndFreeReq); + + REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); + + client->errorValue = stuff->srcCmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->srcCmap, + XRT_COLORMAP, client, + DixReadAccess | DixWriteAccess); + if (result != Success) + return result; + + if(!(newCmap = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newCmap->type = XRT_COLORMAP; + panoramix_setup_ids(newCmap, client, stuff->mid); + + FOR_NSCREENS_BACKWARD(j) { + stuff->srcCmap = cmap->info[j].id; + stuff->mid = newCmap->info[j].id; + result = (* SavedProcVector[X_CopyColormapAndFree])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap); + else + free(newCmap); + + return result; +} + + +int PanoramiXInstallColormap(ClientPtr client) +{ + REQUEST(xResourceReq); + int result, j; + PanoramiXRes *cmap; + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_InstallColormap])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXUninstallColormap(ClientPtr client) +{ + REQUEST(xResourceReq); + int result, j; + PanoramiXRes *cmap; + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_UninstallColormap])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorReq); + + REQUEST_SIZE_MATCH(xAllocColorReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColor])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocNamedColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocNamedColorReq); + + REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocNamedColor])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColorCells(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorCellsReq); + + REQUEST_SIZE_MATCH(xAllocColorCellsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColorCells])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColorPlanes(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorPlanesReq); + + REQUEST_SIZE_MATCH(xAllocColorPlanesReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColorPlanes])(client); + if(result != Success) break; + } + return result; +} + + + +int PanoramiXFreeColors(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xFreeColorsReq); + + REQUEST_AT_LEAST_SIZE(xFreeColorsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_FreeColors])(client); + } + return result; +} + + +int PanoramiXStoreColors(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xStoreColorsReq); + + REQUEST_AT_LEAST_SIZE(xStoreColorsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_StoreColors])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXStoreNamedColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xStoreNamedColorReq); + + REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_StoreNamedColor])(client); + if(result != Success) break; + } + return result; +} diff --git a/xorg-server/Xext/panoramiXsrv.h b/xorg-server/Xext/panoramiXsrv.h index 9751feb54..6fc903b88 100644 --- a/xorg-server/Xext/panoramiXsrv.h +++ b/xorg-server/Xext/panoramiXsrv.h @@ -51,4 +51,15 @@ extern _X_EXPORT void XineramaGetImageData( Bool isRoot ); +static inline void panoramix_setup_ids(PanoramiXRes *resource, + ClientPtr client, XID base_id) +{ + int j; + + resource->info[0].id = base_id; + FOR_NSCREENS_FORWARD_SKIP(j) { + resource->info[j].id = FakeClientID(client->index); + } +} + #endif /* _PANORAMIXSRV_H_ */ diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c index 8a048deb0..b08af821b 100644 --- a/xorg-server/Xext/shm.c +++ b/xorg-server/Xext/shm.c @@ -1,1327 +1,1325 @@ -/************************************************************
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-********************************************************/
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
-
-
-#define SHM
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "extnsionst.h"
-#include "servermd.h"
-#include "shmint.h"
-#include "xace.h"
-#include <X11/extensions/shmproto.h>
-#include <X11/Xfuncproto.h>
-#include "protocol-versions.h"
-
-/* Needed for Solaris cross-zone shared memory extension */
-#ifdef HAVE_SHMCTL64
-#include <sys/ipc_impl.h>
-#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
-#define SHMSTAT_TYPE struct shmid_ds64
-#define SHMPERM_TYPE struct ipc_perm64
-#define SHM_PERM(buf) buf.shmx_perm
-#define SHM_SEGSZ(buf) buf.shmx_segsz
-#define SHMPERM_UID(p) p->ipcx_uid
-#define SHMPERM_CUID(p) p->ipcx_cuid
-#define SHMPERM_GID(p) p->ipcx_gid
-#define SHMPERM_CGID(p) p->ipcx_cgid
-#define SHMPERM_MODE(p) p->ipcx_mode
-#define SHMPERM_ZONEID(p) p->ipcx_zoneid
-#else
-#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
-#define SHMSTAT_TYPE struct shmid_ds
-#define SHMPERM_TYPE struct ipc_perm
-#define SHM_PERM(buf) buf.shm_perm
-#define SHM_SEGSZ(buf) buf.shm_segsz
-#define SHMPERM_UID(p) p->uid
-#define SHMPERM_CUID(p) p->cuid
-#define SHMPERM_GID(p) p->gid
-#define SHMPERM_CGID(p) p->cgid
-#define SHMPERM_MODE(p) p->mode
-#endif
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-#include "modinit.h"
-
-typedef struct _ShmDesc {
- struct _ShmDesc *next;
- int shmid;
- int refcnt;
- char *addr;
- Bool writable;
- unsigned long size;
-} ShmDescRec, *ShmDescPtr;
-
-typedef struct _ShmScrPrivateRec {
- CloseScreenProcPtr CloseScreen;
- ShmFuncsPtr shmFuncs;
- DestroyPixmapProcPtr destroyPixmap;
-} ShmScrPrivateRec;
-
-static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
-static int ShmDetachSegment(
- pointer /* value */,
- XID /* shmseg */
- );
-static void ShmResetProc(
- ExtensionEntry * /* extEntry */
- );
-static void SShmCompletionEvent(
- xShmCompletionEvent * /* from */,
- xShmCompletionEvent * /* to */
- );
-
-static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
-
-
-static unsigned char ShmReqCode;
-int ShmCompletionCode;
-int BadShmSegCode;
-RESTYPE ShmSegType;
-static ShmDescPtr Shmsegs;
-static Bool sharedPixmaps;
-static DevPrivateKeyRec shmScrPrivateKeyRec;
-#define shmScrPrivateKey (&shmScrPrivateKeyRec)
-static DevPrivateKeyRec shmPixmapPrivateKeyRec;
-#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec)
-static ShmFuncs miFuncs = {NULL, NULL};
-static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
-
-#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
-
-#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
-{ \
- int rc; \
- rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \
- client, DixReadAccess); \
- if (rc != Success) \
- return rc; \
-}
-
-#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
-{ \
- VERIFY_SHMSEG(shmseg, shmdesc, client); \
- if ((offset & 3) || (offset > shmdesc->size)) \
- { \
- client->errorValue = offset; \
- return BadValue; \
- } \
- if (needwrite && !shmdesc->writable) \
- return BadAccess; \
-}
-
-#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
-{ \
- if ((offset + len) > shmdesc->size) \
- { \
- return BadAccess; \
- } \
-}
-
-
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
-#include <sys/signal.h>
-
-static Bool badSysCall = FALSE;
-
-static void
-SigSysHandler(int signo)
-{
- badSysCall = TRUE;
-}
-
-static Bool CheckForShmSyscall(void)
-{
- void (*oldHandler)();
- int shmid = -1;
-
- /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
- oldHandler = signal(SIGSYS, SigSysHandler);
-
- badSysCall = FALSE;
- shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
-
- if (shmid != -1)
- {
- /* Successful allocation - clean up */
- shmctl(shmid, IPC_RMID, NULL);
- }
- else
- {
- /* Allocation failed */
- badSysCall = TRUE;
- }
- signal(SIGSYS, oldHandler);
- return !badSysCall;
-}
-
-#define MUST_CHECK_FOR_SHM_SYSCALL
-
-#endif
-
-static Bool
-ShmCloseScreen(int i, ScreenPtr pScreen)
-{
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- pScreen->CloseScreen = screen_priv->CloseScreen;
- dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL);
- free(screen_priv);
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static ShmScrPrivateRec *
-ShmInitScreenPriv(ScreenPtr pScreen)
-{
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- if (!screen_priv)
- {
- screen_priv = calloc(1, sizeof (ShmScrPrivateRec));
- screen_priv->CloseScreen = pScreen->CloseScreen;
- dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv);
- pScreen->CloseScreen = ShmCloseScreen;
- }
- return screen_priv;
-}
-
-static Bool
-ShmRegisterPrivates(void)
-{
- if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
- return FALSE;
- return TRUE;
-}
-
-/*ARGSUSED*/
-static void
-ShmResetProc(ExtensionEntry *extEntry)
-{
- int i;
- for (i = 0; i < screenInfo.numScreens; i++)
- ShmRegisterFuncs(screenInfo.screens[i], NULL);
-}
-
-void
-ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
-{
- if (!ShmRegisterPrivates())
- return;
- ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
-}
-
-static Bool
-ShmDestroyPixmap (PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- Bool ret;
- if (pPixmap->refcnt == 1)
- {
- ShmDescPtr shmdesc;
- shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates,
- shmPixmapPrivateKey);
- if (shmdesc)
- ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
- }
-
- pScreen->DestroyPixmap = screen_priv->destroyPixmap;
- ret = (*pScreen->DestroyPixmap) (pPixmap);
- screen_priv->destroyPixmap = pScreen->DestroyPixmap;
- pScreen->DestroyPixmap = ShmDestroyPixmap;
- return ret;
-}
-
-void
-ShmRegisterFbFuncs(ScreenPtr pScreen)
-{
- ShmRegisterFuncs(pScreen, &fbFuncs);
-}
-
-static int
-ProcShmQueryVersion(ClientPtr client)
-{
- xShmQueryVersionReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xShmQueryVersionReq);
- memset(&rep, 0, sizeof(xShmQueryVersionReply));
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.sharedPixmaps = sharedPixmaps;
- rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0;
- rep.majorVersion = SERVER_SHM_MAJOR_VERSION;
- rep.minorVersion = SERVER_SHM_MINOR_VERSION;
- rep.uid = geteuid();
- rep.gid = getegid();
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swaps(&rep.uid, n);
- swaps(&rep.gid, n);
- }
- WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-/*
- * Simulate the access() system call for a shared memory segement,
- * using the credentials from the client if available
- */
-static int
-shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
-{
- int uid, gid;
- mode_t mask;
- int uidset = 0, gidset = 0;
- LocalClientCredRec *lcc;
-
- if (GetLocalClientCreds(client, &lcc) != -1) {
-
- if (lcc->fieldsSet & LCC_UID_SET) {
- uid = lcc->euid;
- uidset = 1;
- }
- if (lcc->fieldsSet & LCC_GID_SET) {
- gid = lcc->egid;
- gidset = 1;
- }
-
-#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
- if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
- || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
- uidset = 0;
- gidset = 0;
- }
-#endif
- FreeLocalClientCreds(lcc);
-
- if (uidset) {
- /* User id 0 always gets access */
- if (uid == 0) {
- return 0;
- }
- /* Check the owner */
- if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
- mask = S_IRUSR;
- if (!readonly) {
- mask |= S_IWUSR;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
- }
- }
-
- if (gidset) {
- /* Check the group */
- if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
- mask = S_IRGRP;
- if (!readonly) {
- mask |= S_IWGRP;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
- }
- }
- }
- /* Otherwise, check everyone else */
- mask = S_IROTH;
- if (!readonly) {
- mask |= S_IWOTH;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
-}
-
-static int
-ProcShmAttach(ClientPtr client)
-{
- SHMSTAT_TYPE buf;
- ShmDescPtr shmdesc;
- REQUEST(xShmAttachReq);
-
- REQUEST_SIZE_MATCH(xShmAttachReq);
- LEGAL_NEW_RESOURCE(stuff->shmseg, client);
- if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
- {
- client->errorValue = stuff->readOnly;
- return BadValue;
- }
- for (shmdesc = Shmsegs;
- shmdesc && (shmdesc->shmid != stuff->shmid);
- shmdesc = shmdesc->next)
- ;
- if (shmdesc)
- {
- if (!stuff->readOnly && !shmdesc->writable)
- return BadAccess;
- shmdesc->refcnt++;
- }
- else
- {
- shmdesc = malloc(sizeof(ShmDescRec));
- if (!shmdesc)
- return BadAlloc;
- shmdesc->addr = shmat(stuff->shmid, 0,
- stuff->readOnly ? SHM_RDONLY : 0);
- if ((shmdesc->addr == ((char *)-1)) ||
- SHMSTAT(stuff->shmid, &buf))
- {
- free(shmdesc);
- return BadAccess;
- }
-
- /* The attach was performed with root privs. We must
- * do manual checking of access rights for the credentials
- * of the client */
-
- if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
- shmdt(shmdesc->addr);
- free(shmdesc);
- return BadAccess;
- }
-
- shmdesc->shmid = stuff->shmid;
- shmdesc->refcnt = 1;
- shmdesc->writable = !stuff->readOnly;
- shmdesc->size = SHM_SEGSZ(buf);
- shmdesc->next = Shmsegs;
- Shmsegs = shmdesc;
- }
- if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
- return BadAlloc;
- return Success;
-}
-
-/*ARGSUSED*/
-static int
-ShmDetachSegment(pointer value, /* must conform to DeleteType */
- XID shmseg)
-{
- ShmDescPtr shmdesc = (ShmDescPtr)value;
- ShmDescPtr *prev;
-
- if (--shmdesc->refcnt)
- return TRUE;
- shmdt(shmdesc->addr);
- for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
- ;
- *prev = shmdesc->next;
- free(shmdesc);
- return Success;
-}
-
-static int
-ProcShmDetach(ClientPtr client)
-{
- ShmDescPtr shmdesc;
- REQUEST(xShmDetachReq);
-
- REQUEST_SIZE_MATCH(xShmDetachReq);
- VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
- FreeResource(stuff->shmseg, RT_NONE);
- return Success;
-}
-
-/*
- * If the given request doesn't exactly match PutImage's constraints,
- * wrap the image in a scratch pixmap header and let CopyArea sort it out.
- */
-static void
-doShmPutImage(DrawablePtr dst, GCPtr pGC,
- int depth, unsigned int format,
- int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
- char *data)
-{
- PixmapPtr pPixmap;
-
- if (format == ZPixmap || depth == 1) {
- pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
- BitsPerPixel(depth),
- PixmapBytePad(w, depth),
- data);
- if (!pPixmap)
- return;
- pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy);
- FreeScratchPixmapHeader(pPixmap);
- } else {
- GCPtr putGC = GetScratchGC(depth, dst->pScreen);
-
- if (!putGC)
- return;
-
- pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pPixmap) {
- FreeScratchGC(putGC);
- return;
- }
- ValidateGC(&pPixmap->drawable, putGC);
- (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0,
- (format == XYPixmap) ? XYPixmap : ZPixmap, data);
- FreeScratchGC(putGC);
- if (format == XYBitmap)
- (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
- dx, dy, 1L);
- else
- (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
- dx, dy);
- (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
- }
-}
-
-static int
-ProcShmPutImage(ClientPtr client)
-{
- GCPtr pGC;
- DrawablePtr pDraw;
- long length;
- ShmDescPtr shmdesc;
- REQUEST(xShmPutImageReq);
-
- REQUEST_SIZE_MATCH(xShmPutImageReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
- if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
- return BadValue;
- if (stuff->format == XYBitmap)
- {
- if (stuff->depth != 1)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, 1);
- }
- else if (stuff->format == XYPixmap)
- {
- if (pDraw->depth != stuff->depth)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, 1);
- length *= stuff->depth;
- }
- else if (stuff->format == ZPixmap)
- {
- if (pDraw->depth != stuff->depth)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, stuff->depth);
- }
- else
- {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- /*
- * There's a potential integer overflow in this check:
- * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
- * client);
- * the version below ought to avoid it
- */
- if (stuff->totalHeight != 0 &&
- length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
- client->errorValue = stuff->totalWidth;
- return BadValue;
- }
- if (stuff->srcX > stuff->totalWidth)
- {
- client->errorValue = stuff->srcX;
- return BadValue;
- }
- if (stuff->srcY > stuff->totalHeight)
- {
- client->errorValue = stuff->srcY;
- return BadValue;
- }
- if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
- {
- client->errorValue = stuff->srcWidth;
- return BadValue;
- }
- if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
- {
- client->errorValue = stuff->srcHeight;
- return BadValue;
- }
-
- if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
- ((stuff->format != ZPixmap) &&
- (stuff->srcX < screenInfo.bitmapScanlinePad) &&
- ((stuff->format == XYBitmap) ||
- ((stuff->srcY == 0) &&
- (stuff->srcHeight == stuff->totalHeight))))) &&
- ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
- (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
- stuff->dstX, stuff->dstY,
- stuff->totalWidth, stuff->srcHeight,
- stuff->srcX, stuff->format,
- shmdesc->addr + stuff->offset +
- (stuff->srcY * length));
- else
- doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
- stuff->totalWidth, stuff->totalHeight,
- stuff->srcX, stuff->srcY,
- stuff->srcWidth, stuff->srcHeight,
- stuff->dstX, stuff->dstY,
- shmdesc->addr + stuff->offset);
-
- if (stuff->sendEvent)
- {
- xShmCompletionEvent ev;
-
- ev.type = ShmCompletionCode;
- ev.drawable = stuff->drawable;
- ev.minorEvent = X_ShmPutImage;
- ev.majorEvent = ShmReqCode;
- ev.shmseg = stuff->shmseg;
- ev.offset = stuff->offset;
- WriteEventsToClient(client, 1, (xEvent *) &ev);
- }
-
- return Success;
-}
-
-static int
-ProcShmGetImage(ClientPtr client)
-{
- DrawablePtr pDraw;
- long lenPer = 0, length;
- Mask plane = 0;
- xShmGetImageReply xgi;
- ShmDescPtr shmdesc;
- int n, rc;
-
- REQUEST(xShmGetImageReq);
-
- REQUEST_SIZE_MATCH(xShmGetImageReq);
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
- {
- client->errorValue = stuff->format;
- return BadValue;
- }
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
- if (pDraw->type == DRAWABLE_WINDOW)
- {
- if( /* check for being viewable */
- !((WindowPtr) pDraw)->realized ||
- /* check for being on screen */
- pDraw->x + stuff->x < 0 ||
- pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
- pDraw->y + stuff->y < 0 ||
- pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
- /* check for being inside of border */
- stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
- stuff->x + (int)stuff->width >
- wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
- stuff->y + (int)stuff->height >
- wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
- )
- return BadMatch;
- xgi.visual = wVisual(((WindowPtr)pDraw));
- }
- else
- {
- if (stuff->x < 0 ||
- stuff->x+(int)stuff->width > pDraw->width ||
- stuff->y < 0 ||
- stuff->y+(int)stuff->height > pDraw->height
- )
- return BadMatch;
- xgi.visual = None;
- }
- xgi.type = X_Reply;
- xgi.length = 0;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
- if(stuff->format == ZPixmap)
- {
- length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
- }
- else
- {
- lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
- plane = ((Mask)1) << (pDraw->depth - 1);
- /* only planes asked for */
- length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
- }
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
- xgi.size = length;
-
- if (length == 0)
- {
- /* nothing to do */
- }
- else if (stuff->format == ZPixmap)
- {
- (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
- stuff->width, stuff->height,
- stuff->format, stuff->planeMask,
- shmdesc->addr + stuff->offset);
- }
- else
- {
-
- length = stuff->offset;
- for (; plane; plane >>= 1)
- {
- if (stuff->planeMask & plane)
- {
- (*pDraw->pScreen->GetImage)(pDraw,
- stuff->x, stuff->y,
- stuff->width, stuff->height,
- stuff->format, plane,
- shmdesc->addr + length);
- length += lenPer;
- }
- }
- }
-
- if (client->swapped) {
- swaps(&xgi.sequenceNumber, n);
- swapl(&xgi.length, n);
- swapl(&xgi.visual, n);
- swapl(&xgi.size, n);
- }
- WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
-
- return Success;
-}
-
-#ifdef PANORAMIX
-static int
-ProcPanoramiXShmPutImage(ClientPtr client)
-{
- int j, result, orig_x, orig_y;
- PanoramiXRes *draw, *gc;
- Bool sendEvent, isRoot;
-
- REQUEST(xShmPutImageReq);
- REQUEST_SIZE_MATCH(xShmPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->dstX;
- orig_y = stuff->dstY;
- sendEvent = stuff->sendEvent;
- stuff->sendEvent = 0;
- FOR_NSCREENS(j) {
- if(!j) stuff->sendEvent = sendEvent;
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->dstX = orig_x - screenInfo.screens[j]->x;
- stuff->dstY = orig_y - screenInfo.screens[j]->y;
- }
- result = ProcShmPutImage(client);
- if(result != Success) break;
- }
- return result;
-}
-
-static int
-ProcPanoramiXShmGetImage(ClientPtr client)
-{
- PanoramiXRes *draw;
- DrawablePtr *drawables;
- DrawablePtr pDraw;
- xShmGetImageReply xgi;
- ShmDescPtr shmdesc;
- int i, x, y, w, h, format, rc;
- Mask plane = 0, planemask;
- long lenPer = 0, length, widthBytesLine;
- Bool isRoot;
-
- REQUEST(xShmGetImageReq);
-
- REQUEST_SIZE_MATCH(xShmGetImageReq);
-
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- if (draw->type == XRT_PIXMAP)
- return ProcShmGetImage(client);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- x = stuff->x;
- y = stuff->y;
- w = stuff->width;
- h = stuff->height;
- format = stuff->format;
- planemask = stuff->planeMask;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- if(isRoot) {
- if( /* check for being onscreen */
- x < 0 || x + w > PanoramiXPixWidth ||
- y < 0 || y + h > PanoramiXPixHeight )
- return BadMatch;
- } else {
- if( /* check for being onscreen */
- screenInfo.screens[0]->x + pDraw->x + x < 0 ||
- screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
- screenInfo.screens[0]->y + pDraw->y + y < 0 ||
- screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
- /* check for being inside of border */
- x < - wBorderWidth((WindowPtr)pDraw) ||
- x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- y < -wBorderWidth((WindowPtr)pDraw) ||
- y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
- return BadMatch;
- }
-
- drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
- if(!drawables)
- return BadAlloc;
-
- drawables[0] = pDraw;
- for(i = 1; i < PanoramiXNumScreens; i++) {
- rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
- DixReadAccess);
- if (rc != Success)
- {
- free(drawables);
- return rc;
- }
- }
-
- xgi.visual = wVisual(((WindowPtr)pDraw));
- xgi.type = X_Reply;
- xgi.length = 0;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
-
- if(format == ZPixmap) {
- widthBytesLine = PixmapBytePad(w, pDraw->depth);
- length = widthBytesLine * h;
- } else {
- widthBytesLine = PixmapBytePad(w, 1);
- lenPer = widthBytesLine * h;
- plane = ((Mask)1) << (pDraw->depth - 1);
- length = lenPer * Ones(planemask & (plane | (plane - 1)));
- }
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
- xgi.size = length;
-
- if (length == 0) {/* nothing to do */ }
- else if (format == ZPixmap) {
- XineramaGetImageData(drawables, x, y, w, h, format, planemask,
- shmdesc->addr + stuff->offset,
- widthBytesLine, isRoot);
- } else {
-
- length = stuff->offset;
- for (; plane; plane >>= 1) {
- if (planemask & plane) {
- XineramaGetImageData(drawables, x, y, w, h,
- format, plane, shmdesc->addr + length,
- widthBytesLine, isRoot);
- length += lenPer;
- }
- }
- }
- free(drawables);
-
- if (client->swapped) {
- int n;
- swaps(&xgi.sequenceNumber, n);
- swapl(&xgi.length, n);
- swapl(&xgi.visual, n);
- swapl(&xgi.size, n);
- }
- WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
-
- return Success;
-}
-
-static int
-ProcPanoramiXShmCreatePixmap(ClientPtr client)
-{
- ScreenPtr pScreen = NULL;
- PixmapPtr pMap = NULL;
- DrawablePtr pDraw;
- DepthPtr pDepth;
- int i, j, result, rc;
- ShmDescPtr shmdesc;
- REQUEST(xShmCreatePixmapReq);
- unsigned int width, height, depth;
- unsigned long size;
- PanoramiXRes *newPix;
-
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- client->errorValue = stuff->pid;
- if (!sharedPixmaps)
- return BadImplementation;
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- width = stuff->width;
- height = stuff->height;
- depth = stuff->depth;
- if (!width || !height || !depth)
- {
- client->errorValue = 0;
- return BadValue;
- }
- if (width > 32767 || height > 32767)
- return BadAlloc;
-
- if (stuff->depth != 1)
- {
- pDepth = pDraw->pScreen->allowedDepths;
- for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
- if (pDepth->depth == stuff->depth)
- goto CreatePmap;
- client->errorValue = stuff->depth;
- return BadValue;
- }
-
-CreatePmap:
- size = PixmapBytePad(width, depth) * height;
- if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
- if (size < width * height)
- return BadAlloc;
- }
- /* thankfully, offset is unsigned */
- if (stuff->offset + size < size)
- return BadAlloc;
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
-
- if(!(newPix = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPix->type = XRT_PIXMAP;
- newPix->u.pix.shared = TRUE;
- newPix->info[0].id = stuff->pid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newPix->info[j].id = FakeClientID(client->index);
-
- result = Success;
-
- FOR_NSCREENS(j) {
- ShmScrPrivateRec *screen_priv;
- pScreen = screenInfo.screens[j];
-
- screen_priv = ShmGetScreenPriv(pScreen);
- pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
- stuff->width, stuff->height, stuff->depth,
- shmdesc->addr + stuff->offset);
-
- if (pMap) {
- dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
- shmdesc->refcnt++;
- pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pMap->drawable.id = newPix->info[j].id;
- if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
- (*pScreen->DestroyPixmap)(pMap);
- result = BadAlloc;
- break;
- }
- } else {
- result = BadAlloc;
- break;
- }
- }
-
- if(result == BadAlloc) {
- while(j--) {
- (*pScreen->DestroyPixmap)(pMap);
- FreeResource(newPix->info[j].id, RT_NONE);
- }
- free(newPix);
- } else
- AddResource(stuff->pid, XRT_PIXMAP, newPix);
-
- return result;
-}
-#endif
-
-static PixmapPtr
-fbShmCreatePixmap (ScreenPtr pScreen,
- int width, int height, int depth, char *addr)
-{
- PixmapPtr pPixmap;
-
- pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
- if (!pPixmap)
- return NullPixmap;
-
- if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
- BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
- (*pScreen->DestroyPixmap)(pPixmap);
- return NullPixmap;
- }
- return pPixmap;
-}
-
-static int
-ProcShmCreatePixmap(ClientPtr client)
-{
- PixmapPtr pMap;
- DrawablePtr pDraw;
- DepthPtr pDepth;
- int i, rc;
- ShmDescPtr shmdesc;
- ShmScrPrivateRec *screen_priv;
- REQUEST(xShmCreatePixmapReq);
- unsigned int width, height, depth;
- unsigned long size;
-
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- client->errorValue = stuff->pid;
- if (!sharedPixmaps)
- return BadImplementation;
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- width = stuff->width;
- height = stuff->height;
- depth = stuff->depth;
- if (!width || !height || !depth)
- {
- client->errorValue = 0;
- return BadValue;
- }
- if (width > 32767 || height > 32767)
- return BadAlloc;
-
- if (stuff->depth != 1)
- {
- pDepth = pDraw->pScreen->allowedDepths;
- for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
- if (pDepth->depth == stuff->depth)
- goto CreatePmap;
- client->errorValue = stuff->depth;
- return BadValue;
- }
-
-CreatePmap:
- size = PixmapBytePad(width, depth) * height;
- if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
- if (size < width * height)
- return BadAlloc;
- }
- /* thankfully, offset is unsigned */
- if (stuff->offset + size < size)
- return BadAlloc;
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
- screen_priv = ShmGetScreenPriv(pDraw->pScreen);
- pMap = (*screen_priv->shmFuncs->CreatePixmap)(
- pDraw->pScreen, stuff->width,
- stuff->height, stuff->depth,
- shmdesc->addr + stuff->offset);
- if (pMap)
- {
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
- pMap, RT_NONE, NULL, DixCreateAccess);
- if (rc != Success) {
- pDraw->pScreen->DestroyPixmap(pMap);
- return rc;
- }
- dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
- shmdesc->refcnt++;
- pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pMap->drawable.id = stuff->pid;
- if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
- {
- return Success;
- }
- pDraw->pScreen->DestroyPixmap(pMap);
- }
- return BadAlloc;
-}
-
-static int
-ProcShmDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_ShmQueryVersion:
- return ProcShmQueryVersion(client);
- case X_ShmAttach:
- return ProcShmAttach(client);
- case X_ShmDetach:
- return ProcShmDetach(client);
- case X_ShmPutImage:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmPutImage(client);
-#endif
- return ProcShmPutImage(client);
- case X_ShmGetImage:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmGetImage(client);
-#endif
- return ProcShmGetImage(client);
- case X_ShmCreatePixmap:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmCreatePixmap(client);
-#endif
- return ProcShmCreatePixmap(client);
- default:
- return BadRequest;
- }
-}
-
-static void
-SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to)
-{
- to->type = from->type;
- cpswaps(from->sequenceNumber, to->sequenceNumber);
- cpswapl(from->drawable, to->drawable);
- cpswaps(from->minorEvent, to->minorEvent);
- to->majorEvent = from->majorEvent;
- cpswapl(from->shmseg, to->shmseg);
- cpswapl(from->offset, to->offset);
-}
-
-static int
-SProcShmQueryVersion(ClientPtr client)
-{
- int n;
- REQUEST(xShmQueryVersionReq);
-
- swaps(&stuff->length, n);
- return ProcShmQueryVersion(client);
-}
-
-static int
-SProcShmAttach(ClientPtr client)
-{
- int n;
- REQUEST(xShmAttachReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmAttachReq);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->shmid, n);
- return ProcShmAttach(client);
-}
-
-static int
-SProcShmDetach(ClientPtr client)
-{
- int n;
- REQUEST(xShmDetachReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmDetachReq);
- swapl(&stuff->shmseg, n);
- return ProcShmDetach(client);
-}
-
-static int
-SProcShmPutImage(ClientPtr client)
-{
- int n;
- REQUEST(xShmPutImageReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmPutImageReq);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->totalWidth, n);
- swaps(&stuff->totalHeight, n);
- swaps(&stuff->srcX, n);
- swaps(&stuff->srcY, n);
- swaps(&stuff->srcWidth, n);
- swaps(&stuff->srcHeight, n);
- swaps(&stuff->dstX, n);
- swaps(&stuff->dstY, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmPutImage(client);
-}
-
-static int
-SProcShmGetImage(ClientPtr client)
-{
- int n;
- REQUEST(xShmGetImageReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmGetImageReq);
- swapl(&stuff->drawable, n);
- swaps(&stuff->x, n);
- swaps(&stuff->y, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- swapl(&stuff->planeMask, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmGetImage(client);
-}
-
-static int
-SProcShmCreatePixmap(ClientPtr client)
-{
- int n;
- REQUEST(xShmCreatePixmapReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- swapl(&stuff->pid, n);
- swapl(&stuff->drawable, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmCreatePixmap(client);
-}
-
-static int
-SProcShmDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_ShmQueryVersion:
- return SProcShmQueryVersion(client);
- case X_ShmAttach:
- return SProcShmAttach(client);
- case X_ShmDetach:
- return SProcShmDetach(client);
- case X_ShmPutImage:
- return SProcShmPutImage(client);
- case X_ShmGetImage:
- return SProcShmGetImage(client);
- case X_ShmCreatePixmap:
- return SProcShmCreatePixmap(client);
- default:
- return BadRequest;
- }
-}
-
-void
-ShmExtensionInit(INITARGS)
-{
- ExtensionEntry *extEntry;
- int i;
-
-#ifdef MUST_CHECK_FOR_SHM_SYSCALL
- if (!CheckForShmSyscall())
- {
- ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
- return;
- }
-#endif
-
- if (!ShmRegisterPrivates())
- return;
-
- sharedPixmaps = xFalse;
- {
- sharedPixmaps = xTrue;
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
- if (!screen_priv->shmFuncs)
- screen_priv->shmFuncs = &miFuncs;
- if (!screen_priv->shmFuncs->CreatePixmap)
- sharedPixmaps = xFalse;
- }
- if (sharedPixmaps)
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
- screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
- screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
- }
- }
- ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
- if (ShmSegType &&
- (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
- ProcShmDispatch, SProcShmDispatch,
- ShmResetProc, StandardMinorOpcode)))
- {
- ShmReqCode = (unsigned char)extEntry->base;
- ShmCompletionCode = extEntry->eventBase;
- BadShmSegCode = extEntry->errorBase;
- SetResourceTypeErrorValue(ShmSegType, BadShmSegCode);
- EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
- }
-}
+/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ + + +#define SHM + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <unistd.h> +#include <sys/stat.h> +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "extnsionst.h" +#include "servermd.h" +#include "shmint.h" +#include "xace.h" +#include <X11/extensions/shmproto.h> +#include <X11/Xfuncproto.h> +#include "protocol-versions.h" + +/* Needed for Solaris cross-zone shared memory extension */ +#ifdef HAVE_SHMCTL64 +#include <sys/ipc_impl.h> +#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf) +#define SHMSTAT_TYPE struct shmid_ds64 +#define SHMPERM_TYPE struct ipc_perm64 +#define SHM_PERM(buf) buf.shmx_perm +#define SHM_SEGSZ(buf) buf.shmx_segsz +#define SHMPERM_UID(p) p->ipcx_uid +#define SHMPERM_CUID(p) p->ipcx_cuid +#define SHMPERM_GID(p) p->ipcx_gid +#define SHMPERM_CGID(p) p->ipcx_cgid +#define SHMPERM_MODE(p) p->ipcx_mode +#define SHMPERM_ZONEID(p) p->ipcx_zoneid +#else +#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf) +#define SHMSTAT_TYPE struct shmid_ds +#define SHMPERM_TYPE struct ipc_perm +#define SHM_PERM(buf) buf.shm_perm +#define SHM_SEGSZ(buf) buf.shm_segsz +#define SHMPERM_UID(p) p->uid +#define SHMPERM_CUID(p) p->cuid +#define SHMPERM_GID(p) p->gid +#define SHMPERM_CGID(p) p->cgid +#define SHMPERM_MODE(p) p->mode +#endif + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +#include "modinit.h" + +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + +typedef struct _ShmScrPrivateRec { + CloseScreenProcPtr CloseScreen; + ShmFuncsPtr shmFuncs; + DestroyPixmapProcPtr destroyPixmap; +} ShmScrPrivateRec; + +static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); +static int ShmDetachSegment( + pointer /* value */, + XID /* shmseg */ + ); +static void ShmResetProc( + ExtensionEntry * /* extEntry */ + ); +static void SShmCompletionEvent( + xShmCompletionEvent * /* from */, + xShmCompletionEvent * /* to */ + ); + +static Bool ShmDestroyPixmap (PixmapPtr pPixmap); + + +static unsigned char ShmReqCode; +int ShmCompletionCode; +int BadShmSegCode; +RESTYPE ShmSegType; +static ShmDescPtr Shmsegs; +static Bool sharedPixmaps; +static DevPrivateKeyRec shmScrPrivateKeyRec; +#define shmScrPrivateKey (&shmScrPrivateKeyRec) +static DevPrivateKeyRec shmPixmapPrivateKeyRec; +#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec) +static ShmFuncs miFuncs = {NULL, NULL}; +static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; + +#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey)) + +#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ +{ \ + int rc; \ + rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \ + client, DixReadAccess); \ + if (rc != Success) \ + return rc; \ +} + +#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \ +{ \ + VERIFY_SHMSEG(shmseg, shmdesc, client); \ + if ((offset & 3) || (offset > shmdesc->size)) \ + { \ + client->errorValue = offset; \ + return BadValue; \ + } \ + if (needwrite && !shmdesc->writable) \ + return BadAccess; \ +} + +#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \ +{ \ + if ((offset + len) > shmdesc->size) \ + { \ + return BadAccess; \ + } \ +} + + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) +#include <sys/signal.h> + +static Bool badSysCall = FALSE; + +static void +SigSysHandler(int signo) +{ + badSysCall = TRUE; +} + +static Bool CheckForShmSyscall(void) +{ + void (*oldHandler)(); + int shmid = -1; + + /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ + oldHandler = signal(SIGSYS, SigSysHandler); + + badSysCall = FALSE; + shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); + + if (shmid != -1) + { + /* Successful allocation - clean up */ + shmctl(shmid, IPC_RMID, NULL); + } + else + { + /* Allocation failed */ + badSysCall = TRUE; + } + signal(SIGSYS, oldHandler); + return !badSysCall; +} + +#define MUST_CHECK_FOR_SHM_SYSCALL + +#endif + +static Bool +ShmCloseScreen(int i, ScreenPtr pScreen) +{ + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + pScreen->CloseScreen = screen_priv->CloseScreen; + dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); + free(screen_priv); + return (*pScreen->CloseScreen) (i, pScreen); +} + +static ShmScrPrivateRec * +ShmInitScreenPriv(ScreenPtr pScreen) +{ + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + if (!screen_priv) + { + screen_priv = calloc(1, sizeof (ShmScrPrivateRec)); + screen_priv->CloseScreen = pScreen->CloseScreen; + dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv); + pScreen->CloseScreen = ShmCloseScreen; + } + return screen_priv; +} + +static Bool +ShmRegisterPrivates(void) +{ + if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) + return FALSE; + return TRUE; +} + +/*ARGSUSED*/ +static void +ShmResetProc(ExtensionEntry *extEntry) +{ + int i; + for (i = 0; i < screenInfo.numScreens; i++) + ShmRegisterFuncs(screenInfo.screens[i], NULL); +} + +void +ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) +{ + if (!ShmRegisterPrivates()) + return; + ShmInitScreenPriv(pScreen)->shmFuncs = funcs; +} + +static Bool +ShmDestroyPixmap (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + Bool ret; + if (pPixmap->refcnt == 1) + { + ShmDescPtr shmdesc; + shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates, + shmPixmapPrivateKey); + if (shmdesc) + ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); + } + + pScreen->DestroyPixmap = screen_priv->destroyPixmap; + ret = (*pScreen->DestroyPixmap) (pPixmap); + screen_priv->destroyPixmap = pScreen->DestroyPixmap; + pScreen->DestroyPixmap = ShmDestroyPixmap; + return ret; +} + +void +ShmRegisterFbFuncs(ScreenPtr pScreen) +{ + ShmRegisterFuncs(pScreen, &fbFuncs); +} + +static int +ProcShmQueryVersion(ClientPtr client) +{ + xShmQueryVersionReply rep; + int n; + + REQUEST_SIZE_MATCH(xShmQueryVersionReq); + memset(&rep, 0, sizeof(xShmQueryVersionReply)); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.sharedPixmaps = sharedPixmaps; + rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0; + rep.majorVersion = SERVER_SHM_MAJOR_VERSION; + rep.minorVersion = SERVER_SHM_MINOR_VERSION; + rep.uid = geteuid(); + rep.gid = getegid(); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + swaps(&rep.uid, n); + swaps(&rep.gid, n); + } + WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep); + return Success; +} + +/* + * Simulate the access() system call for a shared memory segement, + * using the credentials from the client if available + */ +static int +shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly) +{ + int uid, gid; + mode_t mask; + int uidset = 0, gidset = 0; + LocalClientCredRec *lcc; + + if (GetLocalClientCreds(client, &lcc) != -1) { + + if (lcc->fieldsSet & LCC_UID_SET) { + uid = lcc->euid; + uidset = 1; + } + if (lcc->fieldsSet & LCC_GID_SET) { + gid = lcc->egid; + gidset = 1; + } + +#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) + if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1) + || (lcc->zoneid != SHMPERM_ZONEID(perm))) { + uidset = 0; + gidset = 0; + } +#endif + FreeLocalClientCreds(lcc); + + if (uidset) { + /* User id 0 always gets access */ + if (uid == 0) { + return 0; + } + /* Check the owner */ + if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) { + mask = S_IRUSR; + if (!readonly) { + mask |= S_IWUSR; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; + } + } + + if (gidset) { + /* Check the group */ + if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) { + mask = S_IRGRP; + if (!readonly) { + mask |= S_IWGRP; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; + } + } + } + /* Otherwise, check everyone else */ + mask = S_IROTH; + if (!readonly) { + mask |= S_IWOTH; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; +} + +static int +ProcShmAttach(ClientPtr client) +{ + SHMSTAT_TYPE buf; + ShmDescPtr shmdesc; + REQUEST(xShmAttachReq); + + REQUEST_SIZE_MATCH(xShmAttachReq); + LEGAL_NEW_RESOURCE(stuff->shmseg, client); + if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) + { + client->errorValue = stuff->readOnly; + return BadValue; + } + for (shmdesc = Shmsegs; + shmdesc && (shmdesc->shmid != stuff->shmid); + shmdesc = shmdesc->next) + ; + if (shmdesc) + { + if (!stuff->readOnly && !shmdesc->writable) + return BadAccess; + shmdesc->refcnt++; + } + else + { + shmdesc = malloc(sizeof(ShmDescRec)); + if (!shmdesc) + return BadAlloc; + shmdesc->addr = shmat(stuff->shmid, 0, + stuff->readOnly ? SHM_RDONLY : 0); + if ((shmdesc->addr == ((char *)-1)) || + SHMSTAT(stuff->shmid, &buf)) + { + free(shmdesc); + return BadAccess; + } + + /* The attach was performed with root privs. We must + * do manual checking of access rights for the credentials + * of the client */ + + if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) { + shmdt(shmdesc->addr); + free(shmdesc); + return BadAccess; + } + + shmdesc->shmid = stuff->shmid; + shmdesc->refcnt = 1; + shmdesc->writable = !stuff->readOnly; + shmdesc->size = SHM_SEGSZ(buf); + shmdesc->next = Shmsegs; + Shmsegs = shmdesc; + } + if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc)) + return BadAlloc; + return Success; +} + +/*ARGSUSED*/ +static int +ShmDetachSegment(pointer value, /* must conform to DeleteType */ + XID shmseg) +{ + ShmDescPtr shmdesc = (ShmDescPtr)value; + ShmDescPtr *prev; + + if (--shmdesc->refcnt) + return TRUE; + shmdt(shmdesc->addr); + for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next) + ; + *prev = shmdesc->next; + free(shmdesc); + return Success; +} + +static int +ProcShmDetach(ClientPtr client) +{ + ShmDescPtr shmdesc; + REQUEST(xShmDetachReq); + + REQUEST_SIZE_MATCH(xShmDetachReq); + VERIFY_SHMSEG(stuff->shmseg, shmdesc, client); + FreeResource(stuff->shmseg, RT_NONE); + return Success; +} + +/* + * If the given request doesn't exactly match PutImage's constraints, + * wrap the image in a scratch pixmap header and let CopyArea sort it out. + */ +static void +doShmPutImage(DrawablePtr dst, GCPtr pGC, + int depth, unsigned int format, + int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, + char *data) +{ + PixmapPtr pPixmap; + + if (format == ZPixmap || depth == 1) { + pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, + BitsPerPixel(depth), + PixmapBytePad(w, depth), + data); + if (!pPixmap) + return; + pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); + FreeScratchPixmapHeader(pPixmap); + } else { + GCPtr putGC = GetScratchGC(depth, dst->pScreen); + + if (!putGC) + return; + + pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) { + FreeScratchGC(putGC); + return; + } + ValidateGC(&pPixmap->drawable, putGC); + (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, + (format == XYPixmap) ? XYPixmap : ZPixmap, data); + FreeScratchGC(putGC); + if (format == XYBitmap) + (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, + dx, dy, 1L); + else + (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, + dx, dy); + (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); + } +} + +static int +ProcShmPutImage(ClientPtr client) +{ + GCPtr pGC; + DrawablePtr pDraw; + long length; + ShmDescPtr shmdesc; + REQUEST(xShmPutImageReq); + + REQUEST_SIZE_MATCH(xShmPutImageReq); + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); + if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) + return BadValue; + if (stuff->format == XYBitmap) + { + if (stuff->depth != 1) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, 1); + } + else if (stuff->format == XYPixmap) + { + if (pDraw->depth != stuff->depth) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, 1); + length *= stuff->depth; + } + else if (stuff->format == ZPixmap) + { + if (pDraw->depth != stuff->depth) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, stuff->depth); + } + else + { + client->errorValue = stuff->format; + return BadValue; + } + + /* + * There's a potential integer overflow in this check: + * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, + * client); + * the version below ought to avoid it + */ + if (stuff->totalHeight != 0 && + length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { + client->errorValue = stuff->totalWidth; + return BadValue; + } + if (stuff->srcX > stuff->totalWidth) + { + client->errorValue = stuff->srcX; + return BadValue; + } + if (stuff->srcY > stuff->totalHeight) + { + client->errorValue = stuff->srcY; + return BadValue; + } + if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) + { + client->errorValue = stuff->srcWidth; + return BadValue; + } + if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) + { + client->errorValue = stuff->srcHeight; + return BadValue; + } + + if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || + ((stuff->format != ZPixmap) && + (stuff->srcX < screenInfo.bitmapScanlinePad) && + ((stuff->format == XYBitmap) || + ((stuff->srcY == 0) && + (stuff->srcHeight == stuff->totalHeight))))) && + ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) + (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, + stuff->dstX, stuff->dstY, + stuff->totalWidth, stuff->srcHeight, + stuff->srcX, stuff->format, + shmdesc->addr + stuff->offset + + (stuff->srcY * length)); + else + doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, + stuff->totalWidth, stuff->totalHeight, + stuff->srcX, stuff->srcY, + stuff->srcWidth, stuff->srcHeight, + stuff->dstX, stuff->dstY, + shmdesc->addr + stuff->offset); + + if (stuff->sendEvent) + { + xShmCompletionEvent ev; + + ev.type = ShmCompletionCode; + ev.drawable = stuff->drawable; + ev.minorEvent = X_ShmPutImage; + ev.majorEvent = ShmReqCode; + ev.shmseg = stuff->shmseg; + ev.offset = stuff->offset; + WriteEventsToClient(client, 1, (xEvent *) &ev); + } + + return Success; +} + +static int +ProcShmGetImage(ClientPtr client) +{ + DrawablePtr pDraw; + long lenPer = 0, length; + Mask plane = 0; + xShmGetImageReply xgi; + ShmDescPtr shmdesc; + int n, rc; + + REQUEST(xShmGetImageReq); + + REQUEST_SIZE_MATCH(xShmGetImageReq); + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) + { + client->errorValue = stuff->format; + return BadValue; + } + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + if (pDraw->type == DRAWABLE_WINDOW) + { + if( /* check for being viewable */ + !((WindowPtr) pDraw)->realized || + /* check for being on screen */ + pDraw->x + stuff->x < 0 || + pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || + pDraw->y + stuff->y < 0 || + pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || + /* check for being inside of border */ + stuff->x < - wBorderWidth((WindowPtr)pDraw) || + stuff->x + (int)stuff->width > + wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + stuff->y < -wBorderWidth((WindowPtr)pDraw) || + stuff->y + (int)stuff->height > + wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height + ) + return BadMatch; + xgi.visual = wVisual(((WindowPtr)pDraw)); + } + else + { + if (stuff->x < 0 || + stuff->x+(int)stuff->width > pDraw->width || + stuff->y < 0 || + stuff->y+(int)stuff->height > pDraw->height + ) + return BadMatch; + xgi.visual = None; + } + xgi.type = X_Reply; + xgi.length = 0; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + if(stuff->format == ZPixmap) + { + length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; + } + else + { + lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; + plane = ((Mask)1) << (pDraw->depth - 1); + /* only planes asked for */ + length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); + xgi.size = length; + + if (length == 0) + { + /* nothing to do */ + } + else if (stuff->format == ZPixmap) + { + (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, + stuff->width, stuff->height, + stuff->format, stuff->planeMask, + shmdesc->addr + stuff->offset); + } + else + { + + length = stuff->offset; + for (; plane; plane >>= 1) + { + if (stuff->planeMask & plane) + { + (*pDraw->pScreen->GetImage)(pDraw, + stuff->x, stuff->y, + stuff->width, stuff->height, + stuff->format, plane, + shmdesc->addr + length); + length += lenPer; + } + } + } + + if (client->swapped) { + swaps(&xgi.sequenceNumber, n); + swapl(&xgi.length, n); + swapl(&xgi.visual, n); + swapl(&xgi.size, n); + } + WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); + + return Success; +} + +#ifdef PANORAMIX +static int +ProcPanoramiXShmPutImage(ClientPtr client) +{ + int j, result, orig_x, orig_y; + PanoramiXRes *draw, *gc; + Bool sendEvent, isRoot; + + REQUEST(xShmPutImageReq); + REQUEST_SIZE_MATCH(xShmPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + orig_x = stuff->dstX; + orig_y = stuff->dstY; + sendEvent = stuff->sendEvent; + stuff->sendEvent = 0; + FOR_NSCREENS(j) { + if(!j) stuff->sendEvent = sendEvent; + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->dstX = orig_x - screenInfo.screens[j]->x; + stuff->dstY = orig_y - screenInfo.screens[j]->y; + } + result = ProcShmPutImage(client); + if(result != Success) break; + } + return result; +} + +static int +ProcPanoramiXShmGetImage(ClientPtr client) +{ + PanoramiXRes *draw; + DrawablePtr *drawables; + DrawablePtr pDraw; + xShmGetImageReply xgi; + ShmDescPtr shmdesc; + int i, x, y, w, h, format, rc; + Mask plane = 0, planemask; + long lenPer = 0, length, widthBytesLine; + Bool isRoot; + + REQUEST(xShmGetImageReq); + + REQUEST_SIZE_MATCH(xShmGetImageReq); + + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { + client->errorValue = stuff->format; + return BadValue; + } + + rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + if (draw->type == XRT_PIXMAP) + return ProcShmGetImage(client); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + x = stuff->x; + y = stuff->y; + w = stuff->width; + h = stuff->height; + format = stuff->format; + planemask = stuff->planeMask; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + if(isRoot) { + if( /* check for being onscreen */ + x < 0 || x + w > PanoramiXPixWidth || + y < 0 || y + h > PanoramiXPixHeight ) + return BadMatch; + } else { + if( /* check for being onscreen */ + screenInfo.screens[0]->x + pDraw->x + x < 0 || + screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || + screenInfo.screens[0]->y + pDraw->y + y < 0 || + screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || + /* check for being inside of border */ + x < - wBorderWidth((WindowPtr)pDraw) || + x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + y < -wBorderWidth((WindowPtr)pDraw) || + y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) + return BadMatch; + } + + drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); + if(!drawables) + return BadAlloc; + + drawables[0] = pDraw; + FOR_NSCREENS_FORWARD_SKIP(i) { + rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, + DixReadAccess); + if (rc != Success) + { + free(drawables); + return rc; + } + } + + xgi.visual = wVisual(((WindowPtr)pDraw)); + xgi.type = X_Reply; + xgi.length = 0; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + + if(format == ZPixmap) { + widthBytesLine = PixmapBytePad(w, pDraw->depth); + length = widthBytesLine * h; + } else { + widthBytesLine = PixmapBytePad(w, 1); + lenPer = widthBytesLine * h; + plane = ((Mask)1) << (pDraw->depth - 1); + length = lenPer * Ones(planemask & (plane | (plane - 1))); + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); + xgi.size = length; + + if (length == 0) {/* nothing to do */ } + else if (format == ZPixmap) { + XineramaGetImageData(drawables, x, y, w, h, format, planemask, + shmdesc->addr + stuff->offset, + widthBytesLine, isRoot); + } else { + + length = stuff->offset; + for (; plane; plane >>= 1) { + if (planemask & plane) { + XineramaGetImageData(drawables, x, y, w, h, + format, plane, shmdesc->addr + length, + widthBytesLine, isRoot); + length += lenPer; + } + } + } + free(drawables); + + if (client->swapped) { + int n; + swaps(&xgi.sequenceNumber, n); + swapl(&xgi.length, n); + swapl(&xgi.visual, n); + swapl(&xgi.size, n); + } + WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); + + return Success; +} + +static int +ProcPanoramiXShmCreatePixmap(ClientPtr client) +{ + ScreenPtr pScreen = NULL; + PixmapPtr pMap = NULL; + DrawablePtr pDraw; + DepthPtr pDepth; + int i, j, result, rc; + ShmDescPtr shmdesc; + REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; + PanoramiXRes *newPix; + + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + client->errorValue = stuff->pid; + if (!sharedPixmaps) + return BadImplementation; + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, + DixGetAttrAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) + { + client->errorValue = 0; + return BadValue; + } + if (width > 32767 || height > 32767) + return BadAlloc; + + if (stuff->depth != 1) + { + pDepth = pDraw->pScreen->allowedDepths; + for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) + if (pDepth->depth == stuff->depth) + goto CreatePmap; + client->errorValue = stuff->depth; + return BadValue; + } + +CreatePmap: + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + } + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); + + if(!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = TRUE; + panoramix_setup_ids(newPix, client, stuff->pid); + + result = Success; + + FOR_NSCREENS(j) { + ShmScrPrivateRec *screen_priv; + pScreen = screenInfo.screens[j]; + + screen_priv = ShmGetScreenPriv(pScreen); + pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, + stuff->width, stuff->height, stuff->depth, + shmdesc->addr + stuff->offset); + + if (pMap) { + dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); + shmdesc->refcnt++; + pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pMap->drawable.id = newPix->info[j].id; + if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { + (*pScreen->DestroyPixmap)(pMap); + result = BadAlloc; + break; + } + } else { + result = BadAlloc; + break; + } + } + + if(result == BadAlloc) { + while(j--) { + (*pScreen->DestroyPixmap)(pMap); + FreeResource(newPix->info[j].id, RT_NONE); + } + free(newPix); + } else + AddResource(stuff->pid, XRT_PIXMAP, newPix); + + return result; +} +#endif + +static PixmapPtr +fbShmCreatePixmap (ScreenPtr pScreen, + int width, int height, int depth, char *addr) +{ + PixmapPtr pPixmap; + + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); + if (!pPixmap) + return NullPixmap; + + if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, + BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) { + (*pScreen->DestroyPixmap)(pPixmap); + return NullPixmap; + } + return pPixmap; +} + +static int +ProcShmCreatePixmap(ClientPtr client) +{ + PixmapPtr pMap; + DrawablePtr pDraw; + DepthPtr pDepth; + int i, rc; + ShmDescPtr shmdesc; + ShmScrPrivateRec *screen_priv; + REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; + + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + client->errorValue = stuff->pid; + if (!sharedPixmaps) + return BadImplementation; + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, + DixGetAttrAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) + { + client->errorValue = 0; + return BadValue; + } + if (width > 32767 || height > 32767) + return BadAlloc; + + if (stuff->depth != 1) + { + pDepth = pDraw->pScreen->allowedDepths; + for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) + if (pDepth->depth == stuff->depth) + goto CreatePmap; + client->errorValue = stuff->depth; + return BadValue; + } + +CreatePmap: + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + } + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); + screen_priv = ShmGetScreenPriv(pDraw->pScreen); + pMap = (*screen_priv->shmFuncs->CreatePixmap)( + pDraw->pScreen, stuff->width, + stuff->height, stuff->depth, + shmdesc->addr + stuff->offset); + if (pMap) + { + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, + pMap, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) { + pDraw->pScreen->DestroyPixmap(pMap); + return rc; + } + dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); + shmdesc->refcnt++; + pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pMap->drawable.id = stuff->pid; + if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) + { + return Success; + } + pDraw->pScreen->DestroyPixmap(pMap); + } + return BadAlloc; +} + +static int +ProcShmDispatch (ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_ShmQueryVersion: + return ProcShmQueryVersion(client); + case X_ShmAttach: + return ProcShmAttach(client); + case X_ShmDetach: + return ProcShmDetach(client); + case X_ShmPutImage: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmPutImage(client); +#endif + return ProcShmPutImage(client); + case X_ShmGetImage: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmGetImage(client); +#endif + return ProcShmGetImage(client); + case X_ShmCreatePixmap: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmCreatePixmap(client); +#endif + return ProcShmCreatePixmap(client); + default: + return BadRequest; + } +} + +static void +SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to) +{ + to->type = from->type; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->drawable, to->drawable); + cpswaps(from->minorEvent, to->minorEvent); + to->majorEvent = from->majorEvent; + cpswapl(from->shmseg, to->shmseg); + cpswapl(from->offset, to->offset); +} + +static int +SProcShmQueryVersion(ClientPtr client) +{ + int n; + REQUEST(xShmQueryVersionReq); + + swaps(&stuff->length, n); + return ProcShmQueryVersion(client); +} + +static int +SProcShmAttach(ClientPtr client) +{ + int n; + REQUEST(xShmAttachReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmAttachReq); + swapl(&stuff->shmseg, n); + swapl(&stuff->shmid, n); + return ProcShmAttach(client); +} + +static int +SProcShmDetach(ClientPtr client) +{ + int n; + REQUEST(xShmDetachReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmDetachReq); + swapl(&stuff->shmseg, n); + return ProcShmDetach(client); +} + +static int +SProcShmPutImage(ClientPtr client) +{ + int n; + REQUEST(xShmPutImageReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmPutImageReq); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->totalWidth, n); + swaps(&stuff->totalHeight, n); + swaps(&stuff->srcX, n); + swaps(&stuff->srcY, n); + swaps(&stuff->srcWidth, n); + swaps(&stuff->srcHeight, n); + swaps(&stuff->dstX, n); + swaps(&stuff->dstY, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmPutImage(client); +} + +static int +SProcShmGetImage(ClientPtr client) +{ + int n; + REQUEST(xShmGetImageReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmGetImageReq); + swapl(&stuff->drawable, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->planeMask, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmGetImage(client); +} + +static int +SProcShmCreatePixmap(ClientPtr client) +{ + int n; + REQUEST(xShmCreatePixmapReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmCreatePixmap(client); +} + +static int +SProcShmDispatch (ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_ShmQueryVersion: + return SProcShmQueryVersion(client); + case X_ShmAttach: + return SProcShmAttach(client); + case X_ShmDetach: + return SProcShmDetach(client); + case X_ShmPutImage: + return SProcShmPutImage(client); + case X_ShmGetImage: + return SProcShmGetImage(client); + case X_ShmCreatePixmap: + return SProcShmCreatePixmap(client); + default: + return BadRequest; + } +} + +void +ShmExtensionInit(INITARGS) +{ + ExtensionEntry *extEntry; + int i; + +#ifdef MUST_CHECK_FOR_SHM_SYSCALL + if (!CheckForShmSyscall()) + { + ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); + return; + } +#endif + + if (!ShmRegisterPrivates()) + return; + + sharedPixmaps = xFalse; + { + sharedPixmaps = xTrue; + for (i = 0; i < screenInfo.numScreens; i++) + { + ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]); + if (!screen_priv->shmFuncs) + screen_priv->shmFuncs = &miFuncs; + if (!screen_priv->shmFuncs->CreatePixmap) + sharedPixmaps = xFalse; + } + if (sharedPixmaps) + for (i = 0; i < screenInfo.numScreens; i++) + { + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]); + screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap; + screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; + } + } + ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); + if (ShmSegType && + (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors, + ProcShmDispatch, SProcShmDispatch, + ShmResetProc, StandardMinorOpcode))) + { + ShmReqCode = (unsigned char)extEntry->base; + ShmCompletionCode = extEntry->eventBase; + BadShmSegCode = extEntry->errorBase; + SetResourceTypeErrorValue(ShmSegType, BadShmSegCode); + EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; + } +} diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c index e723fd84b..b96843159 100644 --- a/xorg-server/Xext/xvdisp.c +++ b/xorg-server/Xext/xvdisp.c @@ -1,1961 +1,1961 @@ -/***********************************************************
-Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "opaque.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-#ifdef MITSHM
-#include <X11/extensions/shmproto.h>
-#endif
-
-#include "xvdisp.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-
-unsigned long XvXRTPort;
-#endif
-
-static int
-SWriteQueryExtensionReply(
- ClientPtr client,
- xvQueryExtensionReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->version, n);
- swaps(&rep->revision, n);
-
- (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryAdaptorsReply(
- ClientPtr client,
- xvQueryAdaptorsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_adaptors, n);
-
- (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryEncodingsReply(
- ClientPtr client,
- xvQueryEncodingsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_encodings, n);
-
- (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteAdaptorInfo(
- ClientPtr client,
- xvAdaptorInfo *pAdaptor
-){
- char n;
-
- swapl(&pAdaptor->base_id, n);
- swaps(&pAdaptor->name_size, n);
- swaps(&pAdaptor->num_ports, n);
- swaps(&pAdaptor->num_formats, n);
-
- (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
-
- return Success;
-}
-
-static int
-SWriteEncodingInfo(
- ClientPtr client,
- xvEncodingInfo *pEncoding
-){
- char n;
-
- swapl(&pEncoding->encoding, n);
- swaps(&pEncoding->name_size, n);
- swaps(&pEncoding->width, n);
- swaps(&pEncoding->height, n);
- swapl(&pEncoding->rate.numerator, n);
- swapl(&pEncoding->rate.denominator, n);
- (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
-
- return Success;
-}
-
-static int
-SWriteFormat(
- ClientPtr client,
- xvFormat *pFormat
-){
- char n;
-
- swapl(&pFormat->visual, n);
- (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
-
- return Success;
-}
-
-static int
-SWriteAttributeInfo(
- ClientPtr client,
- xvAttributeInfo *pAtt
-){
- char n;
-
- swapl(&pAtt->flags, n);
- swapl(&pAtt->size, n);
- swapl(&pAtt->min, n);
- swapl(&pAtt->max, n);
- (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
-
- return Success;
-}
-
-static int
-SWriteImageFormatInfo(
- ClientPtr client,
- xvImageFormatInfo *pImage
-){
- char n;
-
- swapl(&pImage->id, n);
- swapl(&pImage->red_mask, n);
- swapl(&pImage->green_mask, n);
- swapl(&pImage->blue_mask, n);
- swapl(&pImage->y_sample_bits, n);
- swapl(&pImage->u_sample_bits, n);
- swapl(&pImage->v_sample_bits, n);
- swapl(&pImage->horz_y_period, n);
- swapl(&pImage->horz_u_period, n);
- swapl(&pImage->horz_v_period, n);
- swapl(&pImage->vert_y_period, n);
- swapl(&pImage->vert_u_period, n);
- swapl(&pImage->vert_v_period, n);
-
- (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
-
- return Success;
-}
-
-static int
-SWriteGrabPortReply(
- ClientPtr client,
- xvGrabPortReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
-
- (void)WriteToClient(client, sz_xvGrabPortReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteGetPortAttributeReply(
- ClientPtr client,
- xvGetPortAttributeReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->value, n);
-
- (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryBestSizeReply(
- ClientPtr client,
- xvQueryBestSizeReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->actual_width, n);
- swaps(&rep->actual_height, n);
-
- (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryPortAttributesReply(
- ClientPtr client,
- xvQueryPortAttributesReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_attributes, n);
- swapl(&rep->text_size, n);
-
- (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryImageAttributesReply(
- ClientPtr client,
- xvQueryImageAttributesReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_planes, n);
- swapl(&rep->data_size, n);
- swaps(&rep->width, n);
- swaps(&rep->height, n);
-
- (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteListImageFormatsReply(
- ClientPtr client,
- xvListImageFormatsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_formats, n);
-
- (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)rep);
-
- return Success;
-}
-
-#define _WriteQueryAdaptorsReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
-
-#define _WriteQueryExtensionReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
-
-#define _WriteQueryEncodingsReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
-
-#define _WriteAdaptorInfo(_c,_d) \
- if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
- else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
-
-#define _WriteAttributeInfo(_c,_d) \
- if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
- else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
-
-#define _WriteEncodingInfo(_c,_d) \
- if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
- else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
-
-#define _WriteFormat(_c,_d) \
- if ((_c)->swapped) SWriteFormat(_c, _d); \
- else WriteToClient(_c, sz_xvFormat, (char*)_d)
-
-#define _WriteGrabPortReply(_c,_d) \
- if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
- else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
-
-#define _WriteGetPortAttributeReply(_c,_d) \
- if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
- else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
-
-#define _WriteQueryBestSizeReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
-
-#define _WriteQueryPortAttributesReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
-
-#define _WriteQueryImageAttributesReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
-
-#define _WriteListImageFormatsReply(_c,_d) \
- if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
- else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
-
-#define _WriteImageFormatInfo(_c,_d) \
- if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
- else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
-
-#define _AllocatePort(_i,_p) \
- ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
-
-static int
-ProcXvQueryExtension(ClientPtr client)
-{
- xvQueryExtensionReply rep;
- /* REQUEST(xvQueryExtensionReq); */
- REQUEST_SIZE_MATCH(xvQueryExtensionReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.version = XvVersion;
- rep.revision = XvRevision;
-
- _WriteQueryExtensionReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvQueryAdaptors(ClientPtr client)
-{
- xvFormat format;
- xvAdaptorInfo ainfo;
- xvQueryAdaptorsReply rep;
- int totalSize, na, nf, rc;
- int nameSize;
- XvAdaptorPtr pa;
- XvFormatPtr pf;
- WindowPtr pWin;
- ScreenPtr pScreen;
- XvScreenPtr pxvs;
-
- REQUEST(xvQueryAdaptorsReq);
- REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- pScreen = pWin->drawable.pScreen;
- pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- XvGetScreenKey());
- if (!pxvs)
- {
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_adaptors = 0;
- rep.length = 0;
-
- _WriteQueryAdaptorsReply(client, &rep);
-
- return Success;
- }
-
- (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_adaptors = pxvs->nAdaptors;
-
- /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
-
- totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
-
- /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
-
- na = pxvs->nAdaptors;
- pa = pxvs->pAdaptors;
- while (na--)
- {
- totalSize += pad_to_int32(strlen(pa->name));
- totalSize += pa->nFormats * sz_xvFormat;
- pa++;
- }
-
- rep.length = bytes_to_int32(totalSize);
-
- _WriteQueryAdaptorsReply(client, &rep);
-
- na = pxvs->nAdaptors;
- pa = pxvs->pAdaptors;
- while (na--)
- {
-
- ainfo.base_id = pa->base_id;
- ainfo.num_ports = pa->nPorts;
- ainfo.type = pa->type;
- ainfo.name_size = nameSize = strlen(pa->name);
- ainfo.num_formats = pa->nFormats;
-
- _WriteAdaptorInfo(client, &ainfo);
-
- WriteToClient(client, nameSize, pa->name);
-
- nf = pa->nFormats;
- pf = pa->pFormats;
- while (nf--)
- {
- format.depth = pf->depth;
- format.visual = pf->visual;
- _WriteFormat(client, &format);
- pf++;
- }
-
- pa++;
-
- }
-
- return Success;
-}
-
-static int
-ProcXvQueryEncodings(ClientPtr client)
-{
- xvEncodingInfo einfo;
- xvQueryEncodingsReply rep;
- int totalSize;
- int nameSize;
- XvPortPtr pPort;
- int ne;
- XvEncodingPtr pe;
- int status;
-
- REQUEST(xvQueryEncodingsReq);
- REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_encodings = pPort->pAdaptor->nEncodings;
-
- /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
-
- ne = pPort->pAdaptor->nEncodings;
- pe = pPort->pAdaptor->pEncodings;
- totalSize = ne * sz_xvEncodingInfo;
- while (ne--)
- {
- totalSize += pad_to_int32(strlen(pe->name));
- pe++;
- }
-
- rep.length = bytes_to_int32(totalSize);
-
- _WriteQueryEncodingsReply(client, &rep);
-
- ne = pPort->pAdaptor->nEncodings;
- pe = pPort->pAdaptor->pEncodings;
- while (ne--)
- {
- einfo.encoding = pe->id;
- einfo.name_size = nameSize = strlen(pe->name);
- einfo.width = pe->width;
- einfo.height = pe->height;
- einfo.rate.numerator = pe->rate.numerator;
- einfo.rate.denominator = pe->rate.denominator;
- _WriteEncodingInfo(client, &einfo);
- WriteToClient(client, nameSize, pe->name);
- pe++;
- }
-
- return Success;
-}
-
-static int
-ProcXvPutVideo(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvPutVideoReq);
- REQUEST_SIZE_MATCH(xvPutVideoReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvInputMask) ||
- !(pPort->pAdaptor->type & XvVideoMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvPutStill(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvPutStillReq);
- REQUEST_SIZE_MATCH(xvPutStillReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvInputMask) ||
- !(pPort->pAdaptor->type & XvStillMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvGetVideo(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvGetVideoReq);
- REQUEST_SIZE_MATCH(xvGetVideoReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvOutputMask) ||
- !(pPort->pAdaptor->type & XvVideoMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvGetStill(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvGetStillReq);
- REQUEST_SIZE_MATCH(xvGetStillReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvOutputMask) ||
- !(pPort->pAdaptor->type & XvStillMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvSelectVideoNotify(ClientPtr client)
-{
- DrawablePtr pDraw;
- int rc;
- REQUEST(xvSelectVideoNotifyReq);
- REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess);
- if (rc != Success)
- return rc;
-
- return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
-}
-
-static int
-ProcXvSelectPortNotify(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvSelectPortNotifyReq);
- REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- return XvdiSelectPortNotify(client, pPort, stuff->onoff);
-}
-
-static int
-ProcXvGrabPort(ClientPtr client)
-{
- int result, status;
- XvPortPtr pPort;
- xvGrabPortReply rep;
- REQUEST(xvGrabPortReq);
- REQUEST_SIZE_MATCH(xvGrabPortReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- status = XvdiGrabPort(client, pPort, stuff->time, &result);
-
- if (status != Success)
- {
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.result = result;
-
- _WriteGrabPortReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvUngrabPort(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvGrabPortReq);
- REQUEST_SIZE_MATCH(xvGrabPortReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- return XvdiUngrabPort(client, pPort, stuff->time);
-}
-
-static int
-ProcXvStopVideo(ClientPtr client)
-{
- int status, rc;
- DrawablePtr pDraw;
- XvPortPtr pPort;
- REQUEST(xvStopVideoReq);
- REQUEST_SIZE_MATCH(xvStopVideoReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
- if (rc != Success)
- return rc;
-
- return XvdiStopVideo(client, pPort, pDraw);
-}
-
-static int
-ProcXvSetPortAttribute(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvSetPortAttributeReq);
- REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!ValidAtom(stuff->attribute))
- {
- client->errorValue = stuff->attribute;
- return BadAtom;
- }
-
- status = XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
-
- if (status == BadMatch)
- client->errorValue = stuff->attribute;
- else
- client->errorValue = stuff->value;
-
- return status;
-}
-
-static int
-ProcXvGetPortAttribute(ClientPtr client)
-{
- INT32 value;
- int status;
- XvPortPtr pPort;
- xvGetPortAttributeReply rep;
- REQUEST(xvGetPortAttributeReq);
- REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!ValidAtom(stuff->attribute))
- {
- client->errorValue = stuff->attribute;
- return BadAtom;
- }
-
- status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
- if (status != Success)
- {
- client->errorValue = stuff->attribute;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.value = value;
-
- _WriteGetPortAttributeReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvQueryBestSize(ClientPtr client)
-{
- int status;
- unsigned int actual_width, actual_height;
- XvPortPtr pPort;
- xvQueryBestSizeReply rep;
- REQUEST(xvQueryBestSizeReq);
- REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
-
- (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
- stuff->vid_w, stuff->vid_h,
- stuff->drw_w, stuff->drw_h,
- &actual_width, &actual_height);
-
- rep.actual_width = actual_width;
- rep.actual_height = actual_height;
-
- _WriteQueryBestSizeReply(client, &rep);
-
- return Success;
-}
-
-
-static int
-ProcXvQueryPortAttributes(ClientPtr client)
-{
- int status, size, i;
- XvPortPtr pPort;
- XvAttributePtr pAtt;
- xvQueryPortAttributesReply rep;
- xvAttributeInfo Info;
- REQUEST(xvQueryPortAttributesReq);
- REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_attributes = pPort->pAdaptor->nAttributes;
- rep.text_size = 0;
-
- for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
- i < pPort->pAdaptor->nAttributes; i++, pAtt++)
- {
- rep.text_size += pad_to_int32(strlen(pAtt->name) + 1);
- }
-
- rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
- + rep.text_size;
- rep.length >>= 2;
-
- _WriteQueryPortAttributesReply(client, &rep);
-
- for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
- i < pPort->pAdaptor->nAttributes; i++, pAtt++)
- {
- size = strlen(pAtt->name) + 1; /* pass the NULL */
- Info.flags = pAtt->flags;
- Info.min = pAtt->min_value;
- Info.max = pAtt->max_value;
- Info.size = pad_to_int32(size);
-
- _WriteAttributeInfo(client, &Info);
-
- WriteToClient(client, size, pAtt->name);
- }
-
- return Success;
-}
-
-static int
-ProcXvPutImage(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- XvImagePtr pImage = NULL;
- GCPtr pGC;
- int status, i, size;
- CARD16 width, height;
-
- REQUEST(xvPutImageReq);
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvImageMask) ||
- !(pPort->pAdaptor->type & XvInputMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
- if(!pImage)
- return BadMatch;
-
- width = stuff->width;
- height = stuff->height;
- size = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
- pPort, pImage, &width, &height, NULL, NULL);
- size += sizeof(xvPutImageReq);
- size = bytes_to_int32(size);
-
- if((width < stuff->width) || (height < stuff->height))
- return BadValue;
-
- if(client->req_len < size)
- return BadLength;
-
- return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
- stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h, pImage,
- (unsigned char*)(&stuff[1]), FALSE,
- stuff->width, stuff->height);
-}
-
-#ifdef MITSHM
-/* redefined here since it's not in any header file */
-typedef struct _ShmDesc {
- struct _ShmDesc *next;
- int shmid;
- int refcnt;
- char *addr;
- Bool writable;
- unsigned long size;
-} ShmDescRec, *ShmDescPtr;
-
-extern RESTYPE ShmSegType;
-extern int ShmCompletionCode;
-
-static int
-ProcXvShmPutImage(ClientPtr client)
-{
- ShmDescPtr shmdesc;
- DrawablePtr pDraw;
- XvPortPtr pPort;
- XvImagePtr pImage = NULL;
- GCPtr pGC;
- int status, size_needed, i;
- CARD16 width, height;
-
- REQUEST(xvShmPutImageReq);
- REQUEST_SIZE_MATCH(xvShmPutImageReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvImageMask) ||
- !(pPort->pAdaptor->type & XvInputMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
- if(!pImage)
- return BadMatch;
-
- status = dixLookupResourceByType((pointer *)&shmdesc, stuff->shmseg,
- ShmSegType, serverClient, DixReadAccess);
- if (status != Success)
- return status;
-
- width = stuff->width;
- height = stuff->height;
- size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
- pPort, pImage, &width, &height, NULL, NULL);
- if((size_needed + stuff->offset) > shmdesc->size)
- return BadAccess;
-
- if((width < stuff->width) || (height < stuff->height))
- return BadValue;
-
- status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
- stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h, pImage,
- (unsigned char *)shmdesc->addr + stuff->offset,
- stuff->send_event, stuff->width, stuff->height);
-
- if((status == Success) && stuff->send_event) {
- xShmCompletionEvent ev;
-
- ev.type = ShmCompletionCode;
- ev.drawable = stuff->drawable;
- ev.minorEvent = xv_ShmPutImage;
- ev.majorEvent = XvReqCode;
- ev.shmseg = stuff->shmseg;
- ev.offset = stuff->offset;
- WriteEventsToClient(client, 1, (xEvent *) &ev);
- }
-
- return status;
-}
-#else /* !MITSHM */
-static int
-ProcXvShmPutImage(ClientPtr client)
-{
- SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation);
- return BadImplementation;
-}
-#endif
-
-#ifdef XvMCExtension
-#include "xvmcext.h"
-#endif
-
-static int
-ProcXvQueryImageAttributes(ClientPtr client)
-{
- xvQueryImageAttributesReply rep;
- int size, num_planes, i;
- CARD16 width, height;
- XvImagePtr pImage = NULL;
- XvPortPtr pPort;
- int *offsets;
- int *pitches;
- int planeLength;
- REQUEST(xvQueryImageAttributesReq);
-
- REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
-#ifdef XvMCExtension
- if(!pImage)
- pImage = XvMCFindXvImage(pPort, stuff->id);
-#endif
-
- if(!pImage)
- return BadMatch;
-
- num_planes = pImage->num_planes;
-
- if(!(offsets = malloc(num_planes << 3)))
- return BadAlloc;
- pitches = offsets + num_planes;
-
- width = stuff->width;
- height = stuff->height;
-
- size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
- &width, &height, offsets, pitches);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = planeLength = num_planes << 1;
- rep.num_planes = num_planes;
- rep.width = width;
- rep.height = height;
- rep.data_size = size;
-
- _WriteQueryImageAttributesReply(client, &rep);
- if(client->swapped)
- SwapLongs((CARD32*)offsets, planeLength);
- WriteToClient(client, planeLength << 2, (char*)offsets);
-
- free(offsets);
-
- return Success;
-}
-
-static int
-ProcXvListImageFormats(ClientPtr client)
-{
- XvPortPtr pPort;
- XvImagePtr pImage;
- int i;
- xvListImageFormatsReply rep;
- xvImageFormatInfo info;
- REQUEST(xvListImageFormatsReq);
-
- REQUEST_SIZE_MATCH(xvListImageFormatsReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_formats = pPort->pAdaptor->nImages;
- rep.length = bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo);
-
- _WriteListImageFormatsReply(client, &rep);
-
- pImage = pPort->pAdaptor->pImages;
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) {
- info.id = pImage->id;
- info.type = pImage->type;
- info.byte_order = pImage->byte_order;
- memcpy(&info.guid, pImage->guid, 16);
- info.bpp = pImage->bits_per_pixel;
- info.num_planes = pImage->num_planes;
- info.depth = pImage->depth;
- info.red_mask = pImage->red_mask;
- info.green_mask = pImage->green_mask;
- info.blue_mask = pImage->blue_mask;
- info.format = pImage->format;
- info.y_sample_bits = pImage->y_sample_bits;
- info.u_sample_bits = pImage->u_sample_bits;
- info.v_sample_bits = pImage->v_sample_bits;
- info.horz_y_period = pImage->horz_y_period;
- info.horz_u_period = pImage->horz_u_period;
- info.horz_v_period = pImage->horz_v_period;
- info.vert_y_period = pImage->vert_y_period;
- info.vert_u_period = pImage->vert_u_period;
- info.vert_v_period = pImage->vert_v_period;
- memcpy(&info.comp_order, pImage->component_order, 32);
- info.scanline_order = pImage->scanline_order;
- _WriteImageFormatInfo(client, &info);
- }
-
- return Success;
-}
-
-static int (*XvProcVector[xvNumRequests])(ClientPtr) = {
- ProcXvQueryExtension,
- ProcXvQueryAdaptors,
- ProcXvQueryEncodings,
- ProcXvGrabPort,
- ProcXvUngrabPort,
- ProcXvPutVideo,
- ProcXvPutStill,
- ProcXvGetVideo,
- ProcXvGetStill,
- ProcXvStopVideo,
- ProcXvSelectVideoNotify,
- ProcXvSelectPortNotify,
- ProcXvQueryBestSize,
- ProcXvSetPortAttribute,
- ProcXvGetPortAttribute,
- ProcXvQueryPortAttributes,
- ProcXvListImageFormats,
- ProcXvQueryImageAttributes,
- ProcXvPutImage,
- ProcXvShmPutImage,
-};
-
-int
-ProcXvDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- UpdateCurrentTime();
-
- if (stuff->data > xvNumRequests) {
- SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
- return BadRequest;
- }
-
- return XvProcVector[stuff->data](client);
-}
-
-/* Swapped Procs */
-
-static int
-SProcXvQueryExtension(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryExtensionReq);
- swaps(&stuff->length, n);
- return XvProcVector[xv_QueryExtension](client);
-}
-
-static int
-SProcXvQueryAdaptors(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryAdaptorsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->window, n);
- return XvProcVector[xv_QueryAdaptors](client);
-}
-
-static int
-SProcXvQueryEncodings(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryEncodingsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_QueryEncodings](client);
-}
-
-static int
-SProcXvGrabPort(ClientPtr client)
-{
- char n;
- REQUEST(xvGrabPortReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->time, n);
- return XvProcVector[xv_GrabPort](client);
-}
-
-static int
-SProcXvUngrabPort(ClientPtr client)
-{
- char n;
- REQUEST(xvUngrabPortReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->time, n);
- return XvProcVector[xv_UngrabPort](client);
-}
-
-static int
-SProcXvPutVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvPutVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_PutVideo](client);
-}
-
-static int
-SProcXvPutStill(ClientPtr client)
-{
- char n;
- REQUEST(xvPutStillReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_PutStill](client);
-}
-
-static int
-SProcXvGetVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvGetVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_GetVideo](client);
-}
-
-static int
-SProcXvGetStill(ClientPtr client)
-{
- char n;
- REQUEST(xvGetStillReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_GetStill](client);
-}
-
-static int
-SProcXvPutImage(ClientPtr client)
-{
- char n;
- REQUEST(xvPutImageReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swapl(&stuff->id, n);
- swaps(&stuff->src_x, n);
- swaps(&stuff->src_y, n);
- swaps(&stuff->src_w, n);
- swaps(&stuff->src_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_PutImage](client);
-}
-
-#ifdef MITSHM
-static int
-SProcXvShmPutImage(ClientPtr client)
-{
- char n;
- REQUEST(xvShmPutImageReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->id, n);
- swapl(&stuff->offset, n);
- swaps(&stuff->src_x, n);
- swaps(&stuff->src_y, n);
- swaps(&stuff->src_w, n);
- swaps(&stuff->src_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_ShmPutImage](client);
-}
-#else /* MITSHM */
-#define SProcXvShmPutImage ProcXvShmPutImage
-#endif
-
-static int
-SProcXvSelectVideoNotify(ClientPtr client)
-{
- char n;
- REQUEST(xvSelectVideoNotifyReq);
- swaps(&stuff->length, n);
- swapl(&stuff->drawable, n);
- return XvProcVector[xv_SelectVideoNotify](client);
-}
-
-static int
-SProcXvSelectPortNotify(ClientPtr client)
-{
- char n;
- REQUEST(xvSelectPortNotifyReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_SelectPortNotify](client);
-}
-
-static int
-SProcXvStopVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvStopVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- return XvProcVector[xv_StopVideo](client);
-}
-
-static int
-SProcXvSetPortAttribute(ClientPtr client)
-{
- char n;
- REQUEST(xvSetPortAttributeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->attribute, n);
- swapl(&stuff->value, n);
- return XvProcVector[xv_SetPortAttribute](client);
-}
-
-static int
-SProcXvGetPortAttribute(ClientPtr client)
-{
- char n;
- REQUEST(xvGetPortAttributeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->attribute, n);
- return XvProcVector[xv_GetPortAttribute](client);
-}
-
-static int
-SProcXvQueryBestSize(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryBestSizeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_QueryBestSize](client);
-}
-
-static int
-SProcXvQueryPortAttributes(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryPortAttributesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_QueryPortAttributes](client);
-}
-
-static int
-SProcXvQueryImageAttributes(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryImageAttributesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->id, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_QueryImageAttributes](client);
-}
-
-static int
-SProcXvListImageFormats(ClientPtr client)
-{
- char n;
- REQUEST(xvListImageFormatsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_ListImageFormats](client);
-}
-
-static int (*SXvProcVector[xvNumRequests])(ClientPtr) = {
- SProcXvQueryExtension,
- SProcXvQueryAdaptors,
- SProcXvQueryEncodings,
- SProcXvGrabPort,
- SProcXvUngrabPort,
- SProcXvPutVideo,
- SProcXvPutStill,
- SProcXvGetVideo,
- SProcXvGetStill,
- SProcXvStopVideo,
- SProcXvSelectVideoNotify,
- SProcXvSelectPortNotify,
- SProcXvQueryBestSize,
- SProcXvSetPortAttribute,
- SProcXvGetPortAttribute,
- SProcXvQueryPortAttributes,
- SProcXvListImageFormats,
- SProcXvQueryImageAttributes,
- SProcXvPutImage,
- SProcXvShmPutImage,
-};
-
-int
-SProcXvDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- UpdateCurrentTime();
-
- if (stuff->data > xvNumRequests) {
- SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
- return BadRequest;
- }
-
- return SXvProcVector[stuff->data](client);
-}
-
-#ifdef PANORAMIX
-static int
-XineramaXvStopVideo(ClientPtr client)
-{
- int result, i;
- PanoramiXRes *draw, *port;
- REQUEST(xvStopVideoReq);
- REQUEST_SIZE_MATCH(xvStopVideoReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- result = ProcXvStopVideo(client);
- }
- }
-
- return result;
-}
-
-static int
-XineramaXvSetPortAttribute(ClientPtr client)
-{
- REQUEST(xvSetPortAttributeReq);
- PanoramiXRes *port;
- int result, i;
-
- REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->port = port->info[i].id;
- result = ProcXvSetPortAttribute(client);
- }
- }
- return result;
-}
-
-#ifdef MITSHM
-static int
-XineramaXvShmPutImage(ClientPtr client)
-{
- REQUEST(xvShmPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool send_event = stuff->send_event;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_SIZE_MATCH(xvShmPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
- stuff->send_event = (send_event && !i) ? 1 : 0;
-
- result = ProcXvShmPutImage(client);
- }
- }
- return result;
-}
-#else
-#define XineramaXvShmPutImage ProcXvShmPutImage
-#endif
-
-static int
-XineramaXvPutImage(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutImage(client);
- }
- }
- return result;
-}
-
-static int
-XineramaXvPutVideo(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutVideo(client);
- }
- }
- return result;
-}
-
-static int
-XineramaXvPutStill(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutStill(client);
- }
- }
- return result;
-}
-
-static Bool
-isImageAdaptor(XvAdaptorPtr pAdapt)
-{
- return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
-}
-
-static Bool
-hasOverlay(XvAdaptorPtr pAdapt)
-{
- int i;
- for(i = 0; i < pAdapt->nAttributes; i++)
- if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
- return TRUE;
- return FALSE;
-}
-
-static XvAdaptorPtr
-matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
-{
- int i;
- XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
- /* Do not try to go on if xv is not supported on this screen */
- if(xvsp == NULL)
- return NULL;
-
- /* if the adaptor has the same name it's a perfect match */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(!strcmp(refAdapt->name, pAdapt->name))
- return pAdapt;
- }
-
- /* otherwise we only look for XvImage adaptors */
- if(!isImageAdaptor(refAdapt))
- return NULL;
-
- /* prefer overlay/overlay non-overlay/non-overlay pairing */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
- return pAdapt;
- }
-
- /* but we'll take any XvImage pairing if we can get it */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(isImageAdaptor(pAdapt))
- return pAdapt;
- }
- return NULL;
-}
-
-void XineramifyXv(void)
-{
- XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
- XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
- int i, j, k;
-
- XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
-
- if (!xvsp0 || !XvXRTPort) return;
- SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
-
- for(i = 0; i < xvsp0->nAdaptors; i++) {
- Bool isOverlay;
- XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
- if(!(refAdapt->type & XvInputMask)) continue;
-
- MatchingAdaptors[0] = refAdapt;
- isOverlay = hasOverlay(refAdapt);
- for(j = 1; j < PanoramiXNumScreens; j++)
- MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
-
- /* now create a resource for each port */
- for(j = 0; j < refAdapt->nPorts; j++) {
- PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
- if(!port)
- break;
-
- for(k = 0; k < PanoramiXNumScreens; k++) {
- if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
- port->info[k].id = MatchingAdaptors[k]->base_id + j;
- else
- port->info[k].id = 0;
- }
- AddResource(port->info[0].id, XvXRTPort, port);
- }
- }
-
- /* munge the dispatch vector */
- XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
- XvProcVector[xv_PutStill] = XineramaXvPutStill;
- XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
- XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
- XvProcVector[xv_PutImage] = XineramaXvPutImage;
- XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
-}
-#endif /* PANORAMIX */
-
-void
-XvResetProcVector(void)
-{
-#ifdef PANORAMIX
- XvProcVector[xv_PutVideo] = ProcXvPutVideo;
- XvProcVector[xv_PutStill] = ProcXvPutStill;
- XvProcVector[xv_StopVideo] = ProcXvStopVideo;
- XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
- XvProcVector[xv_PutImage] = ProcXvPutImage;
- XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
-#endif
-}
+/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "dixstruct.h" +#include "resource.h" +#include "opaque.h" + +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> +#include "xvdix.h" +#ifdef MITSHM +#include <X11/extensions/shmproto.h> +#endif + +#include "xvdisp.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" + +unsigned long XvXRTPort; +#endif + +static int +SWriteQueryExtensionReply( + ClientPtr client, + xvQueryExtensionReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->version, n); + swaps(&rep->revision, n); + + (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryAdaptorsReply( + ClientPtr client, + xvQueryAdaptorsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_adaptors, n); + + (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryEncodingsReply( + ClientPtr client, + xvQueryEncodingsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_encodings, n); + + (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)rep); + + return Success; +} + +static int +SWriteAdaptorInfo( + ClientPtr client, + xvAdaptorInfo *pAdaptor +){ + char n; + + swapl(&pAdaptor->base_id, n); + swaps(&pAdaptor->name_size, n); + swaps(&pAdaptor->num_ports, n); + swaps(&pAdaptor->num_formats, n); + + (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor); + + return Success; +} + +static int +SWriteEncodingInfo( + ClientPtr client, + xvEncodingInfo *pEncoding +){ + char n; + + swapl(&pEncoding->encoding, n); + swaps(&pEncoding->name_size, n); + swaps(&pEncoding->width, n); + swaps(&pEncoding->height, n); + swapl(&pEncoding->rate.numerator, n); + swapl(&pEncoding->rate.denominator, n); + (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding); + + return Success; +} + +static int +SWriteFormat( + ClientPtr client, + xvFormat *pFormat +){ + char n; + + swapl(&pFormat->visual, n); + (void)WriteToClient(client, sz_xvFormat, (char *)pFormat); + + return Success; +} + +static int +SWriteAttributeInfo( + ClientPtr client, + xvAttributeInfo *pAtt +){ + char n; + + swapl(&pAtt->flags, n); + swapl(&pAtt->size, n); + swapl(&pAtt->min, n); + swapl(&pAtt->max, n); + (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt); + + return Success; +} + +static int +SWriteImageFormatInfo( + ClientPtr client, + xvImageFormatInfo *pImage +){ + char n; + + swapl(&pImage->id, n); + swapl(&pImage->red_mask, n); + swapl(&pImage->green_mask, n); + swapl(&pImage->blue_mask, n); + swapl(&pImage->y_sample_bits, n); + swapl(&pImage->u_sample_bits, n); + swapl(&pImage->v_sample_bits, n); + swapl(&pImage->horz_y_period, n); + swapl(&pImage->horz_u_period, n); + swapl(&pImage->horz_v_period, n); + swapl(&pImage->vert_y_period, n); + swapl(&pImage->vert_u_period, n); + swapl(&pImage->vert_v_period, n); + + (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage); + + return Success; +} + +static int +SWriteGrabPortReply( + ClientPtr client, + xvGrabPortReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + + (void)WriteToClient(client, sz_xvGrabPortReply, (char *)rep); + + return Success; +} + +static int +SWriteGetPortAttributeReply( + ClientPtr client, + xvGetPortAttributeReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->value, n); + + (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryBestSizeReply( + ClientPtr client, + xvQueryBestSizeReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->actual_width, n); + swaps(&rep->actual_height, n); + + (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryPortAttributesReply( + ClientPtr client, + xvQueryPortAttributesReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_attributes, n); + swapl(&rep->text_size, n); + + (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryImageAttributesReply( + ClientPtr client, + xvQueryImageAttributesReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_planes, n); + swapl(&rep->data_size, n); + swaps(&rep->width, n); + swaps(&rep->height, n); + + (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)rep); + + return Success; +} + +static int +SWriteListImageFormatsReply( + ClientPtr client, + xvListImageFormatsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_formats, n); + + (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)rep); + + return Success; +} + +#define _WriteQueryAdaptorsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d) + +#define _WriteQueryExtensionReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d) + +#define _WriteQueryEncodingsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d) + +#define _WriteAdaptorInfo(_c,_d) \ + if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d) + +#define _WriteAttributeInfo(_c,_d) \ + if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d) + +#define _WriteEncodingInfo(_c,_d) \ + if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \ + else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d) + +#define _WriteFormat(_c,_d) \ + if ((_c)->swapped) SWriteFormat(_c, _d); \ + else WriteToClient(_c, sz_xvFormat, (char*)_d) + +#define _WriteGrabPortReply(_c,_d) \ + if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \ + else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d) + +#define _WriteGetPortAttributeReply(_c,_d) \ + if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \ + else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d) + +#define _WriteQueryBestSizeReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d) + +#define _WriteQueryPortAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d) + +#define _WriteQueryImageAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d) + +#define _WriteListImageFormatsReply(_c,_d) \ + if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \ + else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d) + +#define _WriteImageFormatInfo(_c,_d) \ + if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \ + else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d) + +#define _AllocatePort(_i,_p) \ + ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success + +static int +ProcXvQueryExtension(ClientPtr client) +{ + xvQueryExtensionReply rep; + /* REQUEST(xvQueryExtensionReq); */ + REQUEST_SIZE_MATCH(xvQueryExtensionReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.version = XvVersion; + rep.revision = XvRevision; + + _WriteQueryExtensionReply(client, &rep); + + return Success; +} + +static int +ProcXvQueryAdaptors(ClientPtr client) +{ + xvFormat format; + xvAdaptorInfo ainfo; + xvQueryAdaptorsReply rep; + int totalSize, na, nf, rc; + int nameSize; + XvAdaptorPtr pa; + XvFormatPtr pf; + WindowPtr pWin; + ScreenPtr pScreen; + XvScreenPtr pxvs; + + REQUEST(xvQueryAdaptorsReq); + REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, + XvGetScreenKey()); + if (!pxvs) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = 0; + rep.length = 0; + + _WriteQueryAdaptorsReply(client, &rep); + + return Success; + } + + (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = pxvs->nAdaptors; + + /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */ + + totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo; + + /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */ + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + totalSize += pad_to_int32(strlen(pa->name)); + totalSize += pa->nFormats * sz_xvFormat; + pa++; + } + + rep.length = bytes_to_int32(totalSize); + + _WriteQueryAdaptorsReply(client, &rep); + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + + ainfo.base_id = pa->base_id; + ainfo.num_ports = pa->nPorts; + ainfo.type = pa->type; + ainfo.name_size = nameSize = strlen(pa->name); + ainfo.num_formats = pa->nFormats; + + _WriteAdaptorInfo(client, &ainfo); + + WriteToClient(client, nameSize, pa->name); + + nf = pa->nFormats; + pf = pa->pFormats; + while (nf--) + { + format.depth = pf->depth; + format.visual = pf->visual; + _WriteFormat(client, &format); + pf++; + } + + pa++; + + } + + return Success; +} + +static int +ProcXvQueryEncodings(ClientPtr client) +{ + xvEncodingInfo einfo; + xvQueryEncodingsReply rep; + int totalSize; + int nameSize; + XvPortPtr pPort; + int ne; + XvEncodingPtr pe; + int status; + + REQUEST(xvQueryEncodingsReq); + REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_encodings = pPort->pAdaptor->nEncodings; + + /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */ + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + totalSize = ne * sz_xvEncodingInfo; + while (ne--) + { + totalSize += pad_to_int32(strlen(pe->name)); + pe++; + } + + rep.length = bytes_to_int32(totalSize); + + _WriteQueryEncodingsReply(client, &rep); + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + while (ne--) + { + einfo.encoding = pe->id; + einfo.name_size = nameSize = strlen(pe->name); + einfo.width = pe->width; + einfo.height = pe->height; + einfo.rate.numerator = pe->rate.numerator; + einfo.rate.denominator = pe->rate.denominator; + _WriteEncodingInfo(client, &einfo); + WriteToClient(client, nameSize, pe->name); + pe++; + } + + return Success; +} + +static int +ProcXvPutVideo(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvPutVideoReq); + REQUEST_SIZE_MATCH(xvPutVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvPutStill(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvPutStillReq); + REQUEST_SIZE_MATCH(xvPutStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvGetVideo(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvGetVideoReq); + REQUEST_SIZE_MATCH(xvGetVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvGetStill(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvGetStillReq); + REQUEST_SIZE_MATCH(xvGetStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvSelectVideoNotify(ClientPtr client) +{ + DrawablePtr pDraw; + int rc; + REQUEST(xvSelectVideoNotifyReq); + REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess); + if (rc != Success) + return rc; + + return XvdiSelectVideoNotify(client, pDraw, stuff->onoff); +} + +static int +ProcXvSelectPortNotify(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSelectPortNotifyReq); + REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + return XvdiSelectPortNotify(client, pPort, stuff->onoff); +} + +static int +ProcXvGrabPort(ClientPtr client) +{ + int result, status; + XvPortPtr pPort; + xvGrabPortReply rep; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + status = XvdiGrabPort(client, pPort, stuff->time, &result); + + if (status != Success) + { + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.result = result; + + _WriteGrabPortReply(client, &rep); + + return Success; +} + +static int +ProcXvUngrabPort(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + return XvdiUngrabPort(client, pPort, stuff->time); +} + +static int +ProcXvStopVideo(ClientPtr client) +{ + int status, rc; + DrawablePtr pDraw; + XvPortPtr pPort; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + if (rc != Success) + return rc; + + return XvdiStopVideo(client, pPort, pDraw); +} + +static int +ProcXvSetPortAttribute(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSetPortAttributeReq); + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return BadAtom; + } + + status = XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value); + + if (status == BadMatch) + client->errorValue = stuff->attribute; + else + client->errorValue = stuff->value; + + return status; +} + +static int +ProcXvGetPortAttribute(ClientPtr client) +{ + INT32 value; + int status; + XvPortPtr pPort; + xvGetPortAttributeReply rep; + REQUEST(xvGetPortAttributeReq); + REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return BadAtom; + } + + status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value); + if (status != Success) + { + client->errorValue = stuff->attribute; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.value = value; + + _WriteGetPortAttributeReply(client, &rep); + + return Success; +} + +static int +ProcXvQueryBestSize(ClientPtr client) +{ + int status; + unsigned int actual_width, actual_height; + XvPortPtr pPort; + xvQueryBestSizeReply rep; + REQUEST(xvQueryBestSizeReq); + REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion, + stuff->vid_w, stuff->vid_h, + stuff->drw_w, stuff->drw_h, + &actual_width, &actual_height); + + rep.actual_width = actual_width; + rep.actual_height = actual_height; + + _WriteQueryBestSizeReply(client, &rep); + + return Success; +} + + +static int +ProcXvQueryPortAttributes(ClientPtr client) +{ + int status, size, i; + XvPortPtr pPort; + XvAttributePtr pAtt; + xvQueryPortAttributesReply rep; + xvAttributeInfo Info; + REQUEST(xvQueryPortAttributesReq); + REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_attributes = pPort->pAdaptor->nAttributes; + rep.text_size = 0; + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < pPort->pAdaptor->nAttributes; i++, pAtt++) + { + rep.text_size += pad_to_int32(strlen(pAtt->name) + 1); + } + + rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) + + rep.text_size; + rep.length >>= 2; + + _WriteQueryPortAttributesReply(client, &rep); + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < pPort->pAdaptor->nAttributes; i++, pAtt++) + { + size = strlen(pAtt->name) + 1; /* pass the NULL */ + Info.flags = pAtt->flags; + Info.min = pAtt->min_value; + Info.max = pAtt->max_value; + Info.size = pad_to_int32(size); + + _WriteAttributeInfo(client, &Info); + + WriteToClient(client, size, pAtt->name); + } + + return Success; +} + +static int +ProcXvPutImage(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, i, size; + CARD16 width, height; + + REQUEST(xvPutImageReq); + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + width = stuff->width; + height = stuff->height; + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + size += sizeof(xvPutImageReq); + size = bytes_to_int32(size); + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + if(client->req_len < size) + return BadLength; + + return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, pImage, + (unsigned char*)(&stuff[1]), FALSE, + stuff->width, stuff->height); +} + +#ifdef MITSHM +/* redefined here since it's not in any header file */ +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + +extern RESTYPE ShmSegType; +extern int ShmCompletionCode; + +static int +ProcXvShmPutImage(ClientPtr client) +{ + ShmDescPtr shmdesc; + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, size_needed, i; + CARD16 width, height; + + REQUEST(xvShmPutImageReq); + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + status = dixLookupResourceByType((pointer *)&shmdesc, stuff->shmseg, + ShmSegType, serverClient, DixReadAccess); + if (status != Success) + return status; + + width = stuff->width; + height = stuff->height; + size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + if((size_needed + stuff->offset) > shmdesc->size) + return BadAccess; + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, pImage, + (unsigned char *)shmdesc->addr + stuff->offset, + stuff->send_event, stuff->width, stuff->height); + + if((status == Success) && stuff->send_event) { + xShmCompletionEvent ev; + + ev.type = ShmCompletionCode; + ev.drawable = stuff->drawable; + ev.minorEvent = xv_ShmPutImage; + ev.majorEvent = XvReqCode; + ev.shmseg = stuff->shmseg; + ev.offset = stuff->offset; + WriteEventsToClient(client, 1, (xEvent *) &ev); + } + + return status; +} +#else /* !MITSHM */ +static int +ProcXvShmPutImage(ClientPtr client) +{ + SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation); + return BadImplementation; +} +#endif + +#ifdef XvMCExtension +#include "xvmcext.h" +#endif + +static int +ProcXvQueryImageAttributes(ClientPtr client) +{ + xvQueryImageAttributesReply rep; + int size, num_planes, i; + CARD16 width, height; + XvImagePtr pImage = NULL; + XvPortPtr pPort; + int *offsets; + int *pitches; + int planeLength; + REQUEST(xvQueryImageAttributesReq); + + REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + +#ifdef XvMCExtension + if(!pImage) + pImage = XvMCFindXvImage(pPort, stuff->id); +#endif + + if(!pImage) + return BadMatch; + + num_planes = pImage->num_planes; + + if(!(offsets = malloc(num_planes << 3))) + return BadAlloc; + pitches = offsets + num_planes; + + width = stuff->width; + height = stuff->height; + + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage, + &width, &height, offsets, pitches); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = planeLength = num_planes << 1; + rep.num_planes = num_planes; + rep.width = width; + rep.height = height; + rep.data_size = size; + + _WriteQueryImageAttributesReply(client, &rep); + if(client->swapped) + SwapLongs((CARD32*)offsets, planeLength); + WriteToClient(client, planeLength << 2, (char*)offsets); + + free(offsets); + + return Success; +} + +static int +ProcXvListImageFormats(ClientPtr client) +{ + XvPortPtr pPort; + XvImagePtr pImage; + int i; + xvListImageFormatsReply rep; + xvImageFormatInfo info; + REQUEST(xvListImageFormatsReq); + + REQUEST_SIZE_MATCH(xvListImageFormatsReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_formats = pPort->pAdaptor->nImages; + rep.length = bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo); + + _WriteListImageFormatsReply(client, &rep); + + pImage = pPort->pAdaptor->pImages; + + for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) { + info.id = pImage->id; + info.type = pImage->type; + info.byte_order = pImage->byte_order; + memcpy(&info.guid, pImage->guid, 16); + info.bpp = pImage->bits_per_pixel; + info.num_planes = pImage->num_planes; + info.depth = pImage->depth; + info.red_mask = pImage->red_mask; + info.green_mask = pImage->green_mask; + info.blue_mask = pImage->blue_mask; + info.format = pImage->format; + info.y_sample_bits = pImage->y_sample_bits; + info.u_sample_bits = pImage->u_sample_bits; + info.v_sample_bits = pImage->v_sample_bits; + info.horz_y_period = pImage->horz_y_period; + info.horz_u_period = pImage->horz_u_period; + info.horz_v_period = pImage->horz_v_period; + info.vert_y_period = pImage->vert_y_period; + info.vert_u_period = pImage->vert_u_period; + info.vert_v_period = pImage->vert_v_period; + memcpy(&info.comp_order, pImage->component_order, 32); + info.scanline_order = pImage->scanline_order; + _WriteImageFormatInfo(client, &info); + } + + return Success; +} + +static int (*XvProcVector[xvNumRequests])(ClientPtr) = { + ProcXvQueryExtension, + ProcXvQueryAdaptors, + ProcXvQueryEncodings, + ProcXvGrabPort, + ProcXvUngrabPort, + ProcXvPutVideo, + ProcXvPutStill, + ProcXvGetVideo, + ProcXvGetStill, + ProcXvStopVideo, + ProcXvSelectVideoNotify, + ProcXvSelectPortNotify, + ProcXvQueryBestSize, + ProcXvSetPortAttribute, + ProcXvGetPortAttribute, + ProcXvQueryPortAttributes, + ProcXvListImageFormats, + ProcXvQueryImageAttributes, + ProcXvPutImage, + ProcXvShmPutImage, +}; + +int +ProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + if (stuff->data > xvNumRequests) { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return BadRequest; + } + + return XvProcVector[stuff->data](client); +} + +/* Swapped Procs */ + +static int +SProcXvQueryExtension(ClientPtr client) +{ + char n; + REQUEST(xvQueryExtensionReq); + swaps(&stuff->length, n); + return XvProcVector[xv_QueryExtension](client); +} + +static int +SProcXvQueryAdaptors(ClientPtr client) +{ + char n; + REQUEST(xvQueryAdaptorsReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return XvProcVector[xv_QueryAdaptors](client); +} + +static int +SProcXvQueryEncodings(ClientPtr client) +{ + char n; + REQUEST(xvQueryEncodingsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_QueryEncodings](client); +} + +static int +SProcXvGrabPort(ClientPtr client) +{ + char n; + REQUEST(xvGrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return XvProcVector[xv_GrabPort](client); +} + +static int +SProcXvUngrabPort(ClientPtr client) +{ + char n; + REQUEST(xvUngrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return XvProcVector[xv_UngrabPort](client); +} + +static int +SProcXvPutVideo(ClientPtr client) +{ + char n; + REQUEST(xvPutVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_PutVideo](client); +} + +static int +SProcXvPutStill(ClientPtr client) +{ + char n; + REQUEST(xvPutStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_PutStill](client); +} + +static int +SProcXvGetVideo(ClientPtr client) +{ + char n; + REQUEST(xvGetVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_GetVideo](client); +} + +static int +SProcXvGetStill(ClientPtr client) +{ + char n; + REQUEST(xvGetStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_GetStill](client); +} + +static int +SProcXvPutImage(ClientPtr client) +{ + char n; + REQUEST(xvPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->id, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_PutImage](client); +} + +#ifdef MITSHM +static int +SProcXvShmPutImage(ClientPtr client) +{ + char n; + REQUEST(xvShmPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->id, n); + swapl(&stuff->offset, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_ShmPutImage](client); +} +#else /* MITSHM */ +#define SProcXvShmPutImage ProcXvShmPutImage +#endif + +static int +SProcXvSelectVideoNotify(ClientPtr client) +{ + char n; + REQUEST(xvSelectVideoNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return XvProcVector[xv_SelectVideoNotify](client); +} + +static int +SProcXvSelectPortNotify(ClientPtr client) +{ + char n; + REQUEST(xvSelectPortNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_SelectPortNotify](client); +} + +static int +SProcXvStopVideo(ClientPtr client) +{ + char n; + REQUEST(xvStopVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + return XvProcVector[xv_StopVideo](client); +} + +static int +SProcXvSetPortAttribute(ClientPtr client) +{ + char n; + REQUEST(xvSetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + swapl(&stuff->value, n); + return XvProcVector[xv_SetPortAttribute](client); +} + +static int +SProcXvGetPortAttribute(ClientPtr client) +{ + char n; + REQUEST(xvGetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + return XvProcVector[xv_GetPortAttribute](client); +} + +static int +SProcXvQueryBestSize(ClientPtr client) +{ + char n; + REQUEST(xvQueryBestSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_QueryBestSize](client); +} + +static int +SProcXvQueryPortAttributes(ClientPtr client) +{ + char n; + REQUEST(xvQueryPortAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_QueryPortAttributes](client); +} + +static int +SProcXvQueryImageAttributes(ClientPtr client) +{ + char n; + REQUEST(xvQueryImageAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->id, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_QueryImageAttributes](client); +} + +static int +SProcXvListImageFormats(ClientPtr client) +{ + char n; + REQUEST(xvListImageFormatsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_ListImageFormats](client); +} + +static int (*SXvProcVector[xvNumRequests])(ClientPtr) = { + SProcXvQueryExtension, + SProcXvQueryAdaptors, + SProcXvQueryEncodings, + SProcXvGrabPort, + SProcXvUngrabPort, + SProcXvPutVideo, + SProcXvPutStill, + SProcXvGetVideo, + SProcXvGetStill, + SProcXvStopVideo, + SProcXvSelectVideoNotify, + SProcXvSelectPortNotify, + SProcXvQueryBestSize, + SProcXvSetPortAttribute, + SProcXvGetPortAttribute, + SProcXvQueryPortAttributes, + SProcXvListImageFormats, + SProcXvQueryImageAttributes, + SProcXvPutImage, + SProcXvShmPutImage, +}; + +int +SProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + if (stuff->data > xvNumRequests) { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return BadRequest; + } + + return SXvProcVector[stuff->data](client); +} + +#ifdef PANORAMIX +static int +XineramaXvStopVideo(ClientPtr client) +{ + int result, i; + PanoramiXRes *draw, *port; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + result = ProcXvStopVideo(client); + } + } + + return result; +} + +static int +XineramaXvSetPortAttribute(ClientPtr client) +{ + REQUEST(xvSetPortAttributeReq); + PanoramiXRes *port; + int result, i; + + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->port = port->info[i].id; + result = ProcXvSetPortAttribute(client); + } + } + return result; +} + +#ifdef MITSHM +static int +XineramaXvShmPutImage(ClientPtr client) +{ + REQUEST(xvShmPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool send_event = stuff->send_event; + Bool isRoot; + int result, i, x, y; + + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + stuff->send_event = (send_event && !i) ? 1 : 0; + + result = ProcXvShmPutImage(client); + } + } + return result; +} +#else +#define XineramaXvShmPutImage ProcXvShmPutImage +#endif + +static int +XineramaXvPutImage(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutImage(client); + } + } + return result; +} + +static int +XineramaXvPutVideo(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutVideoReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutVideo(client); + } + } + return result; +} + +static int +XineramaXvPutStill(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutStill(client); + } + } + return result; +} + +static Bool +isImageAdaptor(XvAdaptorPtr pAdapt) +{ + return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0); +} + +static Bool +hasOverlay(XvAdaptorPtr pAdapt) +{ + int i; + for(i = 0; i < pAdapt->nAttributes; i++) + if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY")) + return TRUE; + return FALSE; +} + +static XvAdaptorPtr +matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay) +{ + int i; + XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey()); + /* Do not try to go on if xv is not supported on this screen */ + if(xvsp == NULL) + return NULL; + + /* if the adaptor has the same name it's a perfect match */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(!strcmp(refAdapt->name, pAdapt->name)) + return pAdapt; + } + + /* otherwise we only look for XvImage adaptors */ + if(!isImageAdaptor(refAdapt)) + return NULL; + + /* prefer overlay/overlay non-overlay/non-overlay pairing */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt)) + return pAdapt; + } + + /* but we'll take any XvImage pairing if we can get it */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt)) + return pAdapt; + } + return NULL; +} + +void XineramifyXv(void) +{ + XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey()); + XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; + int i, j, k; + + XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort"); + + if (!xvsp0 || !XvXRTPort) return; + SetResourceTypeErrorValue(XvXRTPort, _XvBadPort); + + for(i = 0; i < xvsp0->nAdaptors; i++) { + Bool isOverlay; + XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i; + if(!(refAdapt->type & XvInputMask)) continue; + + MatchingAdaptors[0] = refAdapt; + isOverlay = hasOverlay(refAdapt); + FOR_NSCREENS_FORWARD_SKIP(j) + MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay); + + /* now create a resource for each port */ + for(j = 0; j < refAdapt->nPorts; j++) { + PanoramiXRes *port = malloc(sizeof(PanoramiXRes)); + if(!port) + break; + + FOR_NSCREENS(k) { + if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) + port->info[k].id = MatchingAdaptors[k]->base_id + j; + else + port->info[k].id = 0; + } + AddResource(port->info[0].id, XvXRTPort, port); + } + } + + /* munge the dispatch vector */ + XvProcVector[xv_PutVideo] = XineramaXvPutVideo; + XvProcVector[xv_PutStill] = XineramaXvPutStill; + XvProcVector[xv_StopVideo] = XineramaXvStopVideo; + XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute; + XvProcVector[xv_PutImage] = XineramaXvPutImage; + XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage; +} +#endif /* PANORAMIX */ + +void +XvResetProcVector(void) +{ +#ifdef PANORAMIX + XvProcVector[xv_PutVideo] = ProcXvPutVideo; + XvProcVector[xv_PutStill] = ProcXvPutStill; + XvProcVector[xv_StopVideo] = ProcXvStopVideo; + XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute; + XvProcVector[xv_PutImage] = ProcXvPutImage; + XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage; +#endif +} diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c index d6f26d688..e0d8e75e4 100644 --- a/xorg-server/composite/compext.c +++ b/xorg-server/composite/compext.c @@ -1,932 +1,929 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright © 2003 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "compint.h"
-#include "xace.h"
-#include "protocol-versions.h"
-
-static CARD8 CompositeReqCode;
-static DevPrivateKeyRec CompositeClientPrivateKeyRec;
-#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
-RESTYPE CompositeClientWindowType;
-RESTYPE CompositeClientSubwindowsType;
-RESTYPE CompositeClientOverlayType;
-
-typedef struct _CompositeClient {
- int major_version;
- int minor_version;
-} CompositeClientRec, *CompositeClientPtr;
-
-#define GetCompositeClient(pClient) ((CompositeClientPtr) \
- dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
-
-static void
-CompositeClientCallback (CallbackListPtr *list,
- pointer closure,
- pointer data)
-{
- NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
- ClientPtr pClient = clientinfo->client;
- CompositeClientPtr pCompositeClient = GetCompositeClient (pClient);
-
- pCompositeClient->major_version = 0;
- pCompositeClient->minor_version = 0;
-}
-
-static int
-FreeCompositeClientWindow (pointer value, XID ccwid)
-{
- WindowPtr pWin = value;
-
- compFreeClientWindow (pWin, ccwid);
- return Success;
-}
-
-static int
-FreeCompositeClientSubwindows (pointer value, XID ccwid)
-{
- WindowPtr pWin = value;
-
- compFreeClientSubwindows (pWin, ccwid);
- return Success;
-}
-
-static int
-FreeCompositeClientOverlay (pointer value, XID ccwid)
-{
- CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
-
- compFreeOverlayClient (pOc);
- return Success;
-}
-
-static int
-ProcCompositeQueryVersion (ClientPtr client)
-{
- CompositeClientPtr pCompositeClient = GetCompositeClient (client);
- xCompositeQueryVersionReply rep;
- register int n;
- REQUEST(xCompositeQueryVersionReq);
-
- REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
- rep.majorVersion = stuff->majorVersion;
- rep.minorVersion = stuff->minorVersion;
- } else {
- rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
- rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
- }
- pCompositeClient->major_version = rep.majorVersion;
- pCompositeClient->minor_version = rep.minorVersion;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.majorVersion, n);
- swapl(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-#define VERIFY_WINDOW(pWindow, wid, client, mode) \
- do { \
- int err; \
- err = dixLookupResourceByType((pointer *) &pWindow, wid, \
- RT_WINDOW, client, mode); \
- if (err != Success) { \
- client->errorValue = wid; \
- return err; \
- } \
- } while (0)
-
-static int
-ProcCompositeRedirectWindow (ClientPtr client)
-{
- WindowPtr pWin;
- REQUEST(xCompositeRedirectWindowReq);
-
- REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
- VERIFY_WINDOW(pWin, stuff->window, client,
- DixSetAttrAccess|DixManageAccess|DixBlendAccess);
-
- return compRedirectWindow (client, pWin, stuff->update);
-}
-
-static int
-ProcCompositeRedirectSubwindows (ClientPtr client)
-{
- WindowPtr pWin;
- REQUEST(xCompositeRedirectSubwindowsReq);
-
- REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
- VERIFY_WINDOW(pWin, stuff->window, client,
- DixSetAttrAccess|DixManageAccess|DixBlendAccess);
-
- return compRedirectSubwindows (client, pWin, stuff->update);
-}
-
-static int
-ProcCompositeUnredirectWindow (ClientPtr client)
-{
- WindowPtr pWin;
- REQUEST(xCompositeUnredirectWindowReq);
-
- REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
- VERIFY_WINDOW(pWin, stuff->window, client,
- DixSetAttrAccess|DixManageAccess|DixBlendAccess);
-
- return compUnredirectWindow (client, pWin, stuff->update);
-}
-
-static int
-ProcCompositeUnredirectSubwindows (ClientPtr client)
-{
- WindowPtr pWin;
- REQUEST(xCompositeUnredirectSubwindowsReq);
-
- REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
- VERIFY_WINDOW(pWin, stuff->window, client,
- DixSetAttrAccess|DixManageAccess|DixBlendAccess);
-
- return compUnredirectSubwindows (client, pWin, stuff->update);
-}
-
-static int
-ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
-{
- WindowPtr pWin;
- CompWindowPtr cw;
- RegionPtr pBorderClip, pRegion;
- REQUEST(xCompositeCreateRegionFromBorderClipReq);
-
- REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
- VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
- LEGAL_NEW_RESOURCE (stuff->region, client);
-
- cw = GetCompWindow (pWin);
- if (cw)
- pBorderClip = &cw->borderClip;
- else
- pBorderClip = &pWin->borderClip;
- pRegion = XFixesRegionCopy (pBorderClip);
- if (!pRegion)
- return BadAlloc;
- RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
-
- if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
- return BadAlloc;
-
- return Success;
-}
-
-static int
-ProcCompositeNameWindowPixmap (ClientPtr client)
-{
- WindowPtr pWin;
- CompWindowPtr cw;
- PixmapPtr pPixmap;
- int rc;
- REQUEST(xCompositeNameWindowPixmapReq);
-
- REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
- VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
-
- if (!pWin->viewable)
- return BadMatch;
-
- LEGAL_NEW_RESOURCE (stuff->pixmap, client);
-
- cw = GetCompWindow (pWin);
- if (!cw)
- return BadMatch;
-
- pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
- if (!pPixmap)
- return BadMatch;
-
- /* security creation/labeling check */
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
- pPixmap, RT_WINDOW, pWin, DixCreateAccess);
- if (rc != Success)
- return rc;
-
- ++pPixmap->refcnt;
-
- if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
- return BadAlloc;
-
- return Success;
-}
-
-
-static int
-ProcCompositeGetOverlayWindow (ClientPtr client)
-{
- REQUEST(xCompositeGetOverlayWindowReq);
- xCompositeGetOverlayWindowReply rep;
- WindowPtr pWin;
- ScreenPtr pScreen;
- CompScreenPtr cs;
- CompOverlayClientPtr pOc;
- int rc;
-
- REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
- VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
- pScreen = pWin->drawable.pScreen;
-
- /*
- * Create an OverlayClient structure to mark this client's
- * interest in the overlay window
- */
- pOc = compCreateOverlayClient(pScreen, client);
- if (pOc == NULL)
- return BadAlloc;
-
- /*
- * Make sure the overlay window exists
- */
- cs = GetCompScreen(pScreen);
- if (cs->pOverlayWin == NULL)
- if (!compCreateOverlayWindow(pScreen))
- {
- FreeResource (pOc->resource, RT_NONE);
- return BadAlloc;
- }
-
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
- RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
- if (rc != Success)
- {
- FreeResource (pOc->resource, RT_NONE);
- return rc;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.overlayWin = cs->pOverlayWin->drawable.id;
-
- if (client->swapped)
- {
- int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.overlayWin, n);
- }
- (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
-
- return Success;
-}
-
-static int
-ProcCompositeReleaseOverlayWindow (ClientPtr client)
-{
- REQUEST(xCompositeReleaseOverlayWindowReq);
- WindowPtr pWin;
- ScreenPtr pScreen;
- CompOverlayClientPtr pOc;
-
- REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
- VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
- pScreen = pWin->drawable.pScreen;
-
- /*
- * Has client queried a reference to the overlay window
- * on this screen? If not, generate an error.
- */
- pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
- if (pOc == NULL)
- return BadMatch;
-
- /* The delete function will free the client structure */
- FreeResource (pOc->resource, RT_NONE);
-
- return Success;
-}
-
-static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
- ProcCompositeQueryVersion,
- ProcCompositeRedirectWindow,
- ProcCompositeRedirectSubwindows,
- ProcCompositeUnredirectWindow,
- ProcCompositeUnredirectSubwindows,
- ProcCompositeCreateRegionFromBorderClip,
- ProcCompositeNameWindowPixmap,
- ProcCompositeGetOverlayWindow,
- ProcCompositeReleaseOverlayWindow,
-};
-
-static int
-ProcCompositeDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (stuff->data < CompositeNumberRequests)
- return (*ProcCompositeVector[stuff->data]) (client);
- else
- return BadRequest;
-}
-
-static int
-SProcCompositeQueryVersion (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeQueryVersionReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
- swapl(&stuff->majorVersion, n);
- swapl(&stuff->minorVersion, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeRedirectWindow (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeRedirectWindowReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
- swapl (&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeRedirectSubwindows (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeRedirectSubwindowsReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
- swapl (&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeUnredirectWindow (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeUnredirectWindowReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
- swapl (&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeUnredirectSubwindows (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeUnredirectSubwindowsReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
- swapl (&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeCreateRegionFromBorderClipReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
- swapl (&stuff->region, n);
- swapl (&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeNameWindowPixmap (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeNameWindowPixmapReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
- swapl (&stuff->window, n);
- swapl (&stuff->pixmap, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeGetOverlayWindow (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeGetOverlayWindowReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
- swapl(&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int
-SProcCompositeReleaseOverlayWindow (ClientPtr client)
-{
- int n;
- REQUEST(xCompositeReleaseOverlayWindowReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
- swapl(&stuff->window, n);
- return (*ProcCompositeVector[stuff->compositeReqType]) (client);
-}
-
-static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
- SProcCompositeQueryVersion,
- SProcCompositeRedirectWindow,
- SProcCompositeRedirectSubwindows,
- SProcCompositeUnredirectWindow,
- SProcCompositeUnredirectSubwindows,
- SProcCompositeCreateRegionFromBorderClip,
- SProcCompositeNameWindowPixmap,
- SProcCompositeGetOverlayWindow,
- SProcCompositeReleaseOverlayWindow,
-};
-
-static int
-SProcCompositeDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (stuff->data < CompositeNumberRequests)
- return (*SProcCompositeVector[stuff->data]) (client);
- else
- return BadRequest;
-}
-
-void
-CompositeExtensionInit (void)
-{
- ExtensionEntry *extEntry;
- int s;
-
- /* Assume initialization is going to fail */
- noCompositeExtension = TRUE;
-
- for (s = 0; s < screenInfo.numScreens; s++) {
- ScreenPtr pScreen = screenInfo.screens[s];
- VisualPtr vis;
-
- /* Composite on 8bpp pseudocolor root windows appears to fail, so
- * just disable it on anything pseudocolor for safety.
- */
- for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
- ;
- if ((vis->class | DynamicClass) == PseudoColor)
- return;
-
- /* Ensure that Render is initialized, which is required for automatic
- * compositing.
- */
- if (GetPictureScreenIfSet(pScreen) == NULL)
- return;
- }
-
- CompositeClientWindowType = CreateNewResourceType
- (FreeCompositeClientWindow, "CompositeClientWindow");
- if (!CompositeClientWindowType)
- return;
-
- CompositeClientSubwindowsType = CreateNewResourceType
- (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
- if (!CompositeClientSubwindowsType)
- return;
-
- CompositeClientOverlayType = CreateNewResourceType
- (FreeCompositeClientOverlay, "CompositeClientOverlay");
- if (!CompositeClientOverlayType)
- return;
-
- if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
- sizeof(CompositeClientRec)))
- return;
-
- if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
- return;
-
- for (s = 0; s < screenInfo.numScreens; s++)
- if (!compScreenInit (screenInfo.screens[s]))
- return;
-
- extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
- ProcCompositeDispatch, SProcCompositeDispatch,
- NULL, StandardMinorOpcode);
- if (!extEntry)
- return;
- CompositeReqCode = (CARD8) extEntry->base;
-
- miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
- compGetRedirectBorderClip);
-
- /* Initialization succeeded */
- noCompositeExtension = FALSE;
-}
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-
-int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
-
-static int
-PanoramiXCompositeRedirectWindow (ClientPtr client)
-{
- PanoramiXRes *win;
- int rc = 0, j;
- REQUEST(xCompositeRedirectWindowReq);
-
- REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
- if (rc != Success) break;
- }
-
- return rc;
-}
-
-static int
-PanoramiXCompositeRedirectSubwindows (ClientPtr client)
-{
- PanoramiXRes *win;
- int rc = 0, j;
- REQUEST(xCompositeRedirectSubwindowsReq);
-
- REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
- if (rc != Success) break;
- }
-
- return rc;
-}
-
-static int
-PanoramiXCompositeUnredirectWindow (ClientPtr client)
-{
- PanoramiXRes *win;
- int rc = 0, j;
- REQUEST(xCompositeUnredirectWindowReq);
-
- REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
- if (rc != Success) break;
- }
-
- return rc;
-}
-
-static int
-PanoramiXCompositeUnredirectSubwindows (ClientPtr client)
-{
- PanoramiXRes *win;
- int rc = 0, j;
- REQUEST(xCompositeUnredirectSubwindowsReq);
-
- REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
- if (rc != Success) break;
- }
-
- return rc;
-}
-
-static int
-PanoramiXCompositeNameWindowPixmap (ClientPtr client)
-{
- WindowPtr pWin;
- CompWindowPtr cw;
- PixmapPtr pPixmap;
- int rc;
- PanoramiXRes *win, *newPix;
- int i;
- REQUEST(xCompositeNameWindowPixmapReq);
-
- REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- LEGAL_NEW_RESOURCE (stuff->pixmap, client);
-
- if(!(newPix = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPix->type = XRT_PIXMAP;
- newPix->u.pix.shared = FALSE;
- newPix->info[0].id = stuff->pixmap;
-
- for (i = 1; i < PanoramiXNumScreens; i++)
- newPix->info[i].id = FakeClientID (client->index);
-
- FOR_NSCREENS(i) {
- rc = dixLookupResourceByType ((void **) &pWin, win->info[i].id,
- RT_WINDOW, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->window;
- free (newPix);
- return rc;
- }
-
- if (!pWin->viewable)
- {
- free (newPix);
- return BadMatch;
- }
-
- cw = GetCompWindow (pWin);
- if (!cw)
- {
- free (newPix);
- return BadMatch;
- }
-
- pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
- if (!pPixmap)
- {
- free (newPix);
- return BadMatch;
- }
-
- if (!AddResource (newPix->info[i].id, RT_PIXMAP,
- (pointer) pPixmap))
- return BadAlloc;
-
- ++pPixmap->refcnt;
- }
-
- if (!AddResource (stuff->pixmap, XRT_PIXMAP, (pointer) newPix))
- return BadAlloc;
-
- return Success;
-}
-
-
-static int
-PanoramiXCompositeGetOverlayWindow (ClientPtr client)
-{
- REQUEST(xCompositeGetOverlayWindowReq);
- xCompositeGetOverlayWindowReply rep;
- WindowPtr pWin;
- ScreenPtr pScreen;
- CompScreenPtr cs;
- CompOverlayClientPtr pOc;
- int rc;
- PanoramiXRes *win, *overlayWin = NULL;
- int i;
-
- REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- cs = GetCompScreen(screenInfo.screens[0]);
- if (!cs->pOverlayWin)
- {
- if(!(overlayWin = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- overlayWin->type = XRT_WINDOW;
- overlayWin->u.win.root = FALSE;
- }
-
- FOR_NSCREENS_BACKWARD(i) {
- rc = dixLookupResourceByType((pointer *)&pWin, win->info[i].id,
- RT_WINDOW, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->window;
- return rc;
- }
- pScreen = pWin->drawable.pScreen;
-
- /*
- * Create an OverlayClient structure to mark this client's
- * interest in the overlay window
- */
- pOc = compCreateOverlayClient(pScreen, client);
- if (pOc == NULL)
- return BadAlloc;
-
- /*
- * Make sure the overlay window exists
- */
- cs = GetCompScreen(pScreen);
- if (cs->pOverlayWin == NULL)
- if (!compCreateOverlayWindow(pScreen))
- {
- FreeResource (pOc->resource, RT_NONE);
- return BadAlloc;
- }
-
- rc = XaceHook(XACE_RESOURCE_ACCESS, client,
- cs->pOverlayWin->drawable.id,
- RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
- DixGetAttrAccess);
- if (rc != Success)
- {
- FreeResource (pOc->resource, RT_NONE);
- return rc;
- }
- }
-
- if (overlayWin)
- {
- FOR_NSCREENS(i) {
- cs = GetCompScreen(screenInfo.screens[i]);
- overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
- }
-
- AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
- }
-
- cs = GetCompScreen(screenInfo.screens[0]);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.overlayWin = cs->pOverlayWin->drawable.id;
-
- if (client->swapped)
- {
- int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.overlayWin, n);
- }
- (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
-
- return Success;
-}
-
-static int
-PanoramiXCompositeReleaseOverlayWindow (ClientPtr client)
-{
- REQUEST(xCompositeReleaseOverlayWindowReq);
- WindowPtr pWin;
- ScreenPtr pScreen;
- CompOverlayClientPtr pOc;
- PanoramiXRes *win;
- int i, rc;
-
- REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
-
- if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
- client, DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- FOR_NSCREENS_BACKWARD(i) {
- if ((rc = dixLookupResourceByType((void **)&pWin, win->info[i].id,
- XRT_WINDOW, client,
- DixUnknownAccess))) {
- client->errorValue = stuff->window;
- return rc;
- }
- pScreen = pWin->drawable.pScreen;
-
- /*
- * Has client queried a reference to the overlay window
- * on this screen? If not, generate an error.
- */
- pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
- if (pOc == NULL)
- return BadMatch;
-
- /* The delete function will free the client structure */
- FreeResource (pOc->resource, RT_NONE);
- }
-
- return Success;
-}
-
-void
-PanoramiXCompositeInit (void)
-{
- int i;
-
- for (i = 0; i < CompositeNumberRequests; i++)
- PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
- /*
- * Stuff in Xinerama aware request processing hooks
- */
- ProcCompositeVector[X_CompositeRedirectWindow] =
- PanoramiXCompositeRedirectWindow;
- ProcCompositeVector[X_CompositeRedirectSubwindows] =
- PanoramiXCompositeRedirectSubwindows;
- ProcCompositeVector[X_CompositeUnredirectWindow] =
- PanoramiXCompositeUnredirectWindow;
- ProcCompositeVector[X_CompositeUnredirectSubwindows] =
- PanoramiXCompositeUnredirectSubwindows;
- ProcCompositeVector[X_CompositeNameWindowPixmap] =
- PanoramiXCompositeNameWindowPixmap;
- ProcCompositeVector[X_CompositeGetOverlayWindow] =
- PanoramiXCompositeGetOverlayWindow;
- ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
- PanoramiXCompositeReleaseOverlayWindow;
-}
-
-void
-PanoramiXCompositeReset (void)
-{
- int i;
-
- for (i = 0; i < CompositeNumberRequests; i++)
- ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
-}
-
-#endif
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright © 2003 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "compint.h" +#include "xace.h" +#include "protocol-versions.h" + +static CARD8 CompositeReqCode; +static DevPrivateKeyRec CompositeClientPrivateKeyRec; +#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) +RESTYPE CompositeClientWindowType; +RESTYPE CompositeClientSubwindowsType; +RESTYPE CompositeClientOverlayType; + +typedef struct _CompositeClient { + int major_version; + int minor_version; +} CompositeClientRec, *CompositeClientPtr; + +#define GetCompositeClient(pClient) ((CompositeClientPtr) \ + dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) + +static void +CompositeClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + CompositeClientPtr pCompositeClient = GetCompositeClient (pClient); + + pCompositeClient->major_version = 0; + pCompositeClient->minor_version = 0; +} + +static int +FreeCompositeClientWindow (pointer value, XID ccwid) +{ + WindowPtr pWin = value; + + compFreeClientWindow (pWin, ccwid); + return Success; +} + +static int +FreeCompositeClientSubwindows (pointer value, XID ccwid) +{ + WindowPtr pWin = value; + + compFreeClientSubwindows (pWin, ccwid); + return Success; +} + +static int +FreeCompositeClientOverlay (pointer value, XID ccwid) +{ + CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; + + compFreeOverlayClient (pOc); + return Success; +} + +static int +ProcCompositeQueryVersion (ClientPtr client) +{ + CompositeClientPtr pCompositeClient = GetCompositeClient (client); + xCompositeQueryVersionReply rep; + register int n; + REQUEST(xCompositeQueryVersionReq); + + REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else { + rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; + rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; + } + pCompositeClient->major_version = rep.majorVersion; + pCompositeClient->minor_version = rep.minorVersion; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep); + return Success; +} + +#define VERIFY_WINDOW(pWindow, wid, client, mode) \ + do { \ + int err; \ + err = dixLookupResourceByType((pointer *) &pWindow, wid, \ + RT_WINDOW, client, mode); \ + if (err != Success) { \ + client->errorValue = wid; \ + return err; \ + } \ + } while (0) + +static int +ProcCompositeRedirectWindow (ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xCompositeRedirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess|DixManageAccess|DixBlendAccess); + + return compRedirectWindow (client, pWin, stuff->update); +} + +static int +ProcCompositeRedirectSubwindows (ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xCompositeRedirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess|DixManageAccess|DixBlendAccess); + + return compRedirectSubwindows (client, pWin, stuff->update); +} + +static int +ProcCompositeUnredirectWindow (ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xCompositeUnredirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess|DixManageAccess|DixBlendAccess); + + return compUnredirectWindow (client, pWin, stuff->update); +} + +static int +ProcCompositeUnredirectSubwindows (ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xCompositeUnredirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess|DixManageAccess|DixBlendAccess); + + return compUnredirectSubwindows (client, pWin, stuff->update); +} + +static int +ProcCompositeCreateRegionFromBorderClip (ClientPtr client) +{ + WindowPtr pWin; + CompWindowPtr cw; + RegionPtr pBorderClip, pRegion; + REQUEST(xCompositeCreateRegionFromBorderClipReq); + + REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + LEGAL_NEW_RESOURCE (stuff->region, client); + + cw = GetCompWindow (pWin); + if (cw) + pBorderClip = &cw->borderClip; + else + pBorderClip = &pWin->borderClip; + pRegion = XFixesRegionCopy (pBorderClip); + if (!pRegion) + return BadAlloc; + RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); + + if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) + return BadAlloc; + + return Success; +} + +static int +ProcCompositeNameWindowPixmap (ClientPtr client) +{ + WindowPtr pWin; + CompWindowPtr cw; + PixmapPtr pPixmap; + int rc; + REQUEST(xCompositeNameWindowPixmapReq); + + REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + + if (!pWin->viewable) + return BadMatch; + + LEGAL_NEW_RESOURCE (stuff->pixmap, client); + + cw = GetCompWindow (pWin); + if (!cw) + return BadMatch; + + pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + if (!pPixmap) + return BadMatch; + + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, + pPixmap, RT_WINDOW, pWin, DixCreateAccess); + if (rc != Success) + return rc; + + ++pPixmap->refcnt; + + if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap)) + return BadAlloc; + + return Success; +} + + +static int +ProcCompositeGetOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeGetOverlayWindowReq); + xCompositeGetOverlayWindowReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + CompScreenPtr cs; + CompOverlayClientPtr pOc; + int rc; + + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + pScreen = pWin->drawable.pScreen; + + /* + * Create an OverlayClient structure to mark this client's + * interest in the overlay window + */ + pOc = compCreateOverlayClient(pScreen, client); + if (pOc == NULL) + return BadAlloc; + + /* + * Make sure the overlay window exists + */ + cs = GetCompScreen(pScreen); + if (cs->pOverlayWin == NULL) + if (!compCreateOverlayWindow(pScreen)) + { + FreeResource (pOc->resource, RT_NONE); + return BadAlloc; + } + + rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, + RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); + if (rc != Success) + { + FreeResource (pOc->resource, RT_NONE); + return rc; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.overlayWin = cs->pOverlayWin->drawable.id; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.overlayWin, n); + } + (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); + + return Success; +} + +static int +ProcCompositeReleaseOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeReleaseOverlayWindowReq); + WindowPtr pWin; + ScreenPtr pScreen; + CompOverlayClientPtr pOc; + + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + pScreen = pWin->drawable.pScreen; + + /* + * Has client queried a reference to the overlay window + * on this screen? If not, generate an error. + */ + pOc = compFindOverlayClient (pWin->drawable.pScreen, client); + if (pOc == NULL) + return BadMatch; + + /* The delete function will free the client structure */ + FreeResource (pOc->resource, RT_NONE); + + return Success; +} + +static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { + ProcCompositeQueryVersion, + ProcCompositeRedirectWindow, + ProcCompositeRedirectSubwindows, + ProcCompositeUnredirectWindow, + ProcCompositeUnredirectSubwindows, + ProcCompositeCreateRegionFromBorderClip, + ProcCompositeNameWindowPixmap, + ProcCompositeGetOverlayWindow, + ProcCompositeReleaseOverlayWindow, +}; + +static int +ProcCompositeDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < CompositeNumberRequests) + return (*ProcCompositeVector[stuff->data]) (client); + else + return BadRequest; +} + +static int +SProcCompositeQueryVersion (ClientPtr client) +{ + int n; + REQUEST(xCompositeQueryVersionReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeRedirectWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeRedirectWindowReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); + swapl (&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeRedirectSubwindows (ClientPtr client) +{ + int n; + REQUEST(xCompositeRedirectSubwindowsReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); + swapl (&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeUnredirectWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeUnredirectWindowReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); + swapl (&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeUnredirectSubwindows (ClientPtr client) +{ + int n; + REQUEST(xCompositeUnredirectSubwindowsReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); + swapl (&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeCreateRegionFromBorderClip (ClientPtr client) +{ + int n; + REQUEST(xCompositeCreateRegionFromBorderClipReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); + swapl (&stuff->region, n); + swapl (&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeNameWindowPixmap (ClientPtr client) +{ + int n; + REQUEST(xCompositeNameWindowPixmapReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); + swapl (&stuff->window, n); + swapl (&stuff->pixmap, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeGetOverlayWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeGetOverlayWindowReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeReleaseOverlayWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeReleaseOverlayWindowReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { + SProcCompositeQueryVersion, + SProcCompositeRedirectWindow, + SProcCompositeRedirectSubwindows, + SProcCompositeUnredirectWindow, + SProcCompositeUnredirectSubwindows, + SProcCompositeCreateRegionFromBorderClip, + SProcCompositeNameWindowPixmap, + SProcCompositeGetOverlayWindow, + SProcCompositeReleaseOverlayWindow, +}; + +static int +SProcCompositeDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < CompositeNumberRequests) + return (*SProcCompositeVector[stuff->data]) (client); + else + return BadRequest; +} + +void +CompositeExtensionInit (void) +{ + ExtensionEntry *extEntry; + int s; + + /* Assume initialization is going to fail */ + noCompositeExtension = TRUE; + + for (s = 0; s < screenInfo.numScreens; s++) { + ScreenPtr pScreen = screenInfo.screens[s]; + VisualPtr vis; + + /* Composite on 8bpp pseudocolor root windows appears to fail, so + * just disable it on anything pseudocolor for safety. + */ + for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++) + ; + if ((vis->class | DynamicClass) == PseudoColor) + return; + + /* Ensure that Render is initialized, which is required for automatic + * compositing. + */ + if (GetPictureScreenIfSet(pScreen) == NULL) + return; + } + + CompositeClientWindowType = CreateNewResourceType + (FreeCompositeClientWindow, "CompositeClientWindow"); + if (!CompositeClientWindowType) + return; + + CompositeClientSubwindowsType = CreateNewResourceType + (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); + if (!CompositeClientSubwindowsType) + return; + + CompositeClientOverlayType = CreateNewResourceType + (FreeCompositeClientOverlay, "CompositeClientOverlay"); + if (!CompositeClientOverlayType) + return; + + if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, + sizeof(CompositeClientRec))) + return; + + if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0)) + return; + + for (s = 0; s < screenInfo.numScreens; s++) + if (!compScreenInit (screenInfo.screens[s])) + return; + + extEntry = AddExtension (COMPOSITE_NAME, 0, 0, + ProcCompositeDispatch, SProcCompositeDispatch, + NULL, StandardMinorOpcode); + if (!extEntry) + return; + CompositeReqCode = (CARD8) extEntry->base; + + miRegisterRedirectBorderClipProc (compSetRedirectBorderClip, + compGetRedirectBorderClip); + + /* Initialization succeeded */ + noCompositeExtension = FALSE; +} + +#ifdef PANORAMIX +#include "panoramiXsrv.h" + +int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); + +static int +PanoramiXCompositeRedirectWindow (ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + REQUEST(xCompositeRedirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) break; + } + + return rc; +} + +static int +PanoramiXCompositeRedirectSubwindows (ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + REQUEST(xCompositeRedirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) break; + } + + return rc; +} + +static int +PanoramiXCompositeUnredirectWindow (ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + REQUEST(xCompositeUnredirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) break; + } + + return rc; +} + +static int +PanoramiXCompositeUnredirectSubwindows (ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + REQUEST(xCompositeUnredirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) break; + } + + return rc; +} + +static int +PanoramiXCompositeNameWindowPixmap (ClientPtr client) +{ + WindowPtr pWin; + CompWindowPtr cw; + PixmapPtr pPixmap; + int rc; + PanoramiXRes *win, *newPix; + int i; + REQUEST(xCompositeNameWindowPixmapReq); + + REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + LEGAL_NEW_RESOURCE (stuff->pixmap, client); + + if(!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = FALSE; + panoramix_setup_ids(newPix, client, stuff->pixmap); + + FOR_NSCREENS(i) { + rc = dixLookupResourceByType ((void **) &pWin, win->info[i].id, + RT_WINDOW, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->window; + free (newPix); + return rc; + } + + if (!pWin->viewable) + { + free (newPix); + return BadMatch; + } + + cw = GetCompWindow (pWin); + if (!cw) + { + free (newPix); + return BadMatch; + } + + pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + if (!pPixmap) + { + free (newPix); + return BadMatch; + } + + if (!AddResource (newPix->info[i].id, RT_PIXMAP, + (pointer) pPixmap)) + return BadAlloc; + + ++pPixmap->refcnt; + } + + if (!AddResource (stuff->pixmap, XRT_PIXMAP, (pointer) newPix)) + return BadAlloc; + + return Success; +} + + +static int +PanoramiXCompositeGetOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeGetOverlayWindowReq); + xCompositeGetOverlayWindowReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + CompScreenPtr cs; + CompOverlayClientPtr pOc; + int rc; + PanoramiXRes *win, *overlayWin = NULL; + int i; + + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + cs = GetCompScreen(screenInfo.screens[0]); + if (!cs->pOverlayWin) + { + if(!(overlayWin = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + overlayWin->type = XRT_WINDOW; + overlayWin->u.win.root = FALSE; + } + + FOR_NSCREENS_BACKWARD(i) { + rc = dixLookupResourceByType((pointer *)&pWin, win->info[i].id, + RT_WINDOW, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->window; + return rc; + } + pScreen = pWin->drawable.pScreen; + + /* + * Create an OverlayClient structure to mark this client's + * interest in the overlay window + */ + pOc = compCreateOverlayClient(pScreen, client); + if (pOc == NULL) + return BadAlloc; + + /* + * Make sure the overlay window exists + */ + cs = GetCompScreen(pScreen); + if (cs->pOverlayWin == NULL) + if (!compCreateOverlayWindow(pScreen)) + { + FreeResource (pOc->resource, RT_NONE); + return BadAlloc; + } + + rc = XaceHook(XACE_RESOURCE_ACCESS, client, + cs->pOverlayWin->drawable.id, + RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, + DixGetAttrAccess); + if (rc != Success) + { + FreeResource (pOc->resource, RT_NONE); + return rc; + } + } + + if (overlayWin) + { + FOR_NSCREENS(i) { + cs = GetCompScreen(screenInfo.screens[i]); + overlayWin->info[i].id = cs->pOverlayWin->drawable.id; + } + + AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); + } + + cs = GetCompScreen(screenInfo.screens[0]); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.overlayWin = cs->pOverlayWin->drawable.id; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.overlayWin, n); + } + (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); + + return Success; +} + +static int +PanoramiXCompositeReleaseOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeReleaseOverlayWindowReq); + WindowPtr pWin; + ScreenPtr pScreen; + CompOverlayClientPtr pOc; + PanoramiXRes *win; + int i, rc; + + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + + if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_BACKWARD(i) { + if ((rc = dixLookupResourceByType((void **)&pWin, win->info[i].id, + XRT_WINDOW, client, + DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + pScreen = pWin->drawable.pScreen; + + /* + * Has client queried a reference to the overlay window + * on this screen? If not, generate an error. + */ + pOc = compFindOverlayClient (pWin->drawable.pScreen, client); + if (pOc == NULL) + return BadMatch; + + /* The delete function will free the client structure */ + FreeResource (pOc->resource, RT_NONE); + } + + return Success; +} + +void +PanoramiXCompositeInit (void) +{ + int i; + + for (i = 0; i < CompositeNumberRequests; i++) + PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; + /* + * Stuff in Xinerama aware request processing hooks + */ + ProcCompositeVector[X_CompositeRedirectWindow] = + PanoramiXCompositeRedirectWindow; + ProcCompositeVector[X_CompositeRedirectSubwindows] = + PanoramiXCompositeRedirectSubwindows; + ProcCompositeVector[X_CompositeUnredirectWindow] = + PanoramiXCompositeUnredirectWindow; + ProcCompositeVector[X_CompositeUnredirectSubwindows] = + PanoramiXCompositeUnredirectSubwindows; + ProcCompositeVector[X_CompositeNameWindowPixmap] = + PanoramiXCompositeNameWindowPixmap; + ProcCompositeVector[X_CompositeGetOverlayWindow] = + PanoramiXCompositeGetOverlayWindow; + ProcCompositeVector[X_CompositeReleaseOverlayWindow] = + PanoramiXCompositeReleaseOverlayWindow; +} + +void +PanoramiXCompositeReset (void) +{ + int i; + + for (i = 0; i < CompositeNumberRequests; i++) + ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; +} + +#endif diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index df62e839b..8835c5e61 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -558,7 +558,7 @@ XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) if(pWin == screenInfo.screens[0]->root) { int i; - for (i = 0; i < PanoramiXNumScreens; i++) + FOR_NSCREENS(i) pSprite->windows[i] = screenInfo.screens[i]->root; } else { PanoramiXRes *win; @@ -569,7 +569,7 @@ XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) if (rc != Success) return FALSE; - for(i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { rc = dixLookupWindow(pSprite->windows + i, win->info[i].id, serverClient, DixReadAccess); if (rc != Success) /* window is being unmapped */ @@ -2554,7 +2554,7 @@ PointInBorderSize(WindowPtr pWin, int x, int y) SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite; int i; - for(i = 1; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS_FORWARD_SKIP(i) { if(RegionContainsPoint(&pSprite->windows[i]->borderSize, x + screenInfo.screens[0]->x - screenInfo.screens[i]->x, y + screenInfo.screens[0]->y - screenInfo.screens[i]->y, @@ -3153,7 +3153,7 @@ XineramaPointInWindowIsVisible( xoff = x + screenInfo.screens[0]->x; yoff = y + screenInfo.screens[0]->y; - for(i = 1; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS_FORWARD_SKIP(i) { pWin = inputInfo.pointer->spriteInfo->sprite->windows[i]; x = xoff - screenInfo.screens[i]->x; y = yoff - screenInfo.screens[i]->y; @@ -3360,7 +3360,7 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) if(!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) { int i; - for(i = 1; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS_FORWARD_SKIP(i) { if(RegionNotEmpty(&pDev->spriteInfo->sprite->windows[i]->borderSize)) return TRUE; } diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c index c2cee9198..3668370b3 100644 --- a/xorg-server/dix/window.c +++ b/xorg-server/dix/window.c @@ -1,3686 +1,3686 @@ -/*
-
-Copyright (c) 2006, Red Hat, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-*/
-
-/* The panoramix components contained the following notice */
-/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "misc.h"
-#include "scrnintstr.h"
-#include "os.h"
-#include "regionstr.h"
-#include "validate.h"
-#include "windowstr.h"
-#include "input.h"
-#include "inputstr.h"
-#include "resource.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "dixstruct.h"
-#include "gcstruct.h"
-#include "servermd.h"
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-#include "dixevents.h"
-#include "globals.h"
-#include "mi.h" /* miPaintWindow */
-
-#include "privates.h"
-#include "xace.h"
-
-/******
- * Window stuff for server
- *
- * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
- * GetWindowAttributes, DeleteWindow, DestroySubWindows,
- * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
- * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
- * ChangeWindowDeviceCursor
- ******/
-
-Bool bgNoneRoot = FALSE;
-
-static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
-static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
-
-static Bool WindowParentHasDeviceCursor(WindowPtr pWin,
- DeviceIntPtr pDev,
- CursorPtr pCurs);
-static Bool
-WindowSeekDeviceCursor(WindowPtr pWin,
- DeviceIntPtr pDev,
- DevCursNodePtr* pNode,
- DevCursNodePtr* pPrev);
-
-int screenIsSaved = SCREEN_SAVER_OFF;
-
-static Bool TileScreenSaver(ScreenPtr pScreen, int kind);
-
-#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
- CWDontPropagate | CWOverrideRedirect | CWCursor )
-
-#define BOXES_OVERLAP(b1, b2) \
- (!( ((b1)->x2 <= (b2)->x1) || \
- ( ((b1)->x1 >= (b2)->x2)) || \
- ( ((b1)->y2 <= (b2)->y1)) || \
- ( ((b1)->y1 >= (b2)->y2)) ) )
-
-#define RedirectSend(pWin) \
- ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
-
-#define SubSend(pWin) \
- ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
-
-#define StrSend(pWin) \
- ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
-
-#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
-
-#ifdef DEBUG
-/******
- * PrintWindowTree
- * For debugging only
- ******/
-
-static void
-PrintChildren(WindowPtr p1, int indent)
-{
- WindowPtr p2;
- int i;
-
- while (p1)
- {
- p2 = p1->firstChild;
- ErrorF("[dix] ");
- for (i=0; i<indent; i++) ErrorF(" ");
- ErrorF("%lx\n", p1->drawable.id);
- RegionPrint(&p1->clipList);
- PrintChildren(p2, indent+4);
- p1 = p1->nextSib;
- }
-}
-
-static void
-PrintWindowTree(void)
-{
- int i;
- WindowPtr pWin, p1;
-
- for (i=0; i<screenInfo.numScreens; i++)
- {
- ErrorF("[dix] WINDOW %d\n", i);
- pWin = screenInfo.screens[i]->root;
- RegionPrint(&pWin->clipList);
- p1 = pWin->firstChild;
- PrintChildren(p1, 4);
- }
-}
-#endif
-
-int
-TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data)
-{
- int result;
- WindowPtr pChild;
-
- if (!(pChild = pWin))
- return WT_NOMATCH;
- while (1)
- {
- result = (* func)(pChild, data);
- if (result == WT_STOPWALKING)
- return WT_STOPWALKING;
- if ((result == WT_WALKCHILDREN) && pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
- return WT_NOMATCH;
-}
-
-/*****
- * WalkTree
- * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
- * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
- * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
- * exit WalkTree. Does depth-first traverse.
- *****/
-
-int
-WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
-{
- return(TraverseTree(pScreen->root, func, data));
-}
-
-/* hack for forcing backing store on all windows */
-int defaultBackingStore = NotUseful;
-/* hack to force no backing store */
-Bool disableBackingStore = FALSE;
-Bool enableBackingStore = FALSE;
-
-static void
-SetWindowToDefaults(WindowPtr pWin)
-{
- pWin->prevSib = NullWindow;
- pWin->firstChild = NullWindow;
- pWin->lastChild = NullWindow;
-
- pWin->valdata = (ValidatePtr)NULL;
- pWin->optional = (WindowOptPtr)NULL;
- pWin->cursorIsNone = TRUE;
-
- pWin->backingStore = NotUseful;
- pWin->DIXsaveUnder = FALSE;
- pWin->backStorage = (pointer) NULL;
-
- pWin->mapped = FALSE; /* off */
- pWin->realized = FALSE; /* off */
- pWin->viewable = FALSE;
- pWin->visibility = VisibilityNotViewable;
- pWin->overrideRedirect = FALSE;
- pWin->saveUnder = FALSE;
-
- pWin->bitGravity = ForgetGravity;
- pWin->winGravity = NorthWestGravity;
-
- pWin->eventMask = 0;
- pWin->deliverableEvents = 0;
- pWin->dontPropagate = 0;
- pWin->forcedBS = FALSE;
- pWin->redirectDraw = RedirectDrawNone;
- pWin->forcedBG = FALSE;
-
-#ifdef ROOTLESS
- pWin->rootlessUnhittable = FALSE;
-#endif
-
-#ifdef COMPOSITE
- pWin->damagedDescendants = FALSE;
-#endif
-}
-
-static void
-MakeRootTile(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- GCPtr pGC;
- unsigned char back[128];
- int len = BitmapBytePad(sizeof(long));
- unsigned char *from, *to;
- int i, j;
-
- pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
- pScreen->rootDepth, 0);
-
- pWin->backgroundState = BackgroundPixmap;
- pGC = GetScratchGC(pScreen->rootDepth, pScreen);
- if (!pWin->background.pixmap || !pGC)
- FatalError("could not create root tile");
-
- {
- ChangeGCVal attributes[2];
-
- attributes[0].val = pScreen->whitePixel;
- attributes[1].val = pScreen->blackPixel;
-
- (void)ChangeGC(NullClient, pGC, GCForeground | GCBackground, attributes);
- }
-
- ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
-
- from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
- to = back;
-
- for (i = 4; i > 0; i--, from++)
- for (j = len; j > 0; j--)
- *to++ = *from;
-
- (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
- 0, 0, len, 4, 0, XYBitmap, (char *)back);
-
- FreeScratchGC(pGC);
-
-}
-
-/*****
- * CreateRootWindow
- * Makes a window at initialization time for specified screen
- *****/
-
-Bool
-CreateRootWindow(ScreenPtr pScreen)
-{
- WindowPtr pWin;
- BoxRec box;
- PixmapFormatRec *format;
-
- pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW);
- if (!pWin)
- return FALSE;
-
- pScreen->screensaver.pWindow = NULL;
- pScreen->screensaver.wid = FakeClientID(0);
- pScreen->screensaver.ExternalScreenSaver = NULL;
- screenIsSaved = SCREEN_SAVER_OFF;
-
- pScreen->root = pWin;
-
- pWin->drawable.pScreen = pScreen;
- pWin->drawable.type = DRAWABLE_WINDOW;
-
- pWin->drawable.depth = pScreen->rootDepth;
- for (format = screenInfo.formats;
- format->depth != pScreen->rootDepth;
- format++)
- ;
- pWin->drawable.bitsPerPixel = format->bitsPerPixel;
-
- pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- pWin->parent = NullWindow;
- SetWindowToDefaults(pWin);
-
- pWin->optional = malloc(sizeof (WindowOptRec));
- if (!pWin->optional)
- return FALSE;
-
- pWin->optional->dontPropagateMask = 0;
- pWin->optional->otherEventMasks = 0;
- pWin->optional->otherClients = NULL;
- pWin->optional->passiveGrabs = NULL;
- pWin->optional->userProps = NULL;
- pWin->optional->backingBitPlanes = ~0L;
- pWin->optional->backingPixel = 0;
- pWin->optional->boundingShape = NULL;
- pWin->optional->clipShape = NULL;
- pWin->optional->inputShape = NULL;
- pWin->optional->inputMasks = NULL;
- pWin->optional->deviceCursors = NULL;
- pWin->optional->colormap = pScreen->defColormap;
- pWin->optional->visual = pScreen->rootVisual;
-
- pWin->nextSib = NullWindow;
-
- pWin->drawable.id = FakeClientID(0);
-
- pWin->origin.x = pWin->origin.y = 0;
- pWin->drawable.height = pScreen->height;
- pWin->drawable.width = pScreen->width;
- pWin->drawable.x = pWin->drawable.y = 0;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pScreen->width;
- box.y2 = pScreen->height;
- RegionInit(&pWin->clipList, &box, 1);
- RegionInit(&pWin->winSize, &box, 1);
- RegionInit(&pWin->borderSize, &box, 1);
- RegionInit(&pWin->borderClip, &box, 1);
-
- pWin->drawable.class = InputOutput;
- pWin->optional->visual = pScreen->rootVisual;
-
- pWin->backgroundState = BackgroundPixel;
- pWin->background.pixel = pScreen->whitePixel;
-
- pWin->borderIsPixel = TRUE;
- pWin->border.pixel = pScreen->blackPixel;
- pWin->borderWidth = 0;
-
- /* security creation/labeling check
- */
- if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id,
- RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess))
- return FALSE;
-
- if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
- return FALSE;
-
- if (disableBackingStore)
- pScreen->backingStoreSupport = NotUseful;
- if (enableBackingStore)
- pScreen->backingStoreSupport = Always;
-
- pScreen->saveUnderSupport = NotUseful;
-
- return TRUE;
-}
-
-void
-InitRootWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
-
- if (!(*pScreen->CreateWindow)(pWin))
- return; /* XXX */
- (*pScreen->PositionWindow)(pWin, 0, 0);
-
- pWin->cursorIsNone = FALSE;
- pWin->optional->cursor = rootCursor;
- rootCursor->refcnt++;
-
-
- if (party_like_its_1989) {
- MakeRootTile(pWin);
- backFlag |= CWBackPixmap;
- } else if (pScreen->canDoBGNoneRoot && bgNoneRoot) {
- pWin->backgroundState = XaceBackgroundNoneState(pWin);
- pWin->background.pixel = pScreen->whitePixel;
- backFlag |= CWBackPixmap;
- } else {
- if (whiteRoot)
- pWin->background.pixel = pScreen->whitePixel;
- else
- pWin->background.pixel = pScreen->blackPixel;
- backFlag |= CWBackPixel;
- }
-
- pWin->backingStore = defaultBackingStore;
- pWin->forcedBS = (defaultBackingStore != NotUseful);
- /* We SHOULD check for an error value here XXX */
- (*pScreen->ChangeWindowAttributes)(pWin, backFlag);
-
- MapWindow(pWin, serverClient);
-}
-
-/* Set the region to the intersection of the rectangle and the
- * window's winSize. The window is typically the parent of the
- * window from which the region came.
- */
-
-static void
-ClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn,
- int x, int y,
- int w, int h)
-{
- BoxRec box = *RegionExtents(&pWin->winSize);
-
- /* we do these calculations to avoid overflows */
- if (x > box.x1)
- box.x1 = x;
- if (y > box.y1)
- box.y1 = y;
- x += w;
- if (x < box.x2)
- box.x2 = x;
- y += h;
- if (y < box.y2)
- box.y2 = y;
- if (box.x1 > box.x2)
- box.x2 = box.x1;
- if (box.y1 > box.y2)
- box.y2 = box.y1;
- RegionReset(Rgn, &box);
- RegionIntersect(Rgn, Rgn, &pWin->winSize);
-}
-
-static RealChildHeadProc realChildHeadProc = NULL;
-
-void
-RegisterRealChildHeadProc (RealChildHeadProc proc)
-{
- realChildHeadProc = proc;
-}
-
-
-WindowPtr
-RealChildHead(WindowPtr pWin)
-{
- if (realChildHeadProc) {
- return realChildHeadProc (pWin);
- }
-
- if (!pWin->parent &&
- (screenIsSaved == SCREEN_SAVER_ON) &&
- (HasSaverWindow (pWin->drawable.pScreen)))
- return pWin->firstChild;
- else
- return NullWindow;
-}
-
-/*****
- * CreateWindow
- * Makes a window in response to client request
- *****/
-
-WindowPtr
-CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
- unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist,
- int depth, ClientPtr client, VisualID visual, int *error)
-{
- WindowPtr pWin;
- WindowPtr pHead;
- ScreenPtr pScreen;
- xEvent event;
- int idepth, ivisual;
- Bool fOK;
- DepthPtr pDepth;
- PixmapFormatRec *format;
- WindowOptPtr ancwopt;
-
- if (class == CopyFromParent)
- class = pParent->drawable.class;
-
- if ((class != InputOutput) && (class != InputOnly))
- {
- *error = BadValue;
- client->errorValue = class;
- return NullWindow;
- }
-
- if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
- {
- *error = BadMatch;
- return NullWindow;
- }
-
- if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
- {
- *error = BadMatch;
- return NullWindow;
- }
-
- pScreen = pParent->drawable.pScreen;
- if ((class == InputOutput) && (depth == 0))
- depth = pParent->drawable.depth;
- ancwopt = pParent->optional;
- if (!ancwopt)
- ancwopt = FindWindowWithOptional(pParent)->optional;
- if (visual == CopyFromParent) {
- visual = ancwopt->visual;
- }
-
- /* Find out if the depth and visual are acceptable for this Screen */
- if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
- {
- fOK = FALSE;
- for(idepth = 0; idepth < pScreen->numDepths; idepth++)
- {
- pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
- if ((depth == pDepth->depth) || (depth == 0))
- {
- for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
- {
- if (visual == pDepth->vids[ivisual])
- {
- fOK = TRUE;
- break;
- }
- }
- }
- }
- if (fOK == FALSE)
- {
- *error = BadMatch;
- return NullWindow;
- }
- }
-
- if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
- (class != InputOnly) &&
- (depth != pParent->drawable.depth))
- {
- *error = BadMatch;
- return NullWindow;
- }
-
- if (((vmask & CWColormap) == 0) &&
- (class != InputOnly) &&
- ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
- {
- *error = BadMatch;
- return NullWindow;
- }
-
- pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW);
- if (!pWin)
- {
- *error = BadAlloc;
- return NullWindow;
- }
- pWin->drawable = pParent->drawable;
- pWin->drawable.depth = depth;
- if (depth == pParent->drawable.depth)
- pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
- else
- {
- for (format = screenInfo.formats; format->depth != depth; format++)
- ;
- pWin->drawable.bitsPerPixel = format->bitsPerPixel;
- }
- if (class == InputOnly)
- pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
- pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- pWin->drawable.id = wid;
- pWin->drawable.class = class;
-
- pWin->parent = pParent;
- SetWindowToDefaults(pWin);
-
- if (visual != ancwopt->visual)
- {
- if (!MakeWindowOptional (pWin))
- {
- dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
- *error = BadAlloc;
- return NullWindow;
- }
- pWin->optional->visual = visual;
- pWin->optional->colormap = None;
- }
-
- pWin->borderWidth = bw;
-
- /* security creation/labeling check
- */
- *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin,
- RT_WINDOW, pWin->parent, DixCreateAccess|DixSetAttrAccess);
- if (*error != Success) {
- dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
- return NullWindow;
- }
-
- pWin->backgroundState = XaceBackgroundNoneState(pWin);
- pWin->background.pixel = pScreen->whitePixel;
-
- pWin->borderIsPixel = pParent->borderIsPixel;
- pWin->border = pParent->border;
- if (pWin->borderIsPixel == FALSE)
- pWin->border.pixmap->refcnt++;
-
- pWin->origin.x = x + (int)bw;
- pWin->origin.y = y + (int)bw;
- pWin->drawable.width = w;
- pWin->drawable.height = h;
- pWin->drawable.x = pParent->drawable.x + x + (int)bw;
- pWin->drawable.y = pParent->drawable.y + y + (int)bw;
-
- /* set up clip list correctly for unobscured WindowPtr */
- RegionNull(&pWin->clipList);
- RegionNull(&pWin->borderClip);
- RegionNull(&pWin->winSize);
- RegionNull(&pWin->borderSize);
-
- pHead = RealChildHead(pParent);
- if (pHead)
- {
- pWin->nextSib = pHead->nextSib;
- if (pHead->nextSib)
- pHead->nextSib->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pHead->nextSib = pWin;
- pWin->prevSib = pHead;
- }
- else
- {
- pWin->nextSib = pParent->firstChild;
- if (pParent->firstChild)
- pParent->firstChild->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pParent->firstChild = pWin;
- }
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- /* We SHOULD check for an error value here XXX */
- if (!(*pScreen->CreateWindow)(pWin))
- {
- *error = BadAlloc;
- DeleteWindow(pWin, None);
- return NullWindow;
- }
- /* We SHOULD check for an error value here XXX */
- (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
-
- if (!(vmask & CWEventMask))
- RecalculateDeliverableEvents(pWin);
-
- if (vmask)
- *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
- else
- *error = Success;
-
- if (*error != Success)
- {
- DeleteWindow(pWin, None);
- return NullWindow;
- }
- if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
- {
- XID value = defaultBackingStore;
- (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
- pWin->forcedBS = TRUE;
- }
-
- if (SubSend(pParent))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = CreateNotify;
- event.u.createNotify.window = wid;
- event.u.createNotify.parent = pParent->drawable.id;
- event.u.createNotify.x = x;
- event.u.createNotify.y = y;
- event.u.createNotify.width = w;
- event.u.createNotify.height = h;
- event.u.createNotify.borderWidth = bw;
- event.u.createNotify.override = pWin->overrideRedirect;
- DeliverEvents(pParent, &event, 1, NullWindow);
- }
- return pWin;
-}
-
-static void
-DisposeWindowOptional (WindowPtr pWin)
-{
- if (!pWin->optional)
- return;
- /*
- * everything is peachy. Delete the optional record
- * and clean up
- */
- if (pWin->optional->cursor)
- {
- FreeCursor (pWin->optional->cursor, (Cursor)0);
- pWin->cursorIsNone = FALSE;
- }
- else
- pWin->cursorIsNone = TRUE;
-
- if (pWin->optional->deviceCursors)
- {
- DevCursorList pList;
- DevCursorList pPrev;
- pList = pWin->optional->deviceCursors;
- while(pList)
- {
- if (pList->cursor)
- FreeCursor(pList->cursor, (XID)0);
- pPrev = pList;
- pList = pList->next;
- free(pPrev);
- }
- pWin->optional->deviceCursors = NULL;
- }
-
- free(pWin->optional);
- pWin->optional = NULL;
-}
-
-static void
-FreeWindowResources(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- DeleteWindowFromAnySaveSet(pWin);
- DeleteWindowFromAnySelections(pWin);
- DeleteWindowFromAnyEvents(pWin, TRUE);
- RegionUninit(&pWin->clipList);
- RegionUninit(&pWin->winSize);
- RegionUninit(&pWin->borderClip);
- RegionUninit(&pWin->borderSize);
- if (wBoundingShape (pWin))
- RegionDestroy(wBoundingShape (pWin));
- if (wClipShape (pWin))
- RegionDestroy(wClipShape (pWin));
- if (wInputShape (pWin))
- RegionDestroy(wInputShape (pWin));
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap)(pWin->border.pixmap);
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap)(pWin->background.pixmap);
-
- DeleteAllWindowProperties(pWin);
- /* We SHOULD check for an error value here XXX */
- (*pScreen->DestroyWindow)(pWin);
- DisposeWindowOptional (pWin);
-}
-
-static void
-CrushTree(WindowPtr pWin)
-{
- WindowPtr pChild, pSib, pParent;
- UnrealizeWindowProcPtr UnrealizeWindow;
- xEvent event;
-
- if (!(pChild = pWin->firstChild))
- return;
- UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
- while (1)
- {
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- while (1)
- {
- pParent = pChild->parent;
- if (SubStrSend(pChild, pParent))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = DestroyNotify;
- event.u.destroyNotify.window = pChild->drawable.id;
- DeliverEvents(pChild, &event, 1, NullWindow);
- }
- FreeResource(pChild->drawable.id, RT_WINDOW);
- pSib = pChild->nextSib;
- pChild->viewable = FALSE;
- if (pChild->realized)
- {
- pChild->realized = FALSE;
- (*UnrealizeWindow)(pChild);
- }
- FreeWindowResources(pChild);
- dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW);
- if ( (pChild = pSib) )
- break;
- pChild = pParent;
- pChild->firstChild = NullWindow;
- pChild->lastChild = NullWindow;
- if (pChild == pWin)
- return;
- }
- }
-}
-
-/*****
- * DeleteWindow
- * Deletes child of window then window itself
- * If wid is None, don't send any events
- *****/
-
-int
-DeleteWindow(pointer value, XID wid)
- {
- WindowPtr pParent;
- WindowPtr pWin = (WindowPtr)value;
- xEvent event;
-
- UnmapWindow(pWin, FALSE);
-
- CrushTree(pWin);
-
- pParent = pWin->parent;
- if (wid && pParent && SubStrSend(pWin, pParent))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = DestroyNotify;
- event.u.destroyNotify.window = pWin->drawable.id;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
-
- FreeWindowResources(pWin);
- if (pParent)
- {
- if (pParent->firstChild == pWin)
- pParent->firstChild = pWin->nextSib;
- if (pParent->lastChild == pWin)
- pParent->lastChild = pWin->prevSib;
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- }
- else
- pWin->drawable.pScreen->root = NULL;
- dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
- return Success;
-}
-
-int
-DestroySubwindows(WindowPtr pWin, ClientPtr client)
-{
- /* XXX
- * The protocol is quite clear that each window should be
- * destroyed in turn, however, unmapping all of the first
- * eliminates most of the calls to ValidateTree. So,
- * this implementation is incorrect in that all of the
- * UnmapNotifies occur before all of the DestroyNotifies.
- * If you care, simply delete the call to UnmapSubwindows.
- */
- UnmapSubwindows(pWin);
- while (pWin->lastChild) {
- int rc = XaceHook(XACE_RESOURCE_ACCESS, client,
- pWin->lastChild->drawable.id, RT_WINDOW,
- pWin->lastChild, RT_NONE, NULL, DixDestroyAccess);
- if (rc != Success)
- return rc;
- FreeResource(pWin->lastChild->drawable.id, RT_NONE);
- }
- return Success;
-}
-
-static void
-SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2)
-{
- /* following the protocol: "Changing the background of a root window to
- * None or ParentRelative restores the default background pixmap" */
- if (bgNoneRoot) {
- pWin->backgroundState = XaceBackgroundNoneState(pWin);
- pWin->background.pixel = pScreen->whitePixel;
- }
- else if (party_like_its_1989)
- MakeRootTile(pWin);
- else {
- if (whiteRoot)
- pWin->background.pixel = pScreen->whitePixel;
- else
- pWin->background.pixel = pScreen->blackPixel;
- *index2 = CWBackPixel;
- }
-}
-
-/*****
- * ChangeWindowAttributes
- *
- * The value-mask specifies which attributes are to be changed; the
- * value-list contains one value for each one bit in the mask, from least
- * to most significant bit in the mask.
- *****/
-
-int
-ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
-{
- XID *pVlist;
- PixmapPtr pPixmap;
- Pixmap pixID;
- CursorPtr pCursor, pOldCursor;
- Cursor cursorID;
- WindowPtr pChild;
- Colormap cmap;
- ColormapPtr pCmap;
- xEvent xE;
- int error, rc;
- ScreenPtr pScreen;
- Mask index2, tmask, vmaskCopy = 0;
- unsigned int val;
- Bool checkOptional = FALSE, borderRelative = FALSE;
-
- if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
-
- error = Success;
- pScreen = pWin->drawable.pScreen;
- pVlist = vlist;
- tmask = vmask;
- while (tmask)
- {
- index2 = (Mask) lowbit (tmask);
- tmask &= ~index2;
- switch (index2)
- {
- case CWBackPixmap:
- pixID = (Pixmap )*pVlist;
- pVlist++;
- if (pWin->backgroundState == ParentRelative)
- borderRelative = TRUE;
- if (pixID == None)
- {
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap)(pWin->background.pixmap);
- if (!pWin->parent)
- SetRootWindowBackground(pWin, pScreen, &index2);
- else {
- pWin->backgroundState = XaceBackgroundNoneState(pWin);
- pWin->background.pixel = pScreen->whitePixel;
- }
- }
- else if (pixID == ParentRelative)
- {
- if (pWin->parent &&
- pWin->drawable.depth != pWin->parent->drawable.depth)
- {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap)(pWin->background.pixmap);
- if (!pWin->parent)
- SetRootWindowBackground(pWin, pScreen, &index2);
- else
- pWin->backgroundState = ParentRelative;
- borderRelative = TRUE;
- /* Note that the parent's backgroundTile's refcnt is NOT
- * incremented. */
- }
- else
- {
- rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
- client, DixReadAccess);
- if (rc == Success)
- {
- if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
- (pPixmap->drawable.pScreen != pScreen))
- {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap)(pWin->background.pixmap);
- pWin->backgroundState = BackgroundPixmap;
- pWin->background.pixmap = pPixmap;
- pPixmap->refcnt++;
- }
- else
- {
- error = rc;
- client->errorValue = pixID;
- goto PatchUp;
- }
- }
- break;
- case CWBackPixel:
- if (pWin->backgroundState == ParentRelative)
- borderRelative = TRUE;
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap)(pWin->background.pixmap);
- pWin->backgroundState = BackgroundPixel;
- pWin->background.pixel = (CARD32 ) *pVlist;
- /* background pixel overrides background pixmap,
- so don't let the ddx layer see both bits */
- vmaskCopy &= ~CWBackPixmap;
- pVlist++;
- break;
- case CWBorderPixmap:
- pixID = (Pixmap ) *pVlist;
- pVlist++;
- if (pixID == CopyFromParent)
- {
- if (!pWin->parent ||
- (pWin->drawable.depth != pWin->parent->drawable.depth))
- {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->parent->borderIsPixel == TRUE) {
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap)(pWin->border.pixmap);
- pWin->border = pWin->parent->border;
- pWin->borderIsPixel = TRUE;
- index2 = CWBorderPixel;
- break;
- }
- else
- {
- pixID = pWin->parent->border.pixmap->drawable.id;
- }
- }
- rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
- client, DixReadAccess);
- if (rc == Success)
- {
- if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
- (pPixmap->drawable.pScreen != pScreen))
- {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap)(pWin->border.pixmap);
- pWin->borderIsPixel = FALSE;
- pWin->border.pixmap = pPixmap;
- pPixmap->refcnt++;
- }
- else
- {
- error = rc;
- client->errorValue = pixID;
- goto PatchUp;
- }
- break;
- case CWBorderPixel:
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap)(pWin->border.pixmap);
- pWin->borderIsPixel = TRUE;
- pWin->border.pixel = (CARD32) *pVlist;
- /* border pixel overrides border pixmap,
- so don't let the ddx layer see both bits */
- vmaskCopy &= ~CWBorderPixmap;
- pVlist++;
- break;
- case CWBitGravity:
- val = (CARD8 )*pVlist;
- pVlist++;
- if (val > StaticGravity)
- {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->bitGravity = val;
- break;
- case CWWinGravity:
- val = (CARD8 )*pVlist;
- pVlist++;
- if (val > StaticGravity)
- {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->winGravity = val;
- break;
- case CWBackingStore:
- val = (CARD8 )*pVlist;
- pVlist++;
- if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
- {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->backingStore = val;
- pWin->forcedBS = FALSE;
- break;
- case CWBackingPlanes:
- if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
- if (!pWin->optional && !MakeWindowOptional (pWin))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- pWin->optional->backingBitPlanes = (CARD32) *pVlist;
- if ((CARD32)*pVlist == (CARD32)~0L)
- checkOptional = TRUE;
- }
- pVlist++;
- break;
- case CWBackingPixel:
- if (pWin->optional || (CARD32) *pVlist) {
- if (!pWin->optional && !MakeWindowOptional (pWin))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- pWin->optional->backingPixel = (CARD32) *pVlist;
- if (!*pVlist)
- checkOptional = TRUE;
- }
- pVlist++;
- break;
- case CWSaveUnder:
- val = (BOOL) *pVlist;
- pVlist++;
- if ((val != xTrue) && (val != xFalse))
- {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->saveUnder = val;
- break;
- case CWEventMask:
- rc = EventSelectForWindow(pWin, client, (Mask )*pVlist);
- if (rc)
- {
- error = rc;
- goto PatchUp;
- }
- pVlist++;
- break;
- case CWDontPropagate:
- rc = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
- &checkOptional);
- if (rc)
- {
- error = rc;
- goto PatchUp;
- }
- pVlist++;
- break;
- case CWOverrideRedirect:
- val = (BOOL ) *pVlist;
- pVlist++;
- if ((val != xTrue) && (val != xFalse))
- {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- if (val == xTrue) {
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id,
- RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess);
- if (rc != Success) {
- error = rc;
- client->errorValue = pWin->drawable.id;
- goto PatchUp;
- }
- }
- pWin->overrideRedirect = val;
- break;
- case CWColormap:
- cmap = (Colormap) *pVlist;
- pVlist++;
- if (cmap == CopyFromParent)
- {
- if (pWin->parent &&
- (!pWin->optional ||
- pWin->optional->visual == wVisual (pWin->parent)))
- {
- cmap = wColormap (pWin->parent);
- }
- else
- cmap = None;
- }
- if (cmap == None)
- {
- error = BadMatch;
- goto PatchUp;
- }
- rc = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP,
- client, DixUseAccess);
- if (rc != Success)
- {
- error = rc;
- client->errorValue = cmap;
- goto PatchUp;
- }
- if (pCmap->pVisual->vid != wVisual (pWin) ||
- pCmap->pScreen != pScreen)
- {
- error = BadMatch;
- goto PatchUp;
- }
- if (cmap != wColormap (pWin))
- {
- if (!pWin->optional)
- {
- if (!MakeWindowOptional (pWin))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- else if (pWin->parent && cmap == wColormap (pWin->parent))
- checkOptional = TRUE;
-
- /*
- * propagate the original colormap to any children
- * inheriting it
- */
-
- for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
- {
- if (!pChild->optional && !MakeWindowOptional (pChild))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- }
-
- pWin->optional->colormap = cmap;
-
- /*
- * check on any children now matching the new colormap
- */
-
- for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
- {
- if (pChild->optional->colormap == cmap)
- CheckWindowOptionalNeed (pChild);
- }
-
- xE.u.u.type = ColormapNotify;
- xE.u.colormap.window = pWin->drawable.id;
- xE.u.colormap.colormap = cmap;
- xE.u.colormap.new = xTrue;
- xE.u.colormap.state = IsMapInstalled(cmap, pWin);
- DeliverEvents(pWin, &xE, 1, NullWindow);
- }
- break;
- case CWCursor:
- cursorID = (Cursor ) *pVlist;
- pVlist++;
- /*
- * install the new
- */
- if ( cursorID == None)
- {
- if (pWin == pWin->drawable.pScreen->root)
- pCursor = rootCursor;
- else
- pCursor = (CursorPtr) None;
- }
- else
- {
- rc = dixLookupResourceByType((pointer *)&pCursor, cursorID,
- RT_CURSOR, client, DixUseAccess);
- if (rc != Success)
- {
- error = rc;
- client->errorValue = cursorID;
- goto PatchUp;
- }
- }
-
- if (pCursor != wCursor (pWin))
- {
- /*
- * patch up child windows so they don't lose cursors.
- */
-
- for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
- {
- if (!pChild->optional && !pChild->cursorIsNone &&
- !MakeWindowOptional (pChild))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- }
-
- pOldCursor = 0;
- if (pCursor == (CursorPtr) None)
- {
- pWin->cursorIsNone = TRUE;
- if (pWin->optional)
- {
- pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = (CursorPtr) None;
- checkOptional = TRUE;
- }
- } else {
- if (!pWin->optional)
- {
- if (!MakeWindowOptional (pWin))
- {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- else if (pWin->parent && pCursor == wCursor (pWin->parent))
- checkOptional = TRUE;
- pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = pCursor;
- pCursor->refcnt++;
- pWin->cursorIsNone = FALSE;
- /*
- * check on any children now matching the new cursor
- */
-
- for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
- {
- if (pChild->optional &&
- (pChild->optional->cursor == pCursor))
- CheckWindowOptionalNeed (pChild);
- }
- }
-
- if (pWin->realized)
- WindowHasNewCursor( pWin);
-
- /* Can't free cursor until here - old cursor
- * is needed in WindowHasNewCursor
- */
- if (pOldCursor)
- FreeCursor (pOldCursor, (Cursor)0);
- }
- break;
- default:
- error = BadValue;
- client->errorValue = vmask;
- goto PatchUp;
- }
- vmaskCopy |= index2;
- }
-PatchUp:
- if (checkOptional)
- CheckWindowOptionalNeed (pWin);
-
- /* We SHOULD check for an error value here XXX */
- (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
-
- /*
- If the border contents have changed, redraw the border.
- Note that this has to be done AFTER pScreen->ChangeWindowAttributes
- for the tile to be rotated, and the correct function selected.
- */
- if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
- && pWin->viewable && HasBorder (pWin))
- {
- RegionRec exposed;
-
- RegionNull(&exposed);
- RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize);
- miPaintWindow(pWin, &exposed, PW_BORDER);
- RegionUninit(&exposed);
- }
- return error;
-}
-
-
-/*****
- * GetWindowAttributes
- * Notice that this is different than ChangeWindowAttributes
- *****/
-
-void
-GetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
-{
- wa->type = X_Reply;
- wa->bitGravity = pWin->bitGravity;
- wa->winGravity = pWin->winGravity;
- if (pWin->forcedBS && pWin->backingStore != Always)
- wa->backingStore = NotUseful;
- else
- wa->backingStore = pWin->backingStore;
- wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) -
- sizeof(xGenericReply));
- wa->sequenceNumber = client->sequence;
- wa->backingBitPlanes = wBackingBitPlanes (pWin);
- wa->backingPixel = wBackingPixel (pWin);
- wa->saveUnder = (BOOL)pWin->saveUnder;
- wa->override = pWin->overrideRedirect;
- if (!pWin->mapped)
- wa->mapState = IsUnmapped;
- else if (pWin->realized)
- wa->mapState = IsViewable;
- else
- wa->mapState = IsUnviewable;
-
- wa->colormap = wColormap (pWin);
- wa->mapInstalled = (wa->colormap == None) ? xFalse
- : IsMapInstalled(wa->colormap, pWin);
-
- wa->yourEventMask = EventMaskForClient(pWin, client);
- wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
- wa->doNotPropagateMask = wDontPropagateMask (pWin);
- wa->class = pWin->drawable.class;
- wa->visualID = wVisual (pWin);
-}
-
-
-WindowPtr
-MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib)
-{
- WindowPtr pParent = pWin->parent;
- WindowPtr pFirstChange = pWin; /* highest window where list changes */
-
- if (pWin->nextSib != pNextSib)
- {
- WindowPtr pOldNextSib = pWin->nextSib;
-
- if (!pNextSib) /* move to bottom */
- {
- if (pParent->firstChild == pWin)
- pParent->firstChild = pWin->nextSib;
- /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
- * and pWin->nextSib != pNextSib
- * therefore pWin->nextSib != NULL */
- pFirstChange = pWin->nextSib;
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pParent->lastChild->nextSib = pWin;
- pWin->prevSib = pParent->lastChild;
- pWin->nextSib = NullWindow;
- pParent->lastChild = pWin;
- }
- else if (pParent->firstChild == pNextSib) /* move to top */
- {
- pFirstChange = pWin;
- if (pParent->lastChild == pWin)
- pParent->lastChild = pWin->prevSib;
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pWin->nextSib = pParent->firstChild;
- pWin->prevSib = (WindowPtr ) NULL;
- pNextSib->prevSib = pWin;
- pParent->firstChild = pWin;
- }
- else /* move in middle of list */
- {
- WindowPtr pOldNext = pWin->nextSib;
-
- pFirstChange = NullWindow;
- if (pParent->firstChild == pWin)
- pFirstChange = pParent->firstChild = pWin->nextSib;
- if (pParent->lastChild == pWin) {
- pFirstChange = pWin;
- pParent->lastChild = pWin->prevSib;
- }
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pWin->nextSib = pNextSib;
- pWin->prevSib = pNextSib->prevSib;
- if (pNextSib->prevSib)
- pNextSib->prevSib->nextSib = pWin;
- pNextSib->prevSib = pWin;
- if (!pFirstChange) { /* do we know it yet? */
- pFirstChange = pParent->firstChild; /* no, search from top */
- while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
- pFirstChange = pFirstChange->nextSib;
- }
- }
- if(pWin->drawable.pScreen->RestackWindow)
- (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
- }
-
-#ifdef ROOTLESS
- /*
- * In rootless mode we can't optimize away window restacks.
- * There may be non-X windows around, so even if the window
- * is in the correct position from X's point of view,
- * the underlying window system may want to reorder it.
- */
- else if (pWin->drawable.pScreen->RestackWindow)
- (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
-#endif
-
- return pFirstChange;
-}
-
-void
-SetWinSize (WindowPtr pWin)
-{
-#ifdef COMPOSITE
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- BoxRec box;
-
- /*
- * Redirected clients get clip list equal to their
- * own geometry, not clipped to their parent
- */
- box.x1 = pWin->drawable.x;
- box.y1 = pWin->drawable.y;
- box.x2 = pWin->drawable.x + pWin->drawable.width;
- box.y2 = pWin->drawable.y + pWin->drawable.height;
- RegionReset(&pWin->winSize, &box);
- }
- else
-#endif
- ClippedRegionFromBox(pWin->parent, &pWin->winSize,
- pWin->drawable.x, pWin->drawable.y,
- (int)pWin->drawable.width,
- (int)pWin->drawable.height);
- if (wBoundingShape (pWin) || wClipShape (pWin)) {
- RegionTranslate(&pWin->winSize, - pWin->drawable.x,
- - pWin->drawable.y);
- if (wBoundingShape (pWin))
- RegionIntersect(&pWin->winSize, &pWin->winSize,
- wBoundingShape (pWin));
- if (wClipShape (pWin))
- RegionIntersect(&pWin->winSize, &pWin->winSize,
- wClipShape (pWin));
- RegionTranslate(&pWin->winSize, pWin->drawable.x,
- pWin->drawable.y);
- }
-}
-
-void
-SetBorderSize (WindowPtr pWin)
-{
- int bw;
-
- if (HasBorder (pWin)) {
- bw = wBorderWidth (pWin);
-#ifdef COMPOSITE
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- BoxRec box;
-
- /*
- * Redirected clients get clip list equal to their
- * own geometry, not clipped to their parent
- */
- box.x1 = pWin->drawable.x - bw;
- box.y1 = pWin->drawable.y - bw;
- box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
- box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
- RegionReset(&pWin->borderSize, &box);
- }
- else
-#endif
- ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
- pWin->drawable.x - bw, pWin->drawable.y - bw,
- (int)(pWin->drawable.width + (bw<<1)),
- (int)(pWin->drawable.height + (bw<<1)));
- if (wBoundingShape (pWin)) {
- RegionTranslate(&pWin->borderSize, - pWin->drawable.x,
- - pWin->drawable.y);
- RegionIntersect(&pWin->borderSize, &pWin->borderSize,
- wBoundingShape (pWin));
- RegionTranslate(&pWin->borderSize, pWin->drawable.x,
- pWin->drawable.y);
- RegionUnion(&pWin->borderSize, &pWin->borderSize,
- &pWin->winSize);
- }
- } else {
- RegionCopy(&pWin->borderSize, &pWin->winSize);
- }
-}
-
-/**
- *
- * \param x,y new window position
- * \param oldx,oldy old window position
- * \param destx,desty position relative to gravity
- */
-
-void
-GravityTranslate (int x, int y, int oldx, int oldy,
- int dw, int dh, unsigned gravity,
- int *destx, int *desty)
-{
- switch (gravity) {
- case NorthGravity:
- *destx = x + dw / 2;
- *desty = y;
- break;
- case NorthEastGravity:
- *destx = x + dw;
- *desty = y;
- break;
- case WestGravity:
- *destx = x;
- *desty = y + dh / 2;
- break;
- case CenterGravity:
- *destx = x + dw / 2;
- *desty = y + dh / 2;
- break;
- case EastGravity:
- *destx = x + dw;
- *desty = y + dh / 2;
- break;
- case SouthWestGravity:
- *destx = x;
- *desty = y + dh;
- break;
- case SouthGravity:
- *destx = x + dw / 2;
- *desty = y + dh;
- break;
- case SouthEastGravity:
- *destx = x + dw;
- *desty = y + dh;
- break;
- case StaticGravity:
- *destx = oldx;
- *desty = oldy;
- break;
- default:
- *destx = x;
- *desty = y;
- break;
- }
-}
-
-/* XXX need to retile border on each window with ParentRelative origin */
-void
-ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
-{
- ScreenPtr pScreen;
- WindowPtr pSib, pChild;
- Bool resized = (dw || dh);
-
- pScreen = pWin->drawable.pScreen;
-
- for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
- {
- if (resized && (pSib->winGravity > NorthWestGravity))
- {
- int cwsx, cwsy;
-
- cwsx = pSib->origin.x;
- cwsy = pSib->origin.y;
- GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
- pSib->winGravity, &cwsx, &cwsy);
- if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
- {
- xEvent event;
-
- event.u.u.type = GravityNotify;
- event.u.gravity.window = pSib->drawable.id;
- event.u.gravity.x = cwsx - wBorderWidth (pSib);
- event.u.gravity.y = cwsy - wBorderWidth (pSib);
- DeliverEvents (pSib, &event, 1, NullWindow);
- pSib->origin.x = cwsx;
- pSib->origin.y = cwsy;
- }
- }
- pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
- pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
- SetWinSize (pSib);
- SetBorderSize (pSib);
- (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
-
- if ( (pChild = pSib->firstChild) )
- {
- while (1)
- {
- pChild->drawable.x = pChild->parent->drawable.x +
- pChild->origin.x;
- pChild->drawable.y = pChild->parent->drawable.y +
- pChild->origin.y;
- SetWinSize (pChild);
- SetBorderSize (pChild);
- (*pScreen->PositionWindow)(pChild,
- pChild->drawable.x, pChild->drawable.y);
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- while (!pChild->nextSib && (pChild != pSib))
- pChild = pChild->parent;
- if (pChild == pSib)
- break;
- pChild = pChild->nextSib;
- }
- }
- }
-}
-
-#define GET_INT16(m, f) \
- if (m & mask) \
- { \
- f = (INT16) *pVlist;\
- pVlist++; \
- }
-#define GET_CARD16(m, f) \
- if (m & mask) \
- { \
- f = (CARD16) *pVlist;\
- pVlist++;\
- }
-
-#define GET_CARD8(m, f) \
- if (m & mask) \
- { \
- f = (CARD8) *pVlist;\
- pVlist++;\
- }
-
-#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
-
-#define IllegalInputOnlyConfigureMask (CWBorderWidth)
-
-/*
- * IsSiblingAboveMe
- * returns Above if pSib above pMe in stack or Below otherwise
- */
-
-static int
-IsSiblingAboveMe(
- WindowPtr pMe,
- WindowPtr pSib)
-{
- WindowPtr pWin;
-
- pWin = pMe->parent->firstChild;
- while (pWin)
- {
- if (pWin == pSib)
- return Above;
- else if (pWin == pMe)
- return Below;
- pWin = pWin->nextSib;
- }
- return Below;
-}
-
-static BoxPtr
-WindowExtents(
- WindowPtr pWin,
- BoxPtr pBox)
-{
- pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
- pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
- pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
- + wBorderWidth (pWin);
- pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
- + wBorderWidth (pWin);
- return pBox;
-}
-
-#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
-
-static RegionPtr
-MakeBoundingRegion (
- WindowPtr pWin,
- BoxPtr pBox)
-{
- RegionPtr pRgn = RegionCreate(pBox, 1);
- if (wBoundingShape (pWin)) {
- RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y);
- RegionIntersect(pRgn, pRgn, wBoundingShape (pWin));
- RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y);
- }
- return pRgn;
-}
-
-static Bool
-ShapeOverlap (
- WindowPtr pWin,
- BoxPtr pWinBox,
- WindowPtr pSib,
- BoxPtr pSibBox)
-{
- RegionPtr pWinRgn, pSibRgn;
- Bool ret;
-
- if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
- return TRUE;
- pWinRgn = MakeBoundingRegion (pWin, pWinBox);
- pSibRgn = MakeBoundingRegion (pSib, pSibBox);
- RegionIntersect(pWinRgn, pWinRgn, pSibRgn);
- ret = RegionNotEmpty(pWinRgn);
- RegionDestroy(pWinRgn);
- RegionDestroy(pSibRgn);
- return ret;
-}
-
-static Bool
-AnyWindowOverlapsMe(
- WindowPtr pWin,
- WindowPtr pHead,
- BoxPtr box)
-{
- WindowPtr pSib;
- BoxRec sboxrec;
- BoxPtr sbox;
-
- for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
- {
- if (pSib->mapped)
- {
- sbox = WindowExtents(pSib, &sboxrec);
- if (BOXES_OVERLAP(sbox, box)
- && ShapeOverlap (pWin, box, pSib, sbox)
- )
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static Bool
-IOverlapAnyWindow(
- WindowPtr pWin,
- BoxPtr box)
-{
- WindowPtr pSib;
- BoxRec sboxrec;
- BoxPtr sbox;
-
- for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
- {
- if (pSib->mapped)
- {
- sbox = WindowExtents(pSib, &sboxrec);
- if (BOXES_OVERLAP(sbox, box)
- && ShapeOverlap (pWin, box, pSib, sbox)
- )
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/*
- * WhereDoIGoInTheStack()
- * Given pWin and pSib and the relationshipe smode, return
- * the window that pWin should go ABOVE.
- * If a pSib is specified:
- * Above: pWin is placed just above pSib
- * Below: pWin is placed just below pSib
- * TopIf: if pSib occludes pWin, then pWin is placed
- * at the top of the stack
- * BottomIf: if pWin occludes pSib, then pWin is
- * placed at the bottom of the stack
- * Opposite: if pSib occludes pWin, then pWin is placed at the
- * top of the stack, else if pWin occludes pSib, then
- * pWin is placed at the bottom of the stack
- *
- * If pSib is NULL:
- * Above: pWin is placed at the top of the stack
- * Below: pWin is placed at the bottom of the stack
- * TopIf: if any sibling occludes pWin, then pWin is placed at
- * the top of the stack
- * BottomIf: if pWin occludes any sibline, then pWin is placed at
- * the bottom of the stack
- * Opposite: if any sibling occludes pWin, then pWin is placed at
- * the top of the stack, else if pWin occludes any
- * sibling, then pWin is placed at the bottom of the stack
- *
- */
-
-static WindowPtr
-WhereDoIGoInTheStack(
- WindowPtr pWin,
- WindowPtr pSib,
- short x,
- short y,
- unsigned short w,
- unsigned short h,
- int smode)
-{
- BoxRec box;
- WindowPtr pHead, pFirst;
-
- if ((pWin == pWin->parent->firstChild) &&
- (pWin == pWin->parent->lastChild))
- return((WindowPtr ) NULL);
- pHead = RealChildHead(pWin->parent);
- pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + (int)w;
- box.y2 = y + (int)h;
- switch (smode)
- {
- case Above:
- if (pSib)
- return pSib;
- else if (pWin == pFirst)
- return pWin->nextSib;
- else
- return pFirst;
- case Below:
- if (pSib)
- if (pSib->nextSib != pWin)
- return pSib->nextSib;
- else
- return pWin->nextSib;
- else
- return NullWindow;
- case TopIf:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return pWin->nextSib;
- else if (pSib)
- {
- if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
- (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
- return pFirst;
- else
- return pWin->nextSib;
- }
- else if (AnyWindowOverlapsMe(pWin, pHead, &box))
- return pFirst;
- else
- return pWin->nextSib;
- case BottomIf:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return pWin->nextSib;
- else if (pSib)
- {
- if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
- (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
- return NullWindow;
- else
- return pWin->nextSib;
- }
- else if (IOverlapAnyWindow(pWin, &box))
- return NullWindow;
- else
- return pWin->nextSib;
- case Opposite:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return pWin->nextSib;
- else if (pSib)
- {
- if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)
- {
- if (IsSiblingAboveMe(pWin, pSib) == Above)
- return pFirst;
- else
- return NullWindow;
- }
- else
- return pWin->nextSib;
- }
- else if (AnyWindowOverlapsMe(pWin, pHead, &box))
- {
- /* If I'm occluded, I can't possibly be the first child
- * if (pWin == pWin->parent->firstChild)
- * return pWin->nextSib;
- */
- return pFirst;
- }
- else if (IOverlapAnyWindow(pWin, &box))
- return NullWindow;
- else
- return pWin->nextSib;
- default:
- {
- /* should never happen; make something up. */
- return pWin->nextSib;
- }
- }
-}
-
-static void
-ReflectStackChange(
- WindowPtr pWin,
- WindowPtr pSib,
- VTKind kind)
-{
-/* Note that pSib might be NULL */
-
- Bool WasViewable = (Bool)pWin->viewable;
- Bool anyMarked;
- WindowPtr pFirstChange;
- WindowPtr pLayerWin;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- /* if this is a root window, can't be restacked */
- if (!pWin->parent)
- return;
-
- pFirstChange = MoveWindowInStack(pWin, pSib);
-
- if (WasViewable)
- {
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
- &pLayerWin);
- if (pLayerWin != pWin) pFirstChange = pLayerWin;
- if (anyMarked)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-/*****
- * ConfigureWindow
- *****/
-
-int
-ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
-{
-#define RESTACK_WIN 0
-#define MOVE_WIN 1
-#define RESIZE_WIN 2
-#define REBORDER_WIN 3
- WindowPtr pSib = NullWindow;
- WindowPtr pParent = pWin->parent;
- Window sibwid = 0;
- Mask index2, tmask;
- XID *pVlist;
- short x, y, beforeX, beforeY;
- unsigned short w = pWin->drawable.width,
- h = pWin->drawable.height,
- bw = pWin->borderWidth;
- int rc, action, smode = Above;
- xEvent event;
-
- if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
- return BadMatch;
-
- if ((mask & CWSibling) && !(mask & CWStackMode))
- return BadMatch;
-
- pVlist = vlist;
-
- if (pParent)
- {
- x = pWin->drawable.x - pParent->drawable.x - (int)bw;
- y = pWin->drawable.y - pParent->drawable.y - (int)bw;
- }
- else
- {
- x = pWin->drawable.x;
- y = pWin->drawable.y;
- }
- beforeX = x;
- beforeY = y;
- action = RESTACK_WIN;
- if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
- {
- GET_INT16(CWX, x);
- GET_INT16(CWY, y);
- action = MOVE_WIN;
- }
- /* or should be resized */
- else if (mask & (CWX | CWY | CWWidth | CWHeight))
- {
- GET_INT16(CWX, x);
- GET_INT16(CWY, y);
- GET_CARD16(CWWidth, w);
- GET_CARD16 (CWHeight, h);
- if (!w || !h)
- {
- client->errorValue = 0;
- return BadValue;
- }
- action = RESIZE_WIN;
- }
- tmask = mask & ~ChangeMask;
- while (tmask)
- {
- index2 = (Mask)lowbit (tmask);
- tmask &= ~index2;
- switch (index2)
- {
- case CWBorderWidth:
- GET_CARD16(CWBorderWidth, bw);
- break;
- case CWSibling:
- sibwid = (Window ) *pVlist;
- pVlist++;
- rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = sibwid;
- return rc;
- }
- if (pSib->parent != pParent)
- return BadMatch;
- if (pSib == pWin)
- return BadMatch;
- break;
- case CWStackMode:
- GET_CARD8(CWStackMode, smode);
- if ((smode != TopIf) && (smode != BottomIf) &&
- (smode != Opposite) && (smode != Above) && (smode != Below))
- {
- client->errorValue = smode;
- return BadValue;
- }
- break;
- default:
- client->errorValue = mask;
- return BadValue;
- }
- }
- /* root really can't be reconfigured, so just return */
- if (!pParent)
- return Success;
-
- /* Figure out if the window should be moved. Doesnt
- make the changes to the window if event sent */
-
- if (mask & CWStackMode)
- pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
- pParent->drawable.y + y,
- w + (bw << 1), h + (bw << 1), smode);
- else
- pSib = pWin->nextSib;
-
-
- if ((!pWin->overrideRedirect) &&
- (RedirectSend(pParent)
- ))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = ConfigureRequest;
- event.u.configureRequest.window = pWin->drawable.id;
- if (mask & CWSibling)
- event.u.configureRequest.sibling = sibwid;
- else
- event.u.configureRequest.sibling = None;
- if (mask & CWStackMode)
- event.u.u.detail = smode;
- else
- event.u.u.detail = Above;
- event.u.configureRequest.x = x;
- event.u.configureRequest.y = y;
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
- event.u.configureRequest.x += screenInfo.screens[0]->x;
- event.u.configureRequest.y += screenInfo.screens[0]->y;
- }
-#endif
- event.u.configureRequest.width = w;
- event.u.configureRequest.height = h;
- event.u.configureRequest.borderWidth = bw;
- event.u.configureRequest.valueMask = mask;
- event.u.configureRequest.parent = pParent->drawable.id;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- return Success;
- }
- if (action == RESIZE_WIN)
- {
- Bool size_change = (w != pWin->drawable.width)
- || (h != pWin->drawable.height);
- if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
- {
- xEvent eventT;
- memset(&eventT, 0, sizeof(xEvent));
- eventT.u.u.type = ResizeRequest;
- eventT.u.resizeRequest.window = pWin->drawable.id;
- eventT.u.resizeRequest.width = w;
- eventT.u.resizeRequest.height = h;
- if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
- ResizeRedirectMask, client) == 1)
- {
- /* if event is delivered, leave the actual size alone. */
- w = pWin->drawable.width;
- h = pWin->drawable.height;
- size_change = FALSE;
- }
- }
- if (!size_change)
- {
- if (mask & (CWX | CWY))
- action = MOVE_WIN;
- else if (mask & (CWStackMode | CWBorderWidth))
- action = RESTACK_WIN;
- else /* really nothing to do */
- return(Success) ;
- }
- }
-
- if (action == RESIZE_WIN)
- /* we've already checked whether there's really a size change */
- goto ActuallyDoSomething;
- if ((mask & CWX) && (x != beforeX))
- goto ActuallyDoSomething;
- if ((mask & CWY) && (y != beforeY))
- goto ActuallyDoSomething;
- if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
- goto ActuallyDoSomething;
- if (mask & CWStackMode)
- {
-#ifndef ROOTLESS
- /* See above for why we always reorder in rootless mode. */
- if (pWin->nextSib != pSib)
-#endif
- goto ActuallyDoSomething;
- }
- return Success;
-
-ActuallyDoSomething:
- if (pWin->drawable.pScreen->ConfigNotify)
- {
- int ret;
- ret = (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
- if (ret) {
- client->errorValue = 0;
- return ret;
- }
- }
-
- if (SubStrSend(pWin, pParent))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = ConfigureNotify;
- event.u.configureNotify.window = pWin->drawable.id;
- if (pSib)
- event.u.configureNotify.aboveSibling = pSib->drawable.id;
- else
- event.u.configureNotify.aboveSibling = None;
- event.u.configureNotify.x = x;
- event.u.configureNotify.y = y;
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
- event.u.configureNotify.x += screenInfo.screens[0]->x;
- event.u.configureNotify.y += screenInfo.screens[0]->y;
- }
-#endif
- event.u.configureNotify.width = w;
- event.u.configureNotify.height = h;
- event.u.configureNotify.borderWidth = bw;
- event.u.configureNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (mask & CWBorderWidth)
- {
- if (action == RESTACK_WIN)
- {
- action = MOVE_WIN;
- pWin->borderWidth = bw;
- }
- else if ((action == MOVE_WIN) &&
- (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
- (beforeY + wBorderWidth (pWin) == y + (int)bw))
- {
- action = REBORDER_WIN;
- (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
- }
- else
- pWin->borderWidth = bw;
- }
- if (action == MOVE_WIN)
- (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
- (mask & CWBorderWidth) ? VTOther : VTMove);
- else if (action == RESIZE_WIN)
- (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
- else if (mask & CWStackMode)
- ReflectStackChange(pWin, pSib, VTOther);
-
- if (action != RESTACK_WIN)
- CheckCursorConfinement(pWin);
- return Success;
-#undef RESTACK_WIN
-#undef MOVE_WIN
-#undef RESIZE_WIN
-#undef REBORDER_WIN
-}
-
-
-/******
- *
- * CirculateWindow
- * For RaiseLowest, raises the lowest mapped child (if any) that is
- * obscured by another child to the top of the stack. For LowerHighest,
- * lowers the highest mapped child (if any) that is obscuring another
- * child to the bottom of the stack. Exposure processing is performed
- *
- ******/
-
-int
-CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
-{
- WindowPtr pWin, pHead, pFirst;
- xEvent event;
- BoxRec box;
-
- pHead = RealChildHead(pParent);
- pFirst = pHead ? pHead->nextSib : pParent->firstChild;
- if (direction == RaiseLowest)
- {
- for (pWin = pParent->lastChild;
- (pWin != pHead) &&
- !(pWin->mapped &&
- AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
- pWin = pWin->prevSib) ;
- if (pWin == pHead)
- return Success;
- }
- else
- {
- for (pWin = pFirst;
- pWin &&
- !(pWin->mapped &&
- IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
- pWin = pWin->nextSib) ;
- if (!pWin)
- return Success;
- }
-
- event.u.circulate.window = pWin->drawable.id;
- event.u.circulate.parent = pParent->drawable.id;
- event.u.circulate.event = pParent->drawable.id;
- if (direction == RaiseLowest)
- event.u.circulate.place = PlaceOnTop;
- else
- event.u.circulate.place = PlaceOnBottom;
-
- if (RedirectSend(pParent))
- {
- event.u.u.type = CirculateRequest;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- return Success;
- }
-
- event.u.u.type = CirculateNotify;
- DeliverEvents(pWin, &event, 1, NullWindow);
- ReflectStackChange(pWin,
- (direction == RaiseLowest) ? pFirst : NullWindow,
- VTStack);
-
- return Success;
-}
-
-static int
-CompareWIDs(
- WindowPtr pWin,
- pointer value) /* must conform to VisitWindowProcPtr */
-{
- Window *wid = (Window *)value;
-
- if (pWin->drawable.id == *wid)
- return WT_STOPWALKING;
- else
- return WT_WALKCHILDREN;
-}
-
-/*****
- * ReparentWindow
- *****/
-
-int
-ReparentWindow(WindowPtr pWin, WindowPtr pParent,
- int x, int y, ClientPtr client)
-{
- WindowPtr pPrev, pPriorParent;
- Bool WasMapped = (Bool)(pWin->mapped);
- xEvent event;
- int bw = wBorderWidth (pWin);
- ScreenPtr pScreen;
-
- pScreen = pWin->drawable.pScreen;
- if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
- return BadMatch;
- if (!MakeWindowOptional(pWin))
- return BadAlloc;
-
- if (WasMapped)
- UnmapWindow(pWin, FALSE);
-
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = ReparentNotify;
- event.u.reparent.window = pWin->drawable.id;
- event.u.reparent.parent = pParent->drawable.id;
- event.u.reparent.x = x;
- event.u.reparent.y = y;
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && !pParent->parent) {
- event.u.reparent.x += screenInfo.screens[0]->x;
- event.u.reparent.y += screenInfo.screens[0]->y;
- }
-#endif
- event.u.reparent.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, pParent);
-
- /* take out of sibling chain */
-
- pPriorParent = pPrev = pWin->parent;
- if (pPrev->firstChild == pWin)
- pPrev->firstChild = pWin->nextSib;
- if (pPrev->lastChild == pWin)
- pPrev->lastChild = pWin->prevSib;
-
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
-
- /* insert at begining of pParent */
- pWin->parent = pParent;
- pPrev = RealChildHead(pParent);
- if (pPrev)
- {
- pWin->nextSib = pPrev->nextSib;
- if (pPrev->nextSib)
- pPrev->nextSib->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pPrev->nextSib = pWin;
- pWin->prevSib = pPrev;
- }
- else
- {
- pWin->nextSib = pParent->firstChild;
- pWin->prevSib = NullWindow;
- if (pParent->firstChild)
- pParent->firstChild->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pParent->firstChild = pWin;
- }
-
- pWin->origin.x = x + bw;
- pWin->origin.y = y + bw;
- pWin->drawable.x = x + bw + pParent->drawable.x;
- pWin->drawable.y = y + bw + pParent->drawable.y;
-
- /* clip to parent */
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- if (pScreen->ReparentWindow)
- (*pScreen->ReparentWindow)(pWin, pPriorParent);
- (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
- ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
-
- CheckWindowOptionalNeed(pWin);
-
- if (WasMapped)
- MapWindow(pWin, client);
- RecalculateDeliverableEvents(pWin);
- return Success;
-}
-
-static void
-RealizeTree(WindowPtr pWin)
-{
- WindowPtr pChild;
- RealizeWindowProcPtr Realize;
-
- Realize = pWin->drawable.pScreen->RealizeWindow;
- pChild = pWin;
- while (1)
- {
- if (pChild->mapped)
- {
- pChild->realized = TRUE;
- pChild->viewable = (pChild->drawable.class == InputOutput);
- (* Realize)(pChild);
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- return;
- pChild = pChild->nextSib;
- }
-}
-
-static WindowPtr windowDisableMapUnmapEvents;
-
-void
-DisableMapUnmapEvents(WindowPtr pWin)
-{
- assert (windowDisableMapUnmapEvents == NULL);
-
- windowDisableMapUnmapEvents = pWin;
-}
-
-void
-EnableMapUnmapEvents(WindowPtr pWin)
-{
- assert (windowDisableMapUnmapEvents != NULL);
-
- windowDisableMapUnmapEvents = NULL;
-}
-
-static Bool
-MapUnmapEventsEnabled(WindowPtr pWin)
-{
- return pWin != windowDisableMapUnmapEvents;
-}
-
-/*****
- * MapWindow
- * If some other client has selected SubStructureReDirect on the parent
- * and override-redirect is xFalse, then a MapRequest event is generated,
- * but the window remains unmapped. Otherwise, the window is mapped and a
- * MapNotify event is generated.
- *****/
-
-int
-MapWindow(WindowPtr pWin, ClientPtr client)
-{
- ScreenPtr pScreen;
-
- WindowPtr pParent;
- WindowPtr pLayerWin;
-
- if (pWin->mapped)
- return Success;
-
- /* general check for permission to map window */
- if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW,
- pWin, RT_NONE, NULL, DixShowAccess) != Success)
- return Success;
-
- pScreen = pWin->drawable.pScreen;
- if ( (pParent = pWin->parent) )
- {
- xEvent event;
- Bool anyMarked;
-
- if ((!pWin->overrideRedirect) &&
- (RedirectSend(pParent)
- ))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = MapRequest;
- event.u.mapRequest.window = pWin->drawable.id;
- event.u.mapRequest.parent = pParent->drawable.id;
-
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- return Success;
- }
-
- pWin->mapped = TRUE;
- if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = MapNotify;
- event.u.mapNotify.window = pWin->drawable.id;
- event.u.mapNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
-
- if (!pParent->realized)
- return Success;
- RealizeTree(pWin);
- if (pWin->viewable)
- {
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- &pLayerWin);
- if (anyMarked)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
- }
- WindowsRestructured ();
- }
- else
- {
- RegionRec temp;
-
- pWin->mapped = TRUE;
- pWin->realized = TRUE; /* for roots */
- pWin->viewable = pWin->drawable.class == InputOutput;
- /* We SHOULD check for an error value here XXX */
- (*pScreen->RealizeWindow)(pWin);
- if (pScreen->ClipNotify)
- (*pScreen->ClipNotify) (pWin, 0, 0);
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
- RegionNull(&temp);
- RegionCopy(&temp, &pWin->clipList);
- (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
- RegionUninit(&temp);
- }
-
- return Success;
-}
-
-
-/*****
- * MapSubwindows
- * Performs a MapWindow all unmapped children of the window, in top
- * to bottom stacking order.
- *****/
-
-void
-MapSubwindows(WindowPtr pParent, ClientPtr client)
-{
- WindowPtr pWin;
- WindowPtr pFirstMapped = NullWindow;
- ScreenPtr pScreen;
- Mask parentRedirect;
- Mask parentNotify;
- xEvent event;
- Bool anyMarked;
- WindowPtr pLayerWin;
-
- pScreen = pParent->drawable.pScreen;
- parentRedirect = RedirectSend(pParent);
- parentNotify = SubSend(pParent);
- anyMarked = FALSE;
- for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
- {
- if (!pWin->mapped)
- {
- if (parentRedirect && !pWin->overrideRedirect)
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = MapRequest;
- event.u.mapRequest.window = pWin->drawable.id;
- event.u.mapRequest.parent = pParent->drawable.id;
-
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- continue;
- }
-
- pWin->mapped = TRUE;
- if (parentNotify || StrSend(pWin))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = MapNotify;
- event.u.mapNotify.window = pWin->drawable.id;
- event.u.mapNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
-
- if (!pFirstMapped)
- pFirstMapped = pWin;
- if (pParent->realized)
- {
- RealizeTree(pWin);
- if (pWin->viewable)
- {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- (WindowPtr *)NULL);
- }
- }
- }
- }
-
- if (pFirstMapped)
- {
- pLayerWin = (*pScreen->GetLayerWindow)(pParent);
- if (pLayerWin->parent != pParent) {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
- pLayerWin,
- (WindowPtr *)NULL);
- pFirstMapped = pLayerWin;
- }
- if (anyMarked)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
- VTMap);
- WindowsRestructured ();
- }
-}
-
-static void
-UnrealizeTree(
- WindowPtr pWin,
- Bool fromConfigure)
-{
- WindowPtr pChild;
- UnrealizeWindowProcPtr Unrealize;
- MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
-
- Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
- MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
- pChild = pWin;
- while (1)
- {
- if (pChild->realized)
- {
- pChild->realized = FALSE;
- pChild->visibility = VisibilityNotViewable;
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
- PanoramiXRes *win;
- int rc = dixLookupResourceByType((pointer *)&win,
- pChild->drawable.id, XRT_WINDOW,
- serverClient, DixWriteAccess);
- if (rc == Success)
- win->u.win.visibility = VisibilityNotViewable;
- }
-#endif
- (* Unrealize)(pChild);
- if (MapUnmapEventsEnabled(pWin))
- DeleteWindowFromAnyEvents(pChild, FALSE);
- if (pChild->viewable)
- {
- pChild->viewable = FALSE;
- (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
- pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- return;
- pChild = pChild->nextSib;
- }
-}
-
-/*****
- * UnmapWindow
- * If the window is already unmapped, this request has no effect.
- * Otherwise, the window is unmapped and an UnMapNotify event is
- * generated. Cannot unmap a root window.
- *****/
-
-int
-UnmapWindow(WindowPtr pWin, Bool fromConfigure)
-{
- WindowPtr pParent;
- xEvent event;
- Bool wasRealized = (Bool)pWin->realized;
- Bool wasViewable = (Bool)pWin->viewable;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- WindowPtr pLayerWin = pWin;
-
- if ((!pWin->mapped) || (!(pParent = pWin->parent)))
- return Success;
- if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
- {
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = UnmapNotify;
- event.u.unmapNotify.window = pWin->drawable.id;
- event.u.unmapNotify.fromConfigure = fromConfigure;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (wasViewable && !fromConfigure)
- {
- pWin->valdata = UnmapValData;
- (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
- (*pScreen->MarkWindow)(pLayerWin->parent);
- }
- pWin->mapped = FALSE;
- if (wasRealized)
- UnrealizeTree(pWin, fromConfigure);
- if (wasViewable)
- {
- if (!fromConfigure)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (!fromConfigure && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
- }
- if (wasRealized && !fromConfigure)
- WindowsRestructured ();
- return Success;
-}
-
-/*****
- * UnmapSubwindows
- * Performs an UnmapWindow request with the specified mode on all mapped
- * children of the window, in bottom to top stacking order.
- *****/
-
-void
-UnmapSubwindows(WindowPtr pWin)
-{
- WindowPtr pChild, pHead;
- xEvent event;
- Bool wasRealized = (Bool)pWin->realized;
- Bool wasViewable = (Bool)pWin->viewable;
- Bool anyMarked = FALSE;
- Mask parentNotify;
- WindowPtr pLayerWin = NULL;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- if (!pWin->firstChild)
- return;
- parentNotify = SubSend(pWin);
- pHead = RealChildHead(pWin);
-
- if (wasViewable)
- pLayerWin = (*pScreen->GetLayerWindow)(pWin);
-
- for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
- {
- if (pChild->mapped)
- {
- if (parentNotify || StrSend(pChild))
- {
- event.u.u.type = UnmapNotify;
- event.u.unmapNotify.window = pChild->drawable.id;
- event.u.unmapNotify.fromConfigure = xFalse;
- DeliverEvents(pChild, &event, 1, NullWindow);
- }
- if (pChild->viewable)
- {
- pChild->valdata = UnmapValData;
- anyMarked = TRUE;
- }
- pChild->mapped = FALSE;
- if (pChild->realized)
- UnrealizeTree(pChild, FALSE);
- if (wasViewable)
- {
- }
- }
- }
- if (wasViewable)
- {
- if (anyMarked)
- {
- if (pLayerWin->parent == pWin)
- (*pScreen->MarkWindow)(pWin);
- else
- {
- WindowPtr ptmp;
- (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
- (WindowPtr *)NULL);
- (*pScreen->MarkWindow)(pLayerWin->parent);
-
- /* Windows between pWin and pLayerWin may not have been marked */
- ptmp = pWin;
-
- while (ptmp != pLayerWin->parent)
- {
- (*pScreen->MarkWindow)(ptmp);
- ptmp = ptmp->parent;
- }
- pHead = pWin->firstChild;
- }
- (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
- }
- if (wasRealized)
- WindowsRestructured ();
-}
-
-
-void
-HandleSaveSet(ClientPtr client)
-{
- WindowPtr pParent, pWin;
- int j;
-
- for (j=0; j<client->numSaved; j++)
- {
- pWin = SaveSetWindow(client->saveSet[j]);
-#ifdef XFIXES
- if (SaveSetToRoot(client->saveSet[j]))
- pParent = pWin->drawable.pScreen->root;
- else
-#endif
- {
- pParent = pWin->parent;
- while (pParent && (wClient (pParent) == client))
- pParent = pParent->parent;
- }
- if (pParent)
- {
- if (pParent != pWin->parent)
- {
-#ifdef XFIXES
- /* unmap first so that ReparentWindow doesn't remap */
- if (!SaveSetShouldMap (client->saveSet[j]))
- UnmapWindow(pWin, FALSE);
-#endif
- ReparentWindow(pWin, pParent,
- pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
- pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
- client);
- if(!pWin->realized && pWin->mapped)
- pWin->mapped = FALSE;
- }
-#ifdef XFIXES
- if (SaveSetShouldMap (client->saveSet[j]))
-#endif
- MapWindow(pWin, client);
- }
- }
- free(client->saveSet);
- client->numSaved = 0;
- client->saveSet = (SaveSetElt *)NULL;
-}
-
-/**
- *
- * \param x,y in root
- */
-Bool
-PointInWindowIsVisible(WindowPtr pWin, int x, int y)
-{
- BoxRec box;
-
- if (!pWin->realized)
- return FALSE;
- if (RegionContainsPoint(&pWin->borderClip,
- x, y, &box)
- && (!wInputShape(pWin) ||
- RegionContainsPoint(wInputShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box)))
- return TRUE;
- return FALSE;
-}
-
-
-RegionPtr
-NotClippedByChildren(WindowPtr pWin)
-{
- RegionPtr pReg = RegionCreate(NullBox, 1);
- if (pWin->parent ||
- screenIsSaved != SCREEN_SAVER_ON ||
- !HasSaverWindow (pWin->drawable.pScreen))
- {
- RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize);
- }
- return pReg;
-}
-
-void
-SendVisibilityNotify(WindowPtr pWin)
-{
- xEvent event;
- unsigned int visibility = pWin->visibility;
-
- if (!MapUnmapEventsEnabled(pWin))
- return;
-#ifdef PANORAMIX
- /* This is not quite correct yet, but it's close */
- if(!noPanoramiXExtension) {
- PanoramiXRes *win;
- WindowPtr pWin2;
- int rc, i, Scrnum;
-
- Scrnum = pWin->drawable.pScreen->myNum;
-
- win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
-
- if(!win || (win->u.win.visibility == visibility))
- return;
-
- switch(visibility) {
- case VisibilityUnobscured:
- for(i = 0; i < PanoramiXNumScreens; i++) {
- if(i == Scrnum) continue;
-
- rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient,
- DixWriteAccess);
-
- if (rc == Success) {
- if(pWin2->visibility == VisibilityPartiallyObscured)
- return;
-
- if(!i) pWin = pWin2;
- }
- }
- break;
- case VisibilityPartiallyObscured:
- if(Scrnum) {
- rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient,
- DixWriteAccess);
- if (rc == Success) pWin = pWin2;
- }
- break;
- case VisibilityFullyObscured:
- for(i = 0; i < PanoramiXNumScreens; i++) {
- if(i == Scrnum) continue;
-
- rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient,
- DixWriteAccess);
-
- if (rc == Success) {
- if(pWin2->visibility != VisibilityFullyObscured)
- return;
-
- if(!i) pWin = pWin2;
- }
- }
- break;
- }
-
- win->u.win.visibility = visibility;
- }
-#endif
-
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = VisibilityNotify;
- event.u.visibility.window = pWin->drawable.id;
- event.u.visibility.state = visibility;
- DeliverEvents(pWin, &event, 1, NullWindow);
-}
-
-#define RANDOM_WIDTH 32
-int
-dixSaveScreens(ClientPtr client, int on, int mode)
-{
- int rc, i, what, type;
-
- if (on == SCREEN_SAVER_FORCER)
- {
- if (mode == ScreenSaverReset)
- what = SCREEN_SAVER_OFF;
- else
- what = SCREEN_SAVER_ON;
- type = what;
- }
- else
- {
- what = on;
- type = what;
- if (what == screenIsSaved)
- type = SCREEN_SAVER_CYCLE;
- }
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
- DixShowAccess | DixHideAccess);
- if (rc != Success)
- return rc;
- }
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ScreenPtr pScreen = screenInfo.screens[i];
- if (on == SCREEN_SAVER_FORCER)
- (* pScreen->SaveScreen) (pScreen, on);
- if (pScreen->screensaver.ExternalScreenSaver)
- {
- if ((*pScreen->screensaver.ExternalScreenSaver)
- (pScreen, type, on == SCREEN_SAVER_FORCER))
- continue;
- }
- if (type == screenIsSaved)
- continue;
- switch (type) {
- case SCREEN_SAVER_OFF:
- if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED)
- {
- (* pScreen->SaveScreen) (pScreen, what);
- }
- else if (HasSaverWindow (pScreen))
- {
- pScreen->screensaver.pWindow = NullWindow;
- FreeResource(pScreen->screensaver.wid, RT_NONE);
- }
- break;
- case SCREEN_SAVER_CYCLE:
- if (pScreen->screensaver.blanked == SCREEN_IS_TILED)
- {
- WindowPtr pWin = pScreen->screensaver.pWindow;
- /* make it look like screen saver is off, so that
- * NotClippedByChildren will compute a clip list
- * for the root window, so miPaintWindow works
- */
- screenIsSaved = SCREEN_SAVER_OFF;
- (*pWin->drawable.pScreen->MoveWindow)(pWin,
- (short)(-(rand() % RANDOM_WIDTH)),
- (short)(-(rand() % RANDOM_WIDTH)),
- pWin->nextSib, VTMove);
- screenIsSaved = SCREEN_SAVER_ON;
- }
- /*
- * Call the DDX saver in case it wants to do something
- * at cycle time
- */
- else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED)
- {
- (* pScreen->SaveScreen) (pScreen, type);
- }
- break;
- case SCREEN_SAVER_ON:
- if (ScreenSaverBlanking != DontPreferBlanking)
- {
- if ((* pScreen->SaveScreen) (pScreen, what))
- {
- pScreen->screensaver.blanked = SCREEN_IS_BLANKED;
- continue;
- }
- if ((ScreenSaverAllowExposures != DontAllowExposures) &&
- TileScreenSaver(pScreen, SCREEN_IS_BLACK))
- {
- pScreen->screensaver.blanked = SCREEN_IS_BLACK;
- continue;
- }
- }
- if ((ScreenSaverAllowExposures != DontAllowExposures) &&
- TileScreenSaver(pScreen, SCREEN_IS_TILED))
- {
- pScreen->screensaver.blanked = SCREEN_IS_TILED;
- }
- else
- pScreen->screensaver.blanked = SCREEN_ISNT_SAVED;
- break;
- }
- }
- screenIsSaved = what;
- if (mode == ScreenSaverReset) {
- if (on == SCREEN_SAVER_FORCER) {
- UpdateCurrentTimeIf();
- lastDeviceEventTime = currentTime;
- }
- SetScreenSaverTimer();
- }
- return Success;
-}
-
-int
-SaveScreens(int on, int mode)
-{
- return dixSaveScreens(serverClient, on, mode);
-}
-
-static Bool
-TileScreenSaver(ScreenPtr pScreen, int kind)
-{
- int j;
- int result;
- XID attributes[3];
- Mask mask;
- WindowPtr pWin;
- CursorMetricRec cm;
- unsigned char *srcbits, *mskbits;
- CursorPtr cursor;
- XID cursorID = 0;
- int attri;
-
- mask = 0;
- attri = 0;
- switch (kind) {
- case SCREEN_IS_TILED:
- switch (pScreen->root->backgroundState) {
- case BackgroundPixel:
- attributes[attri++] = pScreen->root->background.pixel;
- mask |= CWBackPixel;
- break;
- case BackgroundPixmap:
- attributes[attri++] = None;
- mask |= CWBackPixmap;
- break;
- default:
- break;
- }
- break;
- case SCREEN_IS_BLACK:
- attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel;
- mask |= CWBackPixel;
- break;
- }
- mask |= CWOverrideRedirect;
- attributes[attri++] = xTrue;
-
- /*
- * create a blank cursor
- */
-
- cm.width=16;
- cm.height=16;
- cm.xhot=8;
- cm.yhot=8;
- srcbits = malloc( BitmapBytePad(32)*16);
- mskbits = malloc( BitmapBytePad(32)*16);
- if (!srcbits || !mskbits)
- {
- free(srcbits);
- free(mskbits);
- cursor = 0;
- }
- else
- {
- for (j=0; j<BitmapBytePad(32)*16; j++)
- srcbits[j] = mskbits[j] = 0x0;
- result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0,
- &cursor, serverClient, (XID)0);
- if (cursor)
- {
- cursorID = FakeClientID(0);
- if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
- {
- attributes[attri] = cursorID;
- mask |= CWCursor;
- }
- else
- cursor = 0;
- }
- else
- {
- free(srcbits);
- free(mskbits);
- }
- }
-
- pWin = pScreen->screensaver.pWindow =
- CreateWindow(pScreen->screensaver.wid,
- pScreen->root,
- -RANDOM_WIDTH, -RANDOM_WIDTH,
- (unsigned short)pScreen->width + RANDOM_WIDTH,
- (unsigned short)pScreen->height + RANDOM_WIDTH,
- 0, InputOutput, mask, attributes, 0, serverClient,
- wVisual (pScreen->root), &result);
-
- if (cursor)
- FreeResource (cursorID, RT_NONE);
-
- if (!pWin)
- return FALSE;
-
- if (!AddResource(pWin->drawable.id, RT_WINDOW,
- (pointer)pScreen->screensaver.pWindow))
- return FALSE;
-
- if (mask & CWBackPixmap)
- {
- MakeRootTile (pWin);
- (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
- }
- MapWindow(pWin, serverClient);
- return TRUE;
-}
-
-/*
- * FindWindowWithOptional
- *
- * search ancestors of the given window for an entry containing
- * a WindowOpt structure. Assumptions: some parent will
- * contain the structure.
- */
-
-WindowPtr
-FindWindowWithOptional (WindowPtr w)
-{
- do
- w = w->parent;
- while (!w->optional);
- return w;
-}
-
-/*
- * CheckWindowOptionalNeed
- *
- * check each optional entry in the given window to see if
- * the value is satisfied by the default rules. If so,
- * release the optional record
- */
-
-void
-CheckWindowOptionalNeed (WindowPtr w)
-{
- WindowOptPtr optional;
- WindowOptPtr parentOptional;
-
- if (!w->parent || !w->optional)
- return;
- optional = w->optional;
- if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
- return;
- if (optional->otherEventMasks != 0)
- return;
- if (optional->otherClients != NULL)
- return;
- if (optional->passiveGrabs != NULL)
- return;
- if (optional->userProps != NULL)
- return;
- if (optional->backingBitPlanes != ~0L)
- return;
- if (optional->backingPixel != 0)
- return;
- if (optional->boundingShape != NULL)
- return;
- if (optional->clipShape != NULL)
- return;
- if (optional->inputShape != NULL)
- return;
- if (optional->inputMasks != NULL)
- return;
- if (optional->deviceCursors != NULL)
- {
- DevCursNodePtr pNode = optional->deviceCursors;
- while(pNode)
- {
- if (pNode->cursor != None)
- return;
- pNode = pNode->next;
- }
- }
-
- parentOptional = FindWindowWithOptional(w)->optional;
- if (optional->visual != parentOptional->visual)
- return;
- if (optional->cursor != None &&
- (optional->cursor != parentOptional->cursor ||
- w->parent->cursorIsNone))
- return;
- if (optional->colormap != parentOptional->colormap)
- return;
- DisposeWindowOptional (w);
-}
-
-/*
- * MakeWindowOptional
- *
- * create an optional record and initialize it with the default
- * values.
- */
-
-Bool
-MakeWindowOptional (WindowPtr pWin)
-{
- WindowOptPtr optional;
- WindowOptPtr parentOptional;
-
- if (pWin->optional)
- return TRUE;
- optional = malloc(sizeof (WindowOptRec));
- if (!optional)
- return FALSE;
- optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
- optional->otherEventMasks = 0;
- optional->otherClients = NULL;
- optional->passiveGrabs = NULL;
- optional->userProps = NULL;
- optional->backingBitPlanes = ~0L;
- optional->backingPixel = 0;
- optional->boundingShape = NULL;
- optional->clipShape = NULL;
- optional->inputShape = NULL;
- optional->inputMasks = NULL;
- optional->deviceCursors = NULL;
-
- parentOptional = FindWindowWithOptional(pWin)->optional;
- optional->visual = parentOptional->visual;
- if (!pWin->cursorIsNone)
- {
- optional->cursor = parentOptional->cursor;
- optional->cursor->refcnt++;
- }
- else
- {
- optional->cursor = None;
- }
- optional->colormap = parentOptional->colormap;
- pWin->optional = optional;
- return TRUE;
-}
-
-/*
- * Changes the cursor struct for the given device and the given window.
- * A cursor that does not have a device cursor set will use whatever the
- * standard cursor is for the window. If all devices have a cursor set,
- * changing the window cursor (e.g. using XDefineCursor()) will not have any
- * visible effect. Only when one of the device cursors is set to None again,
- * this device's cursor will display the changed standard cursor.
- *
- * CursorIsNone of the window struct is NOT modified if you set a device
- * cursor.
- *
- * Assumption: If there is a node for a device in the list, the device has a
- * cursor. If the cursor is set to None, it is inherited by the parent.
- */
-int
-ChangeWindowDeviceCursor(WindowPtr pWin,
- DeviceIntPtr pDev,
- CursorPtr pCursor)
-{
- DevCursNodePtr pNode, pPrev;
- CursorPtr pOldCursor = NULL;
- ScreenPtr pScreen;
- WindowPtr pChild;
-
- if (!pWin->optional && !MakeWindowOptional(pWin))
- return BadAlloc;
-
- /* 1) Check if window has device cursor set
- * Yes: 1.1) swap cursor with given cursor if parent does not have same
- * cursor, free old cursor
- * 1.2) free old cursor, use parent cursor
- * No: 1.1) add node to beginning of list.
- * 1.2) add cursor to node if parent does not have same cursor
- * 1.3) use parent cursor if parent does not have same cursor
- * 2) Patch up children if child has a devcursor
- * 2.1) if child has cursor None, it inherited from parent, set to old
- * cursor
- * 2.2) if child has same cursor as new cursor, remove and set to None
- */
-
- pScreen = pWin->drawable.pScreen;
-
- if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev))
- {
- /* has device cursor */
-
- if (pNode->cursor == pCursor)
- return Success;
-
- pOldCursor = pNode->cursor;
-
- if (!pCursor) /* remove from list */
- {
- if(pPrev)
- pPrev->next = pNode->next;
- else
- /* first item in list */
- pWin->optional->deviceCursors = pNode->next;
-
- free(pNode);
- goto out;
- }
-
- } else
- {
- /* no device cursor yet */
- DevCursNodePtr pNewNode;
-
- if (!pCursor)
- return Success;
-
- pNewNode = malloc(sizeof(DevCursNodeRec));
- pNewNode->dev = pDev;
- pNewNode->next = pWin->optional->deviceCursors;
- pWin->optional->deviceCursors = pNewNode;
- pNode = pNewNode;
-
- }
-
- if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
- pNode->cursor = None;
- else
- {
- pNode->cursor = pCursor;
- pCursor->refcnt++;
- }
-
- pNode = pPrev = NULL;
- /* fix up children */
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev))
- {
- if (pNode->cursor == None) /* inherited from parent */
- {
- pNode->cursor = pOldCursor;
- pOldCursor->refcnt++;
- } else if (pNode->cursor == pCursor)
- {
- pNode->cursor = None;
- FreeCursor(pCursor, (Cursor)0); /* fix up refcnt */
- }
- }
- }
-
-out:
- if (pWin->realized)
- WindowHasNewCursor(pWin);
-
- if (pOldCursor)
- FreeCursor(pOldCursor, (Cursor)0);
-
- /* FIXME: We SHOULD check for an error value here XXX
- (comment taken from ChangeWindowAttributes) */
- (*pScreen->ChangeWindowAttributes)(pWin, CWCursor);
-
- return Success;
-}
-
-/* Get device cursor for given device or None if none is set */
-CursorPtr
-WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev)
-{
- DevCursorList pList;
-
- if (!pWin->optional || !pWin->optional->deviceCursors)
- return NULL;
-
- pList = pWin->optional->deviceCursors;
-
- while(pList)
- {
- if (pList->dev == pDev)
- {
- if (pList->cursor == None) /* inherited from parent */
- return WindowGetDeviceCursor(pWin->parent, pDev);
- else
- return pList->cursor;
- }
- pList = pList->next;
- }
- return NULL;
-}
-
-/* Searches for a DevCursorNode for the given window and device. If one is
- * found, return True and set pNode and pPrev to the node and to the node
- * before the node respectively. Otherwise return False.
- * If the device is the first in list, pPrev is set to NULL.
- */
-static Bool
-WindowSeekDeviceCursor(WindowPtr pWin,
- DeviceIntPtr pDev,
- DevCursNodePtr* pNode,
- DevCursNodePtr* pPrev)
-{
- DevCursorList pList;
-
- if (!pWin->optional)
- return FALSE;
-
- pList = pWin->optional->deviceCursors;
-
- if (pList && pList->dev == pDev)
- {
- *pNode = pList;
- *pPrev = NULL;
- return TRUE;
- }
-
- while(pList)
- {
- if (pList->next)
- {
- if (pList->next->dev == pDev)
- {
- *pNode = pList->next;
- *pPrev = pList;
- return TRUE;
- }
- }
- pList = pList->next;
- }
- return FALSE;
-}
-
-/* Return True if a parent has the same device cursor set or False if
- * otherwise
- */
-static Bool
-WindowParentHasDeviceCursor(WindowPtr pWin,
- DeviceIntPtr pDev,
- CursorPtr pCursor)
-{
- WindowPtr pParent;
- DevCursNodePtr pParentNode, pParentPrev;
-
- pParent = pWin->parent;
- while(pParent)
- {
- if (WindowSeekDeviceCursor(pParent, pDev,
- &pParentNode, &pParentPrev))
- {
- /* if there is a node in the list, the win has a dev cursor */
- if (!pParentNode->cursor) /* inherited. */
- pParent = pParent->parent;
- else if (pParentNode->cursor == pCursor) /* inherit */
- return TRUE;
- else /* different cursor */
- return FALSE;
- }
- else
- /* parent does not have a device cursor for our device */
- return FALSE;
- }
- return FALSE;
-}
+/* + +Copyright (c) 2006, Red Hat, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +/* The panoramix components contained the following notice */ +/***************************************************************** + +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. + +******************************************************************/ + + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "inputstr.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif +#include "dixevents.h" +#include "globals.h" +#include "mi.h" /* miPaintWindow */ + +#include "privates.h" +#include "xace.h" + +/****** + * Window stuff for server + * + * CreateRootWindow, CreateWindow, ChangeWindowAttributes, + * GetWindowAttributes, DeleteWindow, DestroySubWindows, + * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, + * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, + * ChangeWindowDeviceCursor + ******/ + +Bool bgNoneRoot = FALSE; + +static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11}; +static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88}; + +static Bool WindowParentHasDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCurs); +static Bool +WindowSeekDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + DevCursNodePtr* pNode, + DevCursNodePtr* pPrev); + +int screenIsSaved = SCREEN_SAVER_OFF; + +static Bool TileScreenSaver(ScreenPtr pScreen, int kind); + +#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ + CWDontPropagate | CWOverrideRedirect | CWCursor ) + +#define BOXES_OVERLAP(b1, b2) \ + (!( ((b1)->x2 <= (b2)->x1) || \ + ( ((b1)->x1 >= (b2)->x2)) || \ + ( ((b1)->y2 <= (b2)->y1)) || \ + ( ((b1)->y1 >= (b2)->y2)) ) ) + +#define RedirectSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask) + +#define SubSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) + +#define StrSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) + +#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) + +#ifdef DEBUG +/****** + * PrintWindowTree + * For debugging only + ******/ + +static void +PrintChildren(WindowPtr p1, int indent) +{ + WindowPtr p2; + int i; + + while (p1) + { + p2 = p1->firstChild; + ErrorF("[dix] "); + for (i=0; i<indent; i++) ErrorF(" "); + ErrorF("%lx\n", p1->drawable.id); + RegionPrint(&p1->clipList); + PrintChildren(p2, indent+4); + p1 = p1->nextSib; + } +} + +static void +PrintWindowTree(void) +{ + int i; + WindowPtr pWin, p1; + + for (i=0; i<screenInfo.numScreens; i++) + { + ErrorF("[dix] WINDOW %d\n", i); + pWin = screenInfo.screens[i]->root; + RegionPrint(&pWin->clipList); + p1 = pWin->firstChild; + PrintChildren(p1, 4); + } +} +#endif + +int +TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data) +{ + int result; + WindowPtr pChild; + + if (!(pChild = pWin)) + return WT_NOMATCH; + while (1) + { + result = (* func)(pChild, data); + if (result == WT_STOPWALKING) + return WT_STOPWALKING; + if ((result == WT_WALKCHILDREN) && pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } + return WT_NOMATCH; +} + +/***** + * WalkTree + * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on + * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, + * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING + * exit WalkTree. Does depth-first traverse. + *****/ + +int +WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data) +{ + return(TraverseTree(pScreen->root, func, data)); +} + +/* hack for forcing backing store on all windows */ +int defaultBackingStore = NotUseful; +/* hack to force no backing store */ +Bool disableBackingStore = FALSE; +Bool enableBackingStore = FALSE; + +static void +SetWindowToDefaults(WindowPtr pWin) +{ + pWin->prevSib = NullWindow; + pWin->firstChild = NullWindow; + pWin->lastChild = NullWindow; + + pWin->valdata = (ValidatePtr)NULL; + pWin->optional = (WindowOptPtr)NULL; + pWin->cursorIsNone = TRUE; + + pWin->backingStore = NotUseful; + pWin->DIXsaveUnder = FALSE; + pWin->backStorage = (pointer) NULL; + + pWin->mapped = FALSE; /* off */ + pWin->realized = FALSE; /* off */ + pWin->viewable = FALSE; + pWin->visibility = VisibilityNotViewable; + pWin->overrideRedirect = FALSE; + pWin->saveUnder = FALSE; + + pWin->bitGravity = ForgetGravity; + pWin->winGravity = NorthWestGravity; + + pWin->eventMask = 0; + pWin->deliverableEvents = 0; + pWin->dontPropagate = 0; + pWin->forcedBS = FALSE; + pWin->redirectDraw = RedirectDrawNone; + pWin->forcedBG = FALSE; + +#ifdef ROOTLESS + pWin->rootlessUnhittable = FALSE; +#endif + +#ifdef COMPOSITE + pWin->damagedDescendants = FALSE; +#endif +} + +static void +MakeRootTile(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + GCPtr pGC; + unsigned char back[128]; + int len = BitmapBytePad(sizeof(long)); + unsigned char *from, *to; + int i, j; + + pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, + pScreen->rootDepth, 0); + + pWin->backgroundState = BackgroundPixmap; + pGC = GetScratchGC(pScreen->rootDepth, pScreen); + if (!pWin->background.pixmap || !pGC) + FatalError("could not create root tile"); + + { + ChangeGCVal attributes[2]; + + attributes[0].val = pScreen->whitePixel; + attributes[1].val = pScreen->blackPixel; + + (void)ChangeGC(NullClient, pGC, GCForeground | GCBackground, attributes); + } + + ValidateGC((DrawablePtr)pWin->background.pixmap, pGC); + + from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; + to = back; + + for (i = 4; i > 0; i--, from++) + for (j = len; j > 0; j--) + *to++ = *from; + + (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1, + 0, 0, len, 4, 0, XYBitmap, (char *)back); + + FreeScratchGC(pGC); + +} + +/***** + * CreateRootWindow + * Makes a window at initialization time for specified screen + *****/ + +Bool +CreateRootWindow(ScreenPtr pScreen) +{ + WindowPtr pWin; + BoxRec box; + PixmapFormatRec *format; + + pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); + if (!pWin) + return FALSE; + + pScreen->screensaver.pWindow = NULL; + pScreen->screensaver.wid = FakeClientID(0); + pScreen->screensaver.ExternalScreenSaver = NULL; + screenIsSaved = SCREEN_SAVER_OFF; + + pScreen->root = pWin; + + pWin->drawable.pScreen = pScreen; + pWin->drawable.type = DRAWABLE_WINDOW; + + pWin->drawable.depth = pScreen->rootDepth; + for (format = screenInfo.formats; + format->depth != pScreen->rootDepth; + format++) + ; + pWin->drawable.bitsPerPixel = format->bitsPerPixel; + + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + pWin->parent = NullWindow; + SetWindowToDefaults(pWin); + + pWin->optional = malloc(sizeof (WindowOptRec)); + if (!pWin->optional) + return FALSE; + + pWin->optional->dontPropagateMask = 0; + pWin->optional->otherEventMasks = 0; + pWin->optional->otherClients = NULL; + pWin->optional->passiveGrabs = NULL; + pWin->optional->userProps = NULL; + pWin->optional->backingBitPlanes = ~0L; + pWin->optional->backingPixel = 0; + pWin->optional->boundingShape = NULL; + pWin->optional->clipShape = NULL; + pWin->optional->inputShape = NULL; + pWin->optional->inputMasks = NULL; + pWin->optional->deviceCursors = NULL; + pWin->optional->colormap = pScreen->defColormap; + pWin->optional->visual = pScreen->rootVisual; + + pWin->nextSib = NullWindow; + + pWin->drawable.id = FakeClientID(0); + + pWin->origin.x = pWin->origin.y = 0; + pWin->drawable.height = pScreen->height; + pWin->drawable.width = pScreen->width; + pWin->drawable.x = pWin->drawable.y = 0; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + RegionInit(&pWin->clipList, &box, 1); + RegionInit(&pWin->winSize, &box, 1); + RegionInit(&pWin->borderSize, &box, 1); + RegionInit(&pWin->borderClip, &box, 1); + + pWin->drawable.class = InputOutput; + pWin->optional->visual = pScreen->rootVisual; + + pWin->backgroundState = BackgroundPixel; + pWin->background.pixel = pScreen->whitePixel; + + pWin->borderIsPixel = TRUE; + pWin->border.pixel = pScreen->blackPixel; + pWin->borderWidth = 0; + + /* security creation/labeling check + */ + if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id, + RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess)) + return FALSE; + + if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) + return FALSE; + + if (disableBackingStore) + pScreen->backingStoreSupport = NotUseful; + if (enableBackingStore) + pScreen->backingStoreSupport = Always; + + pScreen->saveUnderSupport = NotUseful; + + return TRUE; +} + +void +InitRootWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + int backFlag = CWBorderPixel | CWCursor | CWBackingStore; + + if (!(*pScreen->CreateWindow)(pWin)) + return; /* XXX */ + (*pScreen->PositionWindow)(pWin, 0, 0); + + pWin->cursorIsNone = FALSE; + pWin->optional->cursor = rootCursor; + rootCursor->refcnt++; + + + if (party_like_its_1989) { + MakeRootTile(pWin); + backFlag |= CWBackPixmap; + } else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { + pWin->backgroundState = XaceBackgroundNoneState(pWin); + pWin->background.pixel = pScreen->whitePixel; + backFlag |= CWBackPixmap; + } else { + if (whiteRoot) + pWin->background.pixel = pScreen->whitePixel; + else + pWin->background.pixel = pScreen->blackPixel; + backFlag |= CWBackPixel; + } + + pWin->backingStore = defaultBackingStore; + pWin->forcedBS = (defaultBackingStore != NotUseful); + /* We SHOULD check for an error value here XXX */ + (*pScreen->ChangeWindowAttributes)(pWin, backFlag); + + MapWindow(pWin, serverClient); +} + +/* Set the region to the intersection of the rectangle and the + * window's winSize. The window is typically the parent of the + * window from which the region came. + */ + +static void +ClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, + int x, int y, + int w, int h) +{ + BoxRec box = *RegionExtents(&pWin->winSize); + + /* we do these calculations to avoid overflows */ + if (x > box.x1) + box.x1 = x; + if (y > box.y1) + box.y1 = y; + x += w; + if (x < box.x2) + box.x2 = x; + y += h; + if (y < box.y2) + box.y2 = y; + if (box.x1 > box.x2) + box.x2 = box.x1; + if (box.y1 > box.y2) + box.y2 = box.y1; + RegionReset(Rgn, &box); + RegionIntersect(Rgn, Rgn, &pWin->winSize); +} + +static RealChildHeadProc realChildHeadProc = NULL; + +void +RegisterRealChildHeadProc (RealChildHeadProc proc) +{ + realChildHeadProc = proc; +} + + +WindowPtr +RealChildHead(WindowPtr pWin) +{ + if (realChildHeadProc) { + return realChildHeadProc (pWin); + } + + if (!pWin->parent && + (screenIsSaved == SCREEN_SAVER_ON) && + (HasSaverWindow (pWin->drawable.pScreen))) + return pWin->firstChild; + else + return NullWindow; +} + +/***** + * CreateWindow + * Makes a window in response to client request + *****/ + +WindowPtr +CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, + unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, + int depth, ClientPtr client, VisualID visual, int *error) +{ + WindowPtr pWin; + WindowPtr pHead; + ScreenPtr pScreen; + xEvent event; + int idepth, ivisual; + Bool fOK; + DepthPtr pDepth; + PixmapFormatRec *format; + WindowOptPtr ancwopt; + + if (class == CopyFromParent) + class = pParent->drawable.class; + + if ((class != InputOutput) && (class != InputOnly)) + { + *error = BadValue; + client->errorValue = class; + return NullWindow; + } + + if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) + { + *error = BadMatch; + return NullWindow; + } + + if ((class == InputOnly) && ((bw != 0) || (depth != 0))) + { + *error = BadMatch; + return NullWindow; + } + + pScreen = pParent->drawable.pScreen; + if ((class == InputOutput) && (depth == 0)) + depth = pParent->drawable.depth; + ancwopt = pParent->optional; + if (!ancwopt) + ancwopt = FindWindowWithOptional(pParent)->optional; + if (visual == CopyFromParent) { + visual = ancwopt->visual; + } + + /* Find out if the depth and visual are acceptable for this Screen */ + if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) + { + fOK = FALSE; + for(idepth = 0; idepth < pScreen->numDepths; idepth++) + { + pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; + if ((depth == pDepth->depth) || (depth == 0)) + { + for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) + { + if (visual == pDepth->vids[ivisual]) + { + fOK = TRUE; + break; + } + } + } + } + if (fOK == FALSE) + { + *error = BadMatch; + return NullWindow; + } + } + + if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) && + (class != InputOnly) && + (depth != pParent->drawable.depth)) + { + *error = BadMatch; + return NullWindow; + } + + if (((vmask & CWColormap) == 0) && + (class != InputOnly) && + ((visual != ancwopt->visual) || (ancwopt->colormap == None))) + { + *error = BadMatch; + return NullWindow; + } + + pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); + if (!pWin) + { + *error = BadAlloc; + return NullWindow; + } + pWin->drawable = pParent->drawable; + pWin->drawable.depth = depth; + if (depth == pParent->drawable.depth) + pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; + else + { + for (format = screenInfo.formats; format->depth != depth; format++) + ; + pWin->drawable.bitsPerPixel = format->bitsPerPixel; + } + if (class == InputOnly) + pWin->drawable.type = (short) UNDRAWABLE_WINDOW; + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + pWin->drawable.id = wid; + pWin->drawable.class = class; + + pWin->parent = pParent; + SetWindowToDefaults(pWin); + + if (visual != ancwopt->visual) + { + if (!MakeWindowOptional (pWin)) + { + dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); + *error = BadAlloc; + return NullWindow; + } + pWin->optional->visual = visual; + pWin->optional->colormap = None; + } + + pWin->borderWidth = bw; + + /* security creation/labeling check + */ + *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin, + RT_WINDOW, pWin->parent, DixCreateAccess|DixSetAttrAccess); + if (*error != Success) { + dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); + return NullWindow; + } + + pWin->backgroundState = XaceBackgroundNoneState(pWin); + pWin->background.pixel = pScreen->whitePixel; + + pWin->borderIsPixel = pParent->borderIsPixel; + pWin->border = pParent->border; + if (pWin->borderIsPixel == FALSE) + pWin->border.pixmap->refcnt++; + + pWin->origin.x = x + (int)bw; + pWin->origin.y = y + (int)bw; + pWin->drawable.width = w; + pWin->drawable.height = h; + pWin->drawable.x = pParent->drawable.x + x + (int)bw; + pWin->drawable.y = pParent->drawable.y + y + (int)bw; + + /* set up clip list correctly for unobscured WindowPtr */ + RegionNull(&pWin->clipList); + RegionNull(&pWin->borderClip); + RegionNull(&pWin->winSize); + RegionNull(&pWin->borderSize); + + pHead = RealChildHead(pParent); + if (pHead) + { + pWin->nextSib = pHead->nextSib; + if (pHead->nextSib) + pHead->nextSib->prevSib = pWin; + else + pParent->lastChild = pWin; + pHead->nextSib = pWin; + pWin->prevSib = pHead; + } + else + { + pWin->nextSib = pParent->firstChild; + if (pParent->firstChild) + pParent->firstChild->prevSib = pWin; + else + pParent->lastChild = pWin; + pParent->firstChild = pWin; + } + + SetWinSize (pWin); + SetBorderSize (pWin); + + /* We SHOULD check for an error value here XXX */ + if (!(*pScreen->CreateWindow)(pWin)) + { + *error = BadAlloc; + DeleteWindow(pWin, None); + return NullWindow; + } + /* We SHOULD check for an error value here XXX */ + (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y); + + if (!(vmask & CWEventMask)) + RecalculateDeliverableEvents(pWin); + + if (vmask) + *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin)); + else + *error = Success; + + if (*error != Success) + { + DeleteWindow(pWin, None); + return NullWindow; + } + if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) + { + XID value = defaultBackingStore; + (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin)); + pWin->forcedBS = TRUE; + } + + if (SubSend(pParent)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = CreateNotify; + event.u.createNotify.window = wid; + event.u.createNotify.parent = pParent->drawable.id; + event.u.createNotify.x = x; + event.u.createNotify.y = y; + event.u.createNotify.width = w; + event.u.createNotify.height = h; + event.u.createNotify.borderWidth = bw; + event.u.createNotify.override = pWin->overrideRedirect; + DeliverEvents(pParent, &event, 1, NullWindow); + } + return pWin; +} + +static void +DisposeWindowOptional (WindowPtr pWin) +{ + if (!pWin->optional) + return; + /* + * everything is peachy. Delete the optional record + * and clean up + */ + if (pWin->optional->cursor) + { + FreeCursor (pWin->optional->cursor, (Cursor)0); + pWin->cursorIsNone = FALSE; + } + else + pWin->cursorIsNone = TRUE; + + if (pWin->optional->deviceCursors) + { + DevCursorList pList; + DevCursorList pPrev; + pList = pWin->optional->deviceCursors; + while(pList) + { + if (pList->cursor) + FreeCursor(pList->cursor, (XID)0); + pPrev = pList; + pList = pList->next; + free(pPrev); + } + pWin->optional->deviceCursors = NULL; + } + + free(pWin->optional); + pWin->optional = NULL; +} + +static void +FreeWindowResources(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + DeleteWindowFromAnySaveSet(pWin); + DeleteWindowFromAnySelections(pWin); + DeleteWindowFromAnyEvents(pWin, TRUE); + RegionUninit(&pWin->clipList); + RegionUninit(&pWin->winSize); + RegionUninit(&pWin->borderClip); + RegionUninit(&pWin->borderSize); + if (wBoundingShape (pWin)) + RegionDestroy(wBoundingShape (pWin)); + if (wClipShape (pWin)) + RegionDestroy(wClipShape (pWin)); + if (wInputShape (pWin)) + RegionDestroy(wInputShape (pWin)); + if (pWin->borderIsPixel == FALSE) + (*pScreen->DestroyPixmap)(pWin->border.pixmap); + if (pWin->backgroundState == BackgroundPixmap) + (*pScreen->DestroyPixmap)(pWin->background.pixmap); + + DeleteAllWindowProperties(pWin); + /* We SHOULD check for an error value here XXX */ + (*pScreen->DestroyWindow)(pWin); + DisposeWindowOptional (pWin); +} + +static void +CrushTree(WindowPtr pWin) +{ + WindowPtr pChild, pSib, pParent; + UnrealizeWindowProcPtr UnrealizeWindow; + xEvent event; + + if (!(pChild = pWin->firstChild)) + return; + UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; + while (1) + { + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + while (1) + { + pParent = pChild->parent; + if (SubStrSend(pChild, pParent)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = DestroyNotify; + event.u.destroyNotify.window = pChild->drawable.id; + DeliverEvents(pChild, &event, 1, NullWindow); + } + FreeResource(pChild->drawable.id, RT_WINDOW); + pSib = pChild->nextSib; + pChild->viewable = FALSE; + if (pChild->realized) + { + pChild->realized = FALSE; + (*UnrealizeWindow)(pChild); + } + FreeWindowResources(pChild); + dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW); + if ( (pChild = pSib) ) + break; + pChild = pParent; + pChild->firstChild = NullWindow; + pChild->lastChild = NullWindow; + if (pChild == pWin) + return; + } + } +} + +/***** + * DeleteWindow + * Deletes child of window then window itself + * If wid is None, don't send any events + *****/ + +int +DeleteWindow(pointer value, XID wid) + { + WindowPtr pParent; + WindowPtr pWin = (WindowPtr)value; + xEvent event; + + UnmapWindow(pWin, FALSE); + + CrushTree(pWin); + + pParent = pWin->parent; + if (wid && pParent && SubStrSend(pWin, pParent)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = DestroyNotify; + event.u.destroyNotify.window = pWin->drawable.id; + DeliverEvents(pWin, &event, 1, NullWindow); + } + + FreeWindowResources(pWin); + if (pParent) + { + if (pParent->firstChild == pWin) + pParent->firstChild = pWin->nextSib; + if (pParent->lastChild == pWin) + pParent->lastChild = pWin->prevSib; + if (pWin->nextSib) + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + } + else + pWin->drawable.pScreen->root = NULL; + dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); + return Success; +} + +int +DestroySubwindows(WindowPtr pWin, ClientPtr client) +{ + /* XXX + * The protocol is quite clear that each window should be + * destroyed in turn, however, unmapping all of the first + * eliminates most of the calls to ValidateTree. So, + * this implementation is incorrect in that all of the + * UnmapNotifies occur before all of the DestroyNotifies. + * If you care, simply delete the call to UnmapSubwindows. + */ + UnmapSubwindows(pWin); + while (pWin->lastChild) { + int rc = XaceHook(XACE_RESOURCE_ACCESS, client, + pWin->lastChild->drawable.id, RT_WINDOW, + pWin->lastChild, RT_NONE, NULL, DixDestroyAccess); + if (rc != Success) + return rc; + FreeResource(pWin->lastChild->drawable.id, RT_NONE); + } + return Success; +} + +static void +SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) +{ + /* following the protocol: "Changing the background of a root window to + * None or ParentRelative restores the default background pixmap" */ + if (bgNoneRoot) { + pWin->backgroundState = XaceBackgroundNoneState(pWin); + pWin->background.pixel = pScreen->whitePixel; + } + else if (party_like_its_1989) + MakeRootTile(pWin); + else { + if (whiteRoot) + pWin->background.pixel = pScreen->whitePixel; + else + pWin->background.pixel = pScreen->blackPixel; + *index2 = CWBackPixel; + } +} + +/***** + * ChangeWindowAttributes + * + * The value-mask specifies which attributes are to be changed; the + * value-list contains one value for each one bit in the mask, from least + * to most significant bit in the mask. + *****/ + +int +ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) +{ + XID *pVlist; + PixmapPtr pPixmap; + Pixmap pixID; + CursorPtr pCursor, pOldCursor; + Cursor cursorID; + WindowPtr pChild; + Colormap cmap; + ColormapPtr pCmap; + xEvent xE; + int error, rc; + ScreenPtr pScreen; + Mask index2, tmask, vmaskCopy = 0; + unsigned int val; + Bool checkOptional = FALSE, borderRelative = FALSE; + + if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK))) + return BadMatch; + + error = Success; + pScreen = pWin->drawable.pScreen; + pVlist = vlist; + tmask = vmask; + while (tmask) + { + index2 = (Mask) lowbit (tmask); + tmask &= ~index2; + switch (index2) + { + case CWBackPixmap: + pixID = (Pixmap )*pVlist; + pVlist++; + if (pWin->backgroundState == ParentRelative) + borderRelative = TRUE; + if (pixID == None) + { + if (pWin->backgroundState == BackgroundPixmap) + (*pScreen->DestroyPixmap)(pWin->background.pixmap); + if (!pWin->parent) + SetRootWindowBackground(pWin, pScreen, &index2); + else { + pWin->backgroundState = XaceBackgroundNoneState(pWin); + pWin->background.pixel = pScreen->whitePixel; + } + } + else if (pixID == ParentRelative) + { + if (pWin->parent && + pWin->drawable.depth != pWin->parent->drawable.depth) + { + error = BadMatch; + goto PatchUp; + } + if (pWin->backgroundState == BackgroundPixmap) + (*pScreen->DestroyPixmap)(pWin->background.pixmap); + if (!pWin->parent) + SetRootWindowBackground(pWin, pScreen, &index2); + else + pWin->backgroundState = ParentRelative; + borderRelative = TRUE; + /* Note that the parent's backgroundTile's refcnt is NOT + * incremented. */ + } + else + { + rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, + client, DixReadAccess); + if (rc == Success) + { + if ((pPixmap->drawable.depth != pWin->drawable.depth) || + (pPixmap->drawable.pScreen != pScreen)) + { + error = BadMatch; + goto PatchUp; + } + if (pWin->backgroundState == BackgroundPixmap) + (*pScreen->DestroyPixmap)(pWin->background.pixmap); + pWin->backgroundState = BackgroundPixmap; + pWin->background.pixmap = pPixmap; + pPixmap->refcnt++; + } + else + { + error = rc; + client->errorValue = pixID; + goto PatchUp; + } + } + break; + case CWBackPixel: + if (pWin->backgroundState == ParentRelative) + borderRelative = TRUE; + if (pWin->backgroundState == BackgroundPixmap) + (*pScreen->DestroyPixmap)(pWin->background.pixmap); + pWin->backgroundState = BackgroundPixel; + pWin->background.pixel = (CARD32 ) *pVlist; + /* background pixel overrides background pixmap, + so don't let the ddx layer see both bits */ + vmaskCopy &= ~CWBackPixmap; + pVlist++; + break; + case CWBorderPixmap: + pixID = (Pixmap ) *pVlist; + pVlist++; + if (pixID == CopyFromParent) + { + if (!pWin->parent || + (pWin->drawable.depth != pWin->parent->drawable.depth)) + { + error = BadMatch; + goto PatchUp; + } + if (pWin->parent->borderIsPixel == TRUE) { + if (pWin->borderIsPixel == FALSE) + (*pScreen->DestroyPixmap)(pWin->border.pixmap); + pWin->border = pWin->parent->border; + pWin->borderIsPixel = TRUE; + index2 = CWBorderPixel; + break; + } + else + { + pixID = pWin->parent->border.pixmap->drawable.id; + } + } + rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, + client, DixReadAccess); + if (rc == Success) + { + if ((pPixmap->drawable.depth != pWin->drawable.depth) || + (pPixmap->drawable.pScreen != pScreen)) + { + error = BadMatch; + goto PatchUp; + } + if (pWin->borderIsPixel == FALSE) + (*pScreen->DestroyPixmap)(pWin->border.pixmap); + pWin->borderIsPixel = FALSE; + pWin->border.pixmap = pPixmap; + pPixmap->refcnt++; + } + else + { + error = rc; + client->errorValue = pixID; + goto PatchUp; + } + break; + case CWBorderPixel: + if (pWin->borderIsPixel == FALSE) + (*pScreen->DestroyPixmap)(pWin->border.pixmap); + pWin->borderIsPixel = TRUE; + pWin->border.pixel = (CARD32) *pVlist; + /* border pixel overrides border pixmap, + so don't let the ddx layer see both bits */ + vmaskCopy &= ~CWBorderPixmap; + pVlist++; + break; + case CWBitGravity: + val = (CARD8 )*pVlist; + pVlist++; + if (val > StaticGravity) + { + error = BadValue; + client->errorValue = val; + goto PatchUp; + } + pWin->bitGravity = val; + break; + case CWWinGravity: + val = (CARD8 )*pVlist; + pVlist++; + if (val > StaticGravity) + { + error = BadValue; + client->errorValue = val; + goto PatchUp; + } + pWin->winGravity = val; + break; + case CWBackingStore: + val = (CARD8 )*pVlist; + pVlist++; + if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) + { + error = BadValue; + client->errorValue = val; + goto PatchUp; + } + pWin->backingStore = val; + pWin->forcedBS = FALSE; + break; + case CWBackingPlanes: + if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) { + if (!pWin->optional && !MakeWindowOptional (pWin)) + { + error = BadAlloc; + goto PatchUp; + } + pWin->optional->backingBitPlanes = (CARD32) *pVlist; + if ((CARD32)*pVlist == (CARD32)~0L) + checkOptional = TRUE; + } + pVlist++; + break; + case CWBackingPixel: + if (pWin->optional || (CARD32) *pVlist) { + if (!pWin->optional && !MakeWindowOptional (pWin)) + { + error = BadAlloc; + goto PatchUp; + } + pWin->optional->backingPixel = (CARD32) *pVlist; + if (!*pVlist) + checkOptional = TRUE; + } + pVlist++; + break; + case CWSaveUnder: + val = (BOOL) *pVlist; + pVlist++; + if ((val != xTrue) && (val != xFalse)) + { + error = BadValue; + client->errorValue = val; + goto PatchUp; + } + pWin->saveUnder = val; + break; + case CWEventMask: + rc = EventSelectForWindow(pWin, client, (Mask )*pVlist); + if (rc) + { + error = rc; + goto PatchUp; + } + pVlist++; + break; + case CWDontPropagate: + rc = EventSuppressForWindow(pWin, client, (Mask )*pVlist, + &checkOptional); + if (rc) + { + error = rc; + goto PatchUp; + } + pVlist++; + break; + case CWOverrideRedirect: + val = (BOOL ) *pVlist; + pVlist++; + if ((val != xTrue) && (val != xFalse)) + { + error = BadValue; + client->errorValue = val; + goto PatchUp; + } + if (val == xTrue) { + rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, + RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess); + if (rc != Success) { + error = rc; + client->errorValue = pWin->drawable.id; + goto PatchUp; + } + } + pWin->overrideRedirect = val; + break; + case CWColormap: + cmap = (Colormap) *pVlist; + pVlist++; + if (cmap == CopyFromParent) + { + if (pWin->parent && + (!pWin->optional || + pWin->optional->visual == wVisual (pWin->parent))) + { + cmap = wColormap (pWin->parent); + } + else + cmap = None; + } + if (cmap == None) + { + error = BadMatch; + goto PatchUp; + } + rc = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, + client, DixUseAccess); + if (rc != Success) + { + error = rc; + client->errorValue = cmap; + goto PatchUp; + } + if (pCmap->pVisual->vid != wVisual (pWin) || + pCmap->pScreen != pScreen) + { + error = BadMatch; + goto PatchUp; + } + if (cmap != wColormap (pWin)) + { + if (!pWin->optional) + { + if (!MakeWindowOptional (pWin)) + { + error = BadAlloc; + goto PatchUp; + } + } + else if (pWin->parent && cmap == wColormap (pWin->parent)) + checkOptional = TRUE; + + /* + * propagate the original colormap to any children + * inheriting it + */ + + for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) + { + if (!pChild->optional && !MakeWindowOptional (pChild)) + { + error = BadAlloc; + goto PatchUp; + } + } + + pWin->optional->colormap = cmap; + + /* + * check on any children now matching the new colormap + */ + + for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) + { + if (pChild->optional->colormap == cmap) + CheckWindowOptionalNeed (pChild); + } + + xE.u.u.type = ColormapNotify; + xE.u.colormap.window = pWin->drawable.id; + xE.u.colormap.colormap = cmap; + xE.u.colormap.new = xTrue; + xE.u.colormap.state = IsMapInstalled(cmap, pWin); + DeliverEvents(pWin, &xE, 1, NullWindow); + } + break; + case CWCursor: + cursorID = (Cursor ) *pVlist; + pVlist++; + /* + * install the new + */ + if ( cursorID == None) + { + if (pWin == pWin->drawable.pScreen->root) + pCursor = rootCursor; + else + pCursor = (CursorPtr) None; + } + else + { + rc = dixLookupResourceByType((pointer *)&pCursor, cursorID, + RT_CURSOR, client, DixUseAccess); + if (rc != Success) + { + error = rc; + client->errorValue = cursorID; + goto PatchUp; + } + } + + if (pCursor != wCursor (pWin)) + { + /* + * patch up child windows so they don't lose cursors. + */ + + for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) + { + if (!pChild->optional && !pChild->cursorIsNone && + !MakeWindowOptional (pChild)) + { + error = BadAlloc; + goto PatchUp; + } + } + + pOldCursor = 0; + if (pCursor == (CursorPtr) None) + { + pWin->cursorIsNone = TRUE; + if (pWin->optional) + { + pOldCursor = pWin->optional->cursor; + pWin->optional->cursor = (CursorPtr) None; + checkOptional = TRUE; + } + } else { + if (!pWin->optional) + { + if (!MakeWindowOptional (pWin)) + { + error = BadAlloc; + goto PatchUp; + } + } + else if (pWin->parent && pCursor == wCursor (pWin->parent)) + checkOptional = TRUE; + pOldCursor = pWin->optional->cursor; + pWin->optional->cursor = pCursor; + pCursor->refcnt++; + pWin->cursorIsNone = FALSE; + /* + * check on any children now matching the new cursor + */ + + for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib) + { + if (pChild->optional && + (pChild->optional->cursor == pCursor)) + CheckWindowOptionalNeed (pChild); + } + } + + if (pWin->realized) + WindowHasNewCursor( pWin); + + /* Can't free cursor until here - old cursor + * is needed in WindowHasNewCursor + */ + if (pOldCursor) + FreeCursor (pOldCursor, (Cursor)0); + } + break; + default: + error = BadValue; + client->errorValue = vmask; + goto PatchUp; + } + vmaskCopy |= index2; + } +PatchUp: + if (checkOptional) + CheckWindowOptionalNeed (pWin); + + /* We SHOULD check for an error value here XXX */ + (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy); + + /* + If the border contents have changed, redraw the border. + Note that this has to be done AFTER pScreen->ChangeWindowAttributes + for the tile to be rotated, and the correct function selected. + */ + if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) + && pWin->viewable && HasBorder (pWin)) + { + RegionRec exposed; + + RegionNull(&exposed); + RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); + miPaintWindow(pWin, &exposed, PW_BORDER); + RegionUninit(&exposed); + } + return error; +} + + +/***** + * GetWindowAttributes + * Notice that this is different than ChangeWindowAttributes + *****/ + +void +GetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa) +{ + wa->type = X_Reply; + wa->bitGravity = pWin->bitGravity; + wa->winGravity = pWin->winGravity; + if (pWin->forcedBS && pWin->backingStore != Always) + wa->backingStore = NotUseful; + else + wa->backingStore = pWin->backingStore; + wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - + sizeof(xGenericReply)); + wa->sequenceNumber = client->sequence; + wa->backingBitPlanes = wBackingBitPlanes (pWin); + wa->backingPixel = wBackingPixel (pWin); + wa->saveUnder = (BOOL)pWin->saveUnder; + wa->override = pWin->overrideRedirect; + if (!pWin->mapped) + wa->mapState = IsUnmapped; + else if (pWin->realized) + wa->mapState = IsViewable; + else + wa->mapState = IsUnviewable; + + wa->colormap = wColormap (pWin); + wa->mapInstalled = (wa->colormap == None) ? xFalse + : IsMapInstalled(wa->colormap, pWin); + + wa->yourEventMask = EventMaskForClient(pWin, client); + wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin); + wa->doNotPropagateMask = wDontPropagateMask (pWin); + wa->class = pWin->drawable.class; + wa->visualID = wVisual (pWin); +} + + +WindowPtr +MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) +{ + WindowPtr pParent = pWin->parent; + WindowPtr pFirstChange = pWin; /* highest window where list changes */ + + if (pWin->nextSib != pNextSib) + { + WindowPtr pOldNextSib = pWin->nextSib; + + if (!pNextSib) /* move to bottom */ + { + if (pParent->firstChild == pWin) + pParent->firstChild = pWin->nextSib; + /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL + * and pWin->nextSib != pNextSib + * therefore pWin->nextSib != NULL */ + pFirstChange = pWin->nextSib; + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + pParent->lastChild->nextSib = pWin; + pWin->prevSib = pParent->lastChild; + pWin->nextSib = NullWindow; + pParent->lastChild = pWin; + } + else if (pParent->firstChild == pNextSib) /* move to top */ + { + pFirstChange = pWin; + if (pParent->lastChild == pWin) + pParent->lastChild = pWin->prevSib; + if (pWin->nextSib) + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + pWin->nextSib = pParent->firstChild; + pWin->prevSib = (WindowPtr ) NULL; + pNextSib->prevSib = pWin; + pParent->firstChild = pWin; + } + else /* move in middle of list */ + { + WindowPtr pOldNext = pWin->nextSib; + + pFirstChange = NullWindow; + if (pParent->firstChild == pWin) + pFirstChange = pParent->firstChild = pWin->nextSib; + if (pParent->lastChild == pWin) { + pFirstChange = pWin; + pParent->lastChild = pWin->prevSib; + } + if (pWin->nextSib) + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + pWin->nextSib = pNextSib; + pWin->prevSib = pNextSib->prevSib; + if (pNextSib->prevSib) + pNextSib->prevSib->nextSib = pWin; + pNextSib->prevSib = pWin; + if (!pFirstChange) { /* do we know it yet? */ + pFirstChange = pParent->firstChild; /* no, search from top */ + while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) + pFirstChange = pFirstChange->nextSib; + } + } + if(pWin->drawable.pScreen->RestackWindow) + (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib); + } + +#ifdef ROOTLESS + /* + * In rootless mode we can't optimize away window restacks. + * There may be non-X windows around, so even if the window + * is in the correct position from X's point of view, + * the underlying window system may want to reorder it. + */ + else if (pWin->drawable.pScreen->RestackWindow) + (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib); +#endif + + return pFirstChange; +} + +void +SetWinSize (WindowPtr pWin) +{ +#ifdef COMPOSITE + if (pWin->redirectDraw != RedirectDrawNone) + { + BoxRec box; + + /* + * Redirected clients get clip list equal to their + * own geometry, not clipped to their parent + */ + box.x1 = pWin->drawable.x; + box.y1 = pWin->drawable.y; + box.x2 = pWin->drawable.x + pWin->drawable.width; + box.y2 = pWin->drawable.y + pWin->drawable.height; + RegionReset(&pWin->winSize, &box); + } + else +#endif + ClippedRegionFromBox(pWin->parent, &pWin->winSize, + pWin->drawable.x, pWin->drawable.y, + (int)pWin->drawable.width, + (int)pWin->drawable.height); + if (wBoundingShape (pWin) || wClipShape (pWin)) { + RegionTranslate(&pWin->winSize, - pWin->drawable.x, + - pWin->drawable.y); + if (wBoundingShape (pWin)) + RegionIntersect(&pWin->winSize, &pWin->winSize, + wBoundingShape (pWin)); + if (wClipShape (pWin)) + RegionIntersect(&pWin->winSize, &pWin->winSize, + wClipShape (pWin)); + RegionTranslate(&pWin->winSize, pWin->drawable.x, + pWin->drawable.y); + } +} + +void +SetBorderSize (WindowPtr pWin) +{ + int bw; + + if (HasBorder (pWin)) { + bw = wBorderWidth (pWin); +#ifdef COMPOSITE + if (pWin->redirectDraw != RedirectDrawNone) + { + BoxRec box; + + /* + * Redirected clients get clip list equal to their + * own geometry, not clipped to their parent + */ + box.x1 = pWin->drawable.x - bw; + box.y1 = pWin->drawable.y - bw; + box.x2 = pWin->drawable.x + pWin->drawable.width + bw; + box.y2 = pWin->drawable.y + pWin->drawable.height + bw; + RegionReset(&pWin->borderSize, &box); + } + else +#endif + ClippedRegionFromBox(pWin->parent, &pWin->borderSize, + pWin->drawable.x - bw, pWin->drawable.y - bw, + (int)(pWin->drawable.width + (bw<<1)), + (int)(pWin->drawable.height + (bw<<1))); + if (wBoundingShape (pWin)) { + RegionTranslate(&pWin->borderSize, - pWin->drawable.x, + - pWin->drawable.y); + RegionIntersect(&pWin->borderSize, &pWin->borderSize, + wBoundingShape (pWin)); + RegionTranslate(&pWin->borderSize, pWin->drawable.x, + pWin->drawable.y); + RegionUnion(&pWin->borderSize, &pWin->borderSize, + &pWin->winSize); + } + } else { + RegionCopy(&pWin->borderSize, &pWin->winSize); + } +} + +/** + * + * \param x,y new window position + * \param oldx,oldy old window position + * \param destx,desty position relative to gravity + */ + +void +GravityTranslate (int x, int y, int oldx, int oldy, + int dw, int dh, unsigned gravity, + int *destx, int *desty) +{ + switch (gravity) { + case NorthGravity: + *destx = x + dw / 2; + *desty = y; + break; + case NorthEastGravity: + *destx = x + dw; + *desty = y; + break; + case WestGravity: + *destx = x; + *desty = y + dh / 2; + break; + case CenterGravity: + *destx = x + dw / 2; + *desty = y + dh / 2; + break; + case EastGravity: + *destx = x + dw; + *desty = y + dh / 2; + break; + case SouthWestGravity: + *destx = x; + *desty = y + dh; + break; + case SouthGravity: + *destx = x + dw / 2; + *desty = y + dh; + break; + case SouthEastGravity: + *destx = x + dw; + *desty = y + dh; + break; + case StaticGravity: + *destx = oldx; + *desty = oldy; + break; + default: + *destx = x; + *desty = y; + break; + } +} + +/* XXX need to retile border on each window with ParentRelative origin */ +void +ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) +{ + ScreenPtr pScreen; + WindowPtr pSib, pChild; + Bool resized = (dw || dh); + + pScreen = pWin->drawable.pScreen; + + for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) + { + if (resized && (pSib->winGravity > NorthWestGravity)) + { + int cwsx, cwsy; + + cwsx = pSib->origin.x; + cwsy = pSib->origin.y; + GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, + pSib->winGravity, &cwsx, &cwsy); + if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) + { + xEvent event; + + event.u.u.type = GravityNotify; + event.u.gravity.window = pSib->drawable.id; + event.u.gravity.x = cwsx - wBorderWidth (pSib); + event.u.gravity.y = cwsy - wBorderWidth (pSib); + DeliverEvents (pSib, &event, 1, NullWindow); + pSib->origin.x = cwsx; + pSib->origin.y = cwsy; + } + } + pSib->drawable.x = pWin->drawable.x + pSib->origin.x; + pSib->drawable.y = pWin->drawable.y + pSib->origin.y; + SetWinSize (pSib); + SetBorderSize (pSib); + (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y); + + if ( (pChild = pSib->firstChild) ) + { + while (1) + { + pChild->drawable.x = pChild->parent->drawable.x + + pChild->origin.x; + pChild->drawable.y = pChild->parent->drawable.y + + pChild->origin.y; + SetWinSize (pChild); + SetBorderSize (pChild); + (*pScreen->PositionWindow)(pChild, + pChild->drawable.x, pChild->drawable.y); + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + while (!pChild->nextSib && (pChild != pSib)) + pChild = pChild->parent; + if (pChild == pSib) + break; + pChild = pChild->nextSib; + } + } + } +} + +#define GET_INT16(m, f) \ + if (m & mask) \ + { \ + f = (INT16) *pVlist;\ + pVlist++; \ + } +#define GET_CARD16(m, f) \ + if (m & mask) \ + { \ + f = (CARD16) *pVlist;\ + pVlist++;\ + } + +#define GET_CARD8(m, f) \ + if (m & mask) \ + { \ + f = (CARD8) *pVlist;\ + pVlist++;\ + } + +#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight)) + +#define IllegalInputOnlyConfigureMask (CWBorderWidth) + +/* + * IsSiblingAboveMe + * returns Above if pSib above pMe in stack or Below otherwise + */ + +static int +IsSiblingAboveMe( + WindowPtr pMe, + WindowPtr pSib) +{ + WindowPtr pWin; + + pWin = pMe->parent->firstChild; + while (pWin) + { + if (pWin == pSib) + return Above; + else if (pWin == pMe) + return Below; + pWin = pWin->nextSib; + } + return Below; +} + +static BoxPtr +WindowExtents( + WindowPtr pWin, + BoxPtr pBox) +{ + pBox->x1 = pWin->drawable.x - wBorderWidth (pWin); + pBox->y1 = pWin->drawable.y - wBorderWidth (pWin); + pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width + + wBorderWidth (pWin); + pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height + + wBorderWidth (pWin); + return pBox; +} + +#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL) + +static RegionPtr +MakeBoundingRegion ( + WindowPtr pWin, + BoxPtr pBox) +{ + RegionPtr pRgn = RegionCreate(pBox, 1); + if (wBoundingShape (pWin)) { + RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); + RegionIntersect(pRgn, pRgn, wBoundingShape (pWin)); + RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); + } + return pRgn; +} + +static Bool +ShapeOverlap ( + WindowPtr pWin, + BoxPtr pWinBox, + WindowPtr pSib, + BoxPtr pSibBox) +{ + RegionPtr pWinRgn, pSibRgn; + Bool ret; + + if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib)) + return TRUE; + pWinRgn = MakeBoundingRegion (pWin, pWinBox); + pSibRgn = MakeBoundingRegion (pSib, pSibBox); + RegionIntersect(pWinRgn, pWinRgn, pSibRgn); + ret = RegionNotEmpty(pWinRgn); + RegionDestroy(pWinRgn); + RegionDestroy(pSibRgn); + return ret; +} + +static Bool +AnyWindowOverlapsMe( + WindowPtr pWin, + WindowPtr pHead, + BoxPtr box) +{ + WindowPtr pSib; + BoxRec sboxrec; + BoxPtr sbox; + + for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) + { + if (pSib->mapped) + { + sbox = WindowExtents(pSib, &sboxrec); + if (BOXES_OVERLAP(sbox, box) + && ShapeOverlap (pWin, box, pSib, sbox) + ) + return TRUE; + } + } + return FALSE; +} + +static Bool +IOverlapAnyWindow( + WindowPtr pWin, + BoxPtr box) +{ + WindowPtr pSib; + BoxRec sboxrec; + BoxPtr sbox; + + for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) + { + if (pSib->mapped) + { + sbox = WindowExtents(pSib, &sboxrec); + if (BOXES_OVERLAP(sbox, box) + && ShapeOverlap (pWin, box, pSib, sbox) + ) + return TRUE; + } + } + return FALSE; +} + +/* + * WhereDoIGoInTheStack() + * Given pWin and pSib and the relationshipe smode, return + * the window that pWin should go ABOVE. + * If a pSib is specified: + * Above: pWin is placed just above pSib + * Below: pWin is placed just below pSib + * TopIf: if pSib occludes pWin, then pWin is placed + * at the top of the stack + * BottomIf: if pWin occludes pSib, then pWin is + * placed at the bottom of the stack + * Opposite: if pSib occludes pWin, then pWin is placed at the + * top of the stack, else if pWin occludes pSib, then + * pWin is placed at the bottom of the stack + * + * If pSib is NULL: + * Above: pWin is placed at the top of the stack + * Below: pWin is placed at the bottom of the stack + * TopIf: if any sibling occludes pWin, then pWin is placed at + * the top of the stack + * BottomIf: if pWin occludes any sibline, then pWin is placed at + * the bottom of the stack + * Opposite: if any sibling occludes pWin, then pWin is placed at + * the top of the stack, else if pWin occludes any + * sibling, then pWin is placed at the bottom of the stack + * + */ + +static WindowPtr +WhereDoIGoInTheStack( + WindowPtr pWin, + WindowPtr pSib, + short x, + short y, + unsigned short w, + unsigned short h, + int smode) +{ + BoxRec box; + WindowPtr pHead, pFirst; + + if ((pWin == pWin->parent->firstChild) && + (pWin == pWin->parent->lastChild)) + return((WindowPtr ) NULL); + pHead = RealChildHead(pWin->parent); + pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; + box.x1 = x; + box.y1 = y; + box.x2 = x + (int)w; + box.y2 = y + (int)h; + switch (smode) + { + case Above: + if (pSib) + return pSib; + else if (pWin == pFirst) + return pWin->nextSib; + else + return pFirst; + case Below: + if (pSib) + if (pSib->nextSib != pWin) + return pSib->nextSib; + else + return pWin->nextSib; + else + return NullWindow; + case TopIf: + if ((!pWin->mapped || (pSib && !pSib->mapped))) + return pWin->nextSib; + else if (pSib) + { + if ((IsSiblingAboveMe(pWin, pSib) == Above) && + (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) + return pFirst; + else + return pWin->nextSib; + } + else if (AnyWindowOverlapsMe(pWin, pHead, &box)) + return pFirst; + else + return pWin->nextSib; + case BottomIf: + if ((!pWin->mapped || (pSib && !pSib->mapped))) + return pWin->nextSib; + else if (pSib) + { + if ((IsSiblingAboveMe(pWin, pSib) == Below) && + (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) + return NullWindow; + else + return pWin->nextSib; + } + else if (IOverlapAnyWindow(pWin, &box)) + return NullWindow; + else + return pWin->nextSib; + case Opposite: + if ((!pWin->mapped || (pSib && !pSib->mapped))) + return pWin->nextSib; + else if (pSib) + { + if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) + { + if (IsSiblingAboveMe(pWin, pSib) == Above) + return pFirst; + else + return NullWindow; + } + else + return pWin->nextSib; + } + else if (AnyWindowOverlapsMe(pWin, pHead, &box)) + { + /* If I'm occluded, I can't possibly be the first child + * if (pWin == pWin->parent->firstChild) + * return pWin->nextSib; + */ + return pFirst; + } + else if (IOverlapAnyWindow(pWin, &box)) + return NullWindow; + else + return pWin->nextSib; + default: + { + /* should never happen; make something up. */ + return pWin->nextSib; + } + } +} + +static void +ReflectStackChange( + WindowPtr pWin, + WindowPtr pSib, + VTKind kind) +{ +/* Note that pSib might be NULL */ + + Bool WasViewable = (Bool)pWin->viewable; + Bool anyMarked; + WindowPtr pFirstChange; + WindowPtr pLayerWin; + ScreenPtr pScreen = pWin->drawable.pScreen; + + /* if this is a root window, can't be restacked */ + if (!pWin->parent) + return; + + pFirstChange = MoveWindowInStack(pWin, pSib); + + if (WasViewable) + { + anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, + &pLayerWin); + if (pLayerWin != pWin) pFirstChange = pLayerWin; + if (anyMarked) + { + (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind); + (*pScreen->HandleExposures)(pLayerWin->parent); + } + if (anyMarked && pWin->drawable.pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind); + } + if (pWin->realized) + WindowsRestructured (); +} + +/***** + * ConfigureWindow + *****/ + +int +ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) +{ +#define RESTACK_WIN 0 +#define MOVE_WIN 1 +#define RESIZE_WIN 2 +#define REBORDER_WIN 3 + WindowPtr pSib = NullWindow; + WindowPtr pParent = pWin->parent; + Window sibwid = 0; + Mask index2, tmask; + XID *pVlist; + short x, y, beforeX, beforeY; + unsigned short w = pWin->drawable.width, + h = pWin->drawable.height, + bw = pWin->borderWidth; + int rc, action, smode = Above; + xEvent event; + + if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask)) + return BadMatch; + + if ((mask & CWSibling) && !(mask & CWStackMode)) + return BadMatch; + + pVlist = vlist; + + if (pParent) + { + x = pWin->drawable.x - pParent->drawable.x - (int)bw; + y = pWin->drawable.y - pParent->drawable.y - (int)bw; + } + else + { + x = pWin->drawable.x; + y = pWin->drawable.y; + } + beforeX = x; + beforeY = y; + action = RESTACK_WIN; + if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) + { + GET_INT16(CWX, x); + GET_INT16(CWY, y); + action = MOVE_WIN; + } + /* or should be resized */ + else if (mask & (CWX | CWY | CWWidth | CWHeight)) + { + GET_INT16(CWX, x); + GET_INT16(CWY, y); + GET_CARD16(CWWidth, w); + GET_CARD16 (CWHeight, h); + if (!w || !h) + { + client->errorValue = 0; + return BadValue; + } + action = RESIZE_WIN; + } + tmask = mask & ~ChangeMask; + while (tmask) + { + index2 = (Mask)lowbit (tmask); + tmask &= ~index2; + switch (index2) + { + case CWBorderWidth: + GET_CARD16(CWBorderWidth, bw); + break; + case CWSibling: + sibwid = (Window ) *pVlist; + pVlist++; + rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = sibwid; + return rc; + } + if (pSib->parent != pParent) + return BadMatch; + if (pSib == pWin) + return BadMatch; + break; + case CWStackMode: + GET_CARD8(CWStackMode, smode); + if ((smode != TopIf) && (smode != BottomIf) && + (smode != Opposite) && (smode != Above) && (smode != Below)) + { + client->errorValue = smode; + return BadValue; + } + break; + default: + client->errorValue = mask; + return BadValue; + } + } + /* root really can't be reconfigured, so just return */ + if (!pParent) + return Success; + + /* Figure out if the window should be moved. Doesnt + make the changes to the window if event sent */ + + if (mask & CWStackMode) + pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, + pParent->drawable.y + y, + w + (bw << 1), h + (bw << 1), smode); + else + pSib = pWin->nextSib; + + + if ((!pWin->overrideRedirect) && + (RedirectSend(pParent) + )) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = ConfigureRequest; + event.u.configureRequest.window = pWin->drawable.id; + if (mask & CWSibling) + event.u.configureRequest.sibling = sibwid; + else + event.u.configureRequest.sibling = None; + if (mask & CWStackMode) + event.u.u.detail = smode; + else + event.u.u.detail = Above; + event.u.configureRequest.x = x; + event.u.configureRequest.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { + event.u.configureRequest.x += screenInfo.screens[0]->x; + event.u.configureRequest.y += screenInfo.screens[0]->y; + } +#endif + event.u.configureRequest.width = w; + event.u.configureRequest.height = h; + event.u.configureRequest.borderWidth = bw; + event.u.configureRequest.valueMask = mask; + event.u.configureRequest.parent = pParent->drawable.id; + if (MaybeDeliverEventsToClient(pParent, &event, 1, + SubstructureRedirectMask, client) == 1) + return Success; + } + if (action == RESIZE_WIN) + { + Bool size_change = (w != pWin->drawable.width) + || (h != pWin->drawable.height); + if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask)) + { + xEvent eventT; + memset(&eventT, 0, sizeof(xEvent)); + eventT.u.u.type = ResizeRequest; + eventT.u.resizeRequest.window = pWin->drawable.id; + eventT.u.resizeRequest.width = w; + eventT.u.resizeRequest.height = h; + if (MaybeDeliverEventsToClient(pWin, &eventT, 1, + ResizeRedirectMask, client) == 1) + { + /* if event is delivered, leave the actual size alone. */ + w = pWin->drawable.width; + h = pWin->drawable.height; + size_change = FALSE; + } + } + if (!size_change) + { + if (mask & (CWX | CWY)) + action = MOVE_WIN; + else if (mask & (CWStackMode | CWBorderWidth)) + action = RESTACK_WIN; + else /* really nothing to do */ + return(Success) ; + } + } + + if (action == RESIZE_WIN) + /* we've already checked whether there's really a size change */ + goto ActuallyDoSomething; + if ((mask & CWX) && (x != beforeX)) + goto ActuallyDoSomething; + if ((mask & CWY) && (y != beforeY)) + goto ActuallyDoSomething; + if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin))) + goto ActuallyDoSomething; + if (mask & CWStackMode) + { +#ifndef ROOTLESS + /* See above for why we always reorder in rootless mode. */ + if (pWin->nextSib != pSib) +#endif + goto ActuallyDoSomething; + } + return Success; + +ActuallyDoSomething: + if (pWin->drawable.pScreen->ConfigNotify) + { + int ret; + ret = (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib); + if (ret) { + client->errorValue = 0; + return ret; + } + } + + if (SubStrSend(pWin, pParent)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = ConfigureNotify; + event.u.configureNotify.window = pWin->drawable.id; + if (pSib) + event.u.configureNotify.aboveSibling = pSib->drawable.id; + else + event.u.configureNotify.aboveSibling = None; + event.u.configureNotify.x = x; + event.u.configureNotify.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { + event.u.configureNotify.x += screenInfo.screens[0]->x; + event.u.configureNotify.y += screenInfo.screens[0]->y; + } +#endif + event.u.configureNotify.width = w; + event.u.configureNotify.height = h; + event.u.configureNotify.borderWidth = bw; + event.u.configureNotify.override = pWin->overrideRedirect; + DeliverEvents(pWin, &event, 1, NullWindow); + } + if (mask & CWBorderWidth) + { + if (action == RESTACK_WIN) + { + action = MOVE_WIN; + pWin->borderWidth = bw; + } + else if ((action == MOVE_WIN) && + (beforeX + wBorderWidth (pWin) == x + (int)bw) && + (beforeY + wBorderWidth (pWin) == y + (int)bw)) + { + action = REBORDER_WIN; + (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw); + } + else + pWin->borderWidth = bw; + } + if (action == MOVE_WIN) + (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib, + (mask & CWBorderWidth) ? VTOther : VTMove); + else if (action == RESIZE_WIN) + (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); + else if (mask & CWStackMode) + ReflectStackChange(pWin, pSib, VTOther); + + if (action != RESTACK_WIN) + CheckCursorConfinement(pWin); + return Success; +#undef RESTACK_WIN +#undef MOVE_WIN +#undef RESIZE_WIN +#undef REBORDER_WIN +} + + +/****** + * + * CirculateWindow + * For RaiseLowest, raises the lowest mapped child (if any) that is + * obscured by another child to the top of the stack. For LowerHighest, + * lowers the highest mapped child (if any) that is obscuring another + * child to the bottom of the stack. Exposure processing is performed + * + ******/ + +int +CirculateWindow(WindowPtr pParent, int direction, ClientPtr client) +{ + WindowPtr pWin, pHead, pFirst; + xEvent event; + BoxRec box; + + pHead = RealChildHead(pParent); + pFirst = pHead ? pHead->nextSib : pParent->firstChild; + if (direction == RaiseLowest) + { + for (pWin = pParent->lastChild; + (pWin != pHead) && + !(pWin->mapped && + AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); + pWin = pWin->prevSib) ; + if (pWin == pHead) + return Success; + } + else + { + for (pWin = pFirst; + pWin && + !(pWin->mapped && + IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); + pWin = pWin->nextSib) ; + if (!pWin) + return Success; + } + + event.u.circulate.window = pWin->drawable.id; + event.u.circulate.parent = pParent->drawable.id; + event.u.circulate.event = pParent->drawable.id; + if (direction == RaiseLowest) + event.u.circulate.place = PlaceOnTop; + else + event.u.circulate.place = PlaceOnBottom; + + if (RedirectSend(pParent)) + { + event.u.u.type = CirculateRequest; + if (MaybeDeliverEventsToClient(pParent, &event, 1, + SubstructureRedirectMask, client) == 1) + return Success; + } + + event.u.u.type = CirculateNotify; + DeliverEvents(pWin, &event, 1, NullWindow); + ReflectStackChange(pWin, + (direction == RaiseLowest) ? pFirst : NullWindow, + VTStack); + + return Success; +} + +static int +CompareWIDs( + WindowPtr pWin, + pointer value) /* must conform to VisitWindowProcPtr */ +{ + Window *wid = (Window *)value; + + if (pWin->drawable.id == *wid) + return WT_STOPWALKING; + else + return WT_WALKCHILDREN; +} + +/***** + * ReparentWindow + *****/ + +int +ReparentWindow(WindowPtr pWin, WindowPtr pParent, + int x, int y, ClientPtr client) +{ + WindowPtr pPrev, pPriorParent; + Bool WasMapped = (Bool)(pWin->mapped); + xEvent event; + int bw = wBorderWidth (pWin); + ScreenPtr pScreen; + + pScreen = pWin->drawable.pScreen; + if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING) + return BadMatch; + if (!MakeWindowOptional(pWin)) + return BadAlloc; + + if (WasMapped) + UnmapWindow(pWin, FALSE); + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = ReparentNotify; + event.u.reparent.window = pWin->drawable.id; + event.u.reparent.parent = pParent->drawable.id; + event.u.reparent.x = x; + event.u.reparent.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && !pParent->parent) { + event.u.reparent.x += screenInfo.screens[0]->x; + event.u.reparent.y += screenInfo.screens[0]->y; + } +#endif + event.u.reparent.override = pWin->overrideRedirect; + DeliverEvents(pWin, &event, 1, pParent); + + /* take out of sibling chain */ + + pPriorParent = pPrev = pWin->parent; + if (pPrev->firstChild == pWin) + pPrev->firstChild = pWin->nextSib; + if (pPrev->lastChild == pWin) + pPrev->lastChild = pWin->prevSib; + + if (pWin->nextSib) + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + + /* insert at begining of pParent */ + pWin->parent = pParent; + pPrev = RealChildHead(pParent); + if (pPrev) + { + pWin->nextSib = pPrev->nextSib; + if (pPrev->nextSib) + pPrev->nextSib->prevSib = pWin; + else + pParent->lastChild = pWin; + pPrev->nextSib = pWin; + pWin->prevSib = pPrev; + } + else + { + pWin->nextSib = pParent->firstChild; + pWin->prevSib = NullWindow; + if (pParent->firstChild) + pParent->firstChild->prevSib = pWin; + else + pParent->lastChild = pWin; + pParent->firstChild = pWin; + } + + pWin->origin.x = x + bw; + pWin->origin.y = y + bw; + pWin->drawable.x = x + bw + pParent->drawable.x; + pWin->drawable.y = y + bw + pParent->drawable.y; + + /* clip to parent */ + SetWinSize (pWin); + SetBorderSize (pWin); + + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow)(pWin, pPriorParent); + (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y); + ResizeChildrenWinSize(pWin, 0, 0, 0, 0); + + CheckWindowOptionalNeed(pWin); + + if (WasMapped) + MapWindow(pWin, client); + RecalculateDeliverableEvents(pWin); + return Success; +} + +static void +RealizeTree(WindowPtr pWin) +{ + WindowPtr pChild; + RealizeWindowProcPtr Realize; + + Realize = pWin->drawable.pScreen->RealizeWindow; + pChild = pWin; + while (1) + { + if (pChild->mapped) + { + pChild->realized = TRUE; + pChild->viewable = (pChild->drawable.class == InputOutput); + (* Realize)(pChild); + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + return; + pChild = pChild->nextSib; + } +} + +static WindowPtr windowDisableMapUnmapEvents; + +void +DisableMapUnmapEvents(WindowPtr pWin) +{ + assert (windowDisableMapUnmapEvents == NULL); + + windowDisableMapUnmapEvents = pWin; +} + +void +EnableMapUnmapEvents(WindowPtr pWin) +{ + assert (windowDisableMapUnmapEvents != NULL); + + windowDisableMapUnmapEvents = NULL; +} + +static Bool +MapUnmapEventsEnabled(WindowPtr pWin) +{ + return pWin != windowDisableMapUnmapEvents; +} + +/***** + * MapWindow + * If some other client has selected SubStructureReDirect on the parent + * and override-redirect is xFalse, then a MapRequest event is generated, + * but the window remains unmapped. Otherwise, the window is mapped and a + * MapNotify event is generated. + *****/ + +int +MapWindow(WindowPtr pWin, ClientPtr client) +{ + ScreenPtr pScreen; + + WindowPtr pParent; + WindowPtr pLayerWin; + + if (pWin->mapped) + return Success; + + /* general check for permission to map window */ + if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, + pWin, RT_NONE, NULL, DixShowAccess) != Success) + return Success; + + pScreen = pWin->drawable.pScreen; + if ( (pParent = pWin->parent) ) + { + xEvent event; + Bool anyMarked; + + if ((!pWin->overrideRedirect) && + (RedirectSend(pParent) + )) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = MapRequest; + event.u.mapRequest.window = pWin->drawable.id; + event.u.mapRequest.parent = pParent->drawable.id; + + if (MaybeDeliverEventsToClient(pParent, &event, 1, + SubstructureRedirectMask, client) == 1) + return Success; + } + + pWin->mapped = TRUE; + if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = MapNotify; + event.u.mapNotify.window = pWin->drawable.id; + event.u.mapNotify.override = pWin->overrideRedirect; + DeliverEvents(pWin, &event, 1, NullWindow); + } + + if (!pParent->realized) + return Success; + RealizeTree(pWin); + if (pWin->viewable) + { + anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, + &pLayerWin); + if (anyMarked) + { + (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap); + (*pScreen->HandleExposures)(pLayerWin->parent); + } + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap); + } + WindowsRestructured (); + } + else + { + RegionRec temp; + + pWin->mapped = TRUE; + pWin->realized = TRUE; /* for roots */ + pWin->viewable = pWin->drawable.class == InputOutput; + /* We SHOULD check for an error value here XXX */ + (*pScreen->RealizeWindow)(pWin); + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pWin, 0, 0); + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap); + RegionNull(&temp); + RegionCopy(&temp, &pWin->clipList); + (*pScreen->WindowExposures) (pWin, &temp, NullRegion); + RegionUninit(&temp); + } + + return Success; +} + + +/***** + * MapSubwindows + * Performs a MapWindow all unmapped children of the window, in top + * to bottom stacking order. + *****/ + +void +MapSubwindows(WindowPtr pParent, ClientPtr client) +{ + WindowPtr pWin; + WindowPtr pFirstMapped = NullWindow; + ScreenPtr pScreen; + Mask parentRedirect; + Mask parentNotify; + xEvent event; + Bool anyMarked; + WindowPtr pLayerWin; + + pScreen = pParent->drawable.pScreen; + parentRedirect = RedirectSend(pParent); + parentNotify = SubSend(pParent); + anyMarked = FALSE; + for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) + { + if (!pWin->mapped) + { + if (parentRedirect && !pWin->overrideRedirect) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = MapRequest; + event.u.mapRequest.window = pWin->drawable.id; + event.u.mapRequest.parent = pParent->drawable.id; + + if (MaybeDeliverEventsToClient(pParent, &event, 1, + SubstructureRedirectMask, client) == 1) + continue; + } + + pWin->mapped = TRUE; + if (parentNotify || StrSend(pWin)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = MapNotify; + event.u.mapNotify.window = pWin->drawable.id; + event.u.mapNotify.override = pWin->overrideRedirect; + DeliverEvents(pWin, &event, 1, NullWindow); + } + + if (!pFirstMapped) + pFirstMapped = pWin; + if (pParent->realized) + { + RealizeTree(pWin); + if (pWin->viewable) + { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, + (WindowPtr *)NULL); + } + } + } + } + + if (pFirstMapped) + { + pLayerWin = (*pScreen->GetLayerWindow)(pParent); + if (pLayerWin->parent != pParent) { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin, + pLayerWin, + (WindowPtr *)NULL); + pFirstMapped = pLayerWin; + } + if (anyMarked) + { + (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap); + (*pScreen->HandleExposures)(pLayerWin->parent); + } + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped, + VTMap); + WindowsRestructured (); + } +} + +static void +UnrealizeTree( + WindowPtr pWin, + Bool fromConfigure) +{ + WindowPtr pChild; + UnrealizeWindowProcPtr Unrealize; + MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; + + Unrealize = pWin->drawable.pScreen->UnrealizeWindow; + MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; + pChild = pWin; + while (1) + { + if (pChild->realized) + { + pChild->realized = FALSE; + pChild->visibility = VisibilityNotViewable; +#ifdef PANORAMIX + if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { + PanoramiXRes *win; + int rc = dixLookupResourceByType((pointer *)&win, + pChild->drawable.id, XRT_WINDOW, + serverClient, DixWriteAccess); + if (rc == Success) + win->u.win.visibility = VisibilityNotViewable; + } +#endif + (* Unrealize)(pChild); + if (MapUnmapEventsEnabled(pWin)) + DeleteWindowFromAnyEvents(pChild, FALSE); + if (pChild->viewable) + { + pChild->viewable = FALSE; + (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } + if (pChild->firstChild) + { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + return; + pChild = pChild->nextSib; + } +} + +/***** + * UnmapWindow + * If the window is already unmapped, this request has no effect. + * Otherwise, the window is unmapped and an UnMapNotify event is + * generated. Cannot unmap a root window. + *****/ + +int +UnmapWindow(WindowPtr pWin, Bool fromConfigure) +{ + WindowPtr pParent; + xEvent event; + Bool wasRealized = (Bool)pWin->realized; + Bool wasViewable = (Bool)pWin->viewable; + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pLayerWin = pWin; + + if ((!pWin->mapped) || (!(pParent = pWin->parent))) + return Success; + if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) + { + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = UnmapNotify; + event.u.unmapNotify.window = pWin->drawable.id; + event.u.unmapNotify.fromConfigure = fromConfigure; + DeliverEvents(pWin, &event, 1, NullWindow); + } + if (wasViewable && !fromConfigure) + { + pWin->valdata = UnmapValData; + (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin); + (*pScreen->MarkWindow)(pLayerWin->parent); + } + pWin->mapped = FALSE; + if (wasRealized) + UnrealizeTree(pWin, fromConfigure); + if (wasViewable) + { + if (!fromConfigure) + { + (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap); + (*pScreen->HandleExposures)(pLayerWin->parent); + } + if (!fromConfigure && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap); + } + if (wasRealized && !fromConfigure) + WindowsRestructured (); + return Success; +} + +/***** + * UnmapSubwindows + * Performs an UnmapWindow request with the specified mode on all mapped + * children of the window, in bottom to top stacking order. + *****/ + +void +UnmapSubwindows(WindowPtr pWin) +{ + WindowPtr pChild, pHead; + xEvent event; + Bool wasRealized = (Bool)pWin->realized; + Bool wasViewable = (Bool)pWin->viewable; + Bool anyMarked = FALSE; + Mask parentNotify; + WindowPtr pLayerWin = NULL; + ScreenPtr pScreen = pWin->drawable.pScreen; + + if (!pWin->firstChild) + return; + parentNotify = SubSend(pWin); + pHead = RealChildHead(pWin); + + if (wasViewable) + pLayerWin = (*pScreen->GetLayerWindow)(pWin); + + for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) + { + if (pChild->mapped) + { + if (parentNotify || StrSend(pChild)) + { + event.u.u.type = UnmapNotify; + event.u.unmapNotify.window = pChild->drawable.id; + event.u.unmapNotify.fromConfigure = xFalse; + DeliverEvents(pChild, &event, 1, NullWindow); + } + if (pChild->viewable) + { + pChild->valdata = UnmapValData; + anyMarked = TRUE; + } + pChild->mapped = FALSE; + if (pChild->realized) + UnrealizeTree(pChild, FALSE); + if (wasViewable) + { + } + } + } + if (wasViewable) + { + if (anyMarked) + { + if (pLayerWin->parent == pWin) + (*pScreen->MarkWindow)(pWin); + else + { + WindowPtr ptmp; + (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, + (WindowPtr *)NULL); + (*pScreen->MarkWindow)(pLayerWin->parent); + + /* Windows between pWin and pLayerWin may not have been marked */ + ptmp = pWin; + + while (ptmp != pLayerWin->parent) + { + (*pScreen->MarkWindow)(ptmp); + ptmp = ptmp->parent; + } + pHead = pWin->firstChild; + } + (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap); + (*pScreen->HandleExposures)(pLayerWin->parent); + } + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap); + } + if (wasRealized) + WindowsRestructured (); +} + + +void +HandleSaveSet(ClientPtr client) +{ + WindowPtr pParent, pWin; + int j; + + for (j=0; j<client->numSaved; j++) + { + pWin = SaveSetWindow(client->saveSet[j]); +#ifdef XFIXES + if (SaveSetToRoot(client->saveSet[j])) + pParent = pWin->drawable.pScreen->root; + else +#endif + { + pParent = pWin->parent; + while (pParent && (wClient (pParent) == client)) + pParent = pParent->parent; + } + if (pParent) + { + if (pParent != pWin->parent) + { +#ifdef XFIXES + /* unmap first so that ReparentWindow doesn't remap */ + if (!SaveSetShouldMap (client->saveSet[j])) + UnmapWindow(pWin, FALSE); +#endif + ReparentWindow(pWin, pParent, + pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x, + pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y, + client); + if(!pWin->realized && pWin->mapped) + pWin->mapped = FALSE; + } +#ifdef XFIXES + if (SaveSetShouldMap (client->saveSet[j])) +#endif + MapWindow(pWin, client); + } + } + free(client->saveSet); + client->numSaved = 0; + client->saveSet = (SaveSetElt *)NULL; +} + +/** + * + * \param x,y in root + */ +Bool +PointInWindowIsVisible(WindowPtr pWin, int x, int y) +{ + BoxRec box; + + if (!pWin->realized) + return FALSE; + if (RegionContainsPoint(&pWin->borderClip, + x, y, &box) + && (!wInputShape(pWin) || + RegionContainsPoint(wInputShape(pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box))) + return TRUE; + return FALSE; +} + + +RegionPtr +NotClippedByChildren(WindowPtr pWin) +{ + RegionPtr pReg = RegionCreate(NullBox, 1); + if (pWin->parent || + screenIsSaved != SCREEN_SAVER_ON || + !HasSaverWindow (pWin->drawable.pScreen)) + { + RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); + } + return pReg; +} + +void +SendVisibilityNotify(WindowPtr pWin) +{ + xEvent event; + unsigned int visibility = pWin->visibility; + + if (!MapUnmapEventsEnabled(pWin)) + return; +#ifdef PANORAMIX + /* This is not quite correct yet, but it's close */ + if(!noPanoramiXExtension) { + PanoramiXRes *win; + WindowPtr pWin2; + int rc, i, Scrnum; + + Scrnum = pWin->drawable.pScreen->myNum; + + win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); + + if(!win || (win->u.win.visibility == visibility)) + return; + + switch(visibility) { + case VisibilityUnobscured: + FOR_NSCREENS(i) { + if(i == Scrnum) continue; + + rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, + DixWriteAccess); + + if (rc == Success) { + if(pWin2->visibility == VisibilityPartiallyObscured) + return; + + if(!i) pWin = pWin2; + } + } + break; + case VisibilityPartiallyObscured: + if(Scrnum) { + rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, + DixWriteAccess); + if (rc == Success) pWin = pWin2; + } + break; + case VisibilityFullyObscured: + FOR_NSCREENS(i) { + if(i == Scrnum) continue; + + rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, + DixWriteAccess); + + if (rc == Success) { + if(pWin2->visibility != VisibilityFullyObscured) + return; + + if(!i) pWin = pWin2; + } + } + break; + } + + win->u.win.visibility = visibility; + } +#endif + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = VisibilityNotify; + event.u.visibility.window = pWin->drawable.id; + event.u.visibility.state = visibility; + DeliverEvents(pWin, &event, 1, NullWindow); +} + +#define RANDOM_WIDTH 32 +int +dixSaveScreens(ClientPtr client, int on, int mode) +{ + int rc, i, what, type; + + if (on == SCREEN_SAVER_FORCER) + { + if (mode == ScreenSaverReset) + what = SCREEN_SAVER_OFF; + else + what = SCREEN_SAVER_ON; + type = what; + } + else + { + what = on; + type = what; + if (what == screenIsSaved) + type = SCREEN_SAVER_CYCLE; + } + + for (i = 0; i < screenInfo.numScreens; i++) { + rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], + DixShowAccess | DixHideAccess); + if (rc != Success) + return rc; + } + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + if (on == SCREEN_SAVER_FORCER) + (* pScreen->SaveScreen) (pScreen, on); + if (pScreen->screensaver.ExternalScreenSaver) + { + if ((*pScreen->screensaver.ExternalScreenSaver) + (pScreen, type, on == SCREEN_SAVER_FORCER)) + continue; + } + if (type == screenIsSaved) + continue; + switch (type) { + case SCREEN_SAVER_OFF: + if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) + { + (* pScreen->SaveScreen) (pScreen, what); + } + else if (HasSaverWindow (pScreen)) + { + pScreen->screensaver.pWindow = NullWindow; + FreeResource(pScreen->screensaver.wid, RT_NONE); + } + break; + case SCREEN_SAVER_CYCLE: + if (pScreen->screensaver.blanked == SCREEN_IS_TILED) + { + WindowPtr pWin = pScreen->screensaver.pWindow; + /* make it look like screen saver is off, so that + * NotClippedByChildren will compute a clip list + * for the root window, so miPaintWindow works + */ + screenIsSaved = SCREEN_SAVER_OFF; + (*pWin->drawable.pScreen->MoveWindow)(pWin, + (short)(-(rand() % RANDOM_WIDTH)), + (short)(-(rand() % RANDOM_WIDTH)), + pWin->nextSib, VTMove); + screenIsSaved = SCREEN_SAVER_ON; + } + /* + * Call the DDX saver in case it wants to do something + * at cycle time + */ + else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) + { + (* pScreen->SaveScreen) (pScreen, type); + } + break; + case SCREEN_SAVER_ON: + if (ScreenSaverBlanking != DontPreferBlanking) + { + if ((* pScreen->SaveScreen) (pScreen, what)) + { + pScreen->screensaver.blanked = SCREEN_IS_BLANKED; + continue; + } + if ((ScreenSaverAllowExposures != DontAllowExposures) && + TileScreenSaver(pScreen, SCREEN_IS_BLACK)) + { + pScreen->screensaver.blanked = SCREEN_IS_BLACK; + continue; + } + } + if ((ScreenSaverAllowExposures != DontAllowExposures) && + TileScreenSaver(pScreen, SCREEN_IS_TILED)) + { + pScreen->screensaver.blanked = SCREEN_IS_TILED; + } + else + pScreen->screensaver.blanked = SCREEN_ISNT_SAVED; + break; + } + } + screenIsSaved = what; + if (mode == ScreenSaverReset) { + if (on == SCREEN_SAVER_FORCER) { + UpdateCurrentTimeIf(); + lastDeviceEventTime = currentTime; + } + SetScreenSaverTimer(); + } + return Success; +} + +int +SaveScreens(int on, int mode) +{ + return dixSaveScreens(serverClient, on, mode); +} + +static Bool +TileScreenSaver(ScreenPtr pScreen, int kind) +{ + int j; + int result; + XID attributes[3]; + Mask mask; + WindowPtr pWin; + CursorMetricRec cm; + unsigned char *srcbits, *mskbits; + CursorPtr cursor; + XID cursorID = 0; + int attri; + + mask = 0; + attri = 0; + switch (kind) { + case SCREEN_IS_TILED: + switch (pScreen->root->backgroundState) { + case BackgroundPixel: + attributes[attri++] = pScreen->root->background.pixel; + mask |= CWBackPixel; + break; + case BackgroundPixmap: + attributes[attri++] = None; + mask |= CWBackPixmap; + break; + default: + break; + } + break; + case SCREEN_IS_BLACK: + attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; + mask |= CWBackPixel; + break; + } + mask |= CWOverrideRedirect; + attributes[attri++] = xTrue; + + /* + * create a blank cursor + */ + + cm.width=16; + cm.height=16; + cm.xhot=8; + cm.yhot=8; + srcbits = malloc( BitmapBytePad(32)*16); + mskbits = malloc( BitmapBytePad(32)*16); + if (!srcbits || !mskbits) + { + free(srcbits); + free(mskbits); + cursor = 0; + } + else + { + for (j=0; j<BitmapBytePad(32)*16; j++) + srcbits[j] = mskbits[j] = 0x0; + result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, + &cursor, serverClient, (XID)0); + if (cursor) + { + cursorID = FakeClientID(0); + if (AddResource (cursorID, RT_CURSOR, (pointer) cursor)) + { + attributes[attri] = cursorID; + mask |= CWCursor; + } + else + cursor = 0; + } + else + { + free(srcbits); + free(mskbits); + } + } + + pWin = pScreen->screensaver.pWindow = + CreateWindow(pScreen->screensaver.wid, + pScreen->root, + -RANDOM_WIDTH, -RANDOM_WIDTH, + (unsigned short)pScreen->width + RANDOM_WIDTH, + (unsigned short)pScreen->height + RANDOM_WIDTH, + 0, InputOutput, mask, attributes, 0, serverClient, + wVisual (pScreen->root), &result); + + if (cursor) + FreeResource (cursorID, RT_NONE); + + if (!pWin) + return FALSE; + + if (!AddResource(pWin->drawable.id, RT_WINDOW, + (pointer)pScreen->screensaver.pWindow)) + return FALSE; + + if (mask & CWBackPixmap) + { + MakeRootTile (pWin); + (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap); + } + MapWindow(pWin, serverClient); + return TRUE; +} + +/* + * FindWindowWithOptional + * + * search ancestors of the given window for an entry containing + * a WindowOpt structure. Assumptions: some parent will + * contain the structure. + */ + +WindowPtr +FindWindowWithOptional (WindowPtr w) +{ + do + w = w->parent; + while (!w->optional); + return w; +} + +/* + * CheckWindowOptionalNeed + * + * check each optional entry in the given window to see if + * the value is satisfied by the default rules. If so, + * release the optional record + */ + +void +CheckWindowOptionalNeed (WindowPtr w) +{ + WindowOptPtr optional; + WindowOptPtr parentOptional; + + if (!w->parent || !w->optional) + return; + optional = w->optional; + if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) + return; + if (optional->otherEventMasks != 0) + return; + if (optional->otherClients != NULL) + return; + if (optional->passiveGrabs != NULL) + return; + if (optional->userProps != NULL) + return; + if (optional->backingBitPlanes != ~0L) + return; + if (optional->backingPixel != 0) + return; + if (optional->boundingShape != NULL) + return; + if (optional->clipShape != NULL) + return; + if (optional->inputShape != NULL) + return; + if (optional->inputMasks != NULL) + return; + if (optional->deviceCursors != NULL) + { + DevCursNodePtr pNode = optional->deviceCursors; + while(pNode) + { + if (pNode->cursor != None) + return; + pNode = pNode->next; + } + } + + parentOptional = FindWindowWithOptional(w)->optional; + if (optional->visual != parentOptional->visual) + return; + if (optional->cursor != None && + (optional->cursor != parentOptional->cursor || + w->parent->cursorIsNone)) + return; + if (optional->colormap != parentOptional->colormap) + return; + DisposeWindowOptional (w); +} + +/* + * MakeWindowOptional + * + * create an optional record and initialize it with the default + * values. + */ + +Bool +MakeWindowOptional (WindowPtr pWin) +{ + WindowOptPtr optional; + WindowOptPtr parentOptional; + + if (pWin->optional) + return TRUE; + optional = malloc(sizeof (WindowOptRec)); + if (!optional) + return FALSE; + optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; + optional->otherEventMasks = 0; + optional->otherClients = NULL; + optional->passiveGrabs = NULL; + optional->userProps = NULL; + optional->backingBitPlanes = ~0L; + optional->backingPixel = 0; + optional->boundingShape = NULL; + optional->clipShape = NULL; + optional->inputShape = NULL; + optional->inputMasks = NULL; + optional->deviceCursors = NULL; + + parentOptional = FindWindowWithOptional(pWin)->optional; + optional->visual = parentOptional->visual; + if (!pWin->cursorIsNone) + { + optional->cursor = parentOptional->cursor; + optional->cursor->refcnt++; + } + else + { + optional->cursor = None; + } + optional->colormap = parentOptional->colormap; + pWin->optional = optional; + return TRUE; +} + +/* + * Changes the cursor struct for the given device and the given window. + * A cursor that does not have a device cursor set will use whatever the + * standard cursor is for the window. If all devices have a cursor set, + * changing the window cursor (e.g. using XDefineCursor()) will not have any + * visible effect. Only when one of the device cursors is set to None again, + * this device's cursor will display the changed standard cursor. + * + * CursorIsNone of the window struct is NOT modified if you set a device + * cursor. + * + * Assumption: If there is a node for a device in the list, the device has a + * cursor. If the cursor is set to None, it is inherited by the parent. + */ +int +ChangeWindowDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCursor) +{ + DevCursNodePtr pNode, pPrev; + CursorPtr pOldCursor = NULL; + ScreenPtr pScreen; + WindowPtr pChild; + + if (!pWin->optional && !MakeWindowOptional(pWin)) + return BadAlloc; + + /* 1) Check if window has device cursor set + * Yes: 1.1) swap cursor with given cursor if parent does not have same + * cursor, free old cursor + * 1.2) free old cursor, use parent cursor + * No: 1.1) add node to beginning of list. + * 1.2) add cursor to node if parent does not have same cursor + * 1.3) use parent cursor if parent does not have same cursor + * 2) Patch up children if child has a devcursor + * 2.1) if child has cursor None, it inherited from parent, set to old + * cursor + * 2.2) if child has same cursor as new cursor, remove and set to None + */ + + pScreen = pWin->drawable.pScreen; + + if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) + { + /* has device cursor */ + + if (pNode->cursor == pCursor) + return Success; + + pOldCursor = pNode->cursor; + + if (!pCursor) /* remove from list */ + { + if(pPrev) + pPrev->next = pNode->next; + else + /* first item in list */ + pWin->optional->deviceCursors = pNode->next; + + free(pNode); + goto out; + } + + } else + { + /* no device cursor yet */ + DevCursNodePtr pNewNode; + + if (!pCursor) + return Success; + + pNewNode = malloc(sizeof(DevCursNodeRec)); + pNewNode->dev = pDev; + pNewNode->next = pWin->optional->deviceCursors; + pWin->optional->deviceCursors = pNewNode; + pNode = pNewNode; + + } + + if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) + pNode->cursor = None; + else + { + pNode->cursor = pCursor; + pCursor->refcnt++; + } + + pNode = pPrev = NULL; + /* fix up children */ + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + { + if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) + { + if (pNode->cursor == None) /* inherited from parent */ + { + pNode->cursor = pOldCursor; + pOldCursor->refcnt++; + } else if (pNode->cursor == pCursor) + { + pNode->cursor = None; + FreeCursor(pCursor, (Cursor)0); /* fix up refcnt */ + } + } + } + +out: + if (pWin->realized) + WindowHasNewCursor(pWin); + + if (pOldCursor) + FreeCursor(pOldCursor, (Cursor)0); + + /* FIXME: We SHOULD check for an error value here XXX + (comment taken from ChangeWindowAttributes) */ + (*pScreen->ChangeWindowAttributes)(pWin, CWCursor); + + return Success; +} + +/* Get device cursor for given device or None if none is set */ +CursorPtr +WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) +{ + DevCursorList pList; + + if (!pWin->optional || !pWin->optional->deviceCursors) + return NULL; + + pList = pWin->optional->deviceCursors; + + while(pList) + { + if (pList->dev == pDev) + { + if (pList->cursor == None) /* inherited from parent */ + return WindowGetDeviceCursor(pWin->parent, pDev); + else + return pList->cursor; + } + pList = pList->next; + } + return NULL; +} + +/* Searches for a DevCursorNode for the given window and device. If one is + * found, return True and set pNode and pPrev to the node and to the node + * before the node respectively. Otherwise return False. + * If the device is the first in list, pPrev is set to NULL. + */ +static Bool +WindowSeekDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + DevCursNodePtr* pNode, + DevCursNodePtr* pPrev) +{ + DevCursorList pList; + + if (!pWin->optional) + return FALSE; + + pList = pWin->optional->deviceCursors; + + if (pList && pList->dev == pDev) + { + *pNode = pList; + *pPrev = NULL; + return TRUE; + } + + while(pList) + { + if (pList->next) + { + if (pList->next->dev == pDev) + { + *pNode = pList->next; + *pPrev = pList; + return TRUE; + } + } + pList = pList->next; + } + return FALSE; +} + +/* Return True if a parent has the same device cursor set or False if + * otherwise + */ +static Bool +WindowParentHasDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCursor) +{ + WindowPtr pParent; + DevCursNodePtr pParentNode, pParentPrev; + + pParent = pWin->parent; + while(pParent) + { + if (WindowSeekDeviceCursor(pParent, pDev, + &pParentNode, &pParentPrev)) + { + /* if there is a node in the list, the win has a dev cursor */ + if (!pParentNode->cursor) /* inherited. */ + pParent = pParent->parent; + else if (pParentNode->cursor == pCursor) /* inherit */ + return TRUE; + else /* different cursor */ + return FALSE; + } + else + /* parent does not have a device cursor for our device */ + return FALSE; + } + return FALSE; +} diff --git a/xorg-server/hw/dmx/dmxcb.c b/xorg-server/hw/dmx/dmxcb.c index 4e7279a51..d0eb35117 100644 --- a/xorg-server/hw/dmx/dmxcb.c +++ b/xorg-server/hw/dmx/dmxcb.c @@ -46,6 +46,7 @@ extern int connBlockScreenStart; #ifdef PANORAMIX +#include "panoramiXsrv.h" extern int PanoramiXPixWidth; extern int PanoramiXPixHeight; extern int PanoramiXNumScreens; @@ -137,7 +138,7 @@ void dmxConnectionBlockCallback(void) } dmxLog(dmxInfo, "%d screens configured with Xinerama (%d %d)\n", PanoramiXNumScreens, PanoramiXPixWidth, PanoramiXPixHeight); - for (i = 0; i < PanoramiXNumScreens; i++) found[i] = FALSE; + FOR_NSCREENS(i) found[i] = FALSE; } else { #endif /* This never happens because we're @@ -177,7 +178,7 @@ void dmxConnectionBlockCallback(void) #ifdef PANORAMIX if (!noPanoramiXExtension) { int k; - for (k = 0; k < PanoramiXNumScreens; k++) { + FOR_NSCREENS(k) { DMXScreenInfo *dmxScreen = &dmxScreens[k]; if (dmxScreen->beDisplay) { @@ -203,7 +204,7 @@ void dmxConnectionBlockCallback(void) #ifdef PANORAMIX if (!noPanoramiXExtension) { Bool fatal = FALSE; - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { fatal |= !found[i]; if (!found[i]) { dmxLog(dmxError, diff --git a/xorg-server/hw/dmx/dmxextension.c b/xorg-server/hw/dmx/dmxextension.c index bd326ce2a..db5709ee6 100644 --- a/xorg-server/hw/dmx/dmxextension.c +++ b/xorg-server/hw/dmx/dmxextension.c @@ -703,7 +703,7 @@ static void dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type, RT_PIXMAP, NullClient, DixUnknownAccess); if (pPix != pDst) return; /* Not a match.... Next! */ - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { PixmapPtr pSrc; dmxPixPrivPtr pSrcPriv = NULL; @@ -1372,7 +1372,7 @@ static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type, RT_PIXMAP, NullClient, DixUnknownAccess); if (pPix != pDst) return; /* Not a match.... Next! */ - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { PixmapPtr pSrc; dmxPixPrivPtr pSrcPriv = NULL; diff --git a/xorg-server/hw/dmx/dmxgcops.c b/xorg-server/hw/dmx/dmxgcops.c index 8f4f5c774..500e2cdf1 100644 --- a/xorg-server/hw/dmx/dmxgcops.c +++ b/xorg-server/hw/dmx/dmxgcops.c @@ -1,605 +1,605 @@ -/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for GC operations. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxgc.h"
-#include "dmxgcops.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-
-#include "mi.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "dixfontstr.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \
-do { \
- if ((_pDraw)->type == DRAWABLE_WINDOW) { \
- dmxWinPrivPtr pWinPriv = \
- DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \
- (_draw) = (Drawable)pWinPriv->window; \
- } else { \
- dmxPixPrivPtr pPixPriv = \
- DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \
- (_draw) = (Drawable)pPixPriv->pixmap; \
- } \
-} while (0)
-
-#define DMX_GCOPS_OFFSCREEN(_pDraw) \
- (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \
- (dmxOffScreenOpt && \
- (_pDraw)->type == DRAWABLE_WINDOW && \
- (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \
- !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
-
-/** Fill spans -- this function should never be called. */
-void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
- int nInit, DDXPointPtr pptInit, int *pwidthInit,
- int fSorted)
-{
- /* Error -- this should never happen! */
-}
-
-/** Set spans -- this function should never be called. */
-void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
- char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
- int fSorted)
-{
- /* Error -- this should never happen! */
-}
-
-/** Transfer \a pBits image to back-end server associated with \a
- * pDrawable's screen. If primitive subdivision optimization is
- * enabled, then only transfer the sections of \a pBits that are
- * visible (i.e., not-clipped) to the back-end server. */
-void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
- int depth, int x, int y, int w, int h,
- int leftPad, int format, char *pBits)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- XImage *img;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- img = XCreateImage(dmxScreen->beDisplay,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- depth, format, leftPad, pBits, w, h,
- BitmapPad(dmxScreen->beDisplay),
- (format == ZPixmap) ?
- PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
-
- if (img) {
- Drawable draw;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- if (dmxSubdividePrimitives && pGC->pCompositeClip) {
- RegionPtr pSubImages;
- RegionPtr pClip;
- BoxRec box;
- BoxPtr pBox;
- int nBox;
-
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + w;
- box.y2 = y + h;
- pSubImages = RegionCreate(&box, 1);
-
- pClip = RegionCreate(NullBox, 1);
- RegionCopy(pClip, pGC->pCompositeClip);
- RegionTranslate(pClip,
- -pDrawable->x, -pDrawable->y);
- RegionIntersect(pSubImages, pSubImages, pClip);
-
- nBox = RegionNumRects(pSubImages);
- pBox = RegionRects(pSubImages);
-
- while (nBox--) {
- XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
- pBox->x1 - box.x1,
- pBox->y1 - box.y1,
- pBox->x1,
- pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1);
- pBox++;
- }
- RegionDestroy(pClip);
- RegionDestroy(pSubImages);
- } else {
- XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
- img, 0, 0, x, y, w, h);
- }
- XFree(img); /* Use XFree instead of XDestroyImage
- * because pBits is passed in from the
- * caller. */
-
- dmxSync(dmxScreen, FALSE);
- } else {
- /* Error -- this should not happen! */
- }
-}
-
-/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
- * server associated with \a pSrc drawable's screen. If the offscreen
- * optimization is enabled, only copy when both \a pSrc and \a pDst are
- * at least partially visible. */
-RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable srcDraw, dstDraw;
-
- if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, 0L);
-
- DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
- DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
-
- XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
- srcx, srcy, w, h, dstx, dsty);
- dmxSync(dmxScreen, FALSE);
-
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, 0L);
-}
-
-/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
- * drawable on the back-end server associated with \a pSrc drawable's
- * screen. If the offscreen optimization is enabled, only copy when
- * both \a pSrc and \a pDst are at least partially visible. */
-RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int width, int height,
- int dstx, int dsty, unsigned long bitPlane)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable srcDraw, dstDraw;
-
- if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
- dstx, dsty, bitPlane);
-
- DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
- DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
-
- XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
- srcx, srcy, width, height, dstx, dsty, bitPlane);
- dmxSync(dmxScreen, FALSE);
-
- return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
- dstx, dsty, bitPlane);
-}
-
-/** Render list of points, \a pptInit in \a pDrawable on the back-end
- * server associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pptInit, npt, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of connected lines, \a pptInit in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pptInit, npt, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
- int nseg, xSegment *pSegs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XSegment *)pSegs, nseg);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of rectangle outlines, \a pRects in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
- int nrects, xRectangle *pRects)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XRectangle *)pRects, nrects);
-
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of arc outlines, \a parcs in \a pDrawable on the
- * back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *parcs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XArc *)parcs, narcs);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render a filled polygons in \a pDrawable on the back-end server
- * associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count, DDXPointPtr pPts)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XPoint *)pPts, count, shape, mode);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of filled rectangles, \a prectInit in \a pDrawable on
- * the back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
- int nrectFill, xRectangle *prectInit)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XRectangle *)prectInit, nrectFill);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
- * server associated with \a pDrawable's screen. If the offscreen
- * optimization is enabled, only draw when \a pDrawable is at least
- * partially visible. */
-void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *parcs)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
- (XArc *)parcs, narcs);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
- * the back-end server associated with \a pDrawable's screen. If the
- * offscreen optimization is enabled, only draw when \a pDrawable is at
- * least partially visible. */
-int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255];
- Drawable draw;
-
- GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
- Linear8Bit, &n, charinfo);
-
- /* Calculate text width */
- w = 0;
- for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
-
- if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, chars, count);
- dmxSync(dmxScreen, FALSE);
- }
-
- return x+w;
-}
-
-/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
- * on the back-end server associated with \a pDrawable's screen. If
- * the offscreen optimization is enabled, only draw when \a pDrawable
- * is at least partially visible. */
-int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255];
- Drawable draw;
-
- GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, charinfo);
-
- /* Calculate text width */
- w = 0;
- for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
-
- if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, (XChar2b *)chars, count);
- dmxSync(dmxScreen, FALSE);
- }
-
- return x+w;
-}
-
-/** Render string of 8-bit \a chars (both foreground and background) in
- * \a pDrawable on the back-end server associated with \a pDrawable's
- * screen. If the offscreen optimization is enabled, only draw when \a
- * pDrawable is at least partially visible. */
-void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, chars, count);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Render string of 16-bit \a chars (both foreground and background) in
- * \a pDrawable on the back-end server associated with \a pDrawable's
- * screen. If the offscreen optimization is enabled, only draw when \a
- * pDrawable is at least partially visible. */
-void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short *chars)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Drawable draw;
-
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
-
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-
- XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
- x, y, (XChar2b *)chars, count);
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Image Glyph Blt -- this function should never be called. */
-void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- /* Error -- this should never happen! */
-}
-
-/** Poly Glyph Blt -- this function should never be called. */
-void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- /* Error -- this should never happen! */
-}
-
-/** Push Pixels -- this function should never be called. */
-void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
- int w, int h, int x, int y)
-{
- /* Error -- this should never happen! */
-}
-
-/**********************************************************************
- * Miscellaneous drawing commands
- */
-
-/** When Xinerama is active, the client pixmaps are always obtained from
- * screen 0. When screen 0 is detached, the pixmaps must be obtained
- * from any other screen that is not detached. Usually, this is screen
- * 1. */
-static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
-{
-#ifdef PANORAMIX
- PanoramiXRes *pXinPix;
- int i;
- DMXScreenInfo *dmxScreen;
-
- if (noPanoramiXExtension) return NULL;
- if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
-
- if (Success != dixLookupResourceByType((pointer*) &pXinPix,
- pDrawable->id, XRT_PIXMAP,
- NullClient, DixUnknownAccess))
- return NULL;
-
- for (i = 1; i < PanoramiXNumScreens; i++) {
- dmxScreen = &dmxScreens[i];
- if (dmxScreen->beDisplay) {
- PixmapPtr pSrc;
- dmxPixPrivPtr pSrcPriv;
-
- dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
- RT_PIXMAP, NullClient, DixUnknownAccess);
- pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
- if (pSrcPriv->pixmap) {
- *draw = pSrcPriv->pixmap;
- return dmxScreen;
- }
- }
- }
-#endif
- return NULL;
-}
-
-/** Get an image from the back-end server associated with \a pDrawable's
- * screen. If \a pDrawable is a window, it must be viewable to get an
- * image from it. If it is not viewable, then get the image from the
- * first ancestor of \a pDrawable that is viewable. If no viewable
- * ancestor is found, then simply return without getting an image. */
-void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format, unsigned long planeMask, char *pdstLine)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
- XImage *img;
- Drawable draw;
-
- /* Cannot get image from unviewable window */
- if (pDrawable->type == DRAWABLE_WINDOW) {
- WindowPtr pWindow = (WindowPtr)pDrawable;
- if (!pWindow->viewable) {
- while (!pWindow->viewable && pWindow->parent) {
- sx += pWindow->origin.x - wBorderWidth(pWindow);
- sx += pWindow->origin.y - wBorderWidth(pWindow);
- pWindow = pWindow->parent;
- }
- if (!pWindow->viewable) {
- return;
- }
- }
- DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
- if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
- return;
- } else {
- DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
- /* Try to find the pixmap on a non-detached Xinerama screen */
- dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
- if (!dmxScreen) return;
- }
- }
-
- img = XGetImage(dmxScreen->beDisplay, draw,
- sx, sy, w, h, planeMask, format);
- if (img) {
- int len = img->bytes_per_line * img->height;
- memmove(pdstLine, img->data, len);
- XDestroyImage(img);
- }
-
- dmxSync(dmxScreen, FALSE);
-}
-
-/** Get Spans -- this function should never be called. */
-void dmxGetSpans(DrawablePtr pDrawable, int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans,
- char *pdstStart)
-{
- /* Error -- this should never happen! */
-}
+/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin <kem@redhat.com> + * + */ + +/** \file + * This file provides support for GC operations. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxsync.h" +#include "dmxgc.h" +#include "dmxgcops.h" +#include "dmxwindow.h" +#include "dmxpixmap.h" + +#include "mi.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "dixfontstr.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \ +do { \ + if ((_pDraw)->type == DRAWABLE_WINDOW) { \ + dmxWinPrivPtr pWinPriv = \ + DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \ + (_draw) = (Drawable)pWinPriv->window; \ + } else { \ + dmxPixPrivPtr pPixPriv = \ + DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \ + (_draw) = (Drawable)pPixPriv->pixmap; \ + } \ +} while (0) + +#define DMX_GCOPS_OFFSCREEN(_pDraw) \ + (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \ + (dmxOffScreenOpt && \ + (_pDraw)->type == DRAWABLE_WINDOW && \ + (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \ + !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window))) + +/** Fill spans -- this function should never be called. */ +void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC, + int nInit, DDXPointPtr pptInit, int *pwidthInit, + int fSorted) +{ + /* Error -- this should never happen! */ +} + +/** Set spans -- this function should never be called. */ +void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC, + char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, + int fSorted) +{ + /* Error -- this should never happen! */ +} + +/** Transfer \a pBits image to back-end server associated with \a + * pDrawable's screen. If primitive subdivision optimization is + * enabled, then only transfer the sections of \a pBits that are + * visible (i.e., not-clipped) to the back-end server. */ +void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, + int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + XImage *img; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + img = XCreateImage(dmxScreen->beDisplay, + dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, + depth, format, leftPad, pBits, w, h, + BitmapPad(dmxScreen->beDisplay), + (format == ZPixmap) ? + PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); + + if (img) { + Drawable draw; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + if (dmxSubdividePrimitives && pGC->pCompositeClip) { + RegionPtr pSubImages; + RegionPtr pClip; + BoxRec box; + BoxPtr pBox; + int nBox; + + box.x1 = x; + box.y1 = y; + box.x2 = x + w; + box.y2 = y + h; + pSubImages = RegionCreate(&box, 1); + + pClip = RegionCreate(NullBox, 1); + RegionCopy(pClip, pGC->pCompositeClip); + RegionTranslate(pClip, + -pDrawable->x, -pDrawable->y); + RegionIntersect(pSubImages, pSubImages, pClip); + + nBox = RegionNumRects(pSubImages); + pBox = RegionRects(pSubImages); + + while (nBox--) { + XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, + pBox->x1 - box.x1, + pBox->y1 - box.y1, + pBox->x1, + pBox->y1, + pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1); + pBox++; + } + RegionDestroy(pClip); + RegionDestroy(pSubImages); + } else { + XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, + img, 0, 0, x, y, w, h); + } + XFree(img); /* Use XFree instead of XDestroyImage + * because pBits is passed in from the + * caller. */ + + dmxSync(dmxScreen, FALSE); + } else { + /* Error -- this should not happen! */ + } +} + +/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end + * server associated with \a pSrc drawable's screen. If the offscreen + * optimization is enabled, only copy when both \a pSrc and \a pDst are + * at least partially visible. */ +RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable srcDraw, dstDraw; + + if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, 0L); + + DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); + DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); + + XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, + srcx, srcy, w, h, dstx, dsty); + dmxSync(dmxScreen, FALSE); + + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, 0L); +} + +/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst + * drawable on the back-end server associated with \a pSrc drawable's + * screen. If the offscreen optimization is enabled, only copy when + * both \a pSrc and \a pDst are at least partially visible. */ +RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long bitPlane) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable srcDraw, dstDraw; + + if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, + dstx, dsty, bitPlane); + + DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); + DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); + + XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, + srcx, srcy, width, height, dstx, dsty, bitPlane); + dmxSync(dmxScreen, FALSE); + + return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, + dstx, dsty, bitPlane); +} + +/** Render list of points, \a pptInit in \a pDrawable on the back-end + * server associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pptInit, npt, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of connected lines, \a pptInit in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pptInit, npt, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of disjoint segments, \a pSegs in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC, + int nseg, xSegment *pSegs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XSegment *)pSegs, nseg); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of rectangle outlines, \a pRects in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, + int nrects, xRectangle *pRects) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XRectangle *)pRects, nrects); + + dmxSync(dmxScreen, FALSE); +} + +/** Render list of arc outlines, \a parcs in \a pDrawable on the + * back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *parcs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XArc *)parcs, narcs); + dmxSync(dmxScreen, FALSE); +} + +/** Render a filled polygons in \a pDrawable on the back-end server + * associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC, + int shape, int mode, int count, DDXPointPtr pPts) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XPoint *)pPts, count, shape, mode); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of filled rectangles, \a prectInit in \a pDrawable on + * the back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, + int nrectFill, xRectangle *prectInit) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XRectangle *)prectInit, nrectFill); + dmxSync(dmxScreen, FALSE); +} + +/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end + * server associated with \a pDrawable's screen. If the offscreen + * optimization is enabled, only draw when \a pDrawable is at least + * partially visible. */ +void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *parcs) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, + (XArc *)parcs, narcs); + dmxSync(dmxScreen, FALSE); +} + +/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on + * the back-end server associated with \a pDrawable's screen. If the + * offscreen optimization is enabled, only draw when \a pDrawable is at + * least partially visible. */ +int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, char *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; + Drawable draw; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, + Linear8Bit, &n, charinfo); + + /* Calculate text width */ + w = 0; + for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + + if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, chars, count); + dmxSync(dmxScreen, FALSE); + } + + return x+w; +} + +/** Render string of 16-bit \a chars (foreground only) in \a pDrawable + * on the back-end server associated with \a pDrawable's screen. If + * the offscreen optimization is enabled, only draw when \a pDrawable + * is at least partially visible. */ +int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; + Drawable draw; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + + /* Calculate text width */ + w = 0; + for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + + if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, (XChar2b *)chars, count); + dmxSync(dmxScreen, FALSE); + } + + return x+w; +} + +/** Render string of 8-bit \a chars (both foreground and background) in + * \a pDrawable on the back-end server associated with \a pDrawable's + * screen. If the offscreen optimization is enabled, only draw when \a + * pDrawable is at least partially visible. */ +void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, char *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, chars, count); + dmxSync(dmxScreen, FALSE); +} + +/** Render string of 16-bit \a chars (both foreground and background) in + * \a pDrawable on the back-end server associated with \a pDrawable's + * screen. If the offscreen optimization is enabled, only draw when \a + * pDrawable is at least partially visible. */ +void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, int count, unsigned short *chars) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); + Drawable draw; + + if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; + + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + + XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc, + x, y, (XChar2b *)chars, count); + dmxSync(dmxScreen, FALSE); +} + +/** Image Glyph Blt -- this function should never be called. */ +void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + /* Error -- this should never happen! */ +} + +/** Poly Glyph Blt -- this function should never be called. */ +void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + /* Error -- this should never happen! */ +} + +/** Push Pixels -- this function should never be called. */ +void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, + int w, int h, int x, int y) +{ + /* Error -- this should never happen! */ +} + +/********************************************************************** + * Miscellaneous drawing commands + */ + +/** When Xinerama is active, the client pixmaps are always obtained from + * screen 0. When screen 0 is detached, the pixmaps must be obtained + * from any other screen that is not detached. Usually, this is screen + * 1. */ +static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw) +{ +#ifdef PANORAMIX + PanoramiXRes *pXinPix; + int i; + DMXScreenInfo *dmxScreen; + + if (noPanoramiXExtension) return NULL; + if (pDrawable->type != DRAWABLE_PIXMAP) return NULL; + + if (Success != dixLookupResourceByType((pointer*) &pXinPix, + pDrawable->id, XRT_PIXMAP, + NullClient, DixUnknownAccess)) + return NULL; + + FOR_NSCREENS_FORWARD_SKIP(i) { + dmxScreen = &dmxScreens[i]; + if (dmxScreen->beDisplay) { + PixmapPtr pSrc; + dmxPixPrivPtr pSrcPriv; + + dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id, + RT_PIXMAP, NullClient, DixUnknownAccess); + pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); + if (pSrcPriv->pixmap) { + *draw = pSrcPriv->pixmap; + return dmxScreen; + } + } + } +#endif + return NULL; +} + +/** Get an image from the back-end server associated with \a pDrawable's + * screen. If \a pDrawable is a window, it must be viewable to get an + * image from it. If it is not viewable, then get the image from the + * first ancestor of \a pDrawable that is viewable. If no viewable + * ancestor is found, then simply return without getting an image. */ +void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planeMask, char *pdstLine) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; + XImage *img; + Drawable draw; + + /* Cannot get image from unviewable window */ + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWindow = (WindowPtr)pDrawable; + if (!pWindow->viewable) { + while (!pWindow->viewable && pWindow->parent) { + sx += pWindow->origin.x - wBorderWidth(pWindow); + sx += pWindow->origin.y - wBorderWidth(pWindow); + pWindow = pWindow->parent; + } + if (!pWindow->viewable) { + return; + } + } + DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw); + if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable)) + return; + } else { + DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); + if (DMX_GCOPS_OFFSCREEN(pDrawable)) { + /* Try to find the pixmap on a non-detached Xinerama screen */ + dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw); + if (!dmxScreen) return; + } + } + + img = XGetImage(dmxScreen->beDisplay, draw, + sx, sy, w, h, planeMask, format); + if (img) { + int len = img->bytes_per_line * img->height; + memmove(pdstLine, img->data, len); + XDestroyImage(img); + } + + dmxSync(dmxScreen, FALSE); +} + +/** Get Spans -- this function should never be called. */ +void dmxGetSpans(DrawablePtr pDrawable, int wMax, + DDXPointPtr ppt, int *pwidth, int nspans, + char *pdstStart) +{ + /* Error -- this should never happen! */ +} diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c index fbb296809..8ff8ee6f6 100644 --- a/xorg-server/render/render.c +++ b/xorg-server/render/render.c @@ -2690,7 +2690,7 @@ PanoramiXRenderCreatePicture (ClientPtr client) if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) return BadAlloc; newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; + panoramix_setup_ids(newPict, client, stuff->pid); if (refDraw->type == XRT_WINDOW && stuff->drawable == screenInfo.screens[0]->root->drawable.id) @@ -2699,9 +2699,6 @@ PanoramiXRenderCreatePicture (ClientPtr client) } else newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); FOR_NSCREENS_BACKWARD(j) { stuff->pid = newPict->info[j].id; @@ -3225,11 +3222,8 @@ PanoramiXRenderCreateSolidFill (ClientPtr client) return BadAlloc; newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; + panoramix_setup_ids(newPict, client, stuff->pid); newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); FOR_NSCREENS_BACKWARD(j) { stuff->pid = newPict->info[j].id; @@ -3258,12 +3252,9 @@ PanoramiXRenderCreateLinearGradient (ClientPtr client) return BadAlloc; newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; + panoramix_setup_ids(newPict, client, stuff->pid); newPict->u.pict.root = FALSE; - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - FOR_NSCREENS_BACKWARD(j) { stuff->pid = newPict->info[j].id; result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); @@ -3291,12 +3282,9 @@ PanoramiXRenderCreateRadialGradient (ClientPtr client) return BadAlloc; newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; + panoramix_setup_ids(newPict, client, stuff->pid); newPict->u.pict.root = FALSE; - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - FOR_NSCREENS_BACKWARD(j) { stuff->pid = newPict->info[j].id; result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); @@ -3324,12 +3312,9 @@ PanoramiXRenderCreateConicalGradient (ClientPtr client) return BadAlloc; newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; + panoramix_setup_ids(newPict, client, stuff->pid); newPict->u.pict.root = FALSE; - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - FOR_NSCREENS_BACKWARD(j) { stuff->pid = newPict->info[j].id; result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client); diff --git a/xorg-server/xkeyboard-config/rules/base.extras.xml.in b/xorg-server/xkeyboard-config/rules/base.extras.xml.in index b068589fd..1118bec4d 100644 --- a/xorg-server/xkeyboard-config/rules/base.extras.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.extras.xml.in @@ -23,7 +23,7 @@ <variant> <configItem> <name>ave</name> - <_description>Iran Avestan</_description> + <_description>Iran - Avestan</_description> <languageList><iso639Id>ave</iso639Id></languageList> </configItem> </variant> @@ -31,6 +31,22 @@ </layout> <layout> <configItem> + <name>lt</name> + <_shortDescription>Ltu</_shortDescription> + <_description>Lithuania</_description> + <languageList><iso639Id>lit</iso639Id></languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>dvorak</name> + <_description>Lithuania - Dvorak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> <name>us</name> <_shortDescription>USA</_shortDescription> <_description>USA</_description> @@ -40,26 +56,26 @@ <variant> <configItem> <name>intl-unicode</name> - <_description>USA International (AltGr Unicode combining)</_description> + <_description>USA - International (AltGr Unicode combining)</_description> </configItem> </variant> <variant> <configItem> <name>alt-intl-unicode</name> - <_description>USA International (AltGr Unicode combining, alternative)</_description> + <_description>USA - International (AltGr Unicode combining, alternative)</_description> </configItem> </variant> <variant> <configItem> <name>ats</name> - <_description>USA Atsina</_description> + <_description>USA - Atsina</_description> <!-- No ISO code in ISO639-2, only draft ISO693-3 --> </configItem> </variant> <variant> <configItem> <name>crd</name> - <_description>USA Couer D'alene Salish</_description> + <_description>USA - Couer D'alene Salish</_description> <languageList><iso639Id>crd</iso639Id></languageList> </configItem> </variant> @@ -76,7 +92,7 @@ <variant> <configItem> <name>ergonomic</name> - <_description>Ergonomic Touchtype</_description> + <_description>Romania - Ergonomic Touchtype</_description> </configItem> </variant> </variantList> @@ -84,7 +100,7 @@ <layout> <configItem> <name>rs</name> - <_shortDescription>SRB</_shortDescription> + <_shortDescription>Srb</_shortDescription> <_description>Serbia</_description> <languageList><iso639Id>srp</iso639Id></languageList> </configItem> @@ -92,7 +108,7 @@ <variant> <configItem> <name>combiningkeys</name> - <_description>Serbia Combining accents instead of dead keys</_description> + <_description>Serbia - Combining accents instead of dead keys</_description> </configItem> </variant> </variantList> @@ -107,7 +123,7 @@ <variant> <configItem> <name>chu</name> - <description>Russia Church Slavonic</description> + <description>Russia - Church Slavonic</description> <languageList><iso639Id>chu</iso639Id></languageList> </configItem> </variant> diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in index 1a3d528d1..2d3df0126 100644 --- a/xorg-server/xkeyboard-config/rules/base.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.xml.in @@ -1,6209 +1,6209 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd">
-<xkbConfigRegistry version="1.1">
- <modelList>
- <model>
- <configItem>
- <name>pc101</name>
- <_description>Generic 101-key PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc102</name>
- <_description>Generic 102-key (Intl) PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc104</name>
- <_description>Generic 104-key PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc105</name>
- <_description>Generic 105-key (Intl) PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dell101</name>
- <_description>Dell 101-key PC</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>latitude</name>
- <_description>Dell Latitude series laptop</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellm65</name>
- <_description>Dell Precision M65</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>everex</name>
- <_description>Everex STEPnote</_description>
- <vendor>Everex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>flexpro</name>
- <_description>Keytronic FlexPro</_description>
- <vendor>Keytronic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoft</name>
- <_description>Microsoft Natural</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>omnikey101</name>
- <_description>Northgate OmniKey 101</_description>
- <vendor>Northgate</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>winbook</name>
- <_description>Winbook Model XP5</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc98</name>
- <_description>PC-98xx Series</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4techKB21</name>
- <_description>A4Tech KB-21</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4techKBS8</name>
- <_description>A4Tech KBS-8</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4_rfkb23</name>
- <_description>A4Tech Wireless Desktop RFKB-23</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>airkey</name>
- <_description>Acer AirKey V</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>azonaRF2300</name>
- <_description>Azona RF2300 wireless Internet Keyboard</_description>
- <vendor>Azona</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>scorpius</name>
- <_description>Advance Scorpius KI</_description>
- <vendor>Scorpius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>brother</name>
- <_description>Brother Internet Keyboard</_description>
- <vendor>Brother</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5113rf</name>
- <_description>BTC 5113RF Multimedia</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5126t</name>
- <_description>BTC 5126T</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc6301urf</name>
- <_description>BTC 6301URF</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9000</name>
- <_description>BTC 9000</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9000a</name>
- <_description>BTC 9000A</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9001ah</name>
- <_description>BTC 9001AH</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5090</name>
- <_description>BTC 5090</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9019u</name>
- <_description>BTC 9019U</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9116u</name>
- <_description>BTC 9116U Mini Wireless Internet and Gaming</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherryblue</name>
- <_description>Cherry Blue Line CyBo@rd</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherryblueb</name>
- <_description>Cherry CyMotion Master XPress</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrybluea</name>
- <_description>Cherry Blue Line CyBo@rd (alternate option)</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrycyboard</name>
- <_description>Cherry CyBo@rd USB-Hub</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrycmexpert</name>
- <_description>Cherry CyMotion Expert</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrybunlim</name>
- <_description>Cherry B.UNLIMITED</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony</name>
- <_description>Chicony Internet Keyboard</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony0108</name>
- <_description>Chicony KU-0108</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony0420</name>
- <_description>Chicony KU-0420</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony9885</name>
- <_description>Chicony KB-9885</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqeak8</name>
- <_description>Compaq Easy Access Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik7</name>
- <_description>Compaq Internet Keyboard (7 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik13</name>
- <_description>Compaq Internet Keyboard (13 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik18</name>
- <_description>Compaq Internet Keyboard (18 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cymotionlinux</name>
- <_description>Cherry CyMotion Master Linux</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>armada</name>
- <_description>Laptop/notebook Compaq (eg. Armada) Laptop Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>presario</name>
- <_description>Laptop/notebook Compaq (eg. Presario) Internet Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ipaq</name>
- <_description>Compaq iPaq Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dell</name>
- <_description>Dell</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellsk8125</name>
- <_description>Dell SK-8125</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellsk8135</name>
- <_description>Dell SK-8135</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellusbmm</name>
- <_description>Dell USB Multimedia Keyboard</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>inspiron</name>
- <_description>Dell Laptop/notebook Inspiron 6xxx/8xxx</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>precision_m</name>
- <_description>Dell Laptop/notebook Precision M series</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dexxa</name>
- <_description>Dexxa Wireless Desktop Keyboard</_description>
- <vendor>Dexxa</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>diamond</name>
- <_description>Diamond 9801 / 9802 series</_description>
- <vendor>Diamond</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dtk2000</name>
- <_description>DTK2000</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ennyah_dkb1008</name>
- <_description>Ennyah DKB-1008</_description>
- <vendor>Ennyah</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>fscaa1667g</name>
- <_description>Fujitsu-Siemens Computers AMILO laptop</_description>
- <vendor>Fujitsu-Siemens</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>genius</name>
- <_description>Genius Comfy KB-16M / Genius MM Keyboard KWD-910</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuscomfy</name>
- <_description>Genius Comfy KB-12e</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuscomfy2</name>
- <_description>Genius Comfy KB-21e-Scroll</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuskb19e</name>
- <_description>Genius KB-19e NB</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuskkb2050hs</name>
- <_description>Genius KKB-2050HS</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>gyration</name>
- <_description>Gyration</_description>
- <vendor>Gyration</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>htcdream</name>
- <_description>HTC Dream</_description>
- <vendor>HTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>kinesis</name>
- <_description>Kinesis</_description>
- <vendor>Kinesis</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logitech_base</name>
- <_description>Logitech Generic Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logitech_g15</name>
- <_description>Logitech G15 extra keys via G15daemon</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpi6</name>
- <_description>Hewlett-Packard Internet Keyboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp250x</name>
- <_description>Hewlett-Packard SK-250x Multimedia Keyboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxe3gc</name>
- <_description>Hewlett-Packard Omnibook XE3 GC</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxe3gf</name>
- <_description>Hewlett-Packard Omnibook XE3 GF</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxt1000</name>
- <_description>Hewlett-Packard Omnibook XT1000</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpdv5</name>
- <_description>Hewlett-Packard Pavilion dv5</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpzt11xx</name>
- <_description>Hewlett-Packard Pavilion ZT11xx</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp500fa</name>
- <_description>Hewlett-Packard Omnibook 500 FA</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp5xx</name>
- <_description>Hewlett-Packard Omnibook 5xx</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpnx9020</name>
- <_description>Hewlett-Packard nx9020</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp6000</name>
- <_description>Hewlett-Packard Omnibook 6000/6100</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>honeywell_euroboard</name>
- <_description>Honeywell Euroboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpmini110</name>
- <_description>Hewlett-Packard Mini 110 Notebook</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>rapidaccess</name>
- <_description>IBM Rapid Access</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>rapidaccess2</name>
- <_description>IBM Rapid Access II</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpad</name>
- <_description>IBM ThinkPad 560Z/600/600E/A22E</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpad60</name>
- <_description>IBM ThinkPad R60/T60/R61/T61</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpadz60</name>
- <_description>IBM ThinkPad Z60m/Z60t/Z61m/Z61t</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ibm_spacesaver</name>
- <_description>IBM Space Saver</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiaccess</name>
- <_description>Logitech Access Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiclx300</name>
- <_description>Logitech Cordless Desktop LX-300</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logii350</name>
- <_description>Logitech Internet 350 Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logimel</name>
- <_description>Logitech Media Elite Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd</name>
- <_description>Logitech Cordless Desktop</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_it</name>
- <_description>Logitech Cordless Desktop iTouch</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_nav</name>
- <_description>Logitech Cordless Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_opt</name>
- <_description>Logitech Cordless Desktop Optical</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicda</name>
- <_description>Logitech Cordless Desktop (alternate option)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicdpa2</name>
- <_description>Logitech Cordless Desktop Pro (alternate option 2)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicfn</name>
- <_description>Logitech Cordless Freedom/Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicdn</name>
- <_description>Logitech Cordless Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiitc</name>
- <_description>Logitech iTouch Cordless Keyboard (model Y-RB6)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiik</name>
- <_description>Logitech Internet Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>itouch</name>
- <_description>Logitech iTouch</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicink</name>
- <_description>Logitech Internet Navigator Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiex110</name>
- <_description>Logitech Cordless Desktop EX110</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiinkse</name>
- <_description>Logitech iTouch Internet Navigator Keyboard SE</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiinkseusb</name>
- <_description>Logitech iTouch Internet Navigator Keyboard SE (USB)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiultrax</name>
- <_description>Logitech Ultra-X Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiultraxc</name>
- <_description>Logitech Ultra-X Cordless Media Desktop Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logidinovo</name>
- <_description>Logitech diNovo Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logidinovoedge</name>
- <_description>Logitech diNovo Edge Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx1998</name>
- <_description>Memorex MX1998</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx2500</name>
- <_description>Memorex MX2500 EZ-Access Keyboard</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx2750</name>
- <_description>Memorex MX2750</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoft4000</name>
- <_description>Microsoft Natural Wireless Ergonomic Keyboard 4000</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoft7000</name>
- <_description>Microsoft Natural Wireless Ergonomic Keyboard 7000</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftinet</name>
- <_description>Microsoft Internet Keyboard</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftpro</name>
- <_description>Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprousb</name>
- <_description>Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprooem</name>
- <_description>Microsoft Natural Keyboard Pro OEM</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>vsonku306</name>
- <_description>ViewSonic KU-306 Internet Keyboard</_description>
- <vendor>ViewSonic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprose</name>
- <_description>Microsoft Internet Keyboard Pro, Swedish</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftoffice</name>
- <_description>Microsoft Office Keyboard</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftmult</name>
- <_description>Microsoft Wireless Multimedia Keyboard 1.0A</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftelite</name>
- <_description>Microsoft Natural Keyboard Elite</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftccurve2k</name>
- <_description>Microsoft Comfort Curve Keyboard 2000</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>oretec</name>
- <_description>Ortek MCK-800 MM/Internet keyboard</_description>
- <vendor>Ortek</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>propeller</name>
- <_description>Propeller Voyager (KTEZ-1000)</_description>
- <vendor>KeyTronic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>qtronix</name>
- <_description>QTronix Scorpius 98N+</_description>
- <vendor>QTronix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>samsung4500</name>
- <_description>Samsung SDM 4500P</_description>
- <vendor>Samsung</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>samsung4510</name>
- <_description>Samsung SDM 4510P</_description>
- <vendor>Samsung</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sanwaskbkg3</name>
- <_description>Sanwa Supply SKB-KG3</_description>
- <vendor>Sanwa Supply Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk1300</name>
- <_description>SK-1300</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk2500</name>
- <_description>SK-2500</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk6200</name>
- <_description>SK-6200</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk7100</name>
- <_description>SK-7100</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sp_inet</name>
- <_description>Super Power Multimedia Keyboard</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sven</name>
- <_description>SVEN Ergonomic 2500</_description>
- <vendor>SVEN</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sven303</name>
- <_description>SVEN Slim 303</_description>
- <vendor>SVEN</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>symplon</name>
- <_description>Symplon PaceBook (tablet PC)</_description>
- <vendor>Symplon</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>toshiba_s3000</name>
- <_description>Toshiba Satellite S3000</_description>
- <vendor>Toshiba</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trust</name>
- <_description>Trust Wireless Keyboard Classic</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trustda</name>
- <_description>Trust Direct Access Keyboard</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trust_slimline</name>
- <_description>Trust Slimline</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2020</name>
- <_description>TypeMatrix EZ-Reach 2020</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030PS2</name>
- <_description>TypeMatrix EZ-Reach 2030 PS2</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB</name>
- <_description>TypeMatrix EZ-Reach 2030 USB</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB-102</name>
- <_description>TypeMatrix EZ-Reach 2030 USB (102/105:EU mode)</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB-106</name>
- <_description>TypeMatrix EZ-Reach 2030 USB (106:JP mode)</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>yahoo</name>
- <_description>Yahoo! Internet Keyboard</_description>
- <vendor>Yahoo!</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macbook78</name>
- <_description>MacBook/MacBook Pro</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macbook79</name>
- <_description>MacBook/MacBook Pro (Intl)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh</name>
- <_description>Macintosh</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh_old</name>
- <_description>Macintosh Old</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh_hhk</name>
- <_description>Happy Hacking Keyboard for Mac</_description>
- <vendor>Fujitsu</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_c300</name>
- <_description>Acer C300</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_ferrari4k</name>
- <_description>Acer Ferrari 4000</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_laptop</name>
- <_description>Acer Laptop</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>asus_laptop</name>
- <_description>Asus Laptop</_description>
- <vendor>Asus</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>apple</name>
- <_description>Apple</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>apple_laptop</name>
- <_description>Apple Laptop</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_ansi</name>
- <_description>Apple Aluminium Keyboard (ANSI)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_iso</name>
- <_description>Apple Aluminium Keyboard (ISO)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_jis</name>
- <_description>Apple Aluminium Keyboard (JIS)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>silvercrest</name>
- <_description>SILVERCREST Multimedia Wireless Keyboard</_description>
- <vendor>Silvercrest</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>emachines</name>
- <_description>Laptop/notebook eMachines m68xx</_description>
- <vendor>eMachines</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx</name>
- <_description>BenQ X-Touch</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx730</name>
- <_description>BenQ X-Touch 730</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx800</name>
- <_description>BenQ X-Touch 800</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hhk</name>
- <_description>Happy Hacking Keyboard</_description>
- <vendor>Fujitsu</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>classmate</name>
- <_description>Classmate PC</_description>
- <vendor>Intel</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>olpc</name>
- <_description>OLPC</_description>
- <vendor>OLPC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sun6</name>
- <_description>Sun Type 5/6</_description>
- <vendor>Sun Microsystems</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>targa_v811</name>
- <_description>Targa Visionary 811</_description>
- <vendor>Targa</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>unitekkb1925</name>
- <_description>Unitek KB-1925</_description>
- <vendor>Unitek Group</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compalfl90</name>
- <_description>FL90</_description>
- <vendor>Compal Electronics Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>creativedw7000</name>
- <_description>Creative Desktop Wireless 7000</_description>
- <vendor>Creative</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>htcdream</name>
- <_description>Htc Dream phone</_description>
- <vendor>htc</vendor>
- </configItem>
- </model>
- </modelList>
- <layoutList>
- <layout>
- <configItem>
- <name>us</name>
- <_shortDescription>USA</_shortDescription>
- <_description>USA</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>chr</name>
- <_description>USA - Cherokee</_description>
- <languageList>
- <iso639Id>chr</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>euro</name>
- <_description>USA - With EuroSign on 5</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>USA - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alt-intl</name>
- <_description>USA - Alternative international</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>USA - Colemak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>USA - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-intl</name>
- <_description>USA - Dvorak international (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-alt-intl</name>
- <_description>USA - Dvorak alternative international (no dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-l</name>
- <_description>USA - Left handed Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-r</name>
- <_description>USA - Right handed Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-classic</name>
- <_description>USA - Classic Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvp</name>
- <_description>USA - Programmer Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus</name>
- <_description>USA - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>USA - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>altgr-intl</name>
- <_description>USA - International (AltGr dead keys)</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>fra</iso639Id>
- <iso639Id>ger</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>olpc2</name>
- <_description>USA - Layout toggle on multiply/divide key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hbs</name>
- <_description>USA - Serbo-Croatian</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>bos</iso639Id>
- <iso639Id>hbs</iso639Id>
- <iso639Id>hrv</iso639Id>
- <iso639Id>srp</iso639Id> </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ad</name>
- <_shortDescription>And</_shortDescription>
- <_description>Andorra</_description>
- <languageList>
- <iso639Id>cat</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>af</name>
- <_shortDescription>Afg</_shortDescription>
- <_description>Afghanistan</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ps</name>
- <_description>Afghanistan - Pashto</_description>
- <languageList>
- <iso639Id>pus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uz</name>
- <_description>Afghanistan - Southern Uzbek</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>olpc-ps</name>
- <_description>Afghanistan - OLPC Pashto</_description>
- <languageList>
- <iso639Id>pus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fa-olpc</name>
- <_description>Afghanistan - OLPC Dari</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uz-olpc</name>
- <_description>Afghanistan - OLPC Southern Uzbek</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ara</name>
- <_shortDescription>Ara</_shortDescription>
- <_description>Arabic</_description>
- <countryList>
- <iso3166Id>AE</iso3166Id>
- <iso3166Id>BH</iso3166Id>
- <iso3166Id>DZ</iso3166Id>
- <iso3166Id>EG</iso3166Id>
- <iso3166Id>EH</iso3166Id>
- <iso3166Id>JO</iso3166Id>
- <iso3166Id>KW</iso3166Id>
- <iso3166Id>LB</iso3166Id>
- <iso3166Id>LY</iso3166Id>
- <iso3166Id>MA</iso3166Id>
- <iso3166Id>MR</iso3166Id>
- <iso3166Id>OM</iso3166Id>
- <iso3166Id>PS</iso3166Id>
- <iso3166Id>QA</iso3166Id>
- <iso3166Id>SA</iso3166Id>
- <iso3166Id>SD</iso3166Id>
- <iso3166Id>SY</iso3166Id>
- <iso3166Id>TN</iso3166Id>
- <iso3166Id>YE</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>ara</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>azerty</name>
- <_description>Arabic - azerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>azerty_digits</name>
- <_description>Arabic - azerty/digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>digits</name>
- <_description>Arabic - digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Arabic - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_digits</name>
- <_description>Arabic - qwerty/digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>buckwalter</name>
- <_description>Arabic - Buckwalter</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>al</name>
- <_shortDescription>Alb</_shortDescription>
- <_description>Albania</_description>
- <languageList>
- <iso639Id>alb</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>am</name>
- <_shortDescription>Arm</_shortDescription>
- <_description>Armenia</_description>
- <languageList>
- <iso639Id>hye</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Armenia - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic-alt</name>
- <_description>Armenia - Alternative Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eastern</name>
- <_description>Armenia - Eastern</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>western</name>
- <_description>Armenia - Western</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eastern-alt</name>
- <_description>Armenia - Alternative Eastern</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>at</name>
- <_shortDescription>Aut</_shortDescription>
- <_description>Austria</_description>
- <languageList>
- <iso639Id>ger</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Austria - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Austria - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Austria - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>az</name>
- <_shortDescription>Aze</_shortDescription>
- <_description>Azerbaijan</_description>
- <languageList>
- <iso639Id>aze</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cyrillic</name>
- <_description>Azerbaijan - Cyrillic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>by</name>
- <_shortDescription>Blr</_shortDescription>
- <_description>Belarus</_description>
- <languageList>
- <iso639Id>bel</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Belarus - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Belarus - Latin</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>be</name>
- <_shortDescription>Bel</_shortDescription>
- <_description>Belgium</_description>
- <languageList><iso639Id>ger</iso639Id>
- <iso639Id>nld</iso639Id>
- <iso639Id>fra</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>oss</name>
- <_description>Belgium - Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_latin9</name>
- <_description>Belgium - Alternative, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_sundeadkeys</name>
- <_description>Belgium - Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>iso-alternate</name>
- <_description>Belgium - ISO Alternate</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Belgium - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Belgium - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>wang</name>
- <_description>Belgium - Wang model 724 azerty</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bd</name>
- <_shortDescription>Bgd</_shortDescription>
- <_description>Bangladesh</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>probhat</name>
- <_description>Bangladesh - Probhat</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>in</name>
- <_shortDescription>Ind</_shortDescription>
- <_description>India</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ben</name>
- <_description>India - Bengali</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ben_probhat</name>
- <_description>India - Bengali Probhat</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>guj</name>
- <_description>India - Gujarati</_description>
- <languageList>
- <iso639Id>guj</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>guru</name>
- <_description>India - Gurmukhi</_description>
- <languageList>
- <iso639Id>pan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>jhelum</name>
- <_description>India - Gurmukhi Jhelum</_description>
- <languageList>
- <iso639Id>pan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kan</name>
- <_description>India - Kannada</_description>
- <languageList>
- <iso639Id>kan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mal</name>
- <_description>India - Malayalam</_description>
- <languageList>
- <iso639Id>mal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mal_lalitha</name>
- <_description>India - Malayalam Lalitha</_description>
- <languageList>
- <iso639Id>mal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mal_enhanced</name>
- <_description>India - Malayalam enhanced INSCRIPT with Rupee Sign</_description>
- <languageList><iso639Id>mal</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ori</name>
- <_description>India - Oriya</_description>
- <languageList>
- <iso639Id>ori</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_unicode</name>
- <_description>India - Tamil Unicode</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_keyboard_with_numerals</name>
- <_description>India - Tamil Keyboard with Numerals</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TAB</name>
- <_description>India - Tamil TAB Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TSCII</name>
- <_description>India - Tamil TSCII Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam</name>
- <_description>India - Tamil</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tel</name>
- <_description>India - Telugu</_description>
- <languageList>
- <iso639Id>tel</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-phonetic</name>
- <_description>India - Urdu, Phonetic</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-phonetic3</name>
- <_description>India - Urdu, Alternative phonetic</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-winkeys</name>
- <_description>India - Urdu, Winkeys</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bolnagri</name>
- <_description>India - Hindi Bolnagri</_description>
- <languageList>
- <iso639Id>hin</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hin-wx</name>
- <_description>India - Hindi Wx</_description>
- <languageList>
- <iso639Id>hin</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eng</name>
- <_description>India - English with RupeeSign</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ba</name>
- <_shortDescription>Bih</_shortDescription>
- <_description>Bosnia and Herzegovina</_description>
- <languageList>
- <iso639Id>bos</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Bosnia and Herzegovina - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicode</name>
- <_description>Bosnia and Herzegovina - Use Bosnian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicodeus</name>
- <_description>Bosnia and Herzegovina - US keyboard with Bosnian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Bosnia and Herzegovina - US keyboard with Bosnian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>br</name>
- <_shortDescription>Bra</_shortDescription>
- <_description>Brazil</_description>
- <languageList>
- <iso639Id>por</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Brazil - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Brazil - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo</name>
- <_description>Brazil - Nativo</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-us</name>
- <_description>Brazil - Nativo for USA keyboards</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-epo</name>
- <_description>Brazil - Nativo for Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bg</name>
- <_shortDescription>Bgr</_shortDescription>
- <_description>Bulgaria</_description>
- <languageList>
- <iso639Id>bul</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Bulgaria - Traditional phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bas_phonetic</name>
- <_description>Bulgaria - New phonetic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ma</name>
- <_description>Morocco</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>french</name>
- <_description>Morocco - French</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh</name>
- <_description>Morocco - Tifinagh</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-alt</name>
- <_description>Morocco - Tifinagh alternative</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-alt-phonetic</name>
- <_description>Morocco - Tifinagh alternative phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-extended</name>
- <_description>Morocco - Tifinagh extended</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-phonetic</name>
- <_description>Morocco - Tifinagh phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-extended-phonetic</name>
- <_description>Morocco - Tifinagh extended phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mm</name>
- <_shortDescription>Mmr</_shortDescription>
- <_description>Myanmar</_description>
- <languageList>
- <iso639Id>mya</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ca</name>
- <_shortDescription>Can</_shortDescription>
- <_description>Canada</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>fr-dvorak</name>
- <_description>Canada - French Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr-legacy</name>
- <_description>Canada - French (legacy)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multix</name>
- <_description>Canada - Multilingual</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multi</name>
- <_description>Canada - Multilingual, first part</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multi-2gr</name>
- <_description>Canada - Multilingual, second part</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ike</name>
- <_description>Canada - Inuktitut</_description>
- <languageList>
- <iso639Id>iku</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>shs</name>
- <_description>Canada - Secwepemctsin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kut</name>
- <_description>Canada - Ktunaxa</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eng</name>
- <_description>Canada - English</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>cd</name>
- <_shortDescription>COD</_shortDescription>
- <_description>Congo, Democratic Republic of the</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>cn</name>
- <_shortDescription>Chn</_shortDescription>
- <_description>China</_description>
- <languageList>
- <iso639Id>chi</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tib</name>
- <_description>China - Tibetan</_description>
- <languageList>
- <iso639Id>tib</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tib_asciinum</name>
- <_description>China - Tibetan (with ASCII numerals)</_description>
- <languageList>
- <iso639Id>tib</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uig</name>
- <_description>China - Uyghur</_description>
- <languageList>
- <iso639Id>uig</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>hr</name>
- <_shortDescription>Hrv</_shortDescription>
- <_description>Croatia</_description>
- <languageList>
- <iso639Id>scr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Croatia - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicode</name>
- <_description>Croatia - Use Croatian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicodeus</name>
- <_description>Croatia - US keyboard with Croatian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Croatia - US keyboard with Croatian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>cz</name>
- <_shortDescription>Cze</_shortDescription>
- <_description>Czechia</_description>
- <languageList>
- <iso639Id>cze</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>bksl</name>
- <_description>Czechia - With <\|> key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Czechia - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_bksl</name>
- <_description>Czechia - qwerty, extended Backslash</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ucw</name>
- <_description>Czechia - UCW layout (accented letters only)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-ucw</name>
- <_description>Czechia - US Dvorak with CZ UCW support</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>dk</name>
- <_shortDescription>Dnk</_shortDescription>
- <_description>Denmark</_description>
- <languageList>
- <iso639Id>dan</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Denmark - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Denmark - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Denmark - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Denmark - Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>nl</name>
- <_shortDescription>Nld</_shortDescription>
- <_description>Netherlands</_description>
- <languageList>
- <iso639Id>nld</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Netherlands - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Netherlands - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Netherlands - Standard</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bt</name>
- <_shortDescription>Btn</_shortDescription>
- <_description>Bhutan</_description>
- <languageList>
- <iso639Id>dzo</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ee</name>
- <_shortDescription>Est</_shortDescription>
- <_description>Estonia</_description>
- <languageList>
- <iso639Id>est</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Estonia - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Estonia - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Estonia - US keyboard with Estonian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ir</name>
- <_shortDescription>Irn</_shortDescription>
- <_description>Iran</_description>
- <languageList>
- <iso639Id>per</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>pes_keypad</name>
- <_description>Iran - Persian, with Persian Keypad</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Iran - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Iran - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Iran - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_ara</name>
- <_description>Iran - Kurdish, Arabic-Latin</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>iq</name>
- <_shortDescription>Irq</_shortDescription>
- <_description>Iraq</_description>
- <languageList><iso639Id>ara</iso639Id>
- <iso639Id>kur</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Iraq - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Iraq - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Iraq - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_ara</name>
- <_description>Iraq - Kurdish, Arabic-Latin</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fo</name>
- <_shortDescription>Fro</_shortDescription>
- <_description>Faroe Islands</_description>
- <languageList>
- <iso639Id>fao</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Faroe Islands - Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fi</name>
- <_shortDescription>Fin</_shortDescription>
- <_description>Finland</_description>
- <languageList>
- <iso639Id>fin</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>classic</name>
- <_description>Finland - Classic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Finland - Classic, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Finland - Northern Saami</_description>
- <languageList><iso639Id>smi</iso639Id>
- <iso639Id>sme</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Finland - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fr</name>
- <_shortDescription>Fra</_shortDescription>
- <_description>France</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>France - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>France - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss</name>
- <_description>France - Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_latin9</name>
- <_description>France - Alternative, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_nodeadkeys</name>
- <_description>France - Alternative, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_sundeadkeys</name>
- <_description>France - Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9</name>
- <_description>France - (Legacy) Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9_nodeadkeys</name>
- <_description>France - (Legacy) Alternative, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9_sundeadkeys</name>
- <_description>France - (Legacy) Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bepo</name>
- <_description>France - Bepo, ergonomic, Dvorak way</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bepo_latin9</name>
- <_description>France - Bepo, ergonomic, Dvorak way, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>France - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>France - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bre</name>
- <_description>France - Breton</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oci</name>
- <_description>France - Occitan</_description>
- <languageList>
- <iso639Id>oci</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>geo</name>
- <_description>France - Georgian AZERTY Tskapo</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gh</name>
- <_shortDescription>Gha</_shortDescription>
- <_description>Ghana</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>generic</name>
- <_description>Ghana - Multilingual</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>akan</name>
- <_description>Ghana - Akan</_description>
- <languageList>
- <iso639Id>aka</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ewe</name>
- <_description>Ghana - Ewe</_description>
- <languageList>
- <iso639Id>ewe</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fula</name>
- <_description>Ghana - Fula</_description>
- <languageList>
- <iso639Id>ful</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ga</name>
- <_description>Ghana - Ga</_description>
- <languageList>
- <iso639Id>gaa</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hausa</name>
- <_description>Ghana - Hausa</_description>
- <languageList>
- <iso639Id>hau</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>avn</name>
- <_description>Ghana - Avatime</_description>
- <languageList>
- <iso639Id>avn</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>gillbt</name>
- <_description>Ghana - GILLBT</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gn</name>
- <_shortDescription>Gin</_shortDescription>
- <_description>Guinea</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ge</name>
- <_shortDescription>Geo</_shortDescription>
- <_description>Georgia</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ergonomic</name>
- <_description>Georgia - Ergonomic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mess</name>
- <_description>Georgia - MESS</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru</name>
- <_description>Georgia - Russian</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os</name>
- <_description>Georgia - Ossetian</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>de</name>
- <_shortDescription>Deu</_shortDescription>
- <_description>Germany</_description>
- <languageList>
- <iso639Id>ger</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>deadacute</name>
- <_description>Germany - Dead acute</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadgraveacute</name>
- <_description>Germany - Dead grave acute</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Germany - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ro</name>
- <_description>Germany - Romanian keyboard with German letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ro_nodeadkeys</name>
- <_description>Germany - Romanian keyboard with German letters, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Germany - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Germany - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>neo</name>
- <_description>Germany - Neo 2</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Germany - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Germany - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dsb</name>
- <_description>Germany - Lower Sorbian</_description>
- <languageList>
- <iso639Id>dsb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dsb_qwertz</name>
- <_description>Germany - Lower Sorbian (qwertz)</_description>
- <languageList>
- <iso639Id>dsb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Germany - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru</name>
- <_description>Germany - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gr</name>
- <_shortDescription>Grc</_shortDescription>
- <_description>Greece</_description>
- <languageList>
- <iso639Id>gre</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>simple</name>
- <_description>Greece - Simple</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>extended</name>
- <_description>Greece - Extended</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Greece - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>polytonic</name>
- <_description>Greece - Polytonic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>hu</name>
- <_shortDescription>Hun</_shortDescription>
- <_description>Hungary</_description>
- <languageList>
- <iso639Id>hun</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>standard</name>
- <_description>Hungary - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Hungary - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Hungary - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_comma_dead</name>
- <_description>Hungary - 101/qwertz/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_comma_nodead</name>
- <_description>Hungary - 101/qwertz/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_dot_dead</name>
- <_description>Hungary - 101/qwertz/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_dot_nodead</name>
- <_description>Hungary - 101/qwertz/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_comma_dead</name>
- <_description>Hungary - 101/qwerty/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_comma_nodead</name>
- <_description>Hungary - 101/qwerty/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_dot_dead</name>
- <_description>Hungary - 101/qwerty/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_dot_nodead</name>
- <_description>Hungary - 101/qwerty/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_comma_dead</name>
- <_description>Hungary - 102/qwertz/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_comma_nodead</name>
- <_description>Hungary - 102/qwertz/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_dot_dead</name>
- <_description>Hungary - 102/qwertz/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_dot_nodead</name>
- <_description>Hungary - 102/qwertz/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_comma_dead</name>
- <_description>Hungary - 102/qwerty/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_comma_nodead</name>
- <_description>Hungary - 102/qwerty/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_dot_dead</name>
- <_description>Hungary - 102/qwerty/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_dot_nodead</name>
- <_description>Hungary - 102/qwerty/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>is</name>
- <_shortDescription>Isl</_shortDescription>
- <_description>Iceland</_description>
- <languageList>
- <iso639Id>ice</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>Sundeadkeys</name>
- <_description>Iceland - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Iceland - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Iceland - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Iceland - Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>il</name>
- <_shortDescription>Isr</_shortDescription>
- <_description>Israel</_description>
- <languageList>
- <iso639Id>heb</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>lyx</name>
- <_description>Israel - lyx</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Israel - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>biblical</name>
- <_description>Israel - Biblical Hebrew (Tiro)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>it</name>
- <_shortDescription>Ita</_shortDescription>
- <_description>Italy</_description>
- <languageList>
- <iso639Id>ita</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Italy - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Italy - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Italy - US keyboard with Italian letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>geo</name>
- <_description>Italy - Georgian</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>jp</name>
- <_shortDescription>Jpn</_shortDescription>
- <_description>Japan</_description>
- <languageList>
- <iso639Id>jpn</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kana</name>
- <_description>Japan - Kana</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kana86</name>
- <_description>Japan - Kana 86</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>OADG109A</name>
- <_description>Japan - OADG 109A</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Japan - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>kg</name>
- <_shortDescription>Kgz</_shortDescription>
- <_description>Kyrgyzstan</_description>
- <languageList>
- <iso639Id>kir</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Kyrgyzstan - Phonetic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>kh</name>
- <_shortDescription>Khm</_shortDescription>
- <_description>Cambodia</_description>
- <languageList>
- <iso639Id>khm</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>kz</name>
- <_shortDescription>Kaz</_shortDescription>
- <_description>Kazakhstan</_description>
- <languageList>
- <iso639Id>kaz</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ruskaz</name>
- <_description>Kazakhstan - Russian with Kazakh</_description>
- <languageList><iso639Id>kaz</iso639Id>
- <iso639Id>rus</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kazrus</name>
- <_description>Kazakhstan - Kazakh with Russian</_description>
- <languageList><iso639Id>kaz</iso639Id>
- <iso639Id>rus</iso639Id></languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>la</name>
- <_shortDescription>Lao</_shortDescription>
- <_description>Laos</_description>
- <languageList>
- <iso639Id>lao</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>stea</name>
- <_description>Laos - STEA (proposed standard layout)</_description>
- <languageList><iso639Id>lao</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>latam</name>
- <_shortDescription>Esp</_shortDescription>
- <_description>Latin American</_description>
- <countryList>
- <iso3166Id>AR</iso3166Id>
- <iso3166Id>BO</iso3166Id>
- <iso3166Id>CL</iso3166Id>
- <iso3166Id>CO</iso3166Id>
- <iso3166Id>CR</iso3166Id>
- <iso3166Id>CU</iso3166Id>
- <iso3166Id>DO</iso3166Id>
- <iso3166Id>EC</iso3166Id>
- <iso3166Id>GT</iso3166Id>
- <iso3166Id>HN</iso3166Id>
- <iso3166Id>HT</iso3166Id>
- <iso3166Id>MX</iso3166Id>
- <iso3166Id>NI</iso3166Id>
- <iso3166Id>PA</iso3166Id>
- <iso3166Id>PE</iso3166Id>
- <iso3166Id>PR</iso3166Id>
- <iso3166Id>PY</iso3166Id>
- <iso3166Id>SV</iso3166Id>
- <iso3166Id>US</iso3166Id>
- <iso3166Id>UY</iso3166Id>
- <iso3166Id>VE</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>spa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Latin American - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadtilde</name>
- <_description>Latin American - Include dead tilde</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Latin American - Sun dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lt</name>
- <_shortDescription>Ltu</_shortDescription>
- <_description>Lithuania</_description>
- <languageList>
- <iso639Id>lit</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Lithuania - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Lithuania - US keyboard with Lithuanian letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ibm</name>
- <_description>Lithuania - IBM (LST 1205-92)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>lekp</name>
- <_description>Lithuania - LEKP</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>lekpa</name>
- <_description>Lithuania - LEKPa</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lv</name>
- <_shortDescription>Lva</_shortDescription>
- <_description>Latvia</_description>
- <languageList>
- <iso639Id>lav</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>apostrophe</name>
- <_description>Latvia - Apostrophe (') variant</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tilde</name>
- <_description>Latvia - Tilde (~) variant</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fkey</name>
- <_description>Latvia - F-letter (F) variant</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mao</name>
- <_shortDescription>Mao</_shortDescription>
- <_description>Maori</_description>
- <languageList>
- <iso639Id>mao</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>me</name>
- <_shortDescription>MNE</_shortDescription>
- <_description>Montenegro</_description>
- <languageList>
- <iso639Id>srp</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cyrillic</name>
- <_description>Montenegro - Cyrillic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cyrillicyz</name>
- <_description>Montenegro - Cyrillic, Z and ZHE swapped</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicode</name>
- <_description>Montenegro - Latin unicode</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinyz</name>
- <_description>Montenegro - Latin qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicodeyz</name>
- <_description>Montenegro - Latin unicode qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cyrillicalternatequotes</name>
- <_description>Montenegro - Cyrillic with guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinalternatequotes</name>
- <_description>Montenegro - Latin with guillemets</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mk</name>
- <_shortDescription>Mkd</_shortDescription>
- <_description>Macedonia</_description>
- <languageList>
- <iso639Id>mkd</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Macedonia - Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mt</name>
- <_shortDescription>Mlt</_shortDescription>
- <_description>Malta</_description>
- <languageList>
- <iso639Id>mlt</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Malta - Maltese keyboard with US layout</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mn</name>
- <_shortDescription>Mng</_shortDescription>
- <_description>Mongolia</_description>
- <languageList>
- <iso639Id>mng</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>no</name>
- <_shortDescription>Nor</_shortDescription>
- <_description>Norway</_description>
- <languageList>
- <iso639Id>nor</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Norway - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Norway - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Norway - Northern Saami</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi_nodeadkeys</name>
- <_description>Norway - Northern Saami, eliminate dead keys</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Norway - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Norway - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pl</name>
- <_shortDescription>Pol</_shortDescription>
- <_description>Poland</_description>
- <languageList>
- <iso639Id>pol</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>qwertz</name>
- <_description>Poland - qwertz</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Poland - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak_quotes</name>
- <_description>Poland - Dvorak, Polish quotes on quotemark key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak_altquotes</name>
- <_description>Poland - Dvorak, Polish quotes on key 1</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>csb</name>
- <_description>Poland - Kashubian</_description>
- <languageList>
- <iso639Id>csb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru_phonetic_dvorak</name>
- <_description>Poland - Russian phonetic Dvorak</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvp</name>
- <_description>Poland - Programmer Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pt</name>
- <_shortDescription>Prt</_shortDescription>
- <_description>Portugal</_description>
- <languageList>
- <iso639Id>por</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Portugal - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Portugal - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Portugal - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Portugal - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_sundeadkeys</name>
- <_description>Portugal - Macintosh, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo</name>
- <_description>Portugal - Nativo</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-us</name>
- <_description>Portugal - Nativo for USA keyboards</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-epo</name>
- <_description>Portugal - Nativo for Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ro</name>
- <_shortDescription>Rou</_shortDescription>
- <_description>Romania</_description>
- <languageList>
- <iso639Id>rum</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cedilla</name>
- <_description>Romania - Cedilla</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Romania - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std_cedilla</name>
- <_description>Romania - Standard (Cedilla)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>winkeys</name>
- <_description>Romania - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Romania - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Romania - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_dobruca1</name>
- <_description>Romania - Crimean Tatar (Dobruca-1 Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_dobruca2</name>
- <_description>Romania - Crimean Tatar (Dobruca-2 Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ru</name>
- <_shortDescription>Rus</_shortDescription>
- <_description>Russia</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Russia - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic_winkeys</name>
- <_description>Russia - Phonetic Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter</name>
- <_description>Russia - Typewriter</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Russia - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter-legacy</name>
- <_description>Russia - Typewriter, legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tt</name>
- <_description>Russia - Tatar</_description>
- <languageList>
- <iso639Id>tat</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os_legacy</name>
- <_description>Russia - Ossetian, legacy</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os_winkeys</name>
- <_description>Russia - Ossetian, Winkeys</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cv</name>
- <_description>Russia - Chuvash</_description>
- <languageList>
- <iso639Id>chv</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cv_latin</name>
- <_description>Russia - Chuvash Latin</_description>
- <languageList>
- <iso639Id>chv</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>udm</name>
- <_description>Russia - Udmurt</_description>
- <languageList>
- <iso639Id>udm</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kom</name>
- <_description>Russia - Komi</_description>
- <languageList>
- <iso639Id>kom</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sah</name>
- <_description>Russia - Yakut</_description>
- <languageList>
- <iso639Id>sah</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>xal</name>
- <_description>Russia - Kalmyk</_description>
- <languageList>
- <iso639Id>xal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dos</name>
- <_description>Russia - DOS</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>srp</name>
- <_description>Russia - Serbian</_description>
- <languageList><iso639Id>rus</iso639Id>
- <iso639Id>srp</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bak</name>
- <_description>Russia - Bashkirian</_description>
- <languageList>
- <iso639Id>bak</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>chm</name>
- <_description>Russia - Mari</_description>
- <languageList>
- <iso639Id>chm</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>rs</name>
- <_shortDescription>SRB</_shortDescription>
- <_description>Serbia</_description>
- <languageList>
- <iso639Id>srp</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>yz</name>
- <_description>Serbia - Z and ZHE swapped</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Serbia - Latin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicode</name>
- <_description>Serbia - Latin Unicode</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinyz</name>
- <_description>Serbia - Latin qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicodeyz</name>
- <_description>Serbia - Latin Unicode qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Serbia - With guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinalternatequotes</name>
- <_description>Serbia - Latin with guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rue</name>
- <_description>Serbia - Pannonian Rusyn Homophonic</_description>
- <languageList>
- <iso639Id>rue</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>si</name>
- <_shortDescription>Svn</_shortDescription>
- <_description>Slovenia</_description>
- <languageList>
- <iso639Id>slv</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Slovenia - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Slovenia - US keyboard with Slovenian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>sk</name>
- <_shortDescription>Svk</_shortDescription>
- <_description>Slovakia</_description>
- <languageList>
- <iso639Id>slo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>bksl</name>
- <_description>Slovakia - Extended Backslash</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Slovakia - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_bksl</name>
- <_description>Slovakia - qwerty, extended Backslash</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>es</name>
- <_shortDescription>Esp</_shortDescription>
- <_description>Spain</_description>
- <languageList>
- <iso639Id>spa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Spain - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadtilde</name>
- <_description>Spain - Include dead tilde</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Spain - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Spain - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ast</name>
- <_description>Spain - Asturian variant with bottom-dot H and bottom-dot L</_description>
- <languageList>
- <iso639Id>ast</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cat</name>
- <_description>Spain - Catalan variant with middle-dot L</_description>
- <languageList>
- <iso639Id>cat</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Spain - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>se</name>
- <_shortDescription>Swe</_shortDescription>
- <_description>Sweden</_description>
- <languageList>
- <iso639Id>swe</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Sweden - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Sweden - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus</name>
- <_description>Sweden - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus_nodeadkeys</name>
- <_description>Sweden - Russian phonetic, eliminate dead keys</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Sweden - Northern Saami</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Sweden - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>svdvorak</name>
- <_description>Sweden - Svdvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ch</name>
- <_shortDescription>Che</_shortDescription>
- <_description>Switzerland</_description>
- <languageList><iso639Id>ger</iso639Id>
- <iso639Id>gsw</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Switzerland - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_nodeadkeys</name>
- <_description>Switzerland - German, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_sundeadkeys</name>
- <_description>Switzerland - German, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr</name>
- <_description>Switzerland - French</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_nodeadkeys</name>
- <_description>Switzerland - French, eliminate dead keys</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_sundeadkeys</name>
- <_description>Switzerland - French, Sun dead keys</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_mac</name>
- <_description>Switzerland - French (Macintosh)</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_mac</name>
- <_description>Switzerland - German (Macintosh)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>sy</name>
- <_shortDescription>Syr</_shortDescription>
- <_description>Syria</_description>
- <languageList>
- <iso639Id>syr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>syc</name>
- <_description>Syria - Syriac</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>syc_phonetic</name>
- <_description>Syria - Syriac phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Syria - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Syria - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Syria - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tj</name>
- <_shortDescription>Tjk</_shortDescription>
- <_description>Tajikistan</_description>
- <languageList>
- <iso639Id>tgk</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Tajikistan - Legacy</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lk</name>
- <_shortDescription>Lka</_shortDescription>
- <_description>Sri Lanka</_description>
- <languageList>
- <iso639Id>sin</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tam_unicode</name>
- <_description>Sri Lanka - Tamil Unicode</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TAB</name>
- <_description>Sri Lanka - Tamil TAB Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>th</name>
- <_shortDescription>Tha</_shortDescription>
- <_description>Thailand</_description>
- <languageList>
- <iso639Id>tha</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tis</name>
- <_description>Thailand - TIS-820.2538</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>pat</name>
- <_description>Thailand - Pattachote</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tr</name>
- <_shortDescription>Tur</_shortDescription>
- <_description>Turkey</_description>
- <languageList>
- <iso639Id>tur</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>f</name>
- <_description>Turkey - (F)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alt</name>
- <_description>Turkey - Alt-Q</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Turkey - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Turkey - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Turkey - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Turkey - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>Turkey - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Turkey - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Turkey - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Turkey - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tw</name>
- <_shortDescription>Twn</_shortDescription>
- <_description>Taiwan</_description>
- <languageList>
- <iso639Id>trv</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>indigenous</name>
- <_description>Taiwan - Indigenous</_description>
- <languageList>
- <iso639Id>ami</iso639Id>
- <iso639Id>tay</iso639Id>
- <iso639Id>bnn</iso639Id>
- <iso639Id>ckv</iso639Id>
- <iso639Id>pwn</iso639Id>
- <iso639Id>pyu</iso639Id>
- <iso639Id>dru</iso639Id>
- <iso639Id>ais</iso639Id>
- <iso639Id>ssf</iso639Id>
- <iso639Id>tao</iso639Id>
- <iso639Id>tsu</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>saisiyat</name>
- <_description>Taiwan - Saisiyat</_description>
- <languageList>
- <iso639Id>xsf</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ua</name>
- <_shortDescription>Ukr</_shortDescription>
- <_description>Ukraine</_description>
- <languageList>
- <iso639Id>ukr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Ukraine - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter</name>
- <_description>Ukraine - Typewriter</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>winkeys</name>
- <_description>Ukraine - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Ukraine - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rstu</name>
- <_description>Ukraine - Standard RSTU</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rstu_ru</name>
- <_description>Ukraine - Standard RSTU on Russian layout</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>homophonic</name>
- <_description>Ukraine - Homophonic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Ukraine - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Ukraine - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Ukraine - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gb</name>
- <_shortDescription>GBr</_shortDescription>
- <_description>United Kingdom</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>extd</name>
- <_description>United Kingdom - Extended - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>United Kingdom - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>United Kingdom - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorakukp</name>
- <_description>United Kingdom - Dvorak (UK Punctuation)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>United Kingdom - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_intl</name>
- <_description>United Kingdom - Macintosh (International)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>United Kingdom - Colemak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>uz</name>
- <_shortDescription>Uzb</_shortDescription>
- <_description>Uzbekistan</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Uzbekistan - Latin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>vn</name>
- <_shortDescription>Vnm</_shortDescription>
- <_description>Vietnam</_description>
- <languageList>
- <iso639Id>vie</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>kr</name>
- <_shortDescription>Kor</_shortDescription>
- <_description>Korea, Republic of</_description>
- <languageList>
- <iso639Id>kor</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kr104</name>
- <_description>Korea, Republic of - 101/104 key Compatible</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>nec_vndr/jp</name>
- <_shortDescription>Jpn</_shortDescription>
- <_description>Japan (PC-98xx Series)</_description>
- <countryList>
- <iso3166Id>JP</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>jpn</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ie</name>
- <_shortDescription>Irl</_shortDescription>
- <_description>Ireland</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>CloGaelach</name>
- <_description>Ireland - CloGaelach</_description>
- <languageList>
- <iso639Id>gla</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>UnicodeExpert</name>
- <_description>Ireland - UnicodeExpert</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ogam</name>
- <_description>Ireland - Ogham</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ogam_is434</name>
- <_description>Ireland - Ogham IS434</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pk</name>
- <_shortDescription>Pak</_shortDescription>
- <_description>Pakistan</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>urd-crulp</name>
- <_description>Pakistan - CRULP</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-nla</name>
- <_description>Pakistan - NLA</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ara</name>
- <_description>Pakistan - Arabic</_description>
- <languageList>
- <iso639Id>ara</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>snd</name>
- <_description>Pakistan - Sindhi</_description>
- <languageList>
- <iso639Id>sd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mv</name>
- <_shortDescription>Mdv</_shortDescription>
- <_description>Maldives</_description>
- <languageList>
- <iso639Id>div</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>za</name>
- <_shortDescription>Zaf</_shortDescription>
- <_description>South Africa</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>epo</name>
- <_shortDescription>Epo</_shortDescription>
- <_description>Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Esperanto - displaced semicolon and quote (obsolete)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>np</name>
- <_shortDescription>Npl</_shortDescription>
- <_description>Nepal</_description>
- <languageList>
- <iso639Id>nep</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ng</name>
- <_shortDescription>Nga</_shortDescription>
- <_description>Nigeria</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>igbo</name>
- <_description>Nigeria - Igbo</_description>
- <languageList>
- <iso639Id>ibo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>yoruba</name>
- <_description>Nigeria - Yoruba</_description>
- <languageList>
- <iso639Id>yor</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hausa</name>
- <_description>Nigeria - Hausa</_description>
- <languageList>
- <iso639Id>hau</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>et</name>
- <_shortDescription>Eth</_shortDescription>
- <_description>Ethiopia</_description>
- <languageList>
- <iso639Id>amh</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>sn</name>
- <_shortDescription>Sen</_shortDescription>
- <_description>Senegal</_description>
- <languageList>
- <iso639Id>wol</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>brai</name>
- <_shortDescription>Brl</_shortDescription>
- <_description>Braille</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>left_hand</name>
- <_description>Braille - Left hand</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>right_hand</name>
- <_description>Braille - Right hand</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tm</name>
- <_shortDescription>Tkm</_shortDescription>
- <_description>Turkmenistan</_description>
- <languageList>
- <iso639Id>tuk</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alt</name>
- <_description>Turkmenistan - Alt-Q</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ml</name>
- <_shortDescription>Mli</_shortDescription>
- <_description>Mali</_description>
- <languageList>
- <iso639Id>bam</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>fr-oss</name>
- <_description>Mali - Français (France Alternative)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us-mac</name>
- <_description>Mali - English (USA Macintosh)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us-intl</name>
- <_description>Mali - English (USA International)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tz</name>
- <_shortDescription>Tza</_shortDescription>
- <_description>Tanzania</_description>
- <languageList>
- <iso639Id>swa</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ke</name>
- <_shortDescription>Ken</_shortDescription>
- <_description>Kenya</_description>
- <languageList>
- <iso639Id>swa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kik</name>
- <_description>Kenya - Kikuyu</_description>
- <languageList>
- <iso639Id>kik</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bw</name>
- <_shortDescription>Bwa</_shortDescription>
- <_description>Botswana</_description>
- <languageList>
- <iso639Id>tsn</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ph</name>
- <_shortDescription>Phi</_shortDescription>
- <_description>Philippines</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>qwerty-bay</name>
- <_description>Philippines - QWERTY (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-dvorak</name>
- <_description>Philippines - Capewell-Dvorak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-dvorak-bay</name>
- <_description>Philippines - Capewell-Dvorak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-qwerf2k6</name>
- <_description>Philippines - Capewell-QWERF 2006 (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-qwerf2k6-bay</name>
- <_description>Philippines - Capewell-QWERF 2006 (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>Philippines - Colemak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak-bay</name>
- <_description>Philippines - Colemak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Philippines - Dvorak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-bay</name>
- <_description>Philippines - Dvorak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- </layoutList>
- <optionList>
- <group allowMultipleSelection="true">
- <!-- The key combination used to switch between groups -->
- <configItem>
- <name>grp</name>
- <_description>Key(s) to change layout</_description>
- </configItem>
- <option>
- <configItem>
- <name>grp:switch</name>
- <_description>Right Alt (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lswitch</name>
- <_description>Left Alt (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lwin_switch</name>
- <_description>Left Win (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rwin_switch</name>
- <_description>Right Win (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:win_switch</name>
- <_description>Any Win key (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:caps_switch</name>
- <_description>Caps Lock (while pressed), Alt+Caps Lock does the original capslock action</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_switch</name>
- <_description>Right Ctrl (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:toggle</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lalt_toggle</name>
- <_description>Left Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:caps_toggle</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shift_caps_toggle</name>
- <_description>Shift+Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shift_caps_switch</name>
- <_description>Caps Lock (to first layout), Shift+Caps Lock (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:win_menu_switch</name>
- <_description>Left Win (to first layout), Right Win/Menu (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_rctrl_switch</name>
- <_description>Left Ctrl (to first layout), Right Ctrl (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_caps_toggle</name>
- <_description>Alt+Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shifts_toggle</name>
- <_description>Both Shift keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alts_toggle</name>
- <_description>Both Alt keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrls_toggle</name>
- <_description>Both Ctrl keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrl_shift_toggle</name>
- <_description>Ctrl+Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_lshift_toggle</name>
- <_description>Left Ctrl+Left Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_rshift_toggle</name>
- <_description>Right Ctrl+Right Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrl_alt_toggle</name>
- <_description>Alt+Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_shift_toggle</name>
- <_description>Alt+Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_space_toggle</name>
- <_description>Alt+Space</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:menu_toggle</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lwin_toggle</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rwin_toggle</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lshift_toggle</name>
- <_description>Left Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rshift_toggle</name>
- <_description>Right Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_toggle</name>
- <_description>Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_toggle</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:sclk_toggle</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_lwin_rctrl_menu</name>
- <_description>LeftCtrl+LeftWin (to first layout), RightCtrl+Menu (to second layout)</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- The key combination used to choose the 3rd (and 4th, together with Shift)
- level of symbols -->
- <configItem>
- <name>lv3</name>
- <_description>Key to choose 3rd level</_description>
- </configItem>
- <option>
- <configItem>
- <name>lv3:switch</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:menu_switch</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:win_switch</name>
- <_description>Any Win key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lwin_switch</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:rwin_switch</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:alt_switch</name>
- <_description>Any Alt key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lalt_switch</name>
- <_description>Left Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_switch</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_switch_multikey</name>
- <_description>Right Alt, Shift+Right Alt key is Multi_Key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_alt</name>
- <_description>Right Alt key never chooses 3rd level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:enter_switch</name>
- <_description>Enter on keypad</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:caps_switch</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:bksl_switch</name>
- <_description>Backslash</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lsgt_switch</name>
- <_description><Less/Greater></_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:caps_switch_latch</name>
- <_description>Caps Lock (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:bksl_switch_latch</name>
- <_description>Backslash chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lsgt_switch_latch</name>
- <_description><Less/Greater> (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Tweaking the position of the "Ctrl" key -->
- <configItem>
- <name>ctrl</name>
- <_description>Ctrl key position</_description>
- </configItem>
- <option>
- <configItem>
- <name>ctrl:nocaps</name>
- <_description>Make Caps Lock an additional Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:lctrl_meta</name>
- <_description>Meta on Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:swapcaps</name>
- <_description>Swap Ctrl and Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_ac</name>
- <_description>At left of 'A'</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_aa</name>
- <_description>At bottom left</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_ra</name>
- <_description>Right Ctrl as Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_menu</name>
- <_description>Right Ctrl is mapped to Menu</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Using startard LEDs to indicate the alternative (not first) group(s) -->
- <configItem>
- <name>grp_led</name>
- <_description>Use keyboard LED to show alternative layout</_description>
- </configItem>
- <option>
- <configItem>
- <name>grp_led:num</name>
- <_description>Num Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp_led:caps</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp_led:scroll</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Select a keypad type -->
- <configItem>
- <name>keypad</name>
- <_description>Numeric keypad layout selection</_description>
- </configItem>
- <option>
- <configItem>
- <name>keypad:legacy</name>
- <_description>Legacy</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:oss</name>
- <_description>Unicode additions (arrows and math operators)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:future</name>
- <_description>Unicode additions (arrows and math operators). Math operators on default level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:legacy_wang</name>
- <_description>Legacy Wang 724</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:oss_wang</name>
- <_description>Wang 724 keypad with unicode additions (arrows and math operators)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:future_wang</name>
- <_description>Wang 724 keypad with unicode additions (arrows and math operators). Math operators on default level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:hex</name>
- <_description>Hexadecimal</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:atm</name>
- <_description>ATM/phone-style</_description>
- </configItem>
- </option>
- </group>
- <!-- This option should override the KPDL key defined in keypad; I hope it's declared in the right place -->
- <group allowMultipleSelection="false">
- <!-- Select a keypad KPDL variant -->
- <configItem>
- <name>kpdl</name>
- <_description>Numeric keypad delete key behaviour</_description>
- </configItem>
- <option>
- <configItem>
- <!-- Actually, with KP_DECIMAL, as the old keypad(dot) -->
- <name>kpdl:dot</name>
- <_description>Legacy key with dot</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:comma</name>
- <!-- Actually, with KP_SEPARATOR, as the old keypad(comma) -->
- <_description>Legacy key with comma</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:dotoss</name>
- <_description>Four-level key with dot</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:dotoss_latin9</name>
- <_description>Four-level key with dot, latin-9 restriction</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:commaoss</name>
- <_description>Four-level key with comma</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:momayyezoss</name>
- <_description>Four-level key with momayyez</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:kposs</name>
- <!-- This assumes the KP_ abstract symbols are actually useful for some apps
- The description needs to be rewritten -->
- <_description>Four-level key with abstract separators</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:semi</name>
- <_description>Semi-colon on third level</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Caps Lock tweaks.
- "Internal" capitalization means capitalization using some internal tables.
- Otherwise "as Shift" - means using next group. -->
- <configItem>
- <name>caps</name>
- <_description>Caps Lock key behavior</_description>
- </configItem>
- <option>
- <configItem>
- <name>caps:internal</name>
- <_description>Caps Lock uses internal capitalization. Shift "pauses" Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:internal_nocancel</name>
- <_description>Caps Lock uses internal capitalization. Shift doesn't affect Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shift</name>
- <_description>Caps Lock acts as Shift with locking. Shift "pauses" Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shift_nocancel</name>
- <_description>Caps Lock acts as Shift with locking. Shift doesn't affect Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:capslock</name>
- <_description>Caps Lock toggles normal capitalization of alphabetic characters</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:numlock</name>
- <_description>Make Caps Lock an additional Num Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:swapescape</name>
- <_description>Swap ESC and Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:escape</name>
- <_description>Make Caps Lock an additional ESC</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:backspace</name>
- <_description>Make Caps Lock an additional Backspace</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:super</name>
- <_description>Make Caps Lock an additional Super</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:hyper</name>
- <_description>Make Caps Lock an additional Hyper</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shiftlock</name>
- <_description>Caps Lock toggles Shift so all keys are affected</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:none</name>
- <_description>Caps Lock is disabled</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:ctrl_modifier</name>
- <_description>Make Caps Lock an additional Control but keep the Caps_Lock keysym</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Using special PC keys (Win, Menu) to work as standard X keys (Super, Hyper, etc.) -->
- <configItem>
- <name>altwin</name>
- <_description>Alt/Win key behavior</_description>
- </configItem>
- <option>
- <configItem>
- <name>altwin:menu</name>
- <_description>Add the standard behavior to Menu key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:meta_alt</name>
- <_description>Alt and Meta are on Alt keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:ctrl_win</name>
- <_description>Control is mapped to Win keys (and the usual Ctrl keys)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:ctrl_alt_win</name>
- <_description>Control is mapped to Alt keys, Alt is mapped to Win keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:meta_win</name>
- <_description>Meta is mapped to Win keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:left_meta_win</name>
- <_description>Meta is mapped to Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:hyper_win</name>
- <_description>Hyper is mapped to Win-keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:alt_super_win</name>
- <_description>Alt is mapped to Right Win, Super to Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:swap_lalt_lwin</name>
- <_description>Left Alt is swapped with Left Win</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Tweaking the position of the "Compose" key: mapping to existing PC keys -->
- <configItem>
- <name>Compose key</name>
- <_description>Compose key position</_description>
- </configItem>
- <option>
- <configItem>
- <name>compose:ralt</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:lwin</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:rwin</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:menu</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:lctrl</name>
- <_description>Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:rctrl</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:caps</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:102</name>
- <_description><Less/Greater></_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:paus</name>
- <_description>Pause</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:prsc</name>
- <_description>PrtSc</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:sclk</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>compat</name>
- <_description>Miscellaneous compatibility options</_description>
- </configItem>
- <option>
- <configItem>
- <name>numpad:pc</name>
- <_description>Default numeric keypad keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:mac</name>
- <_description>Numeric keypad keys work as with Mac</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:microsoft</name>
- <_description>Shift with numeric keypad keys works as in MS Windows</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:shift3</name>
- <_description>Shift does not cancel Num Lock, chooses 3rd level instead</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>srvrkeys:none</name>
- <_description>Special keys (Ctrl+Alt+<key>) handled in a server</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>apple:alupckeys</name>
- <_description>Apple Aluminium Keyboard: emulate PC keys (Print, Scroll Lock, Pause, Num Lock)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:breaks_caps</name>
- <_description>Shift cancels Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>misc:typo</name>
- <_description>Enable extra typographic characters</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_capslock</name>
- <_description>Both Shift-Keys together toggle Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_capslock_cancel</name>
- <_description>Both Shift-Keys together activate Caps Lock, one Shift-Key deactivates</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_shiftlock</name>
- <_description>Both Shift-Keys together toggle ShiftLock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:pointerkeys</name>
- <_description>Toggle PointerKeys with Shift + NumLock.</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Special shortcuts for the Euro character -->
- <configItem>
- <name>eurosign</name>
- <_description>Adding currency signs to certain keys</_description>
- </configItem>
- <option>
- <configItem>
- <name>eurosign:e</name>
- <_description>Euro on E</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:2</name>
- <_description>Euro on 2</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:4</name>
- <_description>Euro on 4</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:5</name>
- <_description>Euro on 5</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>rupeesign:4</name>
- <_description>Rupee on 4</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>lv5</name>
- <_description>Key to choose 5th level</_description>
- </configItem>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock</name>
- <_description><Less/Greater> chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock</name>
- <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lwin_switch_lock</name>
- <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:rwin_switch_lock</name>
- <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock_cancel</name>
- <_description><Less/Greater> chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock_cancel</name>
- <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lwin_switch_lock_cancel</name>
- <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:rwin_switch_lock_cancel</name>
- <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock_cancel</name>
- <_description><Less/Greater> chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock_cancel</name>
- <_description>Right Alt chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Let space output NBSP, NNBSP, ZWNJ, and ZWJ for the desired level -->
- <configItem>
- <name>nbsp</name>
- <_description>Using space key to input non-breakable space character</_description>
- </configItem>
- <option>
- <configItem>
- <name>nbsp:none</name>
- <_description>Usual space at any level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level2</name>
- <_description>Non-breakable space character at second level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3</name>
- <_description>Non-breakable space character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3s</name>
- <_description>Non-breakable space character at third level, nothing at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3n</name>
- <_description>Non-breakable space character at third level, thin non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4</name>
- <_description>Non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4n</name>
- <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4nl</name>
- <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level (via Ctrl+Shift)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2</name>
- <_description>Zero-width non-joiner character at second level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2zwj3</name>
- <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2zwj3nb4</name>
- <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level, non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3s</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, nothing at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3zwj4</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, zero-width joiner at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3nnb4</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, thin non-breakable space at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj3zwj4</name>
- <_description>Zero-width non-joiner character at third level, zero-width joiner at fourth level</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>japan</name>
- <_description>Japanese keyboard options</_description>
- </configItem>
- <option>
- <configItem>
- <name>japan:kana_lock</name>
- <_description>Kana Lock key is locking</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>japan:nicola_f_bs</name>
- <_description>NICOLA-F style Backspace</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <configItem>
- <name>esperanto</name>
- <_description>Adding Esperanto circumflexes (supersigno)</_description>
- </configItem>
- <option>
- <configItem>
- <name>esperanto:qwerty</name>
- <_description>To the corresponding key in a Qwerty keyboard.</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>esperanto:dvorak</name>
- <_description>To the corresponding key in a Dvorak keyboard.</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>terminate</name>
- <_description>Key sequence to kill the X server</_description>
- </configItem>
- <option>
- <configItem>
- <name>terminate:ctrl_alt_bksp</name>
- <_description>Control + Alt + Backspace</_description>
- </configItem>
- </option>
- </group>
- </optionList>
-</xkbConfigRegistry>
+<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd"> +<xkbConfigRegistry version="1.1"> + <modelList> + <model> + <configItem> + <name>pc101</name> + <_description>Generic 101-key PC</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>pc102</name> + <_description>Generic 102-key (Intl) PC</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>pc104</name> + <_description>Generic 104-key PC</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>pc105</name> + <_description>Generic 105-key (Intl) PC</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dell101</name> + <_description>Dell 101-key PC</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>latitude</name> + <_description>Dell Latitude series laptop</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dellm65</name> + <_description>Dell Precision M65</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>everex</name> + <_description>Everex STEPnote</_description> + <vendor>Everex</vendor> + </configItem> + </model> + <model> + <configItem> + <name>flexpro</name> + <_description>Keytronic FlexPro</_description> + <vendor>Keytronic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoft</name> + <_description>Microsoft Natural</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>omnikey101</name> + <_description>Northgate OmniKey 101</_description> + <vendor>Northgate</vendor> + </configItem> + </model> + <model> + <configItem> + <name>winbook</name> + <_description>Winbook Model XP5</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>pc98</name> + <_description>PC-98xx Series</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>a4techKB21</name> + <_description>A4Tech KB-21</_description> + <vendor>A4Tech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>a4techKBS8</name> + <_description>A4Tech KBS-8</_description> + <vendor>A4Tech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>a4_rfkb23</name> + <_description>A4Tech Wireless Desktop RFKB-23</_description> + <vendor>A4Tech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>airkey</name> + <_description>Acer AirKey V</_description> + <vendor>Acer</vendor> + </configItem> + </model> + <model> + <configItem> + <name>azonaRF2300</name> + <_description>Azona RF2300 wireless Internet Keyboard</_description> + <vendor>Azona</vendor> + </configItem> + </model> + <model> + <configItem> + <name>scorpius</name> + <_description>Advance Scorpius KI</_description> + <vendor>Scorpius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>brother</name> + <_description>Brother Internet Keyboard</_description> + <vendor>Brother</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc5113rf</name> + <_description>BTC 5113RF Multimedia</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc5126t</name> + <_description>BTC 5126T</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc6301urf</name> + <_description>BTC 6301URF</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc9000</name> + <_description>BTC 9000</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc9000a</name> + <_description>BTC 9000A</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc9001ah</name> + <_description>BTC 9001AH</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc5090</name> + <_description>BTC 5090</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc9019u</name> + <_description>BTC 9019U</_description> + <vendor>BTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>btc9116u</name> + <_description>BTC 9116U Mini Wireless Internet and Gaming</_description> + </configItem> + </model> + <model> + <configItem> + <name>cherryblue</name> + <_description>Cherry Blue Line CyBo@rd</_description> + </configItem> + </model> + <model> + <configItem> + <name>cherryblueb</name> + <_description>Cherry CyMotion Master XPress</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>cherrybluea</name> + <_description>Cherry Blue Line CyBo@rd (alternate option)</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>cherrycyboard</name> + <_description>Cherry CyBo@rd USB-Hub</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>cherrycmexpert</name> + <_description>Cherry CyMotion Expert</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>cherrybunlim</name> + <_description>Cherry B.UNLIMITED</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>chicony</name> + <_description>Chicony Internet Keyboard</_description> + <vendor>Chicony</vendor> + </configItem> + </model> + <model> + <configItem> + <name>chicony0108</name> + <_description>Chicony KU-0108</_description> + <vendor>Chicony</vendor> + </configItem> + </model> + <model> + <configItem> + <name>chicony0420</name> + <_description>Chicony KU-0420</_description> + <vendor>Chicony</vendor> + </configItem> + </model> + <model> + <configItem> + <name>chicony9885</name> + <_description>Chicony KB-9885</_description> + <vendor>Chicony</vendor> + </configItem> + </model> + <model> + <configItem> + <name>compaqeak8</name> + <_description>Compaq Easy Access Keyboard</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>compaqik7</name> + <_description>Compaq Internet Keyboard (7 keys)</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>compaqik13</name> + <_description>Compaq Internet Keyboard (13 keys)</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>compaqik18</name> + <_description>Compaq Internet Keyboard (18 keys)</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>cymotionlinux</name> + <_description>Cherry CyMotion Master Linux</_description> + <vendor>Cherry</vendor> + </configItem> + </model> + <model> + <configItem> + <name>armada</name> + <_description>Laptop/notebook Compaq (eg. Armada) Laptop Keyboard</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>presario</name> + <_description>Laptop/notebook Compaq (eg. Presario) Internet Keyboard</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>ipaq</name> + <_description>Compaq iPaq Keyboard</_description> + <vendor>Compaq</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dell</name> + <_description>Dell</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dellsk8125</name> + <_description>Dell SK-8125</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dellsk8135</name> + <_description>Dell SK-8135</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dellusbmm</name> + <_description>Dell USB Multimedia Keyboard</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>inspiron</name> + <_description>Dell Laptop/notebook Inspiron 6xxx/8xxx</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>precision_m</name> + <_description>Dell Laptop/notebook Precision M series</_description> + <vendor>Dell</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dexxa</name> + <_description>Dexxa Wireless Desktop Keyboard</_description> + <vendor>Dexxa</vendor> + </configItem> + </model> + <model> + <configItem> + <name>diamond</name> + <_description>Diamond 9801 / 9802 series</_description> + <vendor>Diamond</vendor> + </configItem> + </model> + <model> + <configItem> + <name>dtk2000</name> + <_description>DTK2000</_description> + </configItem> + </model> + <model> + <configItem> + <name>ennyah_dkb1008</name> + <_description>Ennyah DKB-1008</_description> + <vendor>Ennyah</vendor> + </configItem> + </model> + <model> + <configItem> + <name>fscaa1667g</name> + <_description>Fujitsu-Siemens Computers AMILO laptop</_description> + <vendor>Fujitsu-Siemens</vendor> + </configItem> + </model> + <model> + <configItem> + <name>genius</name> + <_description>Genius Comfy KB-16M / Genius MM Keyboard KWD-910</_description> + <vendor>Genius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>geniuscomfy</name> + <_description>Genius Comfy KB-12e</_description> + <vendor>Genius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>geniuscomfy2</name> + <_description>Genius Comfy KB-21e-Scroll</_description> + <vendor>Genius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>geniuskb19e</name> + <_description>Genius KB-19e NB</_description> + <vendor>Genius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>geniuskkb2050hs</name> + <_description>Genius KKB-2050HS</_description> + <vendor>Genius</vendor> + </configItem> + </model> + <model> + <configItem> + <name>gyration</name> + <_description>Gyration</_description> + <vendor>Gyration</vendor> + </configItem> + </model> + <model> + <configItem> + <name>htcdream</name> + <_description>HTC Dream</_description> + <vendor>HTC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>kinesis</name> + <_description>Kinesis</_description> + <vendor>Kinesis</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logitech_base</name> + <_description>Logitech Generic Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logitech_g15</name> + <_description>Logitech G15 extra keys via G15daemon</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpi6</name> + <_description>Hewlett-Packard Internet Keyboard</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hp250x</name> + <_description>Hewlett-Packard SK-250x Multimedia Keyboard</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpxe3gc</name> + <_description>Hewlett-Packard Omnibook XE3 GC</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpxe3gf</name> + <_description>Hewlett-Packard Omnibook XE3 GF</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpxt1000</name> + <_description>Hewlett-Packard Omnibook XT1000</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpdv5</name> + <_description>Hewlett-Packard Pavilion dv5</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpzt11xx</name> + <_description>Hewlett-Packard Pavilion ZT11xx</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hp500fa</name> + <_description>Hewlett-Packard Omnibook 500 FA</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hp5xx</name> + <_description>Hewlett-Packard Omnibook 5xx</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpnx9020</name> + <_description>Hewlett-Packard nx9020</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hp6000</name> + <_description>Hewlett-Packard Omnibook 6000/6100</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>honeywell_euroboard</name> + <_description>Honeywell Euroboard</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hpmini110</name> + <_description>Hewlett-Packard Mini 110 Notebook</_description> + <vendor>Hewlett-Packard</vendor> + </configItem> + </model> + <model> + <configItem> + <name>rapidaccess</name> + <_description>IBM Rapid Access</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>rapidaccess2</name> + <_description>IBM Rapid Access II</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>thinkpad</name> + <_description>IBM ThinkPad 560Z/600/600E/A22E</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>thinkpad60</name> + <_description>IBM ThinkPad R60/T60/R61/T61</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>thinkpadz60</name> + <_description>IBM ThinkPad Z60m/Z60t/Z61m/Z61t</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>ibm_spacesaver</name> + <_description>IBM Space Saver</_description> + <vendor>Lenovo (previously IBM)</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiaccess</name> + <_description>Logitech Access Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiclx300</name> + <_description>Logitech Cordless Desktop LX-300</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logii350</name> + <_description>Logitech Internet 350 Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logimel</name> + <_description>Logitech Media Elite Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicd</name> + <_description>Logitech Cordless Desktop</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicd_it</name> + <_description>Logitech Cordless Desktop iTouch</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicd_nav</name> + <_description>Logitech Cordless Desktop Navigator</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicd_opt</name> + <_description>Logitech Cordless Desktop Optical</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicda</name> + <_description>Logitech Cordless Desktop (alternate option)</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicdpa2</name> + <_description>Logitech Cordless Desktop Pro (alternate option 2)</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicfn</name> + <_description>Logitech Cordless Freedom/Desktop Navigator</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicdn</name> + <_description>Logitech Cordless Desktop Navigator</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiitc</name> + <_description>Logitech iTouch Cordless Keyboard (model Y-RB6)</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiik</name> + <_description>Logitech Internet Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>itouch</name> + <_description>Logitech iTouch</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logicink</name> + <_description>Logitech Internet Navigator Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiex110</name> + <_description>Logitech Cordless Desktop EX110</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiinkse</name> + <_description>Logitech iTouch Internet Navigator Keyboard SE</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiinkseusb</name> + <_description>Logitech iTouch Internet Navigator Keyboard SE (USB)</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiultrax</name> + <_description>Logitech Ultra-X Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logiultraxc</name> + <_description>Logitech Ultra-X Cordless Media Desktop Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logidinovo</name> + <_description>Logitech diNovo Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>logidinovoedge</name> + <_description>Logitech diNovo Edge Keyboard</_description> + <vendor>Logitech</vendor> + </configItem> + </model> + <model> + <configItem> + <name>mx1998</name> + <_description>Memorex MX1998</_description> + <vendor>Memorex</vendor> + </configItem> + </model> + <model> + <configItem> + <name>mx2500</name> + <_description>Memorex MX2500 EZ-Access Keyboard</_description> + <vendor>Memorex</vendor> + </configItem> + </model> + <model> + <configItem> + <name>mx2750</name> + <_description>Memorex MX2750</_description> + <vendor>Memorex</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoft4000</name> + <_description>Microsoft Natural Wireless Ergonomic Keyboard 4000</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoft7000</name> + <_description>Microsoft Natural Wireless Ergonomic Keyboard 7000</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftinet</name> + <_description>Microsoft Internet Keyboard</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftpro</name> + <_description>Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftprousb</name> + <_description>Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftprooem</name> + <_description>Microsoft Natural Keyboard Pro OEM</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>vsonku306</name> + <_description>ViewSonic KU-306 Internet Keyboard</_description> + <vendor>ViewSonic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftprose</name> + <_description>Microsoft Internet Keyboard Pro, Swedish</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftoffice</name> + <_description>Microsoft Office Keyboard</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftmult</name> + <_description>Microsoft Wireless Multimedia Keyboard 1.0A</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftelite</name> + <_description>Microsoft Natural Keyboard Elite</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>microsoftccurve2k</name> + <_description>Microsoft Comfort Curve Keyboard 2000</_description> + <vendor>Microsoft Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>oretec</name> + <_description>Ortek MCK-800 MM/Internet keyboard</_description> + <vendor>Ortek</vendor> + </configItem> + </model> + <model> + <configItem> + <name>propeller</name> + <_description>Propeller Voyager (KTEZ-1000)</_description> + <vendor>KeyTronic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>qtronix</name> + <_description>QTronix Scorpius 98N+</_description> + <vendor>QTronix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>samsung4500</name> + <_description>Samsung SDM 4500P</_description> + <vendor>Samsung</vendor> + </configItem> + </model> + <model> + <configItem> + <name>samsung4510</name> + <_description>Samsung SDM 4510P</_description> + <vendor>Samsung</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sanwaskbkg3</name> + <_description>Sanwa Supply SKB-KG3</_description> + <vendor>Sanwa Supply Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sk1300</name> + <_description>SK-1300</_description> + <vendor>NEC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sk2500</name> + <_description>SK-2500</_description> + <vendor>NEC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sk6200</name> + <_description>SK-6200</_description> + <vendor>NEC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sk7100</name> + <_description>SK-7100</_description> + <vendor>NEC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sp_inet</name> + <_description>Super Power Multimedia Keyboard</_description> + <vendor>Generic</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sven</name> + <_description>SVEN Ergonomic 2500</_description> + <vendor>SVEN</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sven303</name> + <_description>SVEN Slim 303</_description> + <vendor>SVEN</vendor> + </configItem> + </model> + <model> + <configItem> + <name>symplon</name> + <_description>Symplon PaceBook (tablet PC)</_description> + <vendor>Symplon</vendor> + </configItem> + </model> + <model> + <configItem> + <name>toshiba_s3000</name> + <_description>Toshiba Satellite S3000</_description> + <vendor>Toshiba</vendor> + </configItem> + </model> + <model> + <configItem> + <name>trust</name> + <_description>Trust Wireless Keyboard Classic</_description> + <vendor>Trust</vendor> + </configItem> + </model> + <model> + <configItem> + <name>trustda</name> + <_description>Trust Direct Access Keyboard</_description> + <vendor>Trust</vendor> + </configItem> + </model> + <model> + <configItem> + <name>trust_slimline</name> + <_description>Trust Slimline</_description> + <vendor>Trust</vendor> + </configItem> + </model> + <model> + <configItem> + <name>tm2020</name> + <_description>TypeMatrix EZ-Reach 2020</_description> + <vendor>TypeMatrix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>tm2030PS2</name> + <_description>TypeMatrix EZ-Reach 2030 PS2</_description> + <vendor>TypeMatrix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>tm2030USB</name> + <_description>TypeMatrix EZ-Reach 2030 USB</_description> + <vendor>TypeMatrix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>tm2030USB-102</name> + <_description>TypeMatrix EZ-Reach 2030 USB (102/105:EU mode)</_description> + <vendor>TypeMatrix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>tm2030USB-106</name> + <_description>TypeMatrix EZ-Reach 2030 USB (106:JP mode)</_description> + <vendor>TypeMatrix</vendor> + </configItem> + </model> + <model> + <configItem> + <name>yahoo</name> + <_description>Yahoo! Internet Keyboard</_description> + <vendor>Yahoo!</vendor> + </configItem> + </model> + <model> + <configItem> + <name>macbook78</name> + <_description>MacBook/MacBook Pro</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>macbook79</name> + <_description>MacBook/MacBook Pro (Intl)</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>macintosh</name> + <_description>Macintosh</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>macintosh_old</name> + <_description>Macintosh Old</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>macintosh_hhk</name> + <_description>Happy Hacking Keyboard for Mac</_description> + <vendor>Fujitsu</vendor> + </configItem> + </model> + <model> + <configItem> + <name>acer_c300</name> + <_description>Acer C300</_description> + <vendor>Acer</vendor> + </configItem> + </model> + <model> + <configItem> + <name>acer_ferrari4k</name> + <_description>Acer Ferrari 4000</_description> + <vendor>Acer</vendor> + </configItem> + </model> + <model> + <configItem> + <name>acer_laptop</name> + <_description>Acer Laptop</_description> + <vendor>Acer</vendor> + </configItem> + </model> + <model> + <configItem> + <name>asus_laptop</name> + <_description>Asus Laptop</_description> + <vendor>Asus</vendor> + </configItem> + </model> + <model> + <configItem> + <name>apple</name> + <_description>Apple</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>apple_laptop</name> + <_description>Apple Laptop</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>applealu_ansi</name> + <_description>Apple Aluminium Keyboard (ANSI)</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>applealu_iso</name> + <_description>Apple Aluminium Keyboard (ISO)</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>applealu_jis</name> + <_description>Apple Aluminium Keyboard (JIS)</_description> + <vendor>Apple</vendor> + </configItem> + </model> + <model> + <configItem> + <name>silvercrest</name> + <_description>SILVERCREST Multimedia Wireless Keyboard</_description> + <vendor>Silvercrest</vendor> + </configItem> + </model> + <model> + <configItem> + <name>emachines</name> + <_description>Laptop/notebook eMachines m68xx</_description> + <vendor>eMachines</vendor> + </configItem> + </model> + <model> + <configItem> + <name>benqx</name> + <_description>BenQ X-Touch</_description> + <vendor>BenQ</vendor> + </configItem> + </model> + <model> + <configItem> + <name>benqx730</name> + <_description>BenQ X-Touch 730</_description> + <vendor>BenQ</vendor> + </configItem> + </model> + <model> + <configItem> + <name>benqx800</name> + <_description>BenQ X-Touch 800</_description> + <vendor>BenQ</vendor> + </configItem> + </model> + <model> + <configItem> + <name>hhk</name> + <_description>Happy Hacking Keyboard</_description> + <vendor>Fujitsu</vendor> + </configItem> + </model> + <model> + <configItem> + <name>classmate</name> + <_description>Classmate PC</_description> + <vendor>Intel</vendor> + </configItem> + </model> + <model> + <configItem> + <name>olpc</name> + <_description>OLPC</_description> + <vendor>OLPC</vendor> + </configItem> + </model> + <model> + <configItem> + <name>sun6</name> + <_description>Sun Type 5/6</_description> + <vendor>Sun Microsystems</vendor> + </configItem> + </model> + <model> + <configItem> + <name>targa_v811</name> + <_description>Targa Visionary 811</_description> + <vendor>Targa</vendor> + </configItem> + </model> + <model> + <configItem> + <name>unitekkb1925</name> + <_description>Unitek KB-1925</_description> + <vendor>Unitek Group</vendor> + </configItem> + </model> + <model> + <configItem> + <name>compalfl90</name> + <_description>FL90</_description> + <vendor>Compal Electronics Inc.</vendor> + </configItem> + </model> + <model> + <configItem> + <name>creativedw7000</name> + <_description>Creative Desktop Wireless 7000</_description> + <vendor>Creative</vendor> + </configItem> + </model> + <model> + <configItem> + <name>htcdream</name> + <_description>Htc Dream phone</_description> + <vendor>htc</vendor> + </configItem> + </model> + </modelList> + <layoutList> + <layout> + <configItem> + <name>us</name> + <_shortDescription>USA</_shortDescription> + <_description>USA</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>chr</name> + <_description>USA - Cherokee</_description> + <languageList> + <iso639Id>chr</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>euro</name> + <_description>USA - With EuroSign on 5</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>intl</name> + <_description>USA - International (with dead keys)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>alt-intl</name> + <_description>USA - Alternative international</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>colemak</name> + <_description>USA - Colemak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>USA - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-intl</name> + <_description>USA - Dvorak international (with dead keys)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-alt-intl</name> + <_description>USA - Dvorak alternative international (no dead keys)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-l</name> + <_description>USA - Left handed Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-r</name> + <_description>USA - Right handed Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-classic</name> + <_description>USA - Classic Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvp</name> + <_description>USA - Programmer Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>rus</name> + <_description>USA - Russian phonetic</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>USA - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>altgr-intl</name> + <_description>USA - International (AltGr dead keys)</_description> + <languageList><iso639Id>eng</iso639Id> + <iso639Id>fra</iso639Id> + <iso639Id>ger</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>olpc2</name> + <_description>USA - Layout toggle on multiply/divide key</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>hbs</name> + <_description>USA - Serbo-Croatian</_description> + <languageList><iso639Id>eng</iso639Id> + <iso639Id>bos</iso639Id> + <iso639Id>hbs</iso639Id> + <iso639Id>hrv</iso639Id> + <iso639Id>srp</iso639Id> </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ad</name> + <_shortDescription>And</_shortDescription> + <_description>Andorra</_description> + <languageList> + <iso639Id>cat</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>af</name> + <_shortDescription>Afg</_shortDescription> + <_description>Afghanistan</_description> + </configItem> + <variantList> + <variant> + <configItem> + <name>ps</name> + <_description>Afghanistan - Pashto</_description> + <languageList> + <iso639Id>pus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>uz</name> + <_description>Afghanistan - Southern Uzbek</_description> + <languageList> + <iso639Id>uzb</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>olpc-ps</name> + <_description>Afghanistan - OLPC Pashto</_description> + <languageList> + <iso639Id>pus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>fa-olpc</name> + <_description>Afghanistan - OLPC Dari</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>uz-olpc</name> + <_description>Afghanistan - OLPC Southern Uzbek</_description> + <languageList> + <iso639Id>uzb</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ara</name> + <_shortDescription>Ara</_shortDescription> + <_description>Arabic</_description> + <countryList> + <iso3166Id>AE</iso3166Id> + <iso3166Id>BH</iso3166Id> + <iso3166Id>DZ</iso3166Id> + <iso3166Id>EG</iso3166Id> + <iso3166Id>EH</iso3166Id> + <iso3166Id>JO</iso3166Id> + <iso3166Id>KW</iso3166Id> + <iso3166Id>LB</iso3166Id> + <iso3166Id>LY</iso3166Id> + <iso3166Id>MA</iso3166Id> + <iso3166Id>MR</iso3166Id> + <iso3166Id>OM</iso3166Id> + <iso3166Id>PS</iso3166Id> + <iso3166Id>QA</iso3166Id> + <iso3166Id>SA</iso3166Id> + <iso3166Id>SD</iso3166Id> + <iso3166Id>SY</iso3166Id> + <iso3166Id>TN</iso3166Id> + <iso3166Id>YE</iso3166Id> + </countryList> + <languageList> + <iso639Id>ara</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>azerty</name> + <_description>Arabic - azerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>azerty_digits</name> + <_description>Arabic - azerty/digits</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>digits</name> + <_description>Arabic - digits</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty</name> + <_description>Arabic - qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty_digits</name> + <_description>Arabic - qwerty/digits</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>buckwalter</name> + <_description>Arabic - Buckwalter</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>al</name> + <_shortDescription>Alb</_shortDescription> + <_description>Albania</_description> + <languageList> + <iso639Id>alb</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>am</name> + <_shortDescription>Arm</_shortDescription> + <_description>Armenia</_description> + <languageList> + <iso639Id>hye</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>phonetic</name> + <_description>Armenia - Phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>phonetic-alt</name> + <_description>Armenia - Alternative Phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>eastern</name> + <_description>Armenia - Eastern</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>western</name> + <_description>Armenia - Western</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>eastern-alt</name> + <_description>Armenia - Alternative Eastern</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>at</name> + <_shortDescription>Aut</_shortDescription> + <_description>Austria</_description> + <languageList> + <iso639Id>ger</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Austria - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Austria - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Austria - Macintosh</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>az</name> + <_shortDescription>Aze</_shortDescription> + <_description>Azerbaijan</_description> + <languageList> + <iso639Id>aze</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>cyrillic</name> + <_description>Azerbaijan - Cyrillic</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>by</name> + <_shortDescription>Blr</_shortDescription> + <_description>Belarus</_description> + <languageList> + <iso639Id>bel</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>legacy</name> + <_description>Belarus - Legacy</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latin</name> + <_description>Belarus - Latin</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>be</name> + <_shortDescription>Bel</_shortDescription> + <_description>Belgium</_description> + <languageList><iso639Id>ger</iso639Id> + <iso639Id>nld</iso639Id> + <iso639Id>fra</iso639Id></languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>oss</name> + <_description>Belgium - Alternative</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss_latin9</name> + <_description>Belgium - Alternative, latin-9 only</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss_sundeadkeys</name> + <_description>Belgium - Alternative, Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>iso-alternate</name> + <_description>Belgium - ISO Alternate</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Belgium - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Belgium - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>wang</name> + <_description>Belgium - Wang model 724 azerty</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>bd</name> + <_shortDescription>Bgd</_shortDescription> + <_description>Bangladesh</_description> + <languageList> + <iso639Id>ben</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>probhat</name> + <_description>Bangladesh - Probhat</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>in</name> + <_shortDescription>Ind</_shortDescription> + <_description>India</_description> + </configItem> + <variantList> + <variant> + <configItem> + <name>ben</name> + <_description>India - Bengali</_description> + <languageList> + <iso639Id>ben</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ben_probhat</name> + <_description>India - Bengali Probhat</_description> + <languageList> + <iso639Id>ben</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>guj</name> + <_description>India - Gujarati</_description> + <languageList> + <iso639Id>guj</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>guru</name> + <_description>India - Gurmukhi</_description> + <languageList> + <iso639Id>pan</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>jhelum</name> + <_description>India - Gurmukhi Jhelum</_description> + <languageList> + <iso639Id>pan</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>kan</name> + <_description>India - Kannada</_description> + <languageList> + <iso639Id>kan</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mal</name> + <_description>India - Malayalam</_description> + <languageList> + <iso639Id>mal</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mal_lalitha</name> + <_description>India - Malayalam Lalitha</_description> + <languageList> + <iso639Id>mal</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mal_enhanced</name> + <_description>India - Malayalam enhanced Inscript with Rupee Sign</_description> + <languageList><iso639Id>mal</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ori</name> + <_description>India - Oriya</_description> + <languageList> + <iso639Id>ori</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam_unicode</name> + <_description>India - Tamil Unicode</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam_keyboard_with_numerals</name> + <_description>India - Tamil Keyboard with Numerals</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam_TAB</name> + <_description>India - Tamil TAB Typewriter</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam_TSCII</name> + <_description>India - Tamil TSCII Typewriter</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam</name> + <_description>India - Tamil</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tel</name> + <_description>India - Telugu</_description> + <languageList> + <iso639Id>tel</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>urd-phonetic</name> + <_description>India - Urdu, Phonetic</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>urd-phonetic3</name> + <_description>India - Urdu, Alternative phonetic</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>urd-winkeys</name> + <_description>India - Urdu, Winkeys</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>bolnagri</name> + <_description>India - Hindi Bolnagri</_description> + <languageList> + <iso639Id>hin</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>hin-wx</name> + <_description>India - Hindi Wx</_description> + <languageList> + <iso639Id>hin</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>eng</name> + <_description>India - English with RupeeSign</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ba</name> + <_shortDescription>Bih</_shortDescription> + <_description>Bosnia and Herzegovina</_description> + <languageList> + <iso639Id>bos</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>alternatequotes</name> + <_description>Bosnia and Herzegovina - Use guillemets for quotes</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>unicode</name> + <_description>Bosnia and Herzegovina - Use Bosnian digraphs</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>unicodeus</name> + <_description>Bosnia and Herzegovina - US keyboard with Bosnian digraphs</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Bosnia and Herzegovina - US keyboard with Bosnian letters</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>br</name> + <_shortDescription>Bra</_shortDescription> + <_description>Brazil</_description> + <languageList> + <iso639Id>por</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Brazil - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Brazil - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo</name> + <_description>Brazil - Nativo</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo-us</name> + <_description>Brazil - Nativo for USA keyboards</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo-epo</name> + <_description>Brazil - Nativo for Esperanto</_description> + <languageList> + <iso639Id>epo</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>bg</name> + <_shortDescription>Bgr</_shortDescription> + <_description>Bulgaria</_description> + <languageList> + <iso639Id>bul</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>phonetic</name> + <_description>Bulgaria - Traditional phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>bas_phonetic</name> + <_description>Bulgaria - New phonetic</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ma</name> + <_description>Morocco</_description> + </configItem> + <variantList> + <variant> + <configItem> + <name>french</name> + <_description>Morocco - French</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh</name> + <_description>Morocco - Tifinagh</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh-alt</name> + <_description>Morocco - Tifinagh alternative</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh-alt-phonetic</name> + <_description>Morocco - Tifinagh alternative phonetic</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh-extended</name> + <_description>Morocco - Tifinagh extended</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh-phonetic</name> + <_description>Morocco - Tifinagh phonetic</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tifinagh-extended-phonetic</name> + <_description>Morocco - Tifinagh extended phonetic</_description> + <languageList> + <iso639Id>ber</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mm</name> + <_shortDescription>Mmr</_shortDescription> + <_description>Myanmar</_description> + <languageList> + <iso639Id>mya</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>ca</name> + <_shortDescription>Can</_shortDescription> + <_description>Canada</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>fr-dvorak</name> + <_description>Canada - French Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>fr-legacy</name> + <_description>Canada - French (legacy)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>multix</name> + <_description>Canada - Multilingual</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>multi</name> + <_description>Canada - Multilingual, first part</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>multi-2gr</name> + <_description>Canada - Multilingual, second part</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ike</name> + <_description>Canada - Inuktitut</_description> + <languageList> + <iso639Id>iku</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>shs</name> + <_description>Canada - Secwepemctsin</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>kut</name> + <_description>Canada - Ktunaxa</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>eng</name> + <_description>Canada - English</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>cd</name> + <_shortDescription>COD</_shortDescription> + <_description>Congo, Democratic Republic of the</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>cn</name> + <_shortDescription>Chn</_shortDescription> + <_description>China</_description> + <languageList> + <iso639Id>chi</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>tib</name> + <_description>China - Tibetan</_description> + <languageList> + <iso639Id>tib</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tib_asciinum</name> + <_description>China - Tibetan (with ASCII numerals)</_description> + <languageList> + <iso639Id>tib</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>uig</name> + <_description>China - Uyghur</_description> + <languageList> + <iso639Id>uig</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>hr</name> + <_shortDescription>Hrv</_shortDescription> + <_description>Croatia</_description> + <languageList> + <iso639Id>scr</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>alternatequotes</name> + <_description>Croatia - Use guillemets for quotes</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>unicode</name> + <_description>Croatia - Use Croatian digraphs</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>unicodeus</name> + <_description>Croatia - US keyboard with Croatian digraphs</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Croatia - US keyboard with Croatian letters</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>cz</name> + <_shortDescription>Cze</_shortDescription> + <_description>Czechia</_description> + <languageList> + <iso639Id>cze</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>bksl</name> + <_description>Czechia - With <\|> key</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty</name> + <_description>Czechia - qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty_bksl</name> + <_description>Czechia - qwerty, extended Backslash</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ucw</name> + <_description>Czechia - UCW layout (accented letters only)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-ucw</name> + <_description>Czechia - US Dvorak with CZ UCW support</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>dk</name> + <_shortDescription>Dnk</_shortDescription> + <_description>Denmark</_description> + <languageList> + <iso639Id>dan</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Denmark - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Denmark - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_nodeadkeys</name> + <_description>Denmark - Macintosh, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Denmark - Dvorak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>nl</name> + <_shortDescription>Nld</_shortDescription> + <_description>Netherlands</_description> + <languageList> + <iso639Id>nld</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Netherlands - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Netherlands - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>std</name> + <_description>Netherlands - Standard</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>bt</name> + <_shortDescription>Btn</_shortDescription> + <_description>Bhutan</_description> + <languageList> + <iso639Id>dzo</iso639Id> + </languageList> + </configItem> + </layout> + <layout> + <configItem> + <name>ee</name> + <_shortDescription>Est</_shortDescription> + <_description>Estonia</_description> + <languageList> + <iso639Id>est</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Estonia - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Estonia - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Estonia - US keyboard with Estonian letters</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ir</name> + <_shortDescription>Irn</_shortDescription> + <_description>Iran</_description> + <languageList> + <iso639Id>per</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>pes_keypad</name> + <_description>Iran - Persian, with Persian Keypad</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ku</name> + <_description>Iran - Kurdish, Latin Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_f</name> + <_description>Iran - Kurdish, (F)</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_alt</name> + <_description>Iran - Kurdish, Latin Alt-Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_ara</name> + <_description>Iran - Kurdish, Arabic-Latin</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>iq</name> + <_shortDescription>Irq</_shortDescription> + <_description>Iraq</_description> + <languageList><iso639Id>ara</iso639Id> + <iso639Id>kur</iso639Id></languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>ku</name> + <_description>Iraq - Kurdish, Latin Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_f</name> + <_description>Iraq - Kurdish, (F)</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_alt</name> + <_description>Iraq - Kurdish, Latin Alt-Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_ara</name> + <_description>Iraq - Kurdish, Arabic-Latin</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>fo</name> + <_shortDescription>Fro</_shortDescription> + <_description>Faroe Islands</_description> + <languageList> + <iso639Id>fao</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Faroe Islands - Eliminate dead keys</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>fi</name> + <_shortDescription>Fin</_shortDescription> + <_description>Finland</_description> + <languageList> + <iso639Id>fin</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>classic</name> + <_description>Finland - Classic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Finland - Classic, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>smi</name> + <_description>Finland - Northern Saami</_description> + <languageList><iso639Id>smi</iso639Id> + <iso639Id>sme</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Finland - Macintosh</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>fr</name> + <_shortDescription>Fra</_shortDescription> + <_description>France</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>France - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>France - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss</name> + <_description>France - Alternative</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss_latin9</name> + <_description>France - Alternative, latin-9 only</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss_nodeadkeys</name> + <_description>France - Alternative, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oss_sundeadkeys</name> + <_description>France - Alternative, Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latin9</name> + <_description>France - (Legacy) Alternative</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latin9_nodeadkeys</name> + <_description>France - (Legacy) Alternative, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latin9_sundeadkeys</name> + <_description>France - (Legacy) Alternative, Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>bepo</name> + <_description>France - Bepo, ergonomic, Dvorak way</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>bepo_latin9</name> + <_description>France - Bepo, ergonomic, Dvorak way, latin-9 only</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>France - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>France - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>bre</name> + <_description>France - Breton</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>oci</name> + <_description>France - Occitan</_description> + <languageList> + <iso639Id>oci</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>geo</name> + <_description>France - Georgian AZERTY Tskapo</_description> + <languageList> + <iso639Id>geo</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>gh</name> + <_shortDescription>Gha</_shortDescription> + <_description>Ghana</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>generic</name> + <_description>Ghana - Multilingual</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>akan</name> + <_description>Ghana - Akan</_description> + <languageList> + <iso639Id>aka</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ewe</name> + <_description>Ghana - Ewe</_description> + <languageList> + <iso639Id>ewe</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>fula</name> + <_description>Ghana - Fula</_description> + <languageList> + <iso639Id>ful</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ga</name> + <_description>Ghana - Ga</_description> + <languageList> + <iso639Id>gaa</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>hausa</name> + <_description>Ghana - Hausa</_description> + <languageList> + <iso639Id>hau</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>avn</name> + <_description>Ghana - Avatime</_description> + <languageList> + <iso639Id>avn</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>gillbt</name> + <_description>Ghana - GILLBT</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>gn</name> + <_shortDescription>Gin</_shortDescription> + <_description>Guinea</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>ge</name> + <_shortDescription>Geo</_shortDescription> + <_description>Georgia</_description> + <languageList> + <iso639Id>geo</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>ergonomic</name> + <_description>Georgia - Ergonomic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mess</name> + <_description>Georgia - MESS</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ru</name> + <_description>Georgia - Russian</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>os</name> + <_description>Georgia - Ossetian</_description> + <languageList> + <iso639Id>oss</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>de</name> + <_shortDescription>Deu</_shortDescription> + <_description>Germany</_description> + <languageList> + <iso639Id>ger</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>deadacute</name> + <_description>Germany - Dead acute</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>deadgraveacute</name> + <_description>Germany - Dead grave acute</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Germany - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ro</name> + <_description>Germany - Romanian keyboard with German letters</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ro_nodeadkeys</name> + <_description>Germany - Romanian keyboard with German letters, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Germany - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Germany - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>neo</name> + <_description>Germany - Neo 2</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Germany - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_nodeadkeys</name> + <_description>Germany - Macintosh, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dsb</name> + <_description>Germany - Lower Sorbian</_description> + <languageList> + <iso639Id>dsb</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>dsb_qwertz</name> + <_description>Germany - Lower Sorbian (qwertz)</_description> + <languageList> + <iso639Id>dsb</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty</name> + <_description>Germany - qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ru</name> + <_description>Germany - Russian phonetic</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>gr</name> + <_shortDescription>Grc</_shortDescription> + <_description>Greece</_description> + <languageList> + <iso639Id>gre</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>simple</name> + <_description>Greece - Simple</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>extended</name> + <_description>Greece - Extended</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Greece - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>polytonic</name> + <_description>Greece - Polytonic</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>hu</name> + <_shortDescription>Hun</_shortDescription> + <_description>Hungary</_description> + <languageList> + <iso639Id>hun</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>standard</name> + <_description>Hungary - Standard</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Hungary - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty</name> + <_description>Hungary - qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwertz_comma_dead</name> + <_description>Hungary - 101/qwertz/comma/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwertz_comma_nodead</name> + <_description>Hungary - 101/qwertz/comma/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwertz_dot_dead</name> + <_description>Hungary - 101/qwertz/dot/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwertz_dot_nodead</name> + <_description>Hungary - 101/qwertz/dot/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwerty_comma_dead</name> + <_description>Hungary - 101/qwerty/comma/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwerty_comma_nodead</name> + <_description>Hungary - 101/qwerty/comma/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwerty_dot_dead</name> + <_description>Hungary - 101/qwerty/dot/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>101_qwerty_dot_nodead</name> + <_description>Hungary - 101/qwerty/dot/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwertz_comma_dead</name> + <_description>Hungary - 102/qwertz/comma/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwertz_comma_nodead</name> + <_description>Hungary - 102/qwertz/comma/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwertz_dot_dead</name> + <_description>Hungary - 102/qwertz/dot/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwertz_dot_nodead</name> + <_description>Hungary - 102/qwertz/dot/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwerty_comma_dead</name> + <_description>Hungary - 102/qwerty/comma/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwerty_comma_nodead</name> + <_description>Hungary - 102/qwerty/comma/Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwerty_dot_dead</name> + <_description>Hungary - 102/qwerty/dot/Dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>102_qwerty_dot_nodead</name> + <_description>Hungary - 102/qwerty/dot/Eliminate dead keys</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>is</name> + <_shortDescription>Isl</_shortDescription> + <_description>Iceland</_description> + <languageList> + <iso639Id>ice</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>Sundeadkeys</name> + <_description>Iceland - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Iceland - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Iceland - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Iceland - Dvorak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>il</name> + <_shortDescription>Isr</_shortDescription> + <_description>Israel</_description> + <languageList> + <iso639Id>heb</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>lyx</name> + <_description>Israel - lyx</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>phonetic</name> + <_description>Israel - Phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>biblical</name> + <_description>Israel - Biblical Hebrew (Tiro)</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>it</name> + <_shortDescription>Ita</_shortDescription> + <_description>Italy</_description> + <languageList> + <iso639Id>ita</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Italy - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Italy - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Italy - US keyboard with Italian letters</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>geo</name> + <_description>Italy - Georgian</_description> + <languageList> + <iso639Id>geo</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>jp</name> + <_shortDescription>Jpn</_shortDescription> + <_description>Japan</_description> + <languageList> + <iso639Id>jpn</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>kana</name> + <_description>Japan - Kana</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>kana86</name> + <_description>Japan - Kana 86</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>OADG109A</name> + <_description>Japan - OADG 109A</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Japan - Macintosh</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>kg</name> + <_shortDescription>Kgz</_shortDescription> + <_description>Kyrgyzstan</_description> + <languageList> + <iso639Id>kir</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>phonetic</name> + <_description>Kyrgyzstan - Phonetic</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>kh</name> + <_shortDescription>Khm</_shortDescription> + <_description>Cambodia</_description> + <languageList> + <iso639Id>khm</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>kz</name> + <_shortDescription>Kaz</_shortDescription> + <_description>Kazakhstan</_description> + <languageList> + <iso639Id>kaz</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>ruskaz</name> + <_description>Kazakhstan - Russian with Kazakh</_description> + <languageList><iso639Id>kaz</iso639Id> + <iso639Id>rus</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>kazrus</name> + <_description>Kazakhstan - Kazakh with Russian</_description> + <languageList><iso639Id>kaz</iso639Id> + <iso639Id>rus</iso639Id></languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>la</name> + <_shortDescription>Lao</_shortDescription> + <_description>Laos</_description> + <languageList> + <iso639Id>lao</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>stea</name> + <_description>Laos - STEA (proposed standard layout)</_description> + <languageList><iso639Id>lao</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>latam</name> + <_shortDescription>Esp</_shortDescription> + <_description>Latin American</_description> + <countryList> + <iso3166Id>AR</iso3166Id> + <iso3166Id>BO</iso3166Id> + <iso3166Id>CL</iso3166Id> + <iso3166Id>CO</iso3166Id> + <iso3166Id>CR</iso3166Id> + <iso3166Id>CU</iso3166Id> + <iso3166Id>DO</iso3166Id> + <iso3166Id>EC</iso3166Id> + <iso3166Id>GT</iso3166Id> + <iso3166Id>HN</iso3166Id> + <iso3166Id>HT</iso3166Id> + <iso3166Id>MX</iso3166Id> + <iso3166Id>NI</iso3166Id> + <iso3166Id>PA</iso3166Id> + <iso3166Id>PE</iso3166Id> + <iso3166Id>PR</iso3166Id> + <iso3166Id>PY</iso3166Id> + <iso3166Id>SV</iso3166Id> + <iso3166Id>US</iso3166Id> + <iso3166Id>UY</iso3166Id> + <iso3166Id>VE</iso3166Id> + </countryList> + <languageList> + <iso639Id>spa</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Latin American - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>deadtilde</name> + <_description>Latin American - Include dead tilde</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Latin American - Sun dead keys</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>lt</name> + <_shortDescription>Ltu</_shortDescription> + <_description>Lithuania</_description> + <languageList> + <iso639Id>lit</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>std</name> + <_description>Lithuania - Standard</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Lithuania - US keyboard with Lithuanian letters</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ibm</name> + <_description>Lithuania - IBM (LST 1205-92)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>lekp</name> + <_description>Lithuania - LEKP</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>lekpa</name> + <_description>Lithuania - LEKPa</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>lv</name> + <_shortDescription>Lva</_shortDescription> + <_description>Latvia</_description> + <languageList> + <iso639Id>lav</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>apostrophe</name> + <_description>Latvia - Apostrophe (') variant</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>tilde</name> + <_description>Latvia - Tilde (~) variant</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>fkey</name> + <_description>Latvia - F-letter (F) variant</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mao</name> + <_shortDescription>Mao</_shortDescription> + <_description>Maori</_description> + <languageList> + <iso639Id>mao</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>me</name> + <_shortDescription>MNE</_shortDescription> + <_description>Montenegro</_description> + <languageList> + <iso639Id>srp</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>cyrillic</name> + <_description>Montenegro - Cyrillic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>cyrillicyz</name> + <_description>Montenegro - Cyrillic, Z and ZHE swapped</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinunicode</name> + <_description>Montenegro - Latin unicode</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinyz</name> + <_description>Montenegro - Latin qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinunicodeyz</name> + <_description>Montenegro - Latin unicode qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>cyrillicalternatequotes</name> + <_description>Montenegro - Cyrillic with guillemets</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinalternatequotes</name> + <_description>Montenegro - Latin with guillemets</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mk</name> + <_shortDescription>Mkd</_shortDescription> + <_description>Macedonia</_description> + <languageList> + <iso639Id>mkd</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Macedonia - Eliminate dead keys</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mt</name> + <_shortDescription>Mlt</_shortDescription> + <_description>Malta</_description> + <languageList> + <iso639Id>mlt</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>us</name> + <_description>Malta - Maltese keyboard with US layout</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mn</name> + <_shortDescription>Mng</_shortDescription> + <_description>Mongolia</_description> + <languageList> + <iso639Id>mng</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>no</name> + <_shortDescription>Nor</_shortDescription> + <_description>Norway</_description> + <languageList> + <iso639Id>nor</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Norway - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Norway - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>smi</name> + <_description>Norway - Northern Saami</_description> + <languageList> + <iso639Id>sme</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>smi_nodeadkeys</name> + <_description>Norway - Northern Saami, eliminate dead keys</_description> + <languageList> + <iso639Id>sme</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Norway - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_nodeadkeys</name> + <_description>Norway - Macintosh, eliminate dead keys</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>pl</name> + <_shortDescription>Pol</_shortDescription> + <_description>Poland</_description> + <languageList> + <iso639Id>pol</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>qwertz</name> + <_description>Poland - qwertz</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Poland - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak_quotes</name> + <_description>Poland - Dvorak, Polish quotes on quotemark key</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak_altquotes</name> + <_description>Poland - Dvorak, Polish quotes on key 1</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>csb</name> + <_description>Poland - Kashubian</_description> + <languageList> + <iso639Id>csb</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ru_phonetic_dvorak</name> + <_description>Poland - Russian phonetic Dvorak</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>dvp</name> + <_description>Poland - Programmer Dvorak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>pt</name> + <_shortDescription>Prt</_shortDescription> + <_description>Portugal</_description> + <languageList> + <iso639Id>por</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Portugal - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Portugal - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Portugal - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_nodeadkeys</name> + <_description>Portugal - Macintosh, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_sundeadkeys</name> + <_description>Portugal - Macintosh, Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo</name> + <_description>Portugal - Nativo</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo-us</name> + <_description>Portugal - Nativo for USA keyboards</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>nativo-epo</name> + <_description>Portugal - Nativo for Esperanto</_description> + <languageList> + <iso639Id>epo</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ro</name> + <_shortDescription>Rou</_shortDescription> + <_description>Romania</_description> + <languageList> + <iso639Id>rum</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>cedilla</name> + <_description>Romania - Cedilla</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>std</name> + <_description>Romania - Standard</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>std_cedilla</name> + <_description>Romania - Standard (Cedilla)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>winkeys</name> + <_description>Romania - Winkeys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_f</name> + <_description>Romania - Crimean Tatar (Turkish F)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_alt</name> + <_description>Romania - Crimean Tatar (Turkish Alt-Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_dobruca1</name> + <_description>Romania - Crimean Tatar (Dobruca-1 Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_dobruca2</name> + <_description>Romania - Crimean Tatar (Dobruca-2 Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ru</name> + <_shortDescription>Rus</_shortDescription> + <_description>Russia</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>phonetic</name> + <_description>Russia - Phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>phonetic_winkeys</name> + <_description>Russia - Phonetic Winkeys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>typewriter</name> + <_description>Russia - Typewriter</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>legacy</name> + <_description>Russia - Legacy</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>typewriter-legacy</name> + <_description>Russia - Typewriter, legacy</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>tt</name> + <_description>Russia - Tatar</_description> + <languageList> + <iso639Id>tat</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>os_legacy</name> + <_description>Russia - Ossetian, legacy</_description> + <languageList> + <iso639Id>oss</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>os_winkeys</name> + <_description>Russia - Ossetian, Winkeys</_description> + <languageList> + <iso639Id>oss</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>cv</name> + <_description>Russia - Chuvash</_description> + <languageList> + <iso639Id>chv</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>cv_latin</name> + <_description>Russia - Chuvash Latin</_description> + <languageList> + <iso639Id>chv</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>udm</name> + <_description>Russia - Udmurt</_description> + <languageList> + <iso639Id>udm</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>kom</name> + <_description>Russia - Komi</_description> + <languageList> + <iso639Id>kom</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>sah</name> + <_description>Russia - Yakut</_description> + <languageList> + <iso639Id>sah</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>xal</name> + <_description>Russia - Kalmyk</_description> + <languageList> + <iso639Id>xal</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>dos</name> + <_description>Russia - DOS</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>srp</name> + <_description>Russia - Serbian</_description> + <languageList><iso639Id>rus</iso639Id> + <iso639Id>srp</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>bak</name> + <_description>Russia - Bashkirian</_description> + <languageList> + <iso639Id>bak</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>chm</name> + <_description>Russia - Mari</_description> + <languageList> + <iso639Id>chm</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>rs</name> + <_shortDescription>Srb</_shortDescription> + <_description>Serbia</_description> + <languageList> + <iso639Id>srp</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>yz</name> + <_description>Serbia - Z and ZHE swapped</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latin</name> + <_description>Serbia - Latin</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinunicode</name> + <_description>Serbia - Latin Unicode</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinyz</name> + <_description>Serbia - Latin qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinunicodeyz</name> + <_description>Serbia - Latin Unicode qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>alternatequotes</name> + <_description>Serbia - With guillemets</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>latinalternatequotes</name> + <_description>Serbia - Latin with guillemets</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>rue</name> + <_description>Serbia - Pannonian Rusyn Homophonic</_description> + <languageList> + <iso639Id>rue</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>si</name> + <_shortDescription>Svn</_shortDescription> + <_description>Slovenia</_description> + <languageList> + <iso639Id>slv</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>alternatequotes</name> + <_description>Slovenia - Use guillemets for quotes</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us</name> + <_description>Slovenia - US keyboard with Slovenian letters</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>sk</name> + <_shortDescription>Svk</_shortDescription> + <_description>Slovakia</_description> + <languageList> + <iso639Id>slo</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>bksl</name> + <_description>Slovakia - Extended Backslash</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty</name> + <_description>Slovakia - qwerty</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>qwerty_bksl</name> + <_description>Slovakia - qwerty, extended Backslash</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>es</name> + <_shortDescription>Esp</_shortDescription> + <_description>Spain</_description> + <languageList> + <iso639Id>spa</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Spain - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>deadtilde</name> + <_description>Spain - Include dead tilde</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Spain - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Spain - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ast</name> + <_description>Spain - Asturian variant with bottom-dot H and bottom-dot L</_description> + <languageList> + <iso639Id>ast</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>cat</name> + <_description>Spain - Catalan variant with middle-dot L</_description> + <languageList> + <iso639Id>cat</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Spain - Macintosh</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>se</name> + <_shortDescription>Swe</_shortDescription> + <_description>Sweden</_description> + <languageList> + <iso639Id>swe</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>nodeadkeys</name> + <_description>Sweden - Eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Sweden - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>rus</name> + <_description>Sweden - Russian phonetic</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>rus_nodeadkeys</name> + <_description>Sweden - Russian phonetic, eliminate dead keys</_description> + <languageList> + <iso639Id>rus</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>smi</name> + <_description>Sweden - Northern Saami</_description> + <languageList> + <iso639Id>sme</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>Sweden - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>svdvorak</name> + <_description>Sweden - Svdvorak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ch</name> + <_shortDescription>Che</_shortDescription> + <_description>Switzerland</_description> + <languageList><iso639Id>ger</iso639Id> + <iso639Id>gsw</iso639Id></languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>legacy</name> + <_description>Switzerland - Legacy</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>de_nodeadkeys</name> + <_description>Switzerland - German, eliminate dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>de_sundeadkeys</name> + <_description>Switzerland - German, Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>fr</name> + <_description>Switzerland - French</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>fr_nodeadkeys</name> + <_description>Switzerland - French, eliminate dead keys</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>fr_sundeadkeys</name> + <_description>Switzerland - French, Sun dead keys</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>fr_mac</name> + <_description>Switzerland - French (Macintosh)</_description> + <languageList> + <iso639Id>fra</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>de_mac</name> + <_description>Switzerland - German (Macintosh)</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>sy</name> + <_shortDescription>Syr</_shortDescription> + <_description>Syria</_description> + <languageList> + <iso639Id>syr</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>syc</name> + <_description>Syria - Syriac</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>syc_phonetic</name> + <_description>Syria - Syriac phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ku</name> + <_description>Syria - Kurdish, Latin Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_f</name> + <_description>Syria - Kurdish, (F)</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_alt</name> + <_description>Syria - Kurdish, Latin Alt-Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>tj</name> + <_shortDescription>Tjk</_shortDescription> + <_description>Tajikistan</_description> + <languageList> + <iso639Id>tgk</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>legacy</name> + <_description>Tajikistan - Legacy</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>lk</name> + <_shortDescription>Lka</_shortDescription> + <_description>Sri Lanka</_description> + <languageList> + <iso639Id>sin</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>tam_unicode</name> + <_description>Sri Lanka - Tamil Unicode</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>tam_TAB</name> + <_description>Sri Lanka - Tamil TAB Typewriter</_description> + <languageList> + <iso639Id>tam</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>th</name> + <_shortDescription>Tha</_shortDescription> + <_description>Thailand</_description> + <languageList> + <iso639Id>tha</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>tis</name> + <_description>Thailand - TIS-820.2538</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>pat</name> + <_description>Thailand - Pattachote</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>tr</name> + <_shortDescription>Tur</_shortDescription> + <_description>Turkey</_description> + <languageList> + <iso639Id>tur</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>f</name> + <_description>Turkey - (F)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>alt</name> + <_description>Turkey - Alt-Q</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>sundeadkeys</name> + <_description>Turkey - Sun dead keys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ku</name> + <_description>Turkey - Kurdish, Latin Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_f</name> + <_description>Turkey - Kurdish, (F)</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ku_alt</name> + <_description>Turkey - Kurdish, Latin Alt-Q</_description> + <languageList> + <iso639Id>kur</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>intl</name> + <_description>Turkey - International (with dead keys)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>crh</name> + <_description>Turkey - Crimean Tatar (Turkish Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_f</name> + <_description>Turkey - Crimean Tatar (Turkish F)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_alt</name> + <_description>Turkey - Crimean Tatar (Turkish Alt-Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>tw</name> + <_shortDescription>Twn</_shortDescription> + <_description>Taiwan</_description> + <languageList> + <iso639Id>trv</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>indigenous</name> + <_description>Taiwan - Indigenous</_description> + <languageList> + <iso639Id>ami</iso639Id> + <iso639Id>tay</iso639Id> + <iso639Id>bnn</iso639Id> + <iso639Id>ckv</iso639Id> + <iso639Id>pwn</iso639Id> + <iso639Id>pyu</iso639Id> + <iso639Id>dru</iso639Id> + <iso639Id>ais</iso639Id> + <iso639Id>ssf</iso639Id> + <iso639Id>tao</iso639Id> + <iso639Id>tsu</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>saisiyat</name> + <_description>Taiwan - Saisiyat</_description> + <languageList> + <iso639Id>xsf</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ua</name> + <_shortDescription>Ukr</_shortDescription> + <_description>Ukraine</_description> + <languageList> + <iso639Id>ukr</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>phonetic</name> + <_description>Ukraine - Phonetic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>typewriter</name> + <_description>Ukraine - Typewriter</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>winkeys</name> + <_description>Ukraine - Winkeys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>legacy</name> + <_description>Ukraine - Legacy</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>rstu</name> + <_description>Ukraine - Standard RSTU</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>rstu_ru</name> + <_description>Ukraine - Standard RSTU on Russian layout</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>homophonic</name> + <_description>Ukraine - Homophonic</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>crh</name> + <_description>Ukraine - Crimean Tatar (Turkish Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_f</name> + <_description>Ukraine - Crimean Tatar (Turkish F)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_alt</name> + <_description>Ukraine - Crimean Tatar (Turkish Alt-Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>gb</name> + <_shortDescription>GBr</_shortDescription> + <_description>United Kingdom</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>extd</name> + <_description>United Kingdom - Extended - Winkeys</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>intl</name> + <_description>United Kingdom - International (with dead keys)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>United Kingdom - Dvorak</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorakukp</name> + <_description>United Kingdom - Dvorak (UK Punctuation)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac</name> + <_description>United Kingdom - Macintosh</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>mac_intl</name> + <_description>United Kingdom - Macintosh (International)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>colemak</name> + <_description>United Kingdom - Colemak</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>uz</name> + <_shortDescription>Uzb</_shortDescription> + <_description>Uzbekistan</_description> + <languageList> + <iso639Id>uzb</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>latin</name> + <_description>Uzbekistan - Latin</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>crh</name> + <_description>Uzbekistan - Crimean Tatar (Turkish Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_f</name> + <_description>Uzbekistan - Crimean Tatar (Turkish F)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>crh_alt</name> + <_description>Uzbekistan - Crimean Tatar (Turkish Alt-Q)</_description> + <languageList> + <iso639Id>crh</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>vn</name> + <_shortDescription>Vnm</_shortDescription> + <_description>Vietnam</_description> + <languageList> + <iso639Id>vie</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>kr</name> + <_shortDescription>Kor</_shortDescription> + <_description>Korea, Republic of</_description> + <languageList> + <iso639Id>kor</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>kr104</name> + <_description>Korea, Republic of - 101/104 key Compatible</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>nec_vndr/jp</name> + <_shortDescription>Jpn</_shortDescription> + <_description>Japan (PC-98xx Series)</_description> + <countryList> + <iso3166Id>JP</iso3166Id> + </countryList> + <languageList> + <iso639Id>jpn</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>ie</name> + <_shortDescription>Irl</_shortDescription> + <_description>Ireland</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>CloGaelach</name> + <_description>Ireland - CloGaelach</_description> + <languageList> + <iso639Id>gla</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>UnicodeExpert</name> + <_description>Ireland - UnicodeExpert</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ogam</name> + <_description>Ireland - Ogham</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>ogam_is434</name> + <_description>Ireland - Ogham IS434</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>pk</name> + <_shortDescription>Pak</_shortDescription> + <_description>Pakistan</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>urd-crulp</name> + <_description>Pakistan - CRULP</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>urd-nla</name> + <_description>Pakistan - NLA</_description> + <languageList> + <iso639Id>urd</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>ara</name> + <_description>Pakistan - Arabic</_description> + <languageList> + <iso639Id>ara</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>snd</name> + <_description>Pakistan - Sindhi</_description> + <languageList> + <iso639Id>sd</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>mv</name> + <_shortDescription>Mdv</_shortDescription> + <_description>Maldives</_description> + <languageList> + <iso639Id>div</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>za</name> + <_shortDescription>Zaf</_shortDescription> + <_description>South Africa</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + </layout> + <layout> + <configItem> + <name>epo</name> + <_shortDescription>Epo</_shortDescription> + <_description>Esperanto</_description> + <languageList> + <iso639Id>epo</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>legacy</name> + <_description>Esperanto - displaced semicolon and quote (obsolete)</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>np</name> + <_shortDescription>Npl</_shortDescription> + <_description>Nepal</_description> + <languageList> + <iso639Id>nep</iso639Id> + </languageList> + </configItem> + </layout> + <layout> + <configItem> + <name>ng</name> + <_shortDescription>Nga</_shortDescription> + <_description>Nigeria</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>igbo</name> + <_description>Nigeria - Igbo</_description> + <languageList> + <iso639Id>ibo</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>yoruba</name> + <_description>Nigeria - Yoruba</_description> + <languageList> + <iso639Id>yor</iso639Id> + </languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>hausa</name> + <_description>Nigeria - Hausa</_description> + <languageList> + <iso639Id>hau</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>et</name> + <_shortDescription>Eth</_shortDescription> + <_description>Ethiopia</_description> + <languageList> + <iso639Id>amh</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>sn</name> + <_shortDescription>Sen</_shortDescription> + <_description>Senegal</_description> + <languageList> + <iso639Id>wol</iso639Id> + </languageList> + </configItem> + <variantList/> + </layout> + <layout> + <configItem> + <name>brai</name> + <_shortDescription>Brl</_shortDescription> + <_description>Braille</_description> + </configItem> + <variantList> + <variant> + <configItem> + <name>left_hand</name> + <_description>Braille - Left hand</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>right_hand</name> + <_description>Braille - Right hand</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>tm</name> + <_shortDescription>Tkm</_shortDescription> + <_description>Turkmenistan</_description> + <languageList> + <iso639Id>tuk</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>alt</name> + <_description>Turkmenistan - Alt-Q</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>ml</name> + <_shortDescription>Mli</_shortDescription> + <_description>Mali</_description> + <languageList> + <iso639Id>bam</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>fr-oss</name> + <_description>Mali - Français (France Alternative)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us-mac</name> + <_description>Mali - English (USA Macintosh)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>us-intl</name> + <_description>Mali - English (USA International)</_description> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>tz</name> + <_shortDescription>Tza</_shortDescription> + <_description>Tanzania</_description> + <languageList> + <iso639Id>swa</iso639Id> + </languageList> + </configItem> + </layout> + <layout> + <configItem> + <name>ke</name> + <_shortDescription>Ken</_shortDescription> + <_description>Kenya</_description> + <languageList> + <iso639Id>swa</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>kik</name> + <_description>Kenya - Kikuyu</_description> + <languageList> + <iso639Id>kik</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> + <name>bw</name> + <_shortDescription>Bwa</_shortDescription> + <_description>Botswana</_description> + <languageList> + <iso639Id>tsn</iso639Id> + </languageList> + </configItem> + </layout> + <layout> + <configItem> + <name>ph</name> + <_shortDescription>Phi</_shortDescription> + <_description>Philippines</_description> + <languageList><iso639Id>eng</iso639Id> + <iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>qwerty-bay</name> + <_description>Philippines - QWERTY (Baybayin)</_description> + <languageList><iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>capewell-dvorak</name> + <_description>Philippines - Capewell-Dvorak (Latin)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>capewell-dvorak-bay</name> + <_description>Philippines - Capewell-Dvorak (Baybayin)</_description> + <languageList><iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>capewell-qwerf2k6</name> + <_description>Philippines - Capewell-QWERF 2006 (Latin)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>capewell-qwerf2k6-bay</name> + <_description>Philippines - Capewell-QWERF 2006 (Baybayin)</_description> + <languageList><iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>colemak</name> + <_description>Philippines - Colemak (Latin)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>colemak-bay</name> + <_description>Philippines - Colemak (Baybayin)</_description> + <languageList><iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak</name> + <_description>Philippines - Dvorak (Latin)</_description> + </configItem> + </variant> + <variant> + <configItem> + <name>dvorak-bay</name> + <_description>Philippines - Dvorak (Baybayin)</_description> + <languageList><iso639Id>bik</iso639Id> + <iso639Id>ceb</iso639Id> + <iso639Id>fil</iso639Id> + <iso639Id>hil</iso639Id> + <iso639Id>ilo</iso639Id> + <iso639Id>pam</iso639Id> + <iso639Id>pag</iso639Id> + <iso639Id>phi</iso639Id> + <iso639Id>tgl</iso639Id> + <iso639Id>war</iso639Id></languageList> + </configItem> + </variant> + </variantList> + </layout> + </layoutList> + <optionList> + <group allowMultipleSelection="true"> + <!-- The key combination used to switch between groups --> + <configItem> + <name>grp</name> + <_description>Key(s) to change layout</_description> + </configItem> + <option> + <configItem> + <name>grp:switch</name> + <_description>Right Alt (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lswitch</name> + <_description>Left Alt (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lwin_switch</name> + <_description>Left Win (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rwin_switch</name> + <_description>Right Win (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:win_switch</name> + <_description>Any Win key (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:caps_switch</name> + <_description>Caps Lock (while pressed), Alt+Caps Lock does the original capslock action</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rctrl_switch</name> + <_description>Right Ctrl (while pressed)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:toggle</name> + <_description>Right Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lalt_toggle</name> + <_description>Left Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:caps_toggle</name> + <_description>Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:shift_caps_toggle</name> + <_description>Shift+Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:shift_caps_switch</name> + <_description>Caps Lock (to first layout), Shift+Caps Lock (to last layout)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:win_menu_switch</name> + <_description>Left Win (to first layout), Right Win/Menu (to last layout)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lctrl_rctrl_switch</name> + <_description>Left Ctrl (to first layout), Right Ctrl (to last layout)</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:alt_caps_toggle</name> + <_description>Alt+Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:shifts_toggle</name> + <_description>Both Shift keys together</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:alts_toggle</name> + <_description>Both Alt keys together</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:ctrls_toggle</name> + <_description>Both Ctrl keys together</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:ctrl_shift_toggle</name> + <_description>Ctrl+Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lctrl_lshift_toggle</name> + <_description>Left Ctrl+Left Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rctrl_rshift_toggle</name> + <_description>Right Ctrl+Right Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:ctrl_alt_toggle</name> + <_description>Alt+Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:alt_shift_toggle</name> + <_description>Alt+Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:alt_space_toggle</name> + <_description>Alt+Space</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:menu_toggle</name> + <_description>Menu</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lwin_toggle</name> + <_description>Left Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rwin_toggle</name> + <_description>Right Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lshift_toggle</name> + <_description>Left Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rshift_toggle</name> + <_description>Right Shift</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lctrl_toggle</name> + <_description>Left Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:rctrl_toggle</name> + <_description>Right Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:sclk_toggle</name> + <_description>Scroll Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp:lctrl_lwin_rctrl_menu</name> + <_description>LeftCtrl+LeftWin (to first layout), RightCtrl+Menu (to second layout)</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <!-- The key combination used to choose the 3rd (and 4th, together with Shift) + level of symbols --> + <configItem> + <name>lv3</name> + <_description>Key to choose 3rd level</_description> + </configItem> + <option> + <configItem> + <name>lv3:switch</name> + <_description>Right Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:menu_switch</name> + <_description>Menu</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:win_switch</name> + <_description>Any Win key</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:lwin_switch</name> + <_description>Left Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:rwin_switch</name> + <_description>Right Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:alt_switch</name> + <_description>Any Alt key</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:lalt_switch</name> + <_description>Left Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:ralt_switch</name> + <_description>Right Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:ralt_switch_multikey</name> + <_description>Right Alt, Shift+Right Alt key is Multi_Key</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:ralt_alt</name> + <_description>Right Alt key never chooses 3rd level</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:enter_switch</name> + <_description>Enter on keypad</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:caps_switch</name> + <_description>Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:bksl_switch</name> + <_description>Backslash</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:lsgt_switch</name> + <_description><Less/Greater></_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:caps_switch_latch</name> + <_description>Caps Lock (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:bksl_switch_latch</name> + <_description>Backslash chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv3:lsgt_switch_latch</name> + <_description><Less/Greater> (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <!-- Tweaking the position of the "Ctrl" key --> + <configItem> + <name>ctrl</name> + <_description>Ctrl key position</_description> + </configItem> + <option> + <configItem> + <name>ctrl:nocaps</name> + <_description>Make Caps Lock an additional Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:lctrl_meta</name> + <_description>Meta on Left Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:swapcaps</name> + <_description>Swap Ctrl and Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:ctrl_ac</name> + <_description>At left of 'A'</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:ctrl_aa</name> + <_description>At bottom left</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:ctrl_ra</name> + <_description>Right Ctrl as Right Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>ctrl:ctrl_menu</name> + <_description>Right Ctrl is mapped to Menu</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <!-- Using startard LEDs to indicate the alternative (not first) group(s) --> + <configItem> + <name>grp_led</name> + <_description>Use keyboard LED to show alternative layout</_description> + </configItem> + <option> + <configItem> + <name>grp_led:num</name> + <_description>Num Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp_led:caps</name> + <_description>Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>grp_led:scroll</name> + <_description>Scroll Lock</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="false"> + <!-- Select a keypad type --> + <configItem> + <name>keypad</name> + <_description>Numeric keypad layout selection</_description> + </configItem> + <option> + <configItem> + <name>keypad:legacy</name> + <_description>Legacy</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:oss</name> + <_description>Unicode additions (arrows and math operators)</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:future</name> + <_description>Unicode additions (arrows and math operators). Math operators on default level</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:legacy_wang</name> + <_description>Legacy Wang 724</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:oss_wang</name> + <_description>Wang 724 keypad with unicode additions (arrows and math operators)</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:future_wang</name> + <_description>Wang 724 keypad with unicode additions (arrows and math operators). Math operators on default level</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:hex</name> + <_description>Hexadecimal</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:atm</name> + <_description>ATM/phone-style</_description> + </configItem> + </option> + </group> + <!-- This option should override the KPDL key defined in keypad; I hope it's declared in the right place --> + <group allowMultipleSelection="false"> + <!-- Select a keypad KPDL variant --> + <configItem> + <name>kpdl</name> + <_description>Numeric keypad delete key behaviour</_description> + </configItem> + <option> + <configItem> + <!-- Actually, with KP_DECIMAL, as the old keypad(dot) --> + <name>kpdl:dot</name> + <_description>Legacy key with dot</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:comma</name> + <!-- Actually, with KP_SEPARATOR, as the old keypad(comma) --> + <_description>Legacy key with comma</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:dotoss</name> + <_description>Four-level key with dot</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:dotoss_latin9</name> + <_description>Four-level key with dot, latin-9 restriction</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:commaoss</name> + <_description>Four-level key with comma</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:momayyezoss</name> + <_description>Four-level key with momayyez</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:kposs</name> + <!-- This assumes the KP_ abstract symbols are actually useful for some apps + The description needs to be rewritten --> + <_description>Four-level key with abstract separators</_description> + </configItem> + </option> + <option> + <configItem> + <name>kpdl:semi</name> + <_description>Semi-colon on third level</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="false"> + <!-- Caps Lock tweaks. + "Internal" capitalization means capitalization using some internal tables. + Otherwise "as Shift" - means using next group. --> + <configItem> + <name>caps</name> + <_description>Caps Lock key behavior</_description> + </configItem> + <option> + <configItem> + <name>caps:internal</name> + <_description>Caps Lock uses internal capitalization. Shift "pauses" Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:internal_nocancel</name> + <_description>Caps Lock uses internal capitalization. Shift doesn't affect Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:shift</name> + <_description>Caps Lock acts as Shift with locking. Shift "pauses" Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:shift_nocancel</name> + <_description>Caps Lock acts as Shift with locking. Shift doesn't affect Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:capslock</name> + <_description>Caps Lock toggles normal capitalization of alphabetic characters</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:numlock</name> + <_description>Make Caps Lock an additional Num Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:swapescape</name> + <_description>Swap ESC and Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:escape</name> + <_description>Make Caps Lock an additional ESC</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:backspace</name> + <_description>Make Caps Lock an additional Backspace</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:super</name> + <_description>Make Caps Lock an additional Super</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:hyper</name> + <_description>Make Caps Lock an additional Hyper</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:shiftlock</name> + <_description>Caps Lock toggles Shift so all keys are affected</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:none</name> + <_description>Caps Lock is disabled</_description> + </configItem> + </option> + <option> + <configItem> + <name>caps:ctrl_modifier</name> + <_description>Make Caps Lock an additional Control but keep the Caps_Lock keysym</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="false"> + <!-- Using special PC keys (Win, Menu) to work as standard X keys (Super, Hyper, etc.) --> + <configItem> + <name>altwin</name> + <_description>Alt/Win key behavior</_description> + </configItem> + <option> + <configItem> + <name>altwin:menu</name> + <_description>Add the standard behavior to Menu key</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:meta_alt</name> + <_description>Alt and Meta are on Alt keys</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:ctrl_win</name> + <_description>Control is mapped to Win keys (and the usual Ctrl keys)</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:ctrl_alt_win</name> + <_description>Control is mapped to Alt keys, Alt is mapped to Win keys</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:meta_win</name> + <_description>Meta is mapped to Win keys</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:left_meta_win</name> + <_description>Meta is mapped to Left Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:hyper_win</name> + <_description>Hyper is mapped to Win-keys</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:alt_super_win</name> + <_description>Alt is mapped to Right Win, Super to Menu</_description> + </configItem> + </option> + <option> + <configItem> + <name>altwin:swap_lalt_lwin</name> + <_description>Left Alt is swapped with Left Win</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <!-- Tweaking the position of the "Compose" key: mapping to existing PC keys --> + <configItem> + <name>Compose key</name> + <_description>Compose key position</_description> + </configItem> + <option> + <configItem> + <name>compose:ralt</name> + <_description>Right Alt</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:lwin</name> + <_description>Left Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:rwin</name> + <_description>Right Win</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:menu</name> + <_description>Menu</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:lctrl</name> + <_description>Left Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:rctrl</name> + <_description>Right Ctrl</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:caps</name> + <_description>Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:102</name> + <_description><Less/Greater></_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:paus</name> + <_description>Pause</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:prsc</name> + <_description>PrtSc</_description> + </configItem> + </option> + <option> + <configItem> + <name>compose:sclk</name> + <_description>Scroll Lock</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <configItem> + <name>compat</name> + <_description>Miscellaneous compatibility options</_description> + </configItem> + <option> + <configItem> + <name>numpad:pc</name> + <_description>Default numeric keypad keys</_description> + </configItem> + </option> + <option> + <configItem> + <name>numpad:mac</name> + <_description>Numeric keypad keys work as with Mac</_description> + </configItem> + </option> + <option> + <configItem> + <name>numpad:microsoft</name> + <_description>Shift with numeric keypad keys works as in MS Windows</_description> + </configItem> + </option> + <option> + <configItem> + <name>numpad:shift3</name> + <_description>Shift does not cancel Num Lock, chooses 3rd level instead</_description> + </configItem> + </option> + <option> + <configItem> + <name>srvrkeys:none</name> + <_description>Special keys (Ctrl+Alt+<key>) handled in a server</_description> + </configItem> + </option> + <option> + <configItem> + <name>apple:alupckeys</name> + <_description>Apple Aluminium Keyboard: emulate PC keys (Print, Scroll Lock, Pause, Num Lock)</_description> + </configItem> + </option> + <option> + <configItem> + <name>shift:breaks_caps</name> + <_description>Shift cancels Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>misc:typo</name> + <_description>Enable extra typographic characters</_description> + </configItem> + </option> + <option> + <configItem> + <name>shift:both_capslock</name> + <_description>Both Shift-Keys together toggle Caps Lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>shift:both_capslock_cancel</name> + <_description>Both Shift-Keys together activate Caps Lock, one Shift-Key deactivates</_description> + </configItem> + </option> + <option> + <configItem> + <name>shift:both_shiftlock</name> + <_description>Both Shift-Keys together toggle ShiftLock</_description> + </configItem> + </option> + <option> + <configItem> + <name>keypad:pointerkeys</name> + <_description>Toggle PointerKeys with Shift + NumLock.</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <!-- Special shortcuts for the Euro character --> + <configItem> + <name>eurosign</name> + <_description>Adding currency signs to certain keys</_description> + </configItem> + <option> + <configItem> + <name>eurosign:e</name> + <_description>Euro on E</_description> + </configItem> + </option> + <option> + <configItem> + <name>eurosign:2</name> + <_description>Euro on 2</_description> + </configItem> + </option> + <option> + <configItem> + <name>eurosign:4</name> + <_description>Euro on 4</_description> + </configItem> + </option> + <option> + <configItem> + <name>eurosign:5</name> + <_description>Euro on 5</_description> + </configItem> + </option> + <option> + <configItem> + <name>rupeesign:4</name> + <_description>Rupee on 4</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <configItem> + <name>lv5</name> + <_description>Key to choose 5th level</_description> + </configItem> + <option> + <configItem> + <name>lv5:lsgt_switch_lock</name> + <_description><Less/Greater> chooses 5th level, locks when pressed together with another 5th-level-chooser</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:ralt_switch_lock</name> + <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:lwin_switch_lock</name> + <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:rwin_switch_lock</name> + <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:lsgt_switch_lock_cancel</name> + <_description><Less/Greater> chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:ralt_switch_lock_cancel</name> + <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:lwin_switch_lock_cancel</name> + <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:rwin_switch_lock_cancel</name> + <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:lsgt_switch_lock_cancel</name> + <_description><Less/Greater> chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + <option> + <configItem> + <name>lv5:ralt_switch_lock_cancel</name> + <_description>Right Alt chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="false"> + <!-- Let space output NBSP, NNBSP, ZWNJ, and ZWJ for the desired level --> + <configItem> + <name>nbsp</name> + <_description>Using space key to input non-breakable space character</_description> + </configItem> + <option> + <configItem> + <name>nbsp:none</name> + <_description>Usual space at any level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level2</name> + <_description>Non-breakable space character at second level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level3</name> + <_description>Non-breakable space character at third level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level3s</name> + <_description>Non-breakable space character at third level, nothing at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level3n</name> + <_description>Non-breakable space character at third level, thin non-breakable space character at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level4</name> + <_description>Non-breakable space character at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level4n</name> + <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:level4nl</name> + <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level (via Ctrl+Shift)</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2</name> + <_description>Zero-width non-joiner character at second level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2zwj3</name> + <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2zwj3nb4</name> + <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level, non-breakable space character at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2nb3</name> + <_description>Zero-width non-joiner character at second level, non-breakable space character at third level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2nb3s</name> + <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, nothing at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2nb3zwj4</name> + <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, zero-width joiner at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj2nb3nnb4</name> + <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, thin non-breakable space at fourth level</_description> + </configItem> + </option> + <option> + <configItem> + <name>nbsp:zwnj3zwj4</name> + <_description>Zero-width non-joiner character at third level, zero-width joiner at fourth level</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <configItem> + <name>japan</name> + <_description>Japanese keyboard options</_description> + </configItem> + <option> + <configItem> + <name>japan:kana_lock</name> + <_description>Kana Lock key is locking</_description> + </configItem> + </option> + <option> + <configItem> + <name>japan:nicola_f_bs</name> + <_description>NICOLA-F style Backspace</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="false"> + <configItem> + <name>esperanto</name> + <_description>Adding Esperanto circumflexes (supersigno)</_description> + </configItem> + <option> + <configItem> + <name>esperanto:qwerty</name> + <_description>To the corresponding key in a Qwerty keyboard.</_description> + </configItem> + </option> + <option> + <configItem> + <name>esperanto:dvorak</name> + <_description>To the corresponding key in a Dvorak keyboard.</_description> + </configItem> + </option> + </group> + <group allowMultipleSelection="true"> + <configItem> + <name>terminate</name> + <_description>Key sequence to kill the X server</_description> + </configItem> + <option> + <configItem> + <name>terminate:ctrl_alt_bksp</name> + <_description>Control + Alt + Backspace</_description> + </configItem> + </option> + </group> + </optionList> +</xkbConfigRegistry> diff --git a/xorg-server/xkeyboard-config/symbols/in b/xorg-server/xkeyboard-config/symbols/in index cb38a84c0..75447148e 100644 --- a/xorg-server/xkeyboard-config/symbols/in +++ b/xorg-server/xkeyboard-config/symbols/in @@ -1351,7 +1351,7 @@ xkb_symbols "eng" { partial alphanumeric_keys xkb_symbols "mal_enhanced" { - name[Group1] = "India - Malayalam Modified Inscript with Rupee Sign"; + name[Group1] = "India - Malayalam enhanced Inscript with Rupee Sign"; //From grave to backslash (\) diff --git a/xorg-server/xkeyboard-config/symbols/lk b/xorg-server/xkeyboard-config/symbols/lk index 8480607de..928781d05 100644 --- a/xorg-server/xkeyboard-config/symbols/lk +++ b/xorg-server/xkeyboard-config/symbols/lk @@ -1,90 +1,91 @@ -// X Keyboard Extension file for Sinhala (Sri Lanka) (2004-04-22)
-// Maintainer : Harshula Jayasuriya <harshula@gmail.com>
-// Last Updated: 2007-06-29
-// This is a static phonetic mapping for a standard US-English keyboard
-// (qwerty)
-// http://www.nongnu.org/sinhala/doc/keymaps/sinhala-keyboard_3.html
-
-// Repaya, Rakaransaya and Yansaya aren't inserted with A-r, R and Y,
-// respectively. The problem lies with the XKB infrastructure which
-// only allows a one-to-one mapping of keycodes to Unicode codepoints.
-// Unfortunately, the 3 mentioned glyphs actually consists of 3
-// Unicode codepoints each. The result is that the user must
-// manually construct the glyph by typing each of the 3 codepoints.
-// ALT-, represents the 'JOIN' key, it requires
-// two codepoints, hence it also has to be manually constructed.
-// Similarly, ALT-/ representing the 'TOUCH' key requires
-// two codepoints.
-
-// Repaya = rayanna,AL,ZWJ
-// Rakaransaya = AL,ZWJ,rayanna
-// Yansaya = AL,ZWJ,yayanna
-// JOIN = AL,ZWJ
-// TOUCH = ZWJ,AL
-
-// Where,
-// AL = Al Lakuna = ALT-a
-// ZWJ = Zero Width Joiner = ALT-/
-// rayanna = r
-// yayanna = y
-
-partial default alphanumeric_keys
-xkb_symbols "sin_phonetic" {
-
- include "us"
-// it is default - no details in the name
- name[Group1] = "Sri Lanka";
- key.type[Group1] = "FOUR_LEVEL";
-
- // q - p
- key <AD01> { [ 0x01000d8d, 0x01000d8e, 0x01000dd8, 0x01000df2 ] };
- key <AD02> { [ 0x01000d87, 0x01000d88, 0x01000dd0, 0x01000dd1 ] };
- key <AD03> { [ 0x01000d91, 0x01000d92, 0x01000dd9, 0x01000dda ] };
- key <AD04> { [ 0x01000dbb, 0x01000dca, 0x01000dbb, NoSymbol ] };
- key <AD05> { [ 0x01000dad, 0x01000dae, 0x01000da7, 0x01000da8 ] };
- key <AD06> { [ 0x01000dba, 0x01000dca, NoSymbol, NoSymbol ] };
- key <AD07> { [ 0x01000d8b, 0x01000d8c, 0x01000dd4, 0x01000dd6 ] };
- key <AD08> { [ 0x01000d89, 0x01000d8a, 0x01000dd2, 0x01000dd3 ] };
- key <AD09> { [ 0x01000d94, 0x01000d95, 0x01000ddc, 0x01000ddd ] };
- key <AD10> { [ 0x01000db4, 0x01000db5, NoSymbol, NoSymbol ] };
-
- // a - l
- key <AC01> { [ 0x01000d85, 0x01000d86, 0x01000dca, 0x01000dcf ] };
- key <AC02> { [ 0x01000dc3, 0x01000dc1, 0x01000dc2, NoSymbol ] };
- key <AC03> { [ 0x01000daf, 0x01000db0, 0x01000da9, 0x01000daa ] };
- key <AC04> { [ 0x01000dc6, NoSymbol, 0x01000ddb, 0x01000d93 ] };
- key <AC05> { [ 0x01000d9c, 0x01000d9d, 0x01000d9f, NoSymbol ] };
- key <AC06> { [ 0x01000dc4, 0x01000d83, 0x01000dde, 0x01000d96 ] };
- key <AC07> { [ 0x01000da2, 0x01000da3, 0x01000da6, NoSymbol ] };
- key <AC08> { [ 0x01000d9a, 0x01000d9b, 0x01000d8f, 0x01000d90 ] };
- key <AC09> { [ 0x01000dbd, 0x01000dc5, 0x01000ddf, 0x01000df3 ] };
-
- // z - ?
- key <AB01> { [ 0x01000da4, 0x01000da5, NoSymbol, NoSymbol ] };
- key <AB02> { [ 0x01000db3, 0x01000dac, NoSymbol, NoSymbol ] };
- key <AB03> { [ 0x01000da0, 0x01000da1, NoSymbol, NoSymbol ] };
- key <AB04> { [ 0x01000dc0, NoSymbol, NoSymbol, NoSymbol ] };
- key <AB05> { [ 0x01000db6, 0x01000db7, NoSymbol, NoSymbol ] };
- key <AB06> { [ 0x01000db1, 0x01000dab, 0x01000d82, 0x01000d9e ] };
- key <AB07> { [ 0x01000db8, 0x01000db9, NoSymbol, NoSymbol ] };
- key <AB08> { [ any, any, 0x01000dca, NoSymbol ] };
- key <AB09> { [ any, any, 0x01000df4, NoSymbol ] };
- key <AB10> { [ any, any, 0x0100200d, NoSymbol ] };
-
- // Space
- include "nbsp(zwnj2nb3s)"
-
- include "level3(ralt_switch)"
-};
-
-partial alphanumeric_keys
-xkb_symbols "tam_unicode" {
- include "in(tam_unicode)"
- name[Group1]= "Sri Lanka - Tamil Unicode";
-};
-
-partial alphanumeric_keys
-xkb_symbols "tam_TAB" {
- include "in(tam_TAB)"
- name[Group1]= "Sri Lanka - Tamil TAB Typewriter";
-};
+// X Keyboard Extension file for Sinhala (Sri Lanka) (2004-04-22) +// Maintainer : Harshula Jayasuriya <harshula@gmail.com> +// Last Updated: 2011-03-20 +// This is a phonetic static mapping for a standard US-English keyboard +// (qwerty) +// http://www.nongnu.org/sinhala/doc/keymaps/sinhala-keyboard_3.html + +// Repaya, Rakaransaya and Yansaya aren't inserted with A-r, R and Y, +// respectively. The problem lies with the XKB infrastructure which +// only allows a one-to-one mapping of keycodes to Unicode codepoints. +// Unfortunately, the 3 mentioned glyphs actually consists of 3 +// Unicode codepoints each. The result is that the user must +// manually construct the glyph by typing each of the 3 codepoints. +// ALT-, represents the 'JOIN' key, it requires +// two codepoints, hence it also has to be manually constructed. +// Similarly, ALT-/ representing the 'TOUCH' key requires +// two codepoints. + +// Repaya = rayanna,AL,ZWJ +// Rakaransaya = AL,ZWJ,rayanna +// Yansaya = AL,ZWJ,yayanna +// JOIN = AL,ZWJ +// TOUCH = ZWJ,AL + +// Where, +// AL = Al Lakuna = ALT-a +// ZWJ = Zero Width Joiner = ALT-/ +// rayanna = r +// yayanna = y + +partial default alphanumeric_keys +xkb_symbols "sin_phonetic" { + + include "us" +// it is default - no details in the name + name[Group1] = "Sri Lanka"; + key.type[Group1] = "FOUR_LEVEL"; + + // q - p + key <AD01> { [ Sinh_ri, Sinh_rii, Sinh_ru2, Sinh_ruu2 ] }; + key <AD02> { [ Sinh_ae, Sinh_aee, Sinh_ae2, Sinh_aee2 ] }; + key <AD03> { [ Sinh_e, Sinh_ee, Sinh_e2, Sinh_ee2 ] }; + key <AD04> { [ Sinh_ra, Sinh_al, Sinh_ra, NoSymbol ] }; + key <AD05> { [ Sinh_tha, Sinh_thha, Sinh_tta, Sinh_ttha ] }; + key <AD06> { [ Sinh_ya, Sinh_al, NoSymbol, NoSymbol ] }; + key <AD07> { [ Sinh_u, Sinh_uu, Sinh_u2, Sinh_uu2 ] }; + key <AD08> { [ Sinh_i, Sinh_ii, Sinh_i2, Sinh_ii2 ] }; + key <AD09> { [ Sinh_o, Sinh_oo, Sinh_o2, Sinh_oo2 ] }; + key <AD10> { [ Sinh_pa, Sinh_pha, NoSymbol, NoSymbol ] }; + + // a - l + key <AC01> { [ Sinh_a, Sinh_aa, Sinh_al, Sinh_aa2 ] }; + key <AC02> { [ Sinh_sa, Sinh_sha, Sinh_ssha, NoSymbol ] }; + key <AC03> { [ Sinh_dha, Sinh_dhha, Sinh_dda, Sinh_ddha ] }; + key <AC04> { [ Sinh_fa, NoSymbol, Sinh_ai2, Sinh_ai ] }; + key <AC05> { [ Sinh_ga, Sinh_gha, Sinh_nga, NoSymbol ] }; + key <AC06> { [ Sinh_ha, Sinh_h2, Sinh_au2, Sinh_au ] }; + key <AC07> { [ Sinh_ja, Sinh_jha, Sinh_nja, NoSymbol ] }; + key <AC08> { [ Sinh_ka, Sinh_kha, Sinh_lu, Sinh_luu ] }; + key <AC09> { [ Sinh_la, Sinh_lla, Sinh_lu2, Sinh_luu2 ] }; + + // z - ? + key <AB01> { [ Sinh_nya, Sinh_jnya, NoSymbol, NoSymbol ] }; + key <AB02> { [ Sinh_ndha, Sinh_ndda, NoSymbol, NoSymbol ] }; + key <AB03> { [ Sinh_ca, Sinh_cha, NoSymbol, NoSymbol ] }; + key <AB04> { [ Sinh_va, NoSymbol, NoSymbol, NoSymbol ] }; + key <AB05> { [ Sinh_ba, Sinh_bha, NoSymbol, NoSymbol ] }; + key <AB06> { [ Sinh_na, Sinh_nna, Sinh_ng, Sinh_ng2 ] }; + key <AB07> { [ Sinh_ma, Sinh_mba, NoSymbol, NoSymbol ] }; + key <AB08> { [ any, any, Sinh_al, NoSymbol ] }; + key <AB09> { [ any, any, Sinh_kunddaliya, NoSymbol ] }; + key <AB10> { [ any, any, 0x100200d, NoSymbol ] }; + + // Space + include "nbsp(nb2zwnj3s)" + + include "level3(ralt_switch)" +}; + +partial alphanumeric_keys +xkb_symbols "tam_unicode" { + include "in(tam_unicode)" + name[Group1]= "Sri Lanka - Tamil Unicode"; +}; + +partial alphanumeric_keys +xkb_symbols "tam_TAB" { + include "in(tam_TAB)" + name[Group1]= "Sri Lanka - Tamil TAB Typewriter"; +}; + diff --git a/xorg-server/xkeyboard-config/symbols/lt b/xorg-server/xkeyboard-config/symbols/lt index 5a19dc265..c19629f9d 100644 --- a/xorg-server/xkeyboard-config/symbols/lt +++ b/xorg-server/xkeyboard-config/symbols/lt @@ -1,296 +1,318 @@ -// Separate keymaps merged into one file by Nerijus Baliūnas, 2002
-
-// Lithuanian Numeric layout - Lithuanian letters on the numeric row
-// based on Lithuanian keyboard map by Ričardas Čepas <rch@richard.eu.org>
-// 3rd and 4th levels added by Mantas Kriaučiūnas <mantas@akl.lt>, 2004
-// Minor modifications and cleanup by Rimas Kudelis <rq@akl.lt>, 2010
-//
-// If you want two layouts, use:
-// Option "XkbLayout" "lt,lt(us)"
-partial default alphanumeric_keys modifier_keys
-xkb_symbols "basic" {
-
- include "latin"
- include "eurosign(e)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ aogonek, Aogonek, 1, exclam ]};
- key <AE02> {[ ccaron, Ccaron, 2, at ]};
- key <AE03> {[ eogonek, Eogonek, 3, numbersign ]};
- key <AE04> {[ eabovedot, Eabovedot, 4, dollar ]};
- key <AE05> {[ iogonek, Iogonek, 5, percent ]};
- key <AE06> {[ scaron, Scaron, 6, asciicircum ]};
- key <AE07> {[ uogonek, Uogonek, 7, ampersand ]};
- key <AE08> {[ umacron, Umacron, 8, asterisk ]};
- key <AE09> {[ doublelowquotemark, parenleft, 9, parenleft ]};
- key <AE10> {[ leftdoublequotemark, parenright, 0, parenright ]};
- key <AE11> {[ minus, underscore, endash ]};
- key <AE12> {[ zcaron, Zcaron, equal, plus ]};
-
- key <LSGT> {[ endash, EuroSign ]};
-};
-
-// Similar to the above, but uses 3rd and 4th levels in the numeric row
-// for Lithuanian letters
-partial alphanumeric_keys modifier_keys
-xkb_symbols "us" {
-
- include "latin"
- include "eurosign(e)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania - US keyboard with Lithuanian letters";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ 1, exclam, aogonek, Aogonek ]};
- key <AE02> {[ 2, at, ccaron, Ccaron ]};
- key <AE03> {[ 3, numbersign, eogonek, Eogonek ]};
- key <AE04> {[ 4, dollar, eabovedot, Eabovedot ]};
- key <AE05> {[ 5, percent, iogonek, Iogonek ]};
- key <AE06> {[ 6, asciicircum, scaron, Scaron ]};
- key <AE07> {[ 7, ampersand, uogonek, Uogonek ]};
- key <AE08> {[ 8, asterisk, umacron, Umacron ]};
- key <AE09> {[ 9, parenleft, doublelowquotemark, parenleft ]};
- key <AE10> {[ 0, parenright, leftdoublequotemark, parenright ]};
- key <AE11> {[ minus, underscore, endash ]};
- key <AE12> {[ equal, plus, zcaron, Zcaron ]};
-
- key <LSGT> {[ endash, EuroSign ]};
-};
-
-// Lithuanian keymap LST 1582:2000
-// The standard is described at http://ims.mii.lt/klav/
-// Extensions: B01 L3 is "<" , B02 L3 is ">" and B03 L3 is endash to make this
-// layout usable with pc101 and pc104 keyboards.
-//
-// Made by Gediminas Paulauskas <menesis@delfi.lt>
-// Minor modifications by Ričardas Čepas and Rimas Kudelis
-
-partial alphanumeric_keys modifier_keys
-xkb_symbols "std" {
-
- include "latin"
- include "eurosign(e)"
- include "nbsp(level3)"
- include "kpdl(comma)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania - Standard";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ exclam, 1, at ]};
- key <AE02> {[ minus, 2, underscore ]};
- key <AE03> {[ slash, 3, numbersign ]};
- key <AE04> {[ semicolon, 4, dollar ]};
- key <AE05> {[ colon, 5, section ]};
- key <AE06> {[ comma, 6, asciicircum ]};
- key <AE07> {[ period, 7, ampersand ]};
- key <AE08> {[ equal, 8, asterisk ]};
- key <AE09> {[ parenleft, 9, bracketleft ]};
- key <AE10> {[ parenright, 0, bracketright ]};
- key <AE11> {[ question, plus, apostrophe ]};
- key <AE12> {[ x, X, percent ]};
-
- key <AD01> {[ aogonek, Aogonek ]};
- key <AD02> {[ zcaron, Zcaron ]};
- key <AD11> {[ iogonek, Iogonek, braceleft ]};
- key <AD12> {[ w, W, braceright ]};
-
- key <AC04> {[ scaron, Scaron ]};
- key <AC10> {[ uogonek, Uogonek ]};
- key <AC11> {[ eabovedot, Eabovedot, quotedbl ]};
- key <BKSL> {[ q, Q, bar ]};
-
- key <LSGT> {[ less, greater, endash ]};
- key <AB01> {[ z, Z, less ]};
- key <AB02> {[ umacron, Umacron, greater ]};
- key <AB03> {[ c, C, endash ]};
- key <AB08> {[ ccaron, Ccaron, doublelowquotemark ]};
- key <AB09> {[ f, F, leftdoublequotemark ]};
- key <AB10> {[ eogonek, Eogonek, backslash ]};
-};
-
-// Lithuanian keymap LST 1205-92
-// This standard was made deprecated by LST 1582:2000 above.
-// This keyboard is also know as IBM layout.
-// We follow the map shown at: http://www.registrucentras.lt/litwin/kbdlta.gif
-// and info from Edis Tamošauskas <linas_lietus@yahoo.com>
-//
-// Made by Piter PUNK <piterpk@terra.com.br>
-// Minor modifications and cleanup by Rimas Kudelis, 2010
-
-partial alphanumeric_keys modifier_keys
-xkb_symbols "ibm" {
-
- include "latin"
- include "eurosign(e)"
- include "nbsp(level3)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania - IBM (LST 1205-92)";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ exclam, 1 ]};
- key <AE02> {[ quotedbl, 2, at ]};
- key <AE03> {[ slash, 3, numbersign ]};
- key <AE04> {[ semicolon, 4, dollar ]};
- key <AE05> {[ colon, 5, percent ]};
- key <AE06> {[ comma, 6, asciicircum ]};
- key <AE07> {[ period, 7, ampersand ]};
- key <AE08> {[ question, 8, asterisk ]};
- key <AE09> {[ parenleft, 9 ]};
- key <AE10> {[ parenright, 0 ]};
- key <AE11> {[ underscore, minus, endash ]};
- key <AE12> {[ plus, equal ]};
-
- key <AD01> {[ aogonek, Aogonek, q, Q ]};
- key <AD02> {[ zcaron, Zcaron, w, W ]};
- key <AD11> {[ iogonek, Iogonek, bracketleft, braceleft ]};
- key <AD12> {[ doublelowquotemark, leftdoublequotemark, bracketright, braceright ]};
-
- key <AC10> {[ uogonek, Uogonek, semicolon, colon ]};
- key <AC11> {[ eabovedot, Eabovedot, apostrophe, quotedbl ]};
-
- key <LSGT> {[ less, greater, endash ]};
- key <AB02> {[ umacron, Umacron, x, X ]};
- key <AB08> {[ ccaron, Ccaron, comma, less ]};
- key <AB09> {[ scaron, Scaron, period, greater ]};
- key <AB10> {[ eogonek, Eogonek, slash, question ]};
-};
-
-// LEKP and LEKPa layouts 1.0
-// Copyright (c) 2007 Tautrimas Pajarskas
-// For more info visit http://lekp.info
-//
-// LEKP and LEKPa layouts are licensed under the Creative Commons
-// Attribution-Noncommercial-Share Alike 3.0 License.
-// To view a copy of this license, visit
-// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send
-// a letter to Creative Commons, 171 Second Street, Suite 300,
-// San Francisco, California, 94105, USA.
-//
-// Minor cleanup by Rimas Kudelis, 2010
-
-partial alphanumeric_keys modifier_keys
-xkb_symbols "lekp" {
-
- include "capslock(backspace)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania - LEKP";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ slash, numbersign, bar ]};
- key <AE02> {[ backslash, at, section ]};
- key <AE03> {[ period, braceleft ]};
- key <AE04> {[ comma, braceright ]};
- key <AE05> {[ f, F ]};
- key <AE06> {[ exclam, endash ]};
- key <AE07> {[ w, W ]};
- key <AE08> {[ uogonek, Uogonek ]};
- key <AE09> {[ iogonek, Iogonek ]};
- key <AE10> {[ parenleft, doublelowquotemark, registered ]};
- key <AE11> {[ parenright, leftdoublequotemark, copyright ]};
- key <AE12> {[ colon, ampersand, trademark ]};
-
- key <AD01> {[ q, Q, EuroSign ]};
- key <AD02> {[ g, G, 7 ]};
- key <AD03> {[ r, R, 8 ]};
- key <AD04> {[ l, L, 9 ]};
- key <AD05> {[ d, D, percent ]};
- key <AD06> {[ ccaron, Ccaron ]};
- key <AD07> {[ j, J ]};
- key <AD08> {[ u, U, period ]};
- key <AD09> {[ eabovedot, Eabovedot, minus ]};
- key <AD10> {[ eogonek, Eogonek, slash ]};
- key <AD11> {[ question, bracketleft, division ]};
- key <AD12> {[ equal, bracketright ]};
-
- key <AC01> {[ a, A, 0 ]};
- key <AC02> {[ k, K, 4 ]};
- key <AC03> {[ s, S, 5 ]};
- key <AC04> {[ t, T, 6 ]};
- key <AC05> {[ m, M, dollar ]};
- key <AC06> {[ p, P ]};
- key <AC07> {[ n, N ]};
- key <AC08> {[ e, E, comma ]};
- key <AC09> {[ i, I, plus ]};
- key <AC10> {[ o, O, asterisk ]};
- key <AC11> {[ y, Y, multiply ]};
- key <BKSL> {[ apostrophe, underscore ]};
-
- key <LSGT> {[ semicolon, quotedbl, sterling ]};
- key <AB01> {[ z, Z, asciicircum ]};
- key <AB02> {[ x, X, 1 ]};
- key <AB03> {[ c, C, 2 ]};
- key <AB04> {[ v, V, 3 ]};
- key <AB05> {[ zcaron, Zcaron ]};
- key <AB06> {[ scaron, Scaron ]};
- key <AB07> {[ b, B, degree ]};
- key <AB08> {[ umacron, Umacron, less ]};
- key <AB09> {[ aogonek, Aogonek, greater ]};
- key <AB10> {[ h, H ]};
-};
-
-partial alphanumeric_keys modifier_keys
-xkb_symbols "lekpa" {
-
- include "capslock(backspace)"
- include "level3(ralt_switch)"
-
- name[Group1]="Lithuania - LEKPa";
-
- key <TLDE> {[ grave, asciitilde, acute ]};
- key <AE01> {[ slash, quotedbl, bar ]};
- key <AE02> {[ backslash, at, section ]};
- key <AE03> {[ period, braceleft, numbersign ]};
- key <AE04> {[ comma, braceright, sterling ]};
- key <AE05> {[ f, F, ampersand ]};
- key <AE06> {[ exclam, endash ]};
- key <AE07> {[ w, W ]};
- key <AE08> {[ uogonek, Uogonek ]};
- key <AE09> {[ iogonek, Iogonek ]};
- key <AE10> {[ parenleft, doublelowquotemark, registered ]};
- key <AE11> {[ parenright, leftdoublequotemark, copyright ]};
- key <AE12> {[ colon, semicolon, trademark ]};
-
- key <AD01> {[ q, Q, EuroSign ]};
- key <AD02> {[ g, G, 7 ]};
- key <AD03> {[ r, R, 8 ]};
- key <AD04> {[ l, L, 9 ]};
- key <AD05> {[ d, D, percent ]};
- key <AD06> {[ ccaron, Ccaron ]};
- key <AD07> {[ j, J ]};
- key <AD08> {[ u, U, period ]};
- key <AD09> {[ eabovedot, Eabovedot, minus ]};
- key <AD10> {[ eogonek, Eogonek, slash ]};
- key <AD11> {[ question, bracketleft, division ]};
- key <AD12> {[ equal, bracketright ]};
-
- key <AC01> {[ a, A, 0 ]};
- key <AC02> {[ k, K, 4 ]};
- key <AC03> {[ s, S, 5 ]};
- key <AC04> {[ t, T, 6 ]};
- key <AC05> {[ m, M, dollar ]};
- key <AC06> {[ p, P ]};
- key <AC07> {[ n, N ]};
- key <AC08> {[ e, E, comma ]};
- key <AC09> {[ i, I, plus ]};
- key <AC10> {[ o, O, asterisk ]};
- key <AC11> {[ y, Y, multiply ]};
- key <BKSL> {[ apostrophe, underscore ]};
-
- key <AB01> {[ z, Z, asciicircum ]};
- key <AB02> {[ x, X, 1 ]};
- key <AB03> {[ c, C, 2 ]};
- key <AB04> {[ v, V, 3 ]};
- key <AB05> {[ zcaron, Zcaron ]};
- key <AB06> {[ scaron, Scaron ]};
- key <AB07> {[ b, B, degree ]};
- key <AB08> {[ umacron, Umacron, less ]};
- key <AB09> {[ aogonek, Aogonek, greater ]};
- key <AB10> {[ h, H ]};
-};
+// Separate keymaps merged into one file by Nerijus Baliūnas, 2002 + +// Lithuanian Numeric layout - Lithuanian letters on the numeric row +// based on Lithuanian keyboard map by Ričardas Čepas <rch@richard.eu.org> +// 3rd and 4th levels added by Mantas Kriaučiūnas <mantas@akl.lt>, 2004 +// Minor modifications and cleanup by Rimas Kudelis <rq@akl.lt>, 2010 +// +// If you want two layouts, use: +// Option "XkbLayout" "lt,lt(us)" +partial default alphanumeric_keys modifier_keys +xkb_symbols "basic" { + + include "latin" + include "eurosign(e)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ aogonek, Aogonek, 1, exclam ]}; + key <AE02> {[ ccaron, Ccaron, 2, at ]}; + key <AE03> {[ eogonek, Eogonek, 3, numbersign ]}; + key <AE04> {[ eabovedot, Eabovedot, 4, dollar ]}; + key <AE05> {[ iogonek, Iogonek, 5, percent ]}; + key <AE06> {[ scaron, Scaron, 6, asciicircum ]}; + key <AE07> {[ uogonek, Uogonek, 7, ampersand ]}; + key <AE08> {[ umacron, Umacron, 8, asterisk ]}; + key <AE09> {[ doublelowquotemark, parenleft, 9, parenleft ]}; + key <AE10> {[ leftdoublequotemark, parenright, 0, parenright ]}; + key <AE11> {[ minus, underscore, endash ]}; + key <AE12> {[ zcaron, Zcaron, equal, plus ]}; + + key <LSGT> {[ endash, EuroSign ]}; +}; + +// Similar to the above, but uses 3rd and 4th levels in the numeric row +// for Lithuanian letters +partial alphanumeric_keys modifier_keys +xkb_symbols "us" { + + include "latin" + include "eurosign(e)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania - US keyboard with Lithuanian letters"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ 1, exclam, aogonek, Aogonek ]}; + key <AE02> {[ 2, at, ccaron, Ccaron ]}; + key <AE03> {[ 3, numbersign, eogonek, Eogonek ]}; + key <AE04> {[ 4, dollar, eabovedot, Eabovedot ]}; + key <AE05> {[ 5, percent, iogonek, Iogonek ]}; + key <AE06> {[ 6, asciicircum, scaron, Scaron ]}; + key <AE07> {[ 7, ampersand, uogonek, Uogonek ]}; + key <AE08> {[ 8, asterisk, umacron, Umacron ]}; + key <AE09> {[ 9, parenleft, doublelowquotemark, parenleft ]}; + key <AE10> {[ 0, parenright, leftdoublequotemark, parenright ]}; + key <AE11> {[ minus, underscore, endash ]}; + key <AE12> {[ equal, plus, zcaron, Zcaron ]}; + + key <LSGT> {[ endash, EuroSign ]}; +}; + +// Lithuanian keymap LST 1582:2000 +// The standard is described at http://ims.mii.lt/klav/ +// Extensions: B01 L3 is "<" , B02 L3 is ">" and B03 L3 is endash to make this +// layout usable with pc101 and pc104 keyboards. +// +// Made by Gediminas Paulauskas <menesis@delfi.lt> +// Minor modifications by Ričardas Čepas and Rimas Kudelis + +partial alphanumeric_keys modifier_keys +xkb_symbols "std" { + + include "latin" + include "eurosign(e)" + include "nbsp(level3)" + include "kpdl(comma)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania - Standard"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ exclam, 1, at ]}; + key <AE02> {[ minus, 2, underscore ]}; + key <AE03> {[ slash, 3, numbersign ]}; + key <AE04> {[ semicolon, 4, dollar ]}; + key <AE05> {[ colon, 5, section ]}; + key <AE06> {[ comma, 6, asciicircum ]}; + key <AE07> {[ period, 7, ampersand ]}; + key <AE08> {[ equal, 8, asterisk ]}; + key <AE09> {[ parenleft, 9, bracketleft ]}; + key <AE10> {[ parenright, 0, bracketright ]}; + key <AE11> {[ question, plus, apostrophe ]}; + key <AE12> {[ x, X, percent ]}; + + key <AD01> {[ aogonek, Aogonek ]}; + key <AD02> {[ zcaron, Zcaron ]}; + key <AD11> {[ iogonek, Iogonek, braceleft ]}; + key <AD12> {[ w, W, braceright ]}; + + key <AC04> {[ scaron, Scaron ]}; + key <AC10> {[ uogonek, Uogonek ]}; + key <AC11> {[ eabovedot, Eabovedot, quotedbl ]}; + key <BKSL> {[ q, Q, bar ]}; + + key <LSGT> {[ less, greater, endash ]}; + key <AB01> {[ z, Z, less ]}; + key <AB02> {[ umacron, Umacron, greater ]}; + key <AB03> {[ c, C, endash ]}; + key <AB08> {[ ccaron, Ccaron, doublelowquotemark ]}; + key <AB09> {[ f, F, leftdoublequotemark ]}; + key <AB10> {[ eogonek, Eogonek, backslash ]}; +}; + +// Lithuanian keymap LST 1205-92 +// This standard was made deprecated by LST 1582:2000 above. +// This keyboard is also know as IBM layout. +// We follow the map shown at: http://www.registrucentras.lt/litwin/kbdlta.gif +// and info from Edis Tamošauskas <linas_lietus@yahoo.com> +// +// Made by Piter PUNK <piterpk@terra.com.br> +// Minor modifications and cleanup by Rimas Kudelis, 2010 + +partial alphanumeric_keys modifier_keys +xkb_symbols "ibm" { + + include "latin" + include "eurosign(e)" + include "nbsp(level3)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania - IBM (LST 1205-92)"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ exclam, 1 ]}; + key <AE02> {[ quotedbl, 2, at ]}; + key <AE03> {[ slash, 3, numbersign ]}; + key <AE04> {[ semicolon, 4, dollar ]}; + key <AE05> {[ colon, 5, percent ]}; + key <AE06> {[ comma, 6, asciicircum ]}; + key <AE07> {[ period, 7, ampersand ]}; + key <AE08> {[ question, 8, asterisk ]}; + key <AE09> {[ parenleft, 9 ]}; + key <AE10> {[ parenright, 0 ]}; + key <AE11> {[ underscore, minus, endash ]}; + key <AE12> {[ plus, equal ]}; + + key <AD01> {[ aogonek, Aogonek, q, Q ]}; + key <AD02> {[ zcaron, Zcaron, w, W ]}; + key <AD11> {[ iogonek, Iogonek, bracketleft, braceleft ]}; + key <AD12> {[ doublelowquotemark, leftdoublequotemark, bracketright, braceright ]}; + + key <AC10> {[ uogonek, Uogonek, semicolon, colon ]}; + key <AC11> {[ eabovedot, Eabovedot, apostrophe, quotedbl ]}; + + key <LSGT> {[ less, greater, endash ]}; + key <AB02> {[ umacron, Umacron, x, X ]}; + key <AB08> {[ ccaron, Ccaron, comma, less ]}; + key <AB09> {[ scaron, Scaron, period, greater ]}; + key <AB10> {[ eogonek, Eogonek, slash, question ]}; +}; + +// LEKP and LEKPa layouts 1.0 +// Copyright (c) 2007 Tautrimas Pajarskas +// For more info visit http://lekp.info +// +// LEKP and LEKPa layouts are licensed under the Creative Commons +// Attribution-Noncommercial-Share Alike 3.0 License. +// To view a copy of this license, visit +// http://creativecommons.org/licenses/by-nc-sa/3.0/ or send +// a letter to Creative Commons, 171 Second Street, Suite 300, +// San Francisco, California, 94105, USA. +// +// Minor cleanup by Rimas Kudelis, 2010 + +partial alphanumeric_keys modifier_keys +xkb_symbols "lekp" { + + include "capslock(backspace)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania - LEKP"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ slash, numbersign, bar ]}; + key <AE02> {[ backslash, at, section ]}; + key <AE03> {[ period, braceleft ]}; + key <AE04> {[ comma, braceright ]}; + key <AE05> {[ f, F ]}; + key <AE06> {[ exclam, endash ]}; + key <AE07> {[ w, W ]}; + key <AE08> {[ uogonek, Uogonek ]}; + key <AE09> {[ iogonek, Iogonek ]}; + key <AE10> {[ parenleft, doublelowquotemark, registered ]}; + key <AE11> {[ parenright, leftdoublequotemark, copyright ]}; + key <AE12> {[ colon, ampersand, trademark ]}; + + key <AD01> {[ q, Q, EuroSign ]}; + key <AD02> {[ g, G, 7 ]}; + key <AD03> {[ r, R, 8 ]}; + key <AD04> {[ l, L, 9 ]}; + key <AD05> {[ d, D, percent ]}; + key <AD06> {[ ccaron, Ccaron ]}; + key <AD07> {[ j, J ]}; + key <AD08> {[ u, U, period ]}; + key <AD09> {[ eabovedot, Eabovedot, minus ]}; + key <AD10> {[ eogonek, Eogonek, slash ]}; + key <AD11> {[ question, bracketleft, division ]}; + key <AD12> {[ equal, bracketright ]}; + + key <AC01> {[ a, A, 0 ]}; + key <AC02> {[ k, K, 4 ]}; + key <AC03> {[ s, S, 5 ]}; + key <AC04> {[ t, T, 6 ]}; + key <AC05> {[ m, M, dollar ]}; + key <AC06> {[ p, P ]}; + key <AC07> {[ n, N ]}; + key <AC08> {[ e, E, comma ]}; + key <AC09> {[ i, I, plus ]}; + key <AC10> {[ o, O, asterisk ]}; + key <AC11> {[ y, Y, multiply ]}; + key <BKSL> {[ apostrophe, underscore ]}; + + key <LSGT> {[ semicolon, quotedbl, sterling ]}; + key <AB01> {[ z, Z, asciicircum ]}; + key <AB02> {[ x, X, 1 ]}; + key <AB03> {[ c, C, 2 ]}; + key <AB04> {[ v, V, 3 ]}; + key <AB05> {[ zcaron, Zcaron ]}; + key <AB06> {[ scaron, Scaron ]}; + key <AB07> {[ b, B, degree ]}; + key <AB08> {[ umacron, Umacron, less ]}; + key <AB09> {[ aogonek, Aogonek, greater ]}; + key <AB10> {[ h, H ]}; +}; + +partial alphanumeric_keys modifier_keys +xkb_symbols "lekpa" { + + include "capslock(backspace)" + include "level3(ralt_switch)" + + name[Group1]="Lithuania - LEKPa"; + + key <TLDE> {[ grave, asciitilde, acute ]}; + key <AE01> {[ slash, quotedbl, bar ]}; + key <AE02> {[ backslash, at, section ]}; + key <AE03> {[ period, braceleft, numbersign ]}; + key <AE04> {[ comma, braceright, sterling ]}; + key <AE05> {[ f, F, ampersand ]}; + key <AE06> {[ exclam, endash ]}; + key <AE07> {[ w, W ]}; + key <AE08> {[ uogonek, Uogonek ]}; + key <AE09> {[ iogonek, Iogonek ]}; + key <AE10> {[ parenleft, doublelowquotemark, registered ]}; + key <AE11> {[ parenright, leftdoublequotemark, copyright ]}; + key <AE12> {[ colon, semicolon, trademark ]}; + + key <AD01> {[ q, Q, EuroSign ]}; + key <AD02> {[ g, G, 7 ]}; + key <AD03> {[ r, R, 8 ]}; + key <AD04> {[ l, L, 9 ]}; + key <AD05> {[ d, D, percent ]}; + key <AD06> {[ ccaron, Ccaron ]}; + key <AD07> {[ j, J ]}; + key <AD08> {[ u, U, period ]}; + key <AD09> {[ eabovedot, Eabovedot, minus ]}; + key <AD10> {[ eogonek, Eogonek, slash ]}; + key <AD11> {[ question, bracketleft, division ]}; + key <AD12> {[ equal, bracketright ]}; + + key <AC01> {[ a, A, 0 ]}; + key <AC02> {[ k, K, 4 ]}; + key <AC03> {[ s, S, 5 ]}; + key <AC04> {[ t, T, 6 ]}; + key <AC05> {[ m, M, dollar ]}; + key <AC06> {[ p, P ]}; + key <AC07> {[ n, N ]}; + key <AC08> {[ e, E, comma ]}; + key <AC09> {[ i, I, plus ]}; + key <AC10> {[ o, O, asterisk ]}; + key <AC11> {[ y, Y, multiply ]}; + key <BKSL> {[ apostrophe, underscore ]}; + + key <AB01> {[ z, Z, asciicircum ]}; + key <AB02> {[ x, X, 1 ]}; + key <AB03> {[ c, C, 2 ]}; + key <AB04> {[ v, V, 3 ]}; + key <AB05> {[ zcaron, Zcaron ]}; + key <AB06> {[ scaron, Scaron ]}; + key <AB07> {[ b, B, degree ]}; + key <AB08> {[ umacron, Umacron, less ]}; + key <AB09> {[ aogonek, Aogonek, greater ]}; + key <AB10> {[ h, H ]}; +}; + +partial alphanumeric_keys modifier_keys +xkb_symbols "dvorak" { + + include "us(dvorak)" + + name[Group1]="Lithuania - Dvorak"; + + key <AE01> { [ aogonek, Aogonek, 1, exclam ] }; + key <AE02> { [ ccaron, Ccaron, 2, at ] }; + key <AE03> { [ eogonek, Eogonek, 3, numbersign ] }; + key <AE04> { [ eabovedot, Eabovedot, 4, dollar ] }; + key <AE05> { [ iogonek, Iogonek, 5, percent ] }; + key <AE06> { [ scaron, Scaron, 6, asciicircum ] }; + key <AE07> { [ uogonek, Uogonek, 7, ampersand ] }; + key <AE08> { [ umacron, Umacron, 8, asterisk ] }; + key <AE09> { [doublelowquotemark, parenleft, 9, parenleft ] }; + key <AE10> { [leftdoublequotemark,parenright, 0, parenright ] }; + key <AD12> { [ zcaron, Zcaron, equal, plus ] }; + + include "level3(ralt_switch)" +}; diff --git a/xorg-server/xkeyboard-config/symbols/nbsp b/xorg-server/xkeyboard-config/symbols/nbsp index 220dae460..77b40df07 100644 --- a/xorg-server/xkeyboard-config/symbols/nbsp +++ b/xorg-server/xkeyboard-config/symbols/nbsp @@ -1,194 +1,204 @@ -// Let Space key provide No-Break Space (NBSP), Narrow No-Break Space (NNBSP),
-// Zero-Width Non-Joiner (ZWNJ), and Zero-Width Joiner (ZWJ) for the desired
-// levels.
-
-
-////////////////////////////////////////
-// Only Space
-
-partial
-xkb_symbols "none" {
- key <SPCE> {
- type[Group1]="ONE_LEVEL",
- symbols[Group1]= [ space ]
- };
-};
-
-
-////////////////////////////////////////
-// No-Break Space
-
-partial
-xkb_symbols "level2" {
- key <SPCE> {
- type[Group1]="TWO_LEVEL",
- symbols[Group1]= [ space, nobreakspace ]
- };
-};
-
-
-// level3 & level3ns provide no-breaking spaces starting from level3
-// This is good for typographers but experience shows many users accidently
-// type no-breaking spaces on the CLI (resulting in errors)
-// Used by fr(latin9) and lt(std)
-partial
-xkb_symbols "level3" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, space, nobreakspace ]
- };
-};
-
-// level3s kills fourth level
-// Used by ca(multix)
-partial
-xkb_symbols "level3s" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, space, nobreakspace, NoSymbol ]
- };
-};
-
-// for this reason pushing no-breaking spaces to level4 is the safe default nowadays
-partial
-xkb_symbols "level4" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, space, space, nobreakspace ]
- };
-};
-
-
-////////////////////////////////////////
-// Narrow No-Break Space
-
-// level3n provides narrow no-breaking space in addition to the normal one
-partial
-xkb_symbols "level3n" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, space, nobreakspace, 0x100202F ]
- };
-};
-
-// level4n provides narrow no-breaking space in addition to the normal one
-partial
-xkb_symbols "level4n" {
- key <SPCE> {
- type[Group1]="EIGHT_LEVEL",
- symbols[Group1]= [ space, space, space, nobreakspace, space, 0x100202F, NoSymbol, NoSymbol ]
- };
-};
-
-// level4nl provides narrow no-breaking space in addition to the normal one
-// without forcing the use of level5 for mostly four-level layouts
-// Used by fr(oss), be(oss)…
-partial
-xkb_symbols "level4nl" {
- key <SPCE> {
- type[Group1]="LOCAL_EIGHT_LEVEL",
- symbols[Group1]= [ space, space, space, nobreakspace, space, 0x100202F, NoSymbol, NoSymbol ]
- };
-};
-
-
-////////////////////////////////////////
-// Zero-Width Non-Joiner & Zero-Width Joiner
-// Author: Behnam Esfahbod <behnam@esfahbod.info>
-
-// ZWNJ and ZWJ are widely used in Persian, Kurdinsh, Pashto, Uzbek and other
-// languages that use PersoArabic script.
-
-
-// ZWNJ on level 2
-partial
-xkb_symbols "zwnj2" {
- key <SPCE> {
- type[Group1]="TWO_LEVEL",
- symbols[Group1]= [ space, 0x100200c ]
- };
-};
-
-
-// ZWNJ on level 2
-// ZWJ on level 3
-partial
-xkb_symbols "zwnj2zwj3" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, 0x100200d ]
- };
-};
-
-
-// ZWNJ on level 2
-// ZWJ on level 3
-// NBSP on level 4
-partial
-xkb_symbols "zwnj2zwj3nb4" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, 0x100200d, nobreakspace ]
- };
-};
-
-// ZWNJ on level 2
-// NBSP on level 3
-// Used by ir(ku_ara), af(basic), af(ps), af(uz), af(olpc-fa), af(olpc-ps), af(olpc-uz)
-partial
-xkb_symbols "zwnj2nb3" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, nobreakspace ]
- };
-};
-
-
-// ZWNJ on level 2
-// ZWJ on level 3
-// NBSP on level 4
-// Used by lk(sin_phonetic)
-partial
-xkb_symbols "zwnj2nb3s" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, nobreakspace, NoSymbol ]
- };
-};
-
-
-// ZWNJ on level 2
-// NBSP on level 3
-// ZWJ on level 4
-partial
-xkb_symbols "zwnj2nb3zwj4" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, nobreakspace, 0x100200d ]
- };
-};
-
-
-// ZWNJ on level 2
-// NBSP on level 3
-// NNBSP on level 4
-// Used by ir(pes)
-partial
-xkb_symbols "zwnj2nb3nnb4" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, 0x100200c, nobreakspace, 0x100202F ]
- };
-};
-
-
-// ZWNJ on level 3
-// ZWJ on level 4
-// Used by in(deva), in(olpc)
-partial
-xkb_symbols "zwnj3zwj4" {
- key <SPCE> {
- type[Group1]="FOUR_LEVEL",
- symbols[Group1]= [ space, space, 0x100200c, 0x100200d ]
- };
-};
+// Let Space key provide No-Break Space (NBSP), Narrow No-Break Space (NNBSP), +// Zero-Width Non-Joiner (ZWNJ), and Zero-Width Joiner (ZWJ) for the desired +// levels. + + +//////////////////////////////////////// +// Only Space + +partial +xkb_symbols "none" { + key <SPCE> { + type[Group1]="ONE_LEVEL", + symbols[Group1]= [ space ] + }; +}; + + +//////////////////////////////////////// +// No-Break Space + +partial +xkb_symbols "level2" { + key <SPCE> { + type[Group1]="TWO_LEVEL", + symbols[Group1]= [ space, nobreakspace ] + }; +}; + + +// level3 & level3ns provide no-breaking spaces starting from level3 +// This is good for typographers but experience shows many users accidently +// type no-breaking spaces on the CLI (resulting in errors) +// Used by fr(latin9) and lt(std) +partial +xkb_symbols "level3" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, space, nobreakspace ] + }; +}; + +// level3s kills fourth level +// Used by ca(multix) +partial +xkb_symbols "level3s" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, space, nobreakspace, NoSymbol ] + }; +}; + +// for this reason pushing no-breaking spaces to level4 is the safe default nowadays +partial +xkb_symbols "level4" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, space, space, nobreakspace ] + }; +}; + + +//////////////////////////////////////// +// Narrow No-Break Space + +// level3n provides narrow no-breaking space in addition to the normal one +partial +xkb_symbols "level3n" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, space, nobreakspace, 0x100202F ] + }; +}; + +// level4n provides narrow no-breaking space in addition to the normal one +partial +xkb_symbols "level4n" { + key <SPCE> { + type[Group1]="EIGHT_LEVEL", + symbols[Group1]= [ space, space, space, nobreakspace, space, 0x100202F, NoSymbol, NoSymbol ] + }; +}; + +// level4nl provides narrow no-breaking space in addition to the normal one +// without forcing the use of level5 for mostly four-level layouts +// Used by fr(oss), be(oss)… +partial +xkb_symbols "level4nl" { + key <SPCE> { + type[Group1]="LOCAL_EIGHT_LEVEL", + symbols[Group1]= [ space, space, space, nobreakspace, space, 0x100202F, NoSymbol, NoSymbol ] + }; +}; + + +//////////////////////////////////////// +// Zero-Width Non-Joiner & Zero-Width Joiner +// Author: Behnam Esfahbod <behnam@esfahbod.info> + +// ZWNJ and ZWJ are widely used in Persian, Kurdinsh, Pashto, Uzbek and other +// languages that use PersoArabic script. + + +// ZWNJ on level 2 +partial +xkb_symbols "zwnj2" { + key <SPCE> { + type[Group1]="TWO_LEVEL", + symbols[Group1]= [ space, 0x100200c ] + }; +}; + + +// ZWNJ on level 2 +// ZWJ on level 3 +partial +xkb_symbols "zwnj2zwj3" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, 0x100200d ] + }; +}; + + +// ZWNJ on level 2 +// ZWJ on level 3 +// NBSP on level 4 +partial +xkb_symbols "zwnj2zwj3nb4" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, 0x100200d, nobreakspace ] + }; +}; + +// ZWNJ on level 2 +// NBSP on level 3 +// Used by ir(ku_ara), af(basic), af(ps), af(uz), af(olpc-fa), af(olpc-ps), af(olpc-uz) +partial +xkb_symbols "zwnj2nb3" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, nobreakspace ] + }; +}; + + +// ZWNJ on level 2 +// NBSP on level 3 +partial +xkb_symbols "zwnj2nb3s" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, nobreakspace, NoSymbol ] + }; +}; + + +// ZWNJ on level 2 +// NBSP on level 3 +// ZWJ on level 4 +partial +xkb_symbols "zwnj2nb3zwj4" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, nobreakspace, 0x100200d ] + }; +}; + + +// ZWNJ on level 2 +// NBSP on level 3 +// NNBSP on level 4 +// Used by ir(pes) +partial +xkb_symbols "zwnj2nb3nnb4" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, 0x100200c, nobreakspace, 0x100202F ] + }; +}; + + +// ZWNJ on level 3 +// ZWJ on level 4 +// Used by in(deva), in(olpc) +partial +xkb_symbols "zwnj3zwj4" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, space, 0x100200c, 0x100200d ] + }; +}; + + +// NBSP on level 2 +// ZWNJ on level 3 +// Used by lk(sin_phonetic) +partial +xkb_symbols "nb2zwnj3s" { + key <SPCE> { + type[Group1]="FOUR_LEVEL", + symbols[Group1]= [ space, nobreakspace, 0x100200c, NoSymbol ] + }; +}; |